BMC discovery based on service type
Note:
1. Added test case to discover BMC based on service type
2. Added utils file to parse input string and pack it
in the form of dictionary
Change-Id: I684a40795c0b008c50532778517a78959d6ce4fd
Signed-off-by: Sushil Singh <susilsi7@in.ibm.com>
diff --git a/lib/external_intf/management_console_utils.py b/lib/external_intf/management_console_utils.py
new file mode 100644
index 0000000..b6ac2bc
--- /dev/null
+++ b/lib/external_intf/management_console_utils.py
@@ -0,0 +1,157 @@
+#!/usr/bin/env python
+
+import os
+import re
+import json
+from data import variables
+from collections import OrderedDict
+
+bmc_rec_pattern = '^=(.*)\n(.*)\n(.*)\n(.*)\n(.*)'
+bmc_prop_pattern = [r"\w+", r"\d{1,3}.\d{1,3}.\d{1,3}.\d{1,3}", '443']
+bmc_rec_prop = ['hostname', 'address', 'port', 'txt']
+
+
+class Exception(Exception):
+ def __init__(self, exc_value):
+ self.exc_value = exc_value
+
+ def __str__(self):
+ return repr(self.exc_value)
+
+
+def validate_bmc_properties(bmc_prop_pattern, bmc_prop, bmc_value,
+ bmc_rec_valid):
+ r"""
+ This function is to check pattern match in bmc properties.
+
+ Description of arguments:
+ bmc_prop_pattern Regex pattern.
+ bmc_prop BMC property (e.g. hostname, address, port).
+ bmc_value BMC property value.
+ bmc_rec_valid Contain BMC properties record.
+ """
+
+ try:
+ status = \
+ [lambda bmc_prop: re.search(bmc_prop_pattern, bmc_prob),
+ bmc_value]
+ if None in status:
+ bmc_rec_valid[bmc_prop] = None
+ except Exception as exc_obj:
+ return exc_obj
+ finally:
+ return bmc_rec_valid
+
+
+def bmc_record_validation(bmc_rec_valid):
+ r"""
+ Parse the BMC records to validate the data is valid.
+
+ Description of arguments:
+ bmc_rec_valid Contain BMC properties record.
+ """
+
+ try:
+ for bmc_prop_key, bmc_pattern_val in \
+ zip(bmc_rec_prop, bmc_prop_pattern):
+ bmc_prop_value = bmc_rec_valid.get(bmc_prop_key, False)
+ if bmc_rec_valid[bmc_prop_key] is not False:
+ valid_status = validate_bmc_properties(bmc_pattern_val,
+ bmc_prop_key,
+ bmc_prop_value,
+ bmc_rec_valid)
+ if None not in bmc_rec_valid.values():
+ return bmc_rec_valid
+ else:
+ return None
+ except Exception as exc_obj:
+ return exc_obj
+
+
+def bmc_inventory(service_type, bmc_inv_record):
+ r"""
+ Parse single record of BMC inventory and pack to dictionary form.
+
+ Description of arguments:
+ service_type Service type (e.g. _obmc_rest._tcp, _obmc_redfish._tcp).
+ bmc_inv_record Individual BMC inventory record.
+
+ This function will return this variable i.e.
+ bmc_inv in dictionary form as mention below.
+
+ Below are the discovered BMC detail.
+
+ [service]: _obmc_XXXX._tcp
+ [hostname]: System Name
+ [address]: XXX.XXX.XXX.XXX
+ [port]: XXX
+ [txt]:
+ """
+
+ try:
+ exc_obj = None
+ bmc_inv = OrderedDict()
+ service_count = 0
+ for line in bmc_inv_record.split('\n'):
+ if line == "":
+ pass
+ elif service_type in line:
+ bmc_inv['service'] = service_type
+ service_count += 1
+ elif not line.startswith('=') and service_count == 1:
+ bmc_inv[line.split('=')[0].strip()] = \
+ str(line.split('=')[-1].strip())[1:-1]
+ except Exception as exc_obj:
+ return exc_obj
+ finally:
+ valid_status = bmc_record_validation(bmc_inv)
+ if valid_status is None:
+ return None, exc_obj
+ else:
+ return valid_status, exc_obj
+
+
+def get_bmc_records(service_type, bmc_records):
+ r"""
+ Parse the string to filter BMC discovery.
+
+ Description of arguments:
+ service_type Service type (e.g. RESTService, RedfishService).
+ bmc_records Contains the lis of discoverd BMC records.
+
+ This function will return this variable i.e.
+ bmc_inv_list in dictionary form as mention below.
+
+ Below are the list of discovered BMC details.
+ [1]:
+ [service]: _obmc_XXXX._tcp
+ [hostname]: System Name
+ [address]: XXX.XXX.XXX.XXX
+ [port]: XXX
+ [txt]:
+ [2]:
+ [service]: _obmc_XXXX._tcp
+ [hostname]: System Name
+ [address]: XXX.XXX.XXX.XXX
+ [port]: XXX
+ [txt]:
+ """
+
+ try:
+ count = 0
+ exe_obj = None
+ bmc_inv_list = OrderedDict()
+ for match in re.finditer(bmc_rec_pattern, bmc_records,
+ re.MULTILINE):
+ bmc_record, exc_msg = \
+ bmc_inventory(service_type, match.group())
+ if bmc_record is not None and exc_msg is None:
+ count += 1
+ bmc_inv_list[count] = bmc_record
+ except Exception as exe_obj:
+ return exe_obj
+ finally:
+ if len(bmc_inv_list) == 0:
+ '', exe_obj
+ else:
+ return bmc_inv_list, exe_obj
diff --git a/openpower/ext_interfaces/test_discovery.robot b/openpower/ext_interfaces/test_discovery.robot
new file mode 100644
index 0000000..20410f8
--- /dev/null
+++ b/openpower/ext_interfaces/test_discovery.robot
@@ -0,0 +1,75 @@
+*** Settings ***
+Documentation Test to discover the BMC.
+
+Variables ../../data/variables.py
+Library SSHLibrary
+Library ../../lib/external_intf/management_console_utils.py
+Library ../../lib/gen_robot_print.py
+Library ../../lib/gen_print.py
+Resource ../../syslib/utils_os.robot
+
+Suite Setup Suite Setup Execution
+
+*** Test Cases ***
+
+Discover BMC With Different Service Type
+ [Documentation] Discover all the BMC with different service type support.
+ [Tags] Discover_BMC_With_Different_Service_Type
+ [Template] Discover BMC With Service Type
+
+ # Service type
+ _obmc_rest._tcp
+ _obmc_redfish._tcp
+
+
+*** Keywords ***
+
+Suite Setup Execution
+ [Documentation] Do the suite setup.
+
+ Should Not Be Empty ${AVAHI_CLIENT}
+ Should Not Be Empty ${AVAHI_CLIENT_USERNAME}
+ Should Not Be Empty ${AVAHI_CLIENT_PASSWORD}
+ Login To OS ${AVAHI_CLIENT} ${AVAHI_CLIENT_USERNAME} ${AVAHI_CLIENT_PASSWORD}
+ Check Avahi Package
+
+
+Check Avahi Package
+ [Documentation] To check for avahi-tools package.
+
+ # Expected command output as below.
+ # avahi-tools-0.6.31-19.el7.x86_64
+
+ ${command}= Set Variable rpm -qa | grep avahi-tools
+ ${resp_rpm} ${stderr}= Execute Command ${command} return_stderr=True
+ Should Be Empty ${stderr}
+ Should Contain ${resp_rpm} avahi-tools ignore_case=True msg=avahi-tools is not available.
+
+
+Discover BMC With Service Type
+ [Documentation] To get the discoverd BMC list.
+ [Arguments] ${service_type}
+
+ # Description of argument(s):
+ # service_type BMC service type e.g.
+ # (REST Service = _obmc_rest._tcp, Redfish Service = _obmc_redfish._tcp).
+
+ # bmc_list:
+ # [1]:
+ # [service]: _obmc_XXXX._tcp
+ # [hostname]: System Name
+ # [address]: XXX.XXX.XXX.XXX
+ # [port]: XXX
+ # [txt]:
+ # [2]:
+ # [service]: _obmc_XXXX._tcp
+ # [hostname]: System Name
+ # [address]: XXX.XXX.XXX.XXX
+ # [port]: XXX
+ # [txt]:
+
+ ${resp_service} ${stderr}= Execute Command avahi-browse -rt ${service_type} return_stderr=True
+ ${bmc_list} ${exc_msg}= Get BMC Records ${service_type} ${resp_service}
+ Print Timen Exception message is ${exc_msg}
+ Should Not Be Empty ${bmc_list}
+ Rprint Vars bmc_list