blob: 25d28ae84034e21cfd71a685ee5459c9ec298260 [file] [log] [blame]
#!/usr/bin/python
"""
Copyright 2018-present Open Networking Foundation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""
"""
:Description: Module for fetching OLT information.
This module is used to fetch OLT software and hardware information.
The OLT software information includes Operating system, OS Version,
and ONIE version.
The hardware information includes OLT Serial Number, OLT Hardware Model,
Vendor ID, OLT Hardware Part Number and In-band interfaces MAC addresses.
The gathered information will be output to the screen as a json string.
When passed through a JSON processor (like jq) the output would look
like below(sample output, the keys remain same and values change based on
OLT model and binary versions)
{
"hardware_information": {
"vendor": "Accton",
"hw_part_number": "FN1EC0816400Z",
"hw_version": "0.0.0.3",
"inband_interface": "34:12:78:56:01:00",
"hw_model": "ASXvOLT16-O-AC-F",
"serial_number": "EC1729003537"
},
"software_information": {
"onie_version": "2017.02.00.06",
"os_version": "3.7.10",
"os_name": "OpenNetworkLinux",
"openolt_version": "2.0.0",
"bal_version": "2.6.0.1"
}
}
This script exits with exit code 0 in case of success and 1 in case of failure.
"""
import os
import re
import json
import syslog
import yaml
# dictionary containing OLT information with hardware_information and
# software_information as keys and holds the respective data values
OLT_INFORMATION = {}
# Path where BAL libraries, configuration files, bal_core_dist
# and openolt binaries are located.
BRCM_DIR = '/broadcom'
# Path to inband config file
INBAND_CONFIG_FILE = BRCM_DIR+"/inband.config"
# Operating system name which is running at OLT.
# By default Open Network Linux (ONL) is used as operating
# system at OLT
OS_NAME = 'OpenNetworkLinux'
# BAL library version running at OLT
# openOLT version from OLT when available
OPENOLT_VERSION = " "
# in-band interface incase of device asgvolt64
ETH_1 = 'eth1'
# in-band interface incase of device asfvolt16
ETH_2 = 'eth2'
# Constants for the name of the keys in the JSON being printed
VENDOR = "vendor"
SERIAL_NUMBER = "serial_number"
HARDWARE_MODEL = "hw_model"
HARDWARE_PART_NUMBER = "hw_part_number"
HARDWARE_VERSION = "hw_version"
OPERATING_SYSTEM = "os_name"
OPERATING_SYSTEM_VERSION = "os_version"
ONIE_VERSION = "onie_version"
SOFTWARE_INFORMATION = "software_information"
HARDWARE_INFORMATION = "hardware_information"
INBAND_INTERFACE = "inband_interface"
BAL_VER = "bal_version"
OPENOLT_VER = "openolt_version"
OLT_MODEL=None
ASX_16 = "ASXvOLT16"
ASG_64 = "ASGvOLT64"
# log to syslog
syslog.openlog(facility=syslog.LOG_SYSLOG)
def get_olt_board_name():
"""
Reads the bal package name
This function fetchs bal package whether asfvolt16 or asgvolt64
:return : packge names if successful and None in case of failure.
:rtype : tuple of package name in case of success, else None in case of failure.
"""
try:
OLT_MODEL = os.popen("cat /sys/devices/virtual/dmi/id/board_name").read().strip("\n")
syslog.syslog(syslog.LOG_INFO, "successfully-read-olt-board-name")
return OLT_MODEL
except (IOError, NameError) as exception:
syslog.syslog(syslog.LOG_ERR, "error-executing-command-{}".format(exception))
return None
def retrieve_vlan_id():
"""
Retrieves VLAN ids of in-band interfaces.
This function fetchs vlan ids from OLT /broadcom/bal_config.ini file.
:return : vlan id of in-band interface if successfull and None in case of failure.
:rtype : integer(valid vlan_id) in case of success, else None in case of failure.
"""
eth_vlan = None
# retrieving vlan ids based on the below two keys in bal_config.ini
asf16_vlan = 'asfvolt16_vlan_id_eth2'
asg64_vlan = 'asgvolt64_vlan_id_eth1'
olt_model=get_olt_board_name()
try:
if os.path.exists(INBAND_CONFIG_FILE):
with open(INBAND_CONFIG_FILE, "r") as file_descriptor:
lines = file_descriptor.readlines()
for line in lines:
if olt_model == ASX_16:
if re.search(asf16_vlan, line):
eth_vlan = int(line.split('=')[1].strip())
elif olt_model == ASG_64:
if re.search(asg64_vlan, line):
eth_vlan = int(line.split('=')[1].strip())
else:
syslog.syslog(syslog.LOG_ERR, "{}-file-does-not-exist".format(INBAND_CONFIG_FILE))
return None, None
except(EnvironmentError, re.error) as exception:
syslog.syslog(syslog.LOG_ERR, "error-retreving-vlan-ids-{}".format(exception))
return None, None
if eth_vlan > 4094 or eth_vlan < 1:
syslog.syslog(syslog.LOG_ERR, "vlan-id-not-in-range-{}-{}".format(eth_vlan, eth_vlan_2))
return None, None
return eth_vlan
def get_olt_basic_info():
"""
Fetch OLT basic information
This function retireves OLT's basic information using the command 'onlpdump -s'
:return: OLT's basic info in case of success and None in case of failure
:rtype: json if success and None if failure
"""
# fetch OLT basic information
try:
olt_info = os.popen('onlpdump -s').read()
out = yaml.dump(yaml.load(olt_info)['System Information'])
json_data = json.dumps(yaml.load(out))
data = json.loads(json_data)
except (IOError, TypeError, ValueError, yaml.YAMLError, yaml.MarkedYAMLError) as exception:
syslog.syslog(syslog.LOG_ERR, "error-fetching-olt-information-{}".format(exception))
return None
return data
def get_bal_openolt_version():
"""
Fetch bal and openolt version
This function retireves OLT's basic information using the command 'onlpdump -s'
:return : bal and openolt version if successfull and None in case of failure.
:rtype : tuple of bal and opneolt version in case of success, else None in case of failure.
"""
try:
os.chdir('/')
os.environ["LD_LIBRARY_PATH"] = "."
version_string = os.popen("./broadcom/openolt --version").read()
version_tuple = tuple(version_string.split("\n"))
openolt_v = version_tuple[0].split(":")
OPENOLT_VERSION = openolt_v[1].split(" ")
bal_v = version_tuple[1].split(":")
BAL_VERSION = bal_v[1].split(" ")
return OPENOLT_VERSION[1], BAL_VERSION[1]
except (IOError, NameError) as exception:
syslog.syslog(syslog.LOG_ERR, "error-executing-command-{}".format(exception))
return None, None
def fetch_olt_info():
"""
Gather OLT software and hardware information.
This function gather OLT information and returns OLT
software and hardware information.
:return: OLT's software and hardware information in case of successful execution
and returns None in case of failure
:rtype: JSON string in case of success and None in case of failure.
"""
hw_facts = {}
sw_facts = {}
# fetch olt basic information
data = get_olt_basic_info()
if data is None:
return None
olt_model=get_olt_board_name()
# retrieving VLAN ids of in-band interfaces
vlan = retrieve_vlan_id()
try:
if vlan is not None:
# Retreiving MAC address for in-band interfaces
if olt_model == ASX_16:
macaddr = os.popen("ifconfig " + ETH_2 + "." + str(vlan) +
" | grep -Po 'HWaddr " + r"\K.*$'").read().strip()
elif olt_model == ASG_64:
macaddr = os.popen("ifconfig " + ETH_1 + "." + str(vlan) +
" | grep -Po 'HWaddr " + r"\K.*$'").read().strip()
else:
return None
# get the operating system version details from olt
operating_sys = os.popen("uname -a").read()
os_tuple = tuple(operating_sys.split(" "))
os_and_version = os_tuple[2].split("-")
os_version = os_and_version[0]
except (IOError, NameError) as exception:
syslog.syslog(syslog.LOG_ERR, "error-executing-command-{}".format(exception))
return None
openolt_v, bal_v = get_bal_openolt_version()
# adding OLT hardware details to dictionary
try:
# adding OLT's in-band interfaces mac addresses
hw_facts[INBAND_INTERFACE] = macaddr
hw_facts[VENDOR] = data.get("Manufacturer", "")
hw_facts[SERIAL_NUMBER] = data.get("Serial Number", "")
hw_facts[HARDWARE_MODEL] = data.get("Product Name", "")
hw_facts[HARDWARE_PART_NUMBER] = data.get("Part Number", "")
hw_facts[HARDWARE_VERSION] = data.get("Diag Version", "")
# adding OLT software details to dictionary
sw_facts[OPERATING_SYSTEM] = OS_NAME
sw_facts[OPERATING_SYSTEM_VERSION] = os_version
sw_facts[ONIE_VERSION] = data.get('ONIE Version', "")
sw_facts[BAL_VER] = bal_v
sw_facts[OPENOLT_VER] = openolt_v
# adding OLT hardware and software information to OLT_INFORMATION dictionary
OLT_INFORMATION[SOFTWARE_INFORMATION] = sw_facts
OLT_INFORMATION[HARDWARE_INFORMATION] = hw_facts
# converting OLT information to json object
olt_json_string = json.dumps(OLT_INFORMATION)
except (TypeError, NameError) as exception:
syslog.syslog(syslog.LOG_ERR, "error-serializing-to-json-data-{}".format(exception))
return None
return olt_json_string
if __name__ == "__main__":
str_data = fetch_olt_info()
if str_data is not None:
print(str_data)
syslog.syslog(syslog.LOG_INFO, "successfull-execution-printing-OLT-information")
exit(0)
else:
print("error-occurred-exiting")
syslog.syslog(syslog.LOG_ERR, "error-occurred-exiting")
exit(1)