コード例 #1
0
def load_ucs_manager_config():
    """
        loads the test configuration into the UCS Manger
        """
    logs.info_1('Loading UCSPE emulator from {0}'.format(
        fit_common.fitcfg()['ucsm_config_file']))

    try:
        handle = ucshandle.UcsHandle(UCSM_IP, UCSM_USER, UCSM_PASS)
        if not handle.login():
            logs.error('Failed to log into UCS Manger!')
            return False
    except Exception as e:
        logs.info_1("error trying to log into UCS Manger!")
        logs.info_1(str(e))
        return False

    # now try to update the UCSPE config, if this fails we can still continue
    try:
        path, file = os.path.split(fit_common.fitcfg()['ucsm_config_file'])
        import_ucs_backup(handle, file_dir=path, file_name=file)
    except Exception as e:
        logs.info_1("error trying to configure UCSPE, continuing to test")
        logs.info_1(str(e))
        # log the error but do not return a failure, we can still run some tests with the default config

    if not handle.logout():
        logs.error('Failed to log out of UCS Manger during exit!')
        return False

    return True
コード例 #2
0
ファイル: test_rackhd_api_ucs.py プロジェクト: changev/RackHD
def load_ucs_manager_config():
        """
        loads the test configuration into the UCS Manger
        """
        logs.info_1('Loading UCSPE emulator from {0}'.format(fit_common.fitcfg()['ucsm_config_file']))

        try:
            handle = ucshandle.UcsHandle(UCSM_IP, UCSM_USER, UCSM_PASS)
            if not handle.login():
                logs.error('Failed to log into UCS Manger!')
                return False
        except Exception as e:
            logs.info_1("error trying to log into UCS Manger!")
            logs.info_1(str(e))
            return False

        # now try to update the UCSPE config, if this fails we can still continue
        try:
            path, file = os.path.split(fit_common.fitcfg()['ucsm_config_file'])
            import_ucs_backup(handle, file_dir=path, file_name=file)
        except Exception as e:
            logs.info_1("error trying to configure UCSPE, continuing to test")
            logs.info_1(str(e))
            # log the error but do not return a failure, we can still run some tests with the default config

        if not handle.logout():
            logs.error('Failed to log out of UCS Manger during exit!')
            return False

        return True
コード例 #3
0
def is_ucs_valid():
    if UCSM_IP is None:
        logs.error("Expected value for UCSM_IP other then None and found {0}".format(UCSM_IP))
        return False
    if UCS_SERVICE_URI is None:
        logs.error("Expected value for UCS_SERVICE_URI other then None and found {0}".format(UCS_SERVICE_URI))
        return False

    if "ucsm_config_file" in fit_common.fitcfg():
        # configure the UCSPE emulator
        if not load_ucs_manager_config():
            # error configureing UCSPE emulaotr, skip all tests
            logs.error("Error Configuring UCSPE emulator, skipping all UCS tests")
            return False

        # wait up to 2 min for config to be valid
        timeout = 120
        ucsCount = get_physical_server_count()
        while (ucsCount) != EXPECTED_UCS_PHYSICAL_NODES:
            if timeout <= 0:
                logs.error("Only found {0} of {1} nodes, skipping all UCS tests"
                           .format(ucsCount, EXPECTED_UCS_PHYSICAL_NODES))
                return False
            logs.info_1("Only found {0} of {1} ucs nodes, retrying in 30 seconds"
                        .format(ucsCount, EXPECTED_UCS_PHYSICAL_NODES))
            timeout -= 5
            time.sleep(5)
            ucsCount = get_physical_server_count()
    return True
コード例 #4
0
ファイル: test_rackhd_api_ucs.py プロジェクト: changev/RackHD
    def test_check_ucs_params(self):
        self.assertNotEqual(UCSM_IP, None, "Expected value for UCSM_IP other then None and found {0}"
                            .format(UCSM_IP))
        self.assertNotEqual(UCS_SERVICE_URI, None,
                            "Expected value for UCS_SERVICE_URI other then None and found {0}"
                            .format(UCS_SERVICE_URI))

        if "ucsm_config_file" in fit_common.fitcfg():
            # configure the UCSPE emulator
            if not load_ucs_manager_config():
                # error configureing UCSPE emulaotr, skip all tests
                raise unittest.SkipTest("Error Configuring UCSPE emulator, skipping all UCS tests")

            # wait up to 2 min for config to be valid
            timeout = 120
            ucsCount = self.get_physical_server_count()
            while (ucsCount) != self.EXPECTED_UCS_PHYSICAL_NODES:
                if timeout <= 0:
                    raise unittest.SkipTest("Only found {0} of {1} nodes, skipping all UCS tests"
                                            .format(ucsCount, self.EXPECTED_UCS_PHYSICAL_NODES))
                logs.info_1("Only found {0} of {1} ucs nodes, retrying in 30 seconds"
                            .format(ucsCount, self.EXPECTED_UCS_PHYSICAL_NODES))
                timeout -= 5
                time.sleep(5)
                ucsCount = self.get_physical_server_count()
コード例 #5
0
ファイル: ucs_common.py プロジェクト: PengTian0/RackHD
def is_ucs_valid():
    if UCSM_IP is None:
        logs.error("Expected value for UCSM_IP other then None and found {0}".format(UCSM_IP))
        return False
    if UCS_SERVICE_URI is None:
        logs.error("Expected value for UCS_SERVICE_URI other then None and found {0}".format(UCS_SERVICE_URI))
        return False

    if "ucsm_config_file" in fit_common.fitcfg():
        # configure the UCSPE emulator
        if not load_ucs_manager_config():
            # error configureing UCSPE emulaotr, skip all tests
            logs.error("Error Configuring UCSPE emulator, skipping all UCS tests")
            return False

        # wait up to 2 min for config to be valid
        timeout = 120
        ucsCount = get_physical_server_count()
        while (ucsCount) != EXPECTED_UCS_PHYSICAL_NODES:
            if timeout <= 0:
                logs.error("Only found {0} of {1} nodes, skipping all UCS tests"
                           .format(ucsCount, EXPECTED_UCS_PHYSICAL_NODES))
                return False
            logs.info_1("Only found {0} of {1} ucs nodes, retrying in 30 seconds"
                        .format(ucsCount, EXPECTED_UCS_PHYSICAL_NODES))
            timeout -= 5
            time.sleep(5)
            ucsCount = get_physical_server_count()
    return True
コード例 #6
0
    def test_check_ucs_params(self):
        self.assertNotEqual(
            UCSM_IP, None,
            "Expected value for UCSM_IP other then None and found {0}".format(
                UCSM_IP))
        self.assertNotEqual(
            UCS_SERVICE_URI, None,
            "Expected value for UCS_SERVICE_URI other then None and found {0}".
            format(UCS_SERVICE_URI))

        if "ucsm_config_file" in fit_common.fitcfg():
            # configure the UCSPE emulator
            if not load_ucs_manager_config():
                # error configureing UCSPE emulaotr, skip all tests
                raise unittest.SkipTest(
                    "Error Configuring UCSPE emulator, skipping all UCS tests")

            # wait up to 2 min for config to be valid
            timeout = 120
            ucsCount = self.get_physical_server_count()
            while (ucsCount) != self.EXPECTED_UCS_PHYSICAL_NODES:
                if timeout <= 0:
                    raise unittest.SkipTest(
                        "Only found {0} of {1} nodes, skipping all UCS tests".
                        format(ucsCount, self.EXPECTED_UCS_PHYSICAL_NODES))
                logs.info_1(
                    "Only found {0} of {1} ucs nodes, retrying in 30 seconds".
                    format(ucsCount, self.EXPECTED_UCS_PHYSICAL_NODES))
                timeout -= 5
                time.sleep(5)
                ucsCount = self.get_physical_server_count()
コード例 #7
0
import unittest
from common import fit_common
import time
from nosedep import depends
import flogging
from nose.plugins.attrib import attr
from config.settings import get_ucs_cred
from ucsmsdk import ucshandle
from ucsmsdk.utils.ucsbackup import import_ucs_backup
import os

logs = flogging.get_loggers()

INITIAL_NODES = {}
INITIAL_OBMS = {}
UCSM_IP = fit_common.fitcfg().get('ucsm_ip')
UCSM_USER, UCSM_PASS = get_ucs_cred()
UCS_SERVICE_URI = fit_common.fitcfg().get('ucs_service_uri')


def get_nodes_utility():
    """
    Takes inventory of the nodes available before discovering the UCS nodes.
    We will restore the nodes collection to this snapshot
    :return: return False on failure, or True otherwise
    """
    api_data = fit_common.rackhdapi('/api/2.0/nodes')
    if api_data['status'] != 200:
        logs.error(
            "get /api/2.0/nodes returned status {}, expected 200".format(
                api_data['status']))
コード例 #8
0
class rackhd20_ucs_redfish_api(unittest.TestCase):

    def validate_simple_storage_data(self, body, url):
        """
        Validate simple storage non-empty data body
        """
        errData = ''
        schema = {
            "str": ["Name", "Id", "Description"],
            "list": ["Devices"]
        }
        errStr = ucs_common.validate_redfish_data_payload(body, schema, url)
        if errStr:
            errData += errStr
        if not re.compile('^\w{0,}_\w{1,3}_\w{1,}_\w{1}$').match(body['Id']):
            errData += "Invalid simpleStorage Id \"{}\" for {}, \n".format(body['Id'], url)
        return errData

    @classmethod
    def setUpClass(cls):
        if not ucs_common.get_nodes_utility():
            raise Exception("error getting node list")
        if not ucs_common.get_obms_utility():
            raise Exception("error getting obms list")

    @classmethod
    def tearDownClass(cls):
        if not ucs_common.restore_node_utility():
            raise Exception("error restoring node list")
        if not ucs_common.restore_obms_utility():
            raise Exception("error restoring obms list")

    @unittest.skipUnless("ucsm_ip" in fit_common.fitcfg(), "")
    def test_check_ucs_params(self):
        if not ucs_common.is_ucs_valid():
            raise unittest.SkipTest("Ucs parameters are not valid or UCSPE emulator is not ready, skipping all UCS tests")

    @depends(after=test_check_ucs_params)
    def test_api_20_ucs_discovery(self):
        """
        Tests the UCS Discovery workflow in rackHD
        :return:
        """
        initialNodeCount = len(ucs_common.get_ucs_node_list())
        data_payload = {
            "name": "Graph.Ucs.Discovery",
            "options": {
                "defaults": {
                    "username": ucs_common.UCSM_USER,
                    "password": ucs_common.UCSM_PASS,
                    "ucs": ucs_common.UCSM_IP,
                    "uri": ucs_common.UCS_SERVICE_URI
                },
                "when-discover-logical-ucs": {
                    "discoverLogicalServer": "false"
                }
            }
        }

        expected_ucs_physical_nodes = ucs_common.get_physical_server_count()
        header = {"Content-Type": "application/json"}
        api_data = fit_common.rackhdapi("/api/2.0/workflows", action="post",
                                        headers=header, payload=data_payload)
        id = api_data["json"]["context"]["graphId"]
        self.assertEqual(api_data['status'], 201,
                         'Incorrect HTTP return code, expected 201, got:' + str(api_data['status']))
        status = ucs_common.wait_utility(str(id), 0, "Discovery")
        self.assertEqual(status, 'succeeded', 'Discovery graph returned status {}'.format(status))

        newNodeCount = len(ucs_common.get_ucs_node_list())
        logs.info_1("Found {0} Nodes after cataloging the UCS".format(len(api_data['json'])))

        self.assertEqual(newNodeCount - initialNodeCount,
                         expected_ucs_physical_nodes,
                         'Expected to discover {0} UCS nodes, got: {1}'
                         .format(expected_ucs_physical_nodes, newNodeCount - initialNodeCount))

    @depends(after=[test_api_20_ucs_discovery])
    def test_api_redfish_chassis(self):
        """
        Tests the redfish /Chassis APIs with UCS nodes
        :return:
        """
        ucsEnclList = ucs_common.get_ucs_encl_id_list()
        errUrls = ''

        api_data = fit_common.rackhdapi('/redfish/v1/Chassis')
        self.assertEqual(api_data['status'], 200,
                         'Incorrect HTTP return code, expected 200, got:' + str(api_data['status']))
        for chassis in api_data['json']['Members']:
            url = chassis['@odata.id']
            id = url[len('/redfish/v1/Chassis/'):]
            if id in ucsEnclList:
                ucsEnclList.remove(id)
                api_data = fit_common.rackhdapi(url)
                if api_data['status'] != 200:
                    errUrls += url + ' returned status ' + str(api_data['status']) + ',\n'
                _body = api_data['json']
                schema = {
                    "str": ["Name", "ChassisType", "Manufacturer", "Model",
                            "SerialNumber", "IndicatorLED"],
                    "dict": ["Thermal", "Power", "Links"]
                }
                errData = ucs_common.validate_redfish_data_payload(_body, schema, url)
                if errData:
                    errUrls += errData
        self.assertEqual(len(ucsEnclList), 0, 'not all UCS chassis were listed under /chassis')
        self.assertEqual(len(errUrls), 0, errUrls)

    @depends(after=[test_api_redfish_chassis])
    def test_api_redfish_chassis_thermal(self):
        """
        Tests the redfish /Chassis/{identifier}/Thermal APIs with UCS nodes
        :return:
        """
        ucsEnclList = ucs_common.get_ucs_encl_id_list()
        errUrls = ''
        for chassis in ucsEnclList:
            url = '/redfish/v1/Chassis/{}/Thermal'.format(chassis)
            api_data = fit_common.rackhdapi(url)
            if api_data['status'] != 200:
                errUrls += url + ' returned status ' + str(api_data['status']) + ',\n'
        self.assertEqual(len(errUrls), 0, errUrls)

    @depends(after=[test_api_redfish_chassis])
    def test_api_redfish_chassis_power(self):
        """
        Tests the redfish /Chassis/{identifier}/Power APIs with UCS nodes
        :return:
        """
        ucsEnclList = ucs_common.get_ucs_encl_id_list()
        errUrls = ''
        for chassis in ucsEnclList:
            url = '/redfish/v1/Chassis/{}/Power'.format(chassis)
            api_data = fit_common.rackhdapi(url)
            if api_data['status'] != 200:
                errUrls += url + ' returned status ' + str(api_data['status']) + ',\n'
        self.assertEqual(len(errUrls), 0, errUrls)

    @depends(after=[test_api_20_ucs_discovery])
    def test_api_redfish_system(self):
        """
        Tests the redfish /Systems APIs with UCS nodes
        :return:
        """
        ucsComputeList = ucs_common.get_ucs_compute_id_list()
        errUrls = ''

        api_data = fit_common.rackhdapi('/redfish/v1/Systems')
        self.assertEqual(api_data['status'], 200,
                         'Incorrect HTTP return code, expected 200, got:' + str(api_data['status']))
        for chassis in api_data['json']['Members']:
            url = chassis['@odata.id']
            id = url[len('/redfish/v1/Systems/'):]
            if id in ucsComputeList:
                ucsComputeList.remove(id)
                api_data = fit_common.rackhdapi(url)
                if api_data['status'] != 200:
                    errUrls += url + ' returned status ' + str(api_data['status']) + ',\n'
                _body = api_data['json']
                schema = {
                    "str": ["Name", "SystemType", "Manufacturer", "Model", "SerialNumber",
                            "IndicatorLED", "PowerState", "BiosVersion"],
                    "dict": ["ProcessorSummary", "MemorySummary", "Actions", "Processors",
                             "EthernetInterfaces", "SimpleStorage", "LogServices",
                             "Links", "Storage"]
                }
                errData = ucs_common.validate_redfish_data_payload(_body, schema, url)
                if errData:
                    errUrls += errData
        self.assertEqual(len(ucsComputeList), 0, 'not all UCS computes were listed under /System')
        self.assertEqual(len(errUrls), 0, errUrls)

    @depends(after=[test_api_redfish_system])
    def test_api_redfish_processor(self):
        """
        Tests the /Systems/{identifier}/processors APIs with UCS nodes
        :return:
        """
        ucsComputeList = ucs_common.get_ucs_compute_id_list()
        errUrls = ''

        for node in ucsComputeList:
            url = "/redfish/v1/Systems/{}/Processors".format(node)
            api_data = fit_common.rackhdapi(url)
            if api_data['status'] != 200:
                errUrls += url + ' returned status ' + str(api_data['status']) + \
                    ', Expected 200,\n'
                continue
            if len(api_data['json']['Members']) == 0:
                errUrls += url + ' CPU count is 0,\n'
                continue
            for member in api_data['json']['Members']:
                _url = member['@odata.id']
                _api_data = fit_common.rackhdapi(_url)
                if _api_data['status'] != 200:
                    errUrls += _url + ' returned status ' + str(api_data['status']) + \
                        ', Expected 200,\n'
                _body = _api_data['json']
                schema = {
                    "str": ["Socket", "ProcessorType", "ProcessorArchitecture",
                            "InstructionSet", "Manufacturer", "Model"],
                    "int": ["MaxSpeedMHz", "TotalCores", "TotalThreads"]
                }
                errData = ucs_common.validate_redfish_data_payload(_body, schema, url)
                if errData:
                    errUrls += errData
        self.assertEqual(len(errUrls), 0, errUrls)

    @depends(after=[test_api_redfish_system])
    def test_api_redfish_simple_storage(self):
        """
        Tests the redfish /Systems/{identifier}/simpleStorage APIs with UCS nodes
        :return:
        """
        ucsComputeList = ucs_common.get_ucs_compute_id_list()
        errUrls = ''

        for node in ucsComputeList:
            url = "/redfish/v1/Systems/{}/SimpleStorage".format(node)
            api_data = fit_common.rackhdapi(url)
            if api_data['status'] != 200:
                errUrls += url + ' returned status ' + str(api_data['status']) + \
                    ', Expected 200,\n'
                continue
            for member in api_data['json']['Members']:
                _url = member['@odata.id']
                _api_data = fit_common.rackhdapi(_url)
                if _api_data['status'] != 200:
                    errUrls += _url + ' returned status ' + str(api_data['status']) + \
                        ', Expected 200,\n'
                _body = _api_data['json']
                errData = self.validate_simple_storage_data(_body, _url)
                if errData:
                    errUrls += errData
        self.assertEqual(len(errUrls), 0, errUrls)
コード例 #9
0
class rackhd_ucs_api(unittest.TestCase):

    MAX_WAIT = 180
    INITIAL_CATALOGS = {}
    UCS_NODES = []
    UCS_COMPUTE_NODES = []
    EXPECTED_UCS_PHYSICAL_NODES = 22
    EXPECTED_UCS_LOGICAL_NODES = 18

    @classmethod
    def setUpClass(cls):
        if not get_nodes_utility():
            raise Exception("error getting node list")
        if not get_obms_utility():
            raise Exception("error getting obms list")

    @classmethod
    def tearDownClass(cls):
        if not restore_node_utility():
            raise Exception("error restoring node list")
        if not restore_obms_utility():
            raise Exception("error restoring obms list")

    def get_physical_server_count(self):
        """
        Get a count of the number of Service Proviles defined by the UCS Manager
        """
        url = UCS_SERVICE_URI + "/rackmount"

        headers = {"ucs-user": UCSM_USER,
                   "ucs-password": UCSM_PASS,
                   "ucs-host": UCSM_IP}

        api_data = fit_common.restful(url, rest_headers=headers)
        self.assertEqual(api_data['status'], 200,
                         'Incorrect HTTP return code, expected 200, got:' + str(api_data['status']))

        count = len(api_data["json"])

        url = UCS_SERVICE_URI + "/chassis"
        api_data = fit_common.restful(url, rest_headers=headers)
        self.assertEqual(api_data['status'], 200,
                         'Incorrect HTTP return code, expected 200, got:' + str(api_data['status']))

        count += len(api_data["json"])
        for element in api_data["json"]:
            count += len(element["members"])

        return count

    def get_service_profile_count(self):
        """
        Get a count of the number of Service Proviles defined by the UCS Manager
        """
        url = UCS_SERVICE_URI + "/serviceProfile"
        headers = {"ucs-user": UCSM_USER,
                   "ucs-password": UCSM_PASS,
                   "ucs-host": UCSM_IP}

        api_data = fit_common.restful(url, rest_headers=headers)
        self.assertEqual(api_data['status'], 200,
                         'Incorrect HTTP return code, expected 200, got:' + str(api_data['status']))

        return len(api_data["json"]["ServiceProfile"]["members"])


    def wait_utility(self, id, counter, name):
        """
        Recursevily wait for the ucs discovery workflow to finish
        :param id:  Graph ID
        :param counter: Safeguard for the number of times we can check the status of the graph
        :param name: Description of graph we are waiting for
        :return: returns status of the taskgraph, or "timeout" if count is exceeded
        """
        api_data = fit_common.rackhdapi('/api/2.0/workflows/' + str(id))
        status = api_data["json"]["status"]
        if status == "running" and counter < self.MAX_WAIT:
            time.sleep(1)
            logs.info_1("In the wait_utility: Workflow status is {0} for the {1}'s run. ID: {2}, name: {3}"
                        .format(status, counter, id, name))
            counter += 1
            return self.wait_utility(id, counter, name)
        elif status == "running" and counter >= self.MAX_WAIT:
            logs.info_1("In the wait_utility: Timed out after trying {0} times. ID: {1}, name: {2}"
                        .format(self.MAX_WAIT, id, name))
            return 'timeout'
        else:
            logs.info_1("In the wait_utility: Waiting for workflow {0}. The status is: {1} for run: {2}. ID: {3}"
                        .format(name, status, counter, id))
            return status

    def get_ucs_node_list(self):
        nodeList = []

        api_data = fit_common.rackhdapi('/api/2.0/nodes')
        self.assertEqual(api_data['status'], 200,
                         'Incorrect HTTP return code, expected 200, got:' + str(api_data['status']))
        for node in api_data['json']:
            if node["obms"] != [] and node["obms"][0]["service"] == "ucs-obm-service":
                nodeList.append(node)

        return (nodeList)

    @unittest.skipUnless("ucsm_ip" in fit_common.fitcfg(), "")
    def test_check_ucs_params(self):
        self.assertNotEqual(UCSM_IP, None, "Expected value for UCSM_IP other then None and found {0}"
                            .format(UCSM_IP))
        self.assertNotEqual(UCS_SERVICE_URI, None,
                            "Expected value for UCS_SERVICE_URI other then None and found {0}"
                            .format(UCS_SERVICE_URI))

    @depends(after=test_check_ucs_params)
    def test_api_20_ucs_discovery(self):
        """
        Tests the UCS Discovery workflow in rackHD
        :return:
        """

        initialNodeCount = len(self.get_ucs_node_list())

        data_payload = {
            "name": "Graph.Ucs.Discovery",
            "options": {
                "defaults": {
                    "username": UCSM_USER,
                    "password": UCSM_PASS,
                    "ucs": UCSM_IP,
                    "uri": UCS_SERVICE_URI
                },
                "when-discover-physical-ucs": {
                    "discoverPhysicalServers": "true",
                },
                "when-discover-logical-ucs": {
                    "discoverLogicalServer": "false"
                },
                "when-catalog-ucs": {
                    "autoCatalogUcs": "false"
                }
            }
        }

        expected_ucs_physical_nodes = self.get_physical_server_count()

        header = {"Content-Type": "application/json"}
        api_data = fit_common.rackhdapi("/api/2.0/workflows", action="post",
                                        headers=header, payload=data_payload)
        id = api_data["json"]["context"]["graphId"]
        self.assertEqual(api_data['status'], 201,
                         'Incorrect HTTP return code, expected 201, got:' + str(api_data['status']))
        status = self.wait_utility(str(id), 0, "Discovery")
        self.assertEqual(status, 'succeeded', 'Discovery graph returned status {}'.format(status))

        newNodeCount = len(self.get_ucs_node_list())

        logs.info_1("Found {0} Nodes after cataloging the UCS".format(len(api_data['json'])))

        self.assertEqual(newNodeCount - initialNodeCount, expected_ucs_physical_nodes,
                                'Expected to discover {0} UCS nodes, got: {1}'
                                .format(expected_ucs_physical_nodes, newNodeCount - initialNodeCount))

        # rerun discovery and verify duplicate nodes are not created
        api_data = fit_common.rackhdapi("/api/2.0/workflows", action="post",
                                        headers=header, payload=data_payload)
        id = api_data["json"]["context"]["graphId"]
        self.assertEqual(api_data['status'], 201,
                         'Incorrect HTTP return code, expected 201, got:' + str(api_data['status']))
        status = self.wait_utility(str(id), 0, "Discovery")
        self.assertEqual(status, 'succeeded', 'Discovery graph returned status {}'.format(status))

        newNodeCount = len(self.get_ucs_node_list())

        logs.info_1("Found {0} Nodes after cataloging the UCS".format(len(api_data['json'])))

        self.assertGreaterEqual(newNodeCount - initialNodeCount, 0,
                                'Expected to discover {0} UCS nodes, got: {1}'
                                .format(0, newNodeCount - initialNodeCount))

    @depends(after=test_api_20_ucs_discovery)
    def test_api_20_ucs_serviceProfile_discovery(self):
        """
        Tests the UCS Service Profile Discovery workflow in rackHD
        :return:
        """
        expected_ucs_logical_nodes = self.get_service_profile_count()
        if (expected_ucs_logical_nodes == 0):
            raise unittest.SkipTest("No Service Profiles Defined")

        initialNodeCount = len(self.get_ucs_node_list())

        data_payload = {
            "name": "Graph.Ucs.Discovery",
            "options": {
                "defaults": {
                    "username": UCSM_USER,
                    "password": UCSM_PASS,
                    "ucs": UCSM_IP,
                    "uri": UCS_SERVICE_URI
                },
                "when-discover-physical-ucs": {
                    "discoverPhysicalServers": "false",
                },
                "when-discover-logical-ucs": {
                    "discoverLogicalServer": "true"
                },
                "when-catalog-ucs": {
                    "autoCatalogUcs": "false"
                }
            }
        }

        header = {"Content-Type": "application/json"}
        api_data = fit_common.rackhdapi("/api/2.0/workflows", action="post",
                                        headers=header, payload=data_payload)
        self.assertEqual(api_data['status'], 201,
                         'Incorrect HTTP return code, expected 201, got:' + str(api_data['status']))
        id = api_data["json"]["context"]["graphId"]
        status = self.wait_utility(str(id), 0, "Service Profile Discovery")
        self.assertEqual(status, 'succeeded', 'Service Profile Discovery graph returned status {}'.format(status))

        newNodeCount = len(self.get_ucs_node_list())

        self.assertEqual(newNodeCount - initialNodeCount, expected_ucs_logical_nodes,
                                'Expected to discover {0} UCS nodes, got: {1}'
                                .format(expected_ucs_logical_nodes, newNodeCount - initialNodeCount))
        logs.info_1("Found {0} UCS nodes {1}".format(len(self.UCS_COMPUTE_NODES), self.UCS_COMPUTE_NODES))

        # rerun discovery graph and verify duplicate nodes are not created
        api_data = fit_common.rackhdapi("/api/2.0/workflows", action="post",
                                        headers=header, payload=data_payload)
        id = api_data["json"]["context"]["graphId"]
        self.assertEqual(api_data['status'], 201,
                         'Incorrect HTTP return code, expected 201, got:' + str(api_data['status']))
        status = self.wait_utility(str(id), 0, "Service Profile Discovery")
        self.assertEqual(status, 'succeeded', 'Service Profile Discovery graph returned status {}'.format(status))

        newNodeCount = len(self.get_ucs_node_list())

        self.assertGreaterEqual(newNodeCount - initialNodeCount, 0,
                                'Expected to discover {0} UCS nodes, got: {1}'
                                .format(0, newNodeCount - initialNodeCount))

    @depends(after=[test_api_20_ucs_discovery])
    def test_api_20_ucs_catalog(self):
        """
        Tests the UCS Catalog workflow in rackHD
        :return:
        """

        ucsNodes = self.get_ucs_node_list()
        errNodes = ''
        errGraphs = ''

        for x in range(len(ucsNodes)):
            postUrl = '/api/2.0/nodes/' + str(ucsNodes[x]["id"]) + "/workflows?name=Graph.Ucs.Catalog"
            header = {"Content-Type": "application/json"}
            api_data = fit_common.rackhdapi(postUrl, headers=header, action="post", payload={})
            if api_data['status'] != 201:
                errNodes += 'POST for node {} returned {}, '.format(ucsNodes[x]['id'], api_data['status'])
            status = self.wait_utility(api_data["json"]["instanceId"], 0, "Catalog")
            if status != 'succeeded':
                errGraphs += 'graph id {} finished with status: {}, '.format(api_data["json"]["instanceId"], status)

            logs.info_1("Posted URL: {0} with status: {1}".format(postUrl, api_data['status']))

        self.assertEqual(len(errNodes), 0, errNodes)
        self.assertEqual(len(errGraphs), 0, errGraphs)

    @depends(after=[test_api_20_ucs_catalog])
    def test_api_20_ucs_discover_and_catalog_all(self):
        """
        Tests the UCS Discovery and Catalon All workflow in rackHD
        :return:
        """

        # delete all previously discovered nodes and catalogs
        self.assertTrue(restore_node_utility(), "failed to restore nodes")
        self.assertTrue(restore_obms_utility(), "failed to restore obms")

        initialNodeCount = len(self.get_ucs_node_list())
        expected_ucs_logical_nodes = self.get_service_profile_count()
        expected_ucs_physical_nodes = self.get_physical_server_count()

        data_payload = {
            "name": "Graph.Ucs.Discovery",
            "options": {
                "defaults": {
                    "username": UCSM_USER,
                    "password": UCSM_PASS,
                    "ucs": UCSM_IP,
                    "uri": UCS_SERVICE_URI
                },
                "when-discover-physical-ucs": {
                    "discoverPhysicalServers": "true",
                },
                "when-discover-logical-ucs": {
                    "discoverLogicalServer": "true"
                },
                "when-catalog-ucs": {
                    "autoCatalogUcs": "true"
                }
            }
        }

        header = {"Content-Type": "application/json"}
        api_data = fit_common.rackhdapi("/api/2.0/workflows", action="post",
                                        headers=header, payload=data_payload)
        id = api_data["json"]["context"]["graphId"]
        self.assertEqual(api_data['status'], 201,
                         'Incorrect HTTP return code, expected 201, got:' + str(api_data['status']))
        status = self.wait_utility(str(id), 0, "Discovery")
        self.assertEqual(status, 'succeeded', 'Discovery graph returned status {}'.format(status))

        newNodeCount = len(self.get_ucs_node_list())

        logs.info_1("Found {0} Nodes after cataloging the UCS".format(len(api_data['json'])))

        self.assertEqual(newNodeCount - initialNodeCount,
                         expected_ucs_physical_nodes + expected_ucs_logical_nodes,
                         'Expected to discover {0} UCS nodes, got: {1}'
                         .format(expected_ucs_physical_nodes + expected_ucs_logical_nodes,
                                 newNodeCount - initialNodeCount))
コード例 #10
0
class rackhd20_ucs_discovery(unittest.TestCase):
    UCS_COMPUTE_NODES = []

    @classmethod
    def setUpClass(cls):
        if not ucs_common.get_nodes_utility():
            raise Exception("error getting node list")
        if not ucs_common.get_obms_utility():
            raise Exception("error getting obms list")

    @classmethod
    def tearDownClass(cls):
        if not ucs_common.restore_node_utility():
            raise Exception("error restoring node list")
        if not ucs_common.restore_obms_utility():
            raise Exception("error restoring obms list")

    def get_ucs_node_list(self):
        nodeList = []
        api_data = fit_common.rackhdapi('/api/2.0/nodes')
        self.assertEqual(
            api_data['status'], 200,
            'Incorrect HTTP return code, expected 200, got:' +
            str(api_data['status']))
        for node in api_data['json']:
            if node["obms"] != [] and node["obms"][0][
                    "service"] == "ucs-obm-service":
                nodeList.append(node)
        return (nodeList)

    def get_ucs_encl_id_list(self):
        enclIdList = []
        nodeList = self.get_ucs_node_list()
        for node in nodeList:
            if node["type"] == 'enclosure':
                enclIdList.append(node['id'])
        return (enclIdList)

    @unittest.skipUnless("ucsm_ip" in fit_common.fitcfg(), "")
    def test_check_ucs_params(self):
        if not ucs_common.is_ucs_valid():
            raise unittest.SkipTest(
                "Ucs parameters are not valid or UCSPE emulator is not ready, skipping all UCS tests"
            )

    @depends(after=test_check_ucs_params)
    def test_api_20_ucs_discovery(self):
        """
        Tests the UCS Discovery workflow in rackHD
        :return:
        """

        initialNodeCount = len(self.get_ucs_node_list())
        data_payload = {
            "name": "Graph.Ucs.Discovery",
            "options": {
                "defaults": {
                    "username": ucs_common.UCSM_USER,
                    "password": ucs_common.UCSM_PASS,
                    "ucs": ucs_common.UCSM_IP,
                    "uri": ucs_common.UCS_SERVICE_URI
                },
                "when-discover-physical-ucs": {
                    "discoverPhysicalServers": "true",
                },
                "when-discover-logical-ucs": {
                    "discoverLogicalServer": "false"
                },
                "when-catalog-ucs": {
                    "autoCatalogUcs": "false"
                }
            }
        }

        expected_ucs_physical_nodes = ucs_common.get_physical_server_count()
        header = {"Content-Type": "application/json"}
        api_data = fit_common.rackhdapi("/api/2.0/workflows",
                                        action="post",
                                        headers=header,
                                        payload=data_payload)
        id = api_data["json"]["context"]["graphId"]
        self.assertEqual(
            api_data['status'], 201,
            'Incorrect HTTP return code, expected 201, got:' +
            str(api_data['status']))
        status = ucs_common.wait_utility(str(id), 0, "Discovery")
        self.assertEqual(status, 'succeeded',
                         'Discovery graph returned status {}'.format(status))

        newNodeCount = len(self.get_ucs_node_list())
        logs.info_1("Found {0} Nodes after cataloging the UCS".format(
            len(api_data['json'])))

        self.assertEqual(
            newNodeCount - initialNodeCount, expected_ucs_physical_nodes,
            'Expected to discover {0} UCS nodes, got: {1}'.format(
                expected_ucs_physical_nodes, newNodeCount - initialNodeCount))

        # rerun discovery and verify duplicate nodes are not created
        initialNodeCount = len(self.get_ucs_node_list())
        api_data = fit_common.rackhdapi("/api/2.0/workflows",
                                        action="post",
                                        headers=header,
                                        payload=data_payload)
        id = api_data["json"]["context"]["graphId"]
        self.assertEqual(
            api_data['status'], 201,
            'Incorrect HTTP return code, expected 201, got:' +
            str(api_data['status']))
        status = ucs_common.wait_utility(str(id), 0, "Discovery")
        self.assertEqual(status, 'succeeded',
                         'Discovery graph returned status {}'.format(status))

        newNodeCount = len(self.get_ucs_node_list())
        logs.info_1("Found {0} Nodes after cataloging the UCS".format(
            len(api_data['json'])))

        self.assertEqual(
            newNodeCount - initialNodeCount, 0,
            'Expected to discover {0} UCS nodes, got: {1}'.format(
                0, newNodeCount - initialNodeCount))

    @depends(after=[test_api_20_ucs_discovery])
    @unittest.skip("Skipping 'test_api_redfish_chassis' bug RAC-5358")
    def test_api_redfish_chassis(self):
        """
        Tests the redfish/chassis routes with UCS nodes
        :return:
        """
        ucsEnclList = self.get_ucs_encl_id_list()
        errUrls = ''

        api_data = fit_common.rackhdapi('/redfish/v1/Chassis')
        self.assertEqual(
            api_data['status'], 200,
            'Incorrect HTTP return code, expected 200, got:' +
            str(api_data['status']))
        for chassis in api_data['json']['Members']:
            url = chassis['@odata.id']
            id = url[len('/redfish/v1/Chassis/'):]
            if id in ucsEnclList:
                ucsEnclList.remove(id)
                api_data = fit_common.rackhdapi(url)
                if api_data['status'] != 200:
                    errUrls += url + ' returned status ' + str(
                        api_data['status']) + ',\n'
        self.assertEqual(len(ucsEnclList), 0,
                         'not all UCS chassis were listed under /chassis')
        self.assertEqual(len(errUrls), 0, errUrls)

    @depends(after=[test_api_20_ucs_discovery])
    def test_api_20_ucs_discover_and_catalog_all(self):
        """
        Tests the UCS Discovery and Catalon All workflow in rackHD
        :return:
        """
        # delete all previously discovered nodes and catalogs
        self.assertTrue(ucs_common.restore_node_utility(),
                        "failed to restore nodes")
        self.assertTrue(ucs_common.restore_obms_utility(),
                        "failed to restore obms")

        initialNodeCount = len(self.get_ucs_node_list())
        expected_ucs_logical_nodes = ucs_common.get_service_profile_count()
        expected_ucs_physical_nodes = ucs_common.get_physical_server_count()

        data_payload = {
            "name": "Graph.Ucs.Discovery",
            "options": {
                "defaults": {
                    "username": ucs_common.UCSM_USER,
                    "password": ucs_common.UCSM_PASS,
                    "ucs": ucs_common.UCSM_IP,
                    "uri": ucs_common.UCS_SERVICE_URI
                },
                "when-discover-physical-ucs": {
                    "discoverPhysicalServers": "true",
                },
                "when-discover-logical-ucs": {
                    "discoverLogicalServer": "true"
                },
                "when-catalog-ucs": {
                    "autoCatalogUcs": "true"
                }
            }
        }

        header = {"Content-Type": "application/json"}
        api_data = fit_common.rackhdapi("/api/2.0/workflows",
                                        action="post",
                                        headers=header,
                                        payload=data_payload)
        id = api_data["json"]["context"]["graphId"]
        self.assertEqual(
            api_data['status'], 201,
            'Incorrect HTTP return code, expected 201, got:' +
            str(api_data['status']))
        status = ucs_common.wait_utility(str(id), 0, "Discovery", 240)
        self.assertEqual(status, 'succeeded',
                         'Discovery graph returned status {}'.format(status))

        newNodeCount = len(self.get_ucs_node_list())

        logs.info_1("Found {0} Nodes after cataloging the UCS".format(
            len(api_data['json'])))

        self.assertEqual(
            newNodeCount - initialNodeCount,
            expected_ucs_physical_nodes + expected_ucs_logical_nodes,
            'Expected to discover {0} UCS nodes, got: {1}'.format(
                expected_ucs_physical_nodes + expected_ucs_logical_nodes,
                newNodeCount - initialNodeCount))

    @depends(after=test_api_20_ucs_discover_and_catalog_all)
    def test_api_20_ucs_serviceProfile_discovery(self):
        """
        Tests the UCS Service Profile Discovery workflow in rackHD
        :return:
        """
        # delete all previously discovered nodes and catalogs
        self.assertTrue(ucs_common.restore_node_utility(),
                        "failed to restore nodes")
        self.assertTrue(ucs_common.restore_obms_utility(),
                        "failed to restore obms")

        expected_ucs_logical_nodes = ucs_common.get_service_profile_count()
        if (expected_ucs_logical_nodes == 0):
            raise unittest.SkipTest("No Service Profiles Defined")

        initialNodeCount = len(self.get_ucs_node_list())

        data_payload = {
            "name": "Graph.Ucs.Discovery",
            "options": {
                "defaults": {
                    "username": ucs_common.UCSM_USER,
                    "password": ucs_common.UCSM_PASS,
                    "ucs": ucs_common.UCSM_IP,
                    "uri": ucs_common.UCS_SERVICE_URI
                },
                "when-discover-physical-ucs": {
                    "discoverPhysicalServers": "false",
                },
                "when-discover-logical-ucs": {
                    "discoverLogicalServer": "true"
                },
                "when-catalog-ucs": {
                    "autoCatalogUcs": "false"
                }
            }
        }

        header = {"Content-Type": "application/json"}
        api_data = fit_common.rackhdapi("/api/2.0/workflows",
                                        action="post",
                                        headers=header,
                                        payload=data_payload)
        self.assertEqual(
            api_data['status'], 201,
            'Incorrect HTTP return code, expected 201, got:' +
            str(api_data['status']))
        id = api_data["json"]["context"]["graphId"]
        status = ucs_common.wait_utility(str(id), 0,
                                         "Service Profile Discovery")
        self.assertEqual(
            status, 'succeeded',
            'Service Profile Discovery graph returned status {}'.format(
                status))

        newNodeCount = len(self.get_ucs_node_list())

        self.assertEqual(
            newNodeCount - initialNodeCount, expected_ucs_logical_nodes,
            'Expected to discover {0} UCS nodes, got: {1}'.format(
                expected_ucs_logical_nodes, newNodeCount - initialNodeCount))
        logs.info_1("Found {0} UCS nodes {1}".format(
            len(self.UCS_COMPUTE_NODES), self.UCS_COMPUTE_NODES))

        # rerun discovery graph and verify duplicate nodes are not created
        api_data = fit_common.rackhdapi("/api/2.0/workflows",
                                        action="post",
                                        headers=header,
                                        payload=data_payload)
        id = api_data["json"]["context"]["graphId"]
        self.assertEqual(
            api_data['status'], 201,
            'Incorrect HTTP return code, expected 201, got:' +
            str(api_data['status']))
        status = ucs_common.wait_utility(str(id), 0,
                                         "Service Profile Discovery")
        self.assertEqual(
            status, 'succeeded',
            'Service Profile Discovery graph returned status {}'.format(
                status))

        newNodeCount = len(self.get_ucs_node_list())
        self.assertGreaterEqual(
            newNodeCount - initialNodeCount, 0,
            'Expected to discover {0} UCS nodes, got: {1}'.format(
                0, newNodeCount - initialNodeCount))
コード例 #11
0
-All the ucs service APIs
-The Discovery workflow
-The Catalog workflow

'''

import fit_path  # NOQA: unused import
import unittest
from common import fit_common
from nosedep import depends
import flogging
from nose.plugins.attrib import attr

logs = flogging.get_loggers()

UCSM_IP = fit_common.fitcfg().get('ucsm_ip')
UCSM_USER = fit_common.fitcfg().get('ucsm_user')
UCSM_PASS = fit_common.fitcfg().get('ucsm_pass')
UCS_SERVICE_URI = fit_common.fitcfg().get('ucs_service_uri')


@attr(all=True, regression=True, smoke=True, ucs=True)
class ucs_api(unittest.TestCase):

    def ucs_url_factory(self, api, identifier=None):
        """
        returns a fully qualified UCS API
        :param api:UCS API
        :param identifier: identify the ucs element in the catalog API
        :return:
        """
コード例 #12
0
ファイル: test_rackhd_api_ucs.py プロジェクト: changev/RackHD
import unittest
from common import fit_common
import time
from nosedep import depends
import flogging
from nose.plugins.attrib import attr
from config.settings import get_ucs_cred
from ucsmsdk import ucshandle
from ucsmsdk.utils.ucsbackup import import_ucs_backup
import os

logs = flogging.get_loggers()

INITIAL_NODES = {}
INITIAL_OBMS = {}
UCSM_IP = fit_common.fitcfg().get('ucsm_ip')
UCSM_USER, UCSM_PASS = get_ucs_cred()
UCS_SERVICE_URI = fit_common.fitcfg().get('ucs_service_uri')


def get_nodes_utility():
    """
    Takes inventory of the nodes available before discovering the UCS nodes.
    We will restore the nodes collection to this snapshot
    :return: return False on failure, or True otherwise
    """
    api_data = fit_common.rackhdapi('/api/2.0/nodes')
    if api_data['status'] != 200:
        logs.error("get /api/2.0/nodes returned status {}, expected 200".format(api_data['status']))
        return False
コード例 #13
0
class rackhd20_ucs_pollers(unittest.TestCase):
    NODELIST = []
    POLLERS = {}

    @classmethod
    def setUpClass(cls):
        if not ucs_common.get_nodes_utility():
            raise Exception("error getting node list")
        if not ucs_common.get_obms_utility():
            raise Exception("error getting obms list")

    @classmethod
    def tearDownClass(cls):
        if not ucs_common.restore_node_utility():
            raise Exception("error restoring node list")
        if not ucs_common.restore_obms_utility():
            raise Exception("error restoring obms list")

    def get_ucs_node_list(self):
        api_data = fit_common.rackhdapi('/api/2.0/nodes')
        self.assertEqual(
            api_data['status'], 200,
            'Incorrect HTTP return code, expected 200, got:' +
            str(api_data['status']))
        for node in api_data['json']:
            if node["obms"] != [] and node["obms"][0][
                    "service"] == "ucs-obm-service":
                self.NODELIST.append(node["id"])

    @unittest.skipUnless("ucsm_ip" in fit_common.fitcfg(), "")
    def test_check_ucs_params(self):
        if not ucs_common.is_ucs_valid():
            raise unittest.SkipTest(
                "Ucs parameters are not valid or UCSPE emulator is not ready, skipping all UCS tests"
            )

    @depends(after=[test_check_ucs_params])
    def test_api_20_workflow_ucs_pollers(self):
        """
        Tests the UCS Poller workflow in rackHD
        :return:
        """
        data_payload = {
            "name": "Graph.Ucs.Discovery",
            "options": {
                "defaults": {
                    "username": ucs_common.UCSM_USER,
                    "password": ucs_common.UCSM_PASS,
                    "ucs": ucs_common.UCSM_IP,
                    "uri": ucs_common.UCS_SERVICE_URI
                },
                "when-discover-physical-ucs": {
                    "discoverPhysicalServers": "true",
                },
                "when-discover-logical-ucs": {
                    "discoverLogicalServer": "false"
                },
                "when-catalog-ucs": {
                    "autoCatalogUcs": "false"
                }
            }
        }

        header = {"Content-Type": "application/json"}
        api_data = fit_common.rackhdapi("/api/2.0/workflows",
                                        action="post",
                                        headers=header,
                                        payload=data_payload)
        self.assertEqual(
            api_data['status'], 201,
            'Incorrect HTTP return code, expected 201, got:' +
            str(api_data['status']))
        id = api_data["json"]["context"]["graphId"]
        status = ucs_common.wait_utility(str(id), 0, "Ucs Discovery")
        self.assertEqual(
            status, 'succeeded',
            'Ucs Discovery graph returned status {}'.format(status))

        self.get_ucs_node_list()
        errNodes = ''
        errGraphs = ''

        for node in self.NODELIST:
            postUrl = '/api/2.0/nodes/' + node + "/workflows?name=Graph.Ucs.Poller"
            header = {"Content-Type": "application/json"}
            api_data = fit_common.rackhdapi(postUrl,
                                            headers=header,
                                            action="post",
                                            payload={})
            if api_data['status'] != 201:
                errNodes += 'POST for node {} returned {}, '.format(
                    node, api_data['status'])
            status = ucs_common.wait_utility(api_data["json"]["instanceId"], 0,
                                             "Poller")
            if status != 'succeeded':
                errGraphs += 'graph id {} finished with status: {}, '.format(
                    api_data["json"]["instanceId"], status)

            logs.info_1("Posted URL: {0} with status: {1}".format(
                postUrl, api_data['status']))

        self.assertEqual(len(errNodes), 0, errNodes)
        self.assertEqual(len(errGraphs), 0, errGraphs)

    @depends(after=[test_api_20_workflow_ucs_pollers])
    def test_api_20_get_pollers_by_id(self):
        msg = "Description: Display the poller data per node."
        logs.info_2("\t{0}".format(msg))

        for node in self.NODELIST:
            api_data = fit_common.rackhdapi("/api/2.0/nodes/" + node +
                                            "/pollers")
            self.assertEqual(
                api_data['status'], 200,
                "Incorrect HTTP return code, expected 200, got:{0}".format(
                    str(api_data['status'])))
            for item in api_data['json']:
                # check required fields
                self.assertGreater(item['pollInterval'], 0,
                                   'pollInterval field error')
                for subitem in [
                        'node', 'config', 'createdAt', 'id', 'name',
                        'failureCount', 'leaseExpires', 'leaseToken',
                        'updatedAt'
                ]:
                    self.assertIn(subitem, item, subitem + ' field error')
            logs.info_2("\nNode: ")
            poller_dict = test_api_utils.get_supported_pollers(node)
            self.POLLERS[node] = poller_dict
            for poller in poller_dict:
                poller_id = poller_dict[poller]["poller_id"]
                logs.info_2("\nPoller: " + poller + " ID: " + str(poller_id))
                poll_data = fit_common.rackhdapi("/api/2.0/pollers/" +
                                                 poller_id)
                logs.info_5(fit_common.json.dumps(poll_data['json'], indent=4))

    @depends(after=[test_api_20_get_pollers_by_id])
    def test_api_20_vefify_pollers_data(self):
        msg = "Description: Check pollers created for node"
        logs.info_2("\t{0}".format(msg))
        errorlist = []
        poller_list = [
            'ucs.led', 'ucs.disk', 'ucs.psu', 'ucs.fan', 'ucs.sel',
            'ucs.powerthermal'
        ]
        logs.info_2("Expected Pollers for a Node: ".format(poller_list))
        for node in self.NODELIST:
            poller_dict = self.POLLERS[node]
            if set(poller_list) == set(poller_dict):
                logs.info_5("Expected pollers instantiated on node")
                logs.info_5("Poller list retreived", poller_dict)
            else:
                if list(set(poller_list) - set(poller_dict)):
                    errorlist.append(
                        "Error: Node {} Pollers not running {}".format(
                            node, list(set(poller_list) - set(poller_dict))))
                if list(set(poller_dict) - set(poller_list)):
                    errorlist.append(
                        "Error: Node {} Unexpected Pollers running {}".format(
                            node, list(set(poller_dict) - set(poller_list))))
        if errorlist != []:
            logs.info_2("{}".format(fit_common.json.dumps(errorlist,
                                                          indent=4)))
            self.assertEqual(errorlist, [], "Error reported.")

    @depends(after=[test_api_20_get_pollers_by_id])
    def test_api_20_verify_poller_headers(self):
        msg = "Description: Verify header data reported on the poller"
        logs.info_2("\t{0}".format(msg))
        errorlist = []
        for node in self.NODELIST:
            poller_dict = self.POLLERS[node]
            for poller in poller_dict:
                poller_id = poller_dict[poller]["poller_id"]
                logs.info_2("Poller: {}  ID: {} ".format(
                    poller, str(poller_id)))
                poller_data = test_api_utils.get_poller_data_by_id(poller_id)
                if poller_data == []:
                    errorlist.append(
                        "Error: Node {} Poller ID {}, {} failed to return any data"
                        .format(node, poller_id, poller))
                logs.info_5(fit_common.json.dumps(poller_data, indent=4))

        if errorlist != []:
            logs.info_2("{}".format(fit_common.json.dumps(errorlist,
                                                          indent=4)))
            self.assertEqual(errorlist, [], "Error reported.")

    @depends(after=[test_api_20_get_pollers_by_id])
    def test_api_20_verify_poller_default_cache(self):
        msg = "Description: Check number of polls being kept for poller ID"
        logs.info_2("\t{0}".format(msg))
        errorlist = []
        for node in self.NODELIST:
            poller_dict = self.POLLERS[node]
            for poller in poller_dict:
                poller_id = poller_dict[poller]["poller_id"]
                poller_data = test_api_utils.get_poller_data_by_id(poller_id)
                poll_len = len(poller_data)
                logs.info_2("Poller: {}  ID: {} ".format(
                    poller, str(poller_id)))
                logs.info_2("Number of polls for " + str(poller_id) + ": " +
                            str(len(poller_data)))
                if poll_len > 10:
                    errorlist.append(
                        'Error: Poller {} ID: {} - Number of cached polls should not exceed 10'
                        .format(poller_id, poller))
                elif poll_len == 0:
                    errorlist.append(
                        'Error: Poller {} ID: {} - Pollers not running'.format(
                            poller_id, poller))
        if errorlist != []:
            logs.info_2("{}".format(fit_common.json.dumps(errorlist,
                                                          indent=4)))
            self.assertEqual(errorlist, [], "Error reported.")

    @depends(after=[test_api_20_get_pollers_by_id])
    def test_api_20_verify_poller_current_data(self):
        msg = "Description: Display most current data from poller"
        logs.info_2("\t{0}".format(msg))
        errorlist = []
        for node in self.NODELIST:
            poller_dict = self.POLLERS[node]
            for poller in poller_dict:
                poller_id = poller_dict[poller]["poller_id"]
                logs.info_2("Poller: {}  ID: {} ".format(
                    poller, str(poller_id)))
                monurl = "/api/2.0/pollers/" + str(poller_id) + "/data/current"
                api_data = fit_common.rackhdapi(url_cmd=monurl)
                if api_data['status'] not in [200, 201, 202, 204]:
                    errorlist.append(
                        "Error: Node {} Poller_ID {} Failed to get current poller data, status {}"
                        .format(node, poller_id, api_data['status']))
                else:
                    logs.info_5(
                        fit_common.json.dumps(api_data['json'], indent=4))

        if errorlist != []:
            logs.info_2("{}".format(fit_common.json.dumps(errorlist,
                                                          indent=4)))
            self.assertEqual(errorlist, [], "Error reported.")
コード例 #14
0
ファイル: ucs_common.py プロジェクト: PengTian0/RackHD
'''

import fit_path  # NOQA: unused import
from common import fit_common
import time
import flogging
from ucsmsdk import ucshandle
from ucsmsdk.utils.ucsbackup import import_ucs_backup
import os

logs = flogging.get_loggers()

INITIAL_NODES = {}
INITIAL_OBMS = {}
MAX_WAIT = 240
UCSM_IP = fit_common.fitcfg().get('ucsm_ip')
UCSM_USER = fit_common.fitcfg().get('ucsm_user')
UCSM_PASS = fit_common.fitcfg().get('ucsm_pass')
EXPECTED_UCS_PHYSICAL_NODES = 22
if fit_common.fitcfg().get('physical_nodes_count') is not None:
    EXPECTED_UCS_PHYSICAL_NODES = int(fit_common.fitcfg().get('physical_nodes_count'))
UCS_SERVICE_URI = fit_common.fitcfg().get('ucs_service_uri')


def get_nodes_utility():
    """
    Takes inventory of the nodes available before discovering the UCS nodes.
    We will restore the nodes collection to this snapshot
    :return: return False on failure, or True otherwise
    """
    api_data = fit_common.rackhdapi('/api/2.0/nodes')
コード例 #15
0
class rackhd_ucs_api(unittest.TestCase):

    UCS_IP = fit_common.fitcfg().get("ucs_ip")
    UCS_PORT = fit_common.fitcfg().get("ucs_port")
    RACKHD_IP = fit_common.fitcfg().get("rackhd_host")
    MAX_WAIT = 60
    INITIAL_NODES = {}
    INITIAL_OBMS = {}
    INITIAL_CATALOGS = {}
    UCS_NODES = []
    UCS_COMPUTE_NODES = []
    EXPECTED_UCS_NODES = 22
    MAX_WAIT_ON_DELETE = 0

    def wait_utility(self, id, counter, name):
        """
        Recursevily wait for the ucs discovery workflow to finish
        :param id:  Graph ID
        :param counter: Safeguard for the number of times we can check the status of the graph
        :param name: Description of graph we are waiting for
        :return: return False on failure, or True otherwise
        """
        api_data = fit_common.rackhdapi('/api/2.0/workflows/' + str(id))
        status = api_data["json"]["status"]
        if status == "running" and counter < self.MAX_WAIT:
            time.sleep(1)
            logs.info_1(
                "In the wait_utility: Workflow status is {0} for the {1}'s run. ID: {2}, name: {3}"
                .format(status, counter, id, name))
            counter += 1
            self.wait_utility(id, counter, name)
        elif status == "running" and counter >= self.MAX_WAIT:
            logs.info_1(
                "In the wait_utility: Timed out after trying {0} times. ID: {1}, name: {2}"
                .format(self.MAX_WAIT, id, name))
            return False
        else:
            logs.info_1(
                "In the wait_utility: Waiting for workflow {0}. The status is: {1} for run: {2}. ID: {3}"
                .format(name, status, counter, id))
            return True

    def get_nodes_utility(self):
        """
        Takes inventory of the nodes available before discovering the UCS nodes.
        We will restore the nodes collection to this snapshot
        :return:
        """
        api_data = fit_common.rackhdapi('/api/2.0/nodes')
        self.assertEqual(
            api_data['status'], 200,
            'Incorrect HTTP return code, expected 200, got:' +
            str(api_data['status']))
        for node in api_data['json']:
            self.INITIAL_NODES[node['id']] = node['type']
        logs.info_1("Found {0} Nodes before cataloging the UCS. {1}".format(
            len(self.INITIAL_NODES), self.INITIAL_NODES))

    def get_obms_utility(self):
        """
        Takes inventory of the obms available before discovering the UCS obms.
        We will restore the obms collection to this snapshot.
        :return:
        """
        api_data = fit_common.rackhdapi('/api/2.0/obms')
        self.assertEqual(
            api_data['status'], 200,
            'Incorrect HTTP return code, expected 200, got:' +
            str(api_data['status']))

        for obm in api_data['json']:
            self.INITIAL_OBMS[obm['id']] = obm['service']
        logs.info_1("Found {0} obms before cataloging the UCS: {1}".format(
            len(self.INITIAL_OBMS), self.INITIAL_OBMS))

    def restore_node_utility(self, catalog_workflows):
        """
        Deletes all the added ucs nodes by the test.
        :param catalog_workflows: A list of the catalog workflow IDs that will wait for their completion .
        :return:
        """
        logs.info_1("Restoring Nodes")
        api_data = fit_common.rackhdapi('/api/2.0/nodes')
        self.assertEqual(
            api_data['status'], 200,
            'Incorrect HTTP return code, expected 200, got:' +
            str(api_data['status']))
        for catalog_workflow in catalog_workflows:
            self.wait_utility(str(catalog_workflow), 0, "Catalog")
        for node in api_data['json']:
            if node['id'] not in self.INITIAL_NODES:
                api_data = fit_common.rackhdapi('/api/2.0/nodes/' + node['id'],
                                                action="delete")
                logs.info_1("Deleting Node: {0}. Status was: {1}".format(
                    node['id'], api_data['status']))
                time.sleep(self.MAX_WAIT_ON_DELETE)

        api_data = fit_common.rackhdapi('/api/2.0/nodes')
        self.assertEqual(
            api_data['status'], 200,
            'Incorrect HTTP return code, expected 200, got:' +
            str(api_data['status']))
        temp = {}
        for node in api_data['json']:
            temp[node['id']] = node['name']

        self.assertEqual(
            len(temp), len(self.INITIAL_NODES),
            "Found {0}  nodes remaining after restoring the nodes, should be {1}, Remaining nodes: {2}"
            .format(len(temp), len(self.INITIAL_NODES), temp))

    def restore_obms_utility(self):
        """
         Deletes all the added ucs obms by this test.
        :return:
        """
        logs.info_1("Restoring OBMs")
        api_data = fit_common.rackhdapi('/api/2.0/obms')
        self.assertEqual(
            api_data['status'], 200,
            'Incorrect HTTP return code, expected 200, got:' +
            str(api_data['status']))

        for obm in api_data['json']:
            if obm['id'] not in self.INITIAL_OBMS:
                api_data = fit_common.rackhdapi('/api/2.0/obms/' + obm['id'],
                                                action="delete")
                logs.info_1("Deleting OBM: {0}. Status was: {1}".format(
                    obm['id'], str(api_data['status'])))
                time.sleep(self.MAX_WAIT_ON_DELETE)
        api_data = fit_common.rackhdapi('/api/2.0/obms')
        self.assertEqual(
            api_data['status'], 200,
            'Incorrect HTTP return code, expected 200, got:' +
            str(api_data['status']))
        temp = {}
        for obm in api_data['json']:
            temp[obm['id']] = obm['service']
        self.assertEqual(
            len(temp), len(self.INITIAL_OBMS),
            "Found {0} ucs obms remaining after restoring the obms, should be {1}. Remaining OBMs: {2}"
            .format(len(temp), len(self.INITIAL_OBMS), temp))

    @unittest.skipUnless("ucs_ip" in fit_common.fitcfg(), "")
    def test_check_ucs_params(self):
        self.assertNotEqual(
            self.UCS_IP, None,
            "Expected value for UCS_IP other then None and found {0}".format(
                self.UCS_IP))
        self.assertNotEqual(
            self.UCS_PORT, None,
            "Expected value for UCS_PORT other then None and found {0}".format(
                self.UCS_IP))

    @depends(after=test_check_ucs_params)
    def test_api_20_ucs_discovery(self):
        """
        Tests the UCS Discovery workflow in rackHD
        :return:
        """
        self.get_nodes_utility()
        self.get_obms_utility()

        data_payload = {
            "name": "Graph.Ucs.Discovery",
            "options": {
                "defaults": {
                    "username": "******",
                    "password": "******",
                    "ucs": self.UCS_IP,
                    "uri": "http://" + self.RACKHD_IP + ":7080/sys"
                }
            }
        }
        header = {"Content-Type": "application/json"}
        api_data = fit_common.rackhdapi("/api/2.0/workflows",
                                        action="post",
                                        headers=header,
                                        payload=data_payload)
        id = api_data["json"]["context"]["graphId"]
        self.assertEqual(
            api_data['status'], 201,
            'Incorrect HTTP return code, expected 201, got:' +
            str(api_data['status']))
        self.wait_utility(str(id), 0, "Discovery")
        api_data = fit_common.rackhdapi('/api/2.0/nodes')
        self.assertEqual(
            api_data['status'], 200,
            'Incorrect HTTP return code, expected 200, got:' +
            str(api_data['status']))
        logs.info_1("Found {0} Nodes after cataloging the UCS".format(
            len(api_data['json'])))

        for node in api_data['json']:
            if node["obms"] != [] and node["obms"][0][
                    "service"] == "ucs-obm-service":
                self.UCS_NODES.append(node)
                if node["type"] == "compute":
                    self.UCS_COMPUTE_NODES.append(node)
        self.assertGreaterEqual(
            len(self.UCS_NODES), self.EXPECTED_UCS_NODES,
            'Expected to discover {0} UCS nodes, got: {1}'.format(
                self.EXPECTED_UCS_NODES, len(self.UCS_NODES)))
        logs.info_1("Found {0} UCS nodes {1}".format(
            len(self.UCS_COMPUTE_NODES), self.UCS_COMPUTE_NODES))

    @depends(after=[test_check_ucs_params, test_api_20_ucs_discovery])
    def test_api_20_ucs_catalog(self):
        """
        Tests the UCS Catalog workflow in rackHD
        :return:
        """
        catalog_workflows = []
        for x in range(len(self.UCS_NODES)):
            postUrl = '/api/2.0/nodes/' + str(
                self.UCS_NODES[x]["id"]) + "/workflows?name=Graph.Ucs.Catalog"
            header = {"Content-Type": "application/json"}
            api_data = fit_common.rackhdapi(postUrl,
                                            headers=header,
                                            action="post")
            self.assertEqual(
                api_data['status'], 201,
                'Expected to catalog {0} UCS nodes with status {1}, got: {2}'.
                format(self.UCS_NODES[x]["id"], 201, api_data['status']))
            catalog_workflows.append(api_data["json"]["instanceId"])
            logs.info_1("Posted URL: {0} with status: {1}".format(
                postUrl, api_data['status']))

        # Restore the nodes, obms, and catalogs to their state before the UCS discovery
        # in order to avoid any failure in other tests
        logs.info_1(
            "Restoring the database to the state it was in before the UCS discovery and catalog"
        )
        self.restore_node_utility(catalog_workflows)
        self.restore_obms_utility()
コード例 #16
0
class rackhd_ucs_api(unittest.TestCase):

    MAX_WAIT = 240
    INITIAL_CATALOGS = {}
    UCS_NODES = []
    UCS_COMPUTE_NODES = []
    EXPECTED_UCS_PHYSICAL_NODES = 22
    EXPECTED_UCS_LOGICAL_NODES = 18

    @classmethod
    def setUpClass(cls):
        if not get_nodes_utility():
            raise Exception("error getting node list")
        if not get_obms_utility():
            raise Exception("error getting obms list")

    @classmethod
    def tearDownClass(cls):
        if not restore_node_utility():
            raise Exception("error restoring node list")
        if not restore_obms_utility():
            raise Exception("error restoring obms list")

    def get_physical_server_count(self):
        """
        Get a count of the number of Service Proviles defined by the UCS Manager
        """
        url = UCS_SERVICE_URI + "/rackmount"

        headers = {
            "ucs-user": UCSM_USER,
            "ucs-password": UCSM_PASS,
            "ucs-host": UCSM_IP
        }

        api_data = fit_common.restful(url, rest_headers=headers)
        if api_data['status'] != 200:
            logs.error(
                'Incorrect HTTP return code, expected 200, got: {0}'.format(
                    api_data['status']))
            return 0

        count = len(api_data["json"])

        url = UCS_SERVICE_URI + "/chassis"
        api_data = fit_common.restful(url, rest_headers=headers)
        if api_data['status'] != 200:
            logs.error(
                'Incorrect HTTP return code, expected 200, got: {0}'.format(
                    api_data['status']))
            return 0

        count += len(api_data["json"])
        for element in api_data["json"]:
            count += len(element["members"])

        return count

    def get_service_profile_count(self):
        """
        Get a count of the number of Service Proviles defined by the UCS Manager
        """
        url = UCS_SERVICE_URI + "/serviceProfile"
        headers = {
            "ucs-user": UCSM_USER,
            "ucs-password": UCSM_PASS,
            "ucs-host": UCSM_IP
        }

        api_data = fit_common.restful(url, rest_headers=headers)
        if api_data['status'] != 200:
            logs.error(
                'Incorrect HTTP return code, expected 200, got: {0}'.format(
                    api_data['status']))
            return 0

        return len(api_data["json"]["ServiceProfile"]["members"])

    def wait_utility(self, id, counter, name, max_wait=MAX_WAIT):
        """
        Wait for the specified graph to finish
        :param id:  Graph ID
        :param counter: Safeguard for the number of times we can check the status of the graph
        :param name: Description of graph we are waiting for
        :return: returns status of the taskgraph, or "timeout" if count is exceeded
        """
        api_data = fit_common.rackhdapi('/api/2.0/workflows/' + str(id))
        status = api_data["json"]["status"]
        logs.info_1(
            "Waiting up to {0} seconds for {1} Workflow, ID: {2}".format(
                max_wait, name, id))
        while (status == 'running' and counter < max_wait):
            time.sleep(1)
            counter += 1
            api_data = fit_common.rackhdapi('/api/2.0/workflows/' + str(id))
            status = api_data["json"]["status"]

        if counter >= max_wait:
            logs.info_1(
                "wait_utility() timed out after {0} attemps. status: {1}, ID: {2}, name: {3}"
                .format(counter, id, name))
            return 'timeout'
        else:
            logs.info_1(
                "wait_utility() copleted with status: {0} for run: {1}. ID: {2}, name: {3}"
                .format(status, counter, id, name))
            return status

    def get_ucs_node_list(self):
        nodeList = []
        api_data = fit_common.rackhdapi('/api/2.0/nodes')
        self.assertEqual(
            api_data['status'], 200,
            'Incorrect HTTP return code, expected 200, got:' +
            str(api_data['status']))
        for node in api_data['json']:
            if node["obms"] != [] and node["obms"][0][
                    "service"] == "ucs-obm-service":
                nodeList.append(node)
        return (nodeList)

    def get_ucs_encl_id_list(self):
        enclIdList = []
        nodeList = self.get_ucs_node_list()
        for node in nodeList:
            if node["type"] == 'enclosure':
                enclIdList.append(node['id'])
        return (enclIdList)

    @unittest.skipUnless("ucsm_ip" in fit_common.fitcfg(), "")
    def test_check_ucs_params(self):
        self.assertNotEqual(
            UCSM_IP, None,
            "Expected value for UCSM_IP other then None and found {0}".format(
                UCSM_IP))
        self.assertNotEqual(
            UCS_SERVICE_URI, None,
            "Expected value for UCS_SERVICE_URI other then None and found {0}".
            format(UCS_SERVICE_URI))

        if "ucsm_config_file" in fit_common.fitcfg():
            # configure the UCSPE emulator
            if not load_ucs_manager_config():
                # error configureing UCSPE emulaotr, skip all tests
                raise unittest.SkipTest(
                    "Error Configuring UCSPE emulator, skipping all UCS tests")

            # wait up to 2 min for config to be valid
            timeout = 120
            ucsCount = self.get_physical_server_count()
            while (ucsCount) != self.EXPECTED_UCS_PHYSICAL_NODES:
                if timeout <= 0:
                    raise unittest.SkipTest(
                        "Only found {0} of {1} nodes, skipping all UCS tests".
                        format(ucsCount, self.EXPECTED_UCS_PHYSICAL_NODES))
                logs.info_1(
                    "Only found {0} of {1} ucs nodes, retrying in 30 seconds".
                    format(ucsCount, self.EXPECTED_UCS_PHYSICAL_NODES))
                timeout -= 5
                time.sleep(5)
                ucsCount = self.get_physical_server_count()

    @depends(after=test_check_ucs_params)
    def test_api_20_ucs_discovery(self):
        """
        Tests the UCS Discovery workflow in rackHD
        :return:
        """

        initialNodeCount = len(self.get_ucs_node_list())

        data_payload = {
            "name": "Graph.Ucs.Discovery",
            "options": {
                "defaults": {
                    "username": UCSM_USER,
                    "password": UCSM_PASS,
                    "ucs": UCSM_IP,
                    "uri": UCS_SERVICE_URI
                },
                "when-discover-physical-ucs": {
                    "discoverPhysicalServers": "true",
                },
                "when-discover-logical-ucs": {
                    "discoverLogicalServer": "false"
                },
                "when-catalog-ucs": {
                    "autoCatalogUcs": "false"
                }
            }
        }

        expected_ucs_physical_nodes = self.get_physical_server_count()

        header = {"Content-Type": "application/json"}
        api_data = fit_common.rackhdapi("/api/2.0/workflows",
                                        action="post",
                                        headers=header,
                                        payload=data_payload)
        id = api_data["json"]["context"]["graphId"]
        self.assertEqual(
            api_data['status'], 201,
            'Incorrect HTTP return code, expected 201, got:' +
            str(api_data['status']))
        status = self.wait_utility(str(id), 0, "Discovery")
        self.assertEqual(status, 'succeeded',
                         'Discovery graph returned status {}'.format(status))

        newNodeCount = len(self.get_ucs_node_list())

        logs.info_1("Found {0} Nodes after cataloging the UCS".format(
            len(api_data['json'])))

        self.assertEqual(
            newNodeCount - initialNodeCount, expected_ucs_physical_nodes,
            'Expected to discover {0} UCS nodes, got: {1}'.format(
                expected_ucs_physical_nodes, newNodeCount - initialNodeCount))

        # rerun discovery and verify duplicate nodes are not created
        api_data = fit_common.rackhdapi("/api/2.0/workflows",
                                        action="post",
                                        headers=header,
                                        payload=data_payload)
        id = api_data["json"]["context"]["graphId"]
        self.assertEqual(
            api_data['status'], 201,
            'Incorrect HTTP return code, expected 201, got:' +
            str(api_data['status']))
        status = self.wait_utility(str(id), 0, "Discovery")
        self.assertEqual(status, 'succeeded',
                         'Discovery graph returned status {}'.format(status))

        newNodeCount = len(self.get_ucs_node_list())

        logs.info_1("Found {0} Nodes after cataloging the UCS".format(
            len(api_data['json'])))

        self.assertGreaterEqual(
            newNodeCount - initialNodeCount, 0,
            'Expected to discover {0} UCS nodes, got: {1}'.format(
                0, newNodeCount - initialNodeCount))

    @depends(after=test_api_20_ucs_discovery)
    def test_api_20_ucs_serviceProfile_discovery(self):
        """
        Tests the UCS Service Profile Discovery workflow in rackHD
        :return:
        """
        expected_ucs_logical_nodes = self.get_service_profile_count()
        if (expected_ucs_logical_nodes == 0):
            raise unittest.SkipTest("No Service Profiles Defined")

        initialNodeCount = len(self.get_ucs_node_list())

        data_payload = {
            "name": "Graph.Ucs.Discovery",
            "options": {
                "defaults": {
                    "username": UCSM_USER,
                    "password": UCSM_PASS,
                    "ucs": UCSM_IP,
                    "uri": UCS_SERVICE_URI
                },
                "when-discover-physical-ucs": {
                    "discoverPhysicalServers": "false",
                },
                "when-discover-logical-ucs": {
                    "discoverLogicalServer": "true"
                },
                "when-catalog-ucs": {
                    "autoCatalogUcs": "false"
                }
            }
        }

        header = {"Content-Type": "application/json"}
        api_data = fit_common.rackhdapi("/api/2.0/workflows",
                                        action="post",
                                        headers=header,
                                        payload=data_payload)
        self.assertEqual(
            api_data['status'], 201,
            'Incorrect HTTP return code, expected 201, got:' +
            str(api_data['status']))
        id = api_data["json"]["context"]["graphId"]
        status = self.wait_utility(str(id), 0, "Service Profile Discovery")
        self.assertEqual(
            status, 'succeeded',
            'Service Profile Discovery graph returned status {}'.format(
                status))

        newNodeCount = len(self.get_ucs_node_list())

        self.assertEqual(
            newNodeCount - initialNodeCount, expected_ucs_logical_nodes,
            'Expected to discover {0} UCS nodes, got: {1}'.format(
                expected_ucs_logical_nodes, newNodeCount - initialNodeCount))
        logs.info_1("Found {0} UCS nodes {1}".format(
            len(self.UCS_COMPUTE_NODES), self.UCS_COMPUTE_NODES))

        # rerun discovery graph and verify duplicate nodes are not created
        api_data = fit_common.rackhdapi("/api/2.0/workflows",
                                        action="post",
                                        headers=header,
                                        payload=data_payload)
        id = api_data["json"]["context"]["graphId"]
        self.assertEqual(
            api_data['status'], 201,
            'Incorrect HTTP return code, expected 201, got:' +
            str(api_data['status']))
        status = self.wait_utility(str(id), 0, "Service Profile Discovery")
        self.assertEqual(
            status, 'succeeded',
            'Service Profile Discovery graph returned status {}'.format(
                status))

        newNodeCount = len(self.get_ucs_node_list())

        self.assertGreaterEqual(
            newNodeCount - initialNodeCount, 0,
            'Expected to discover {0} UCS nodes, got: {1}'.format(
                0, newNodeCount - initialNodeCount))

    @depends(after=[test_api_20_ucs_discovery])
    def test_api_20_ucs_catalog(self):
        """
        Tests the UCS Catalog workflow in rackHD
        :return:
        """

        ucsNodes = self.get_ucs_node_list()
        errNodes = ''
        errGraphs = ''

        for x in range(len(ucsNodes)):
            postUrl = '/api/2.0/nodes/' + str(
                ucsNodes[x]["id"]) + "/workflows?name=Graph.Ucs.Catalog"
            header = {"Content-Type": "application/json"}
            api_data = fit_common.rackhdapi(postUrl,
                                            headers=header,
                                            action="post",
                                            payload={})
            if api_data['status'] != 201:
                errNodes += 'POST for node {} returned {}, '.format(
                    ucsNodes[x]['id'], api_data['status'])
            status = self.wait_utility(api_data["json"]["instanceId"], 0,
                                       "Catalog")
            if status != 'succeeded':
                errGraphs += 'graph id {} finished with status: {}, '.format(
                    api_data["json"]["instanceId"], status)

            logs.info_1("Posted URL: {0} with status: {1}".format(
                postUrl, api_data['status']))

        self.assertEqual(len(errNodes), 0, errNodes)
        self.assertEqual(len(errGraphs), 0, errGraphs)

    @depends(after=[test_api_20_ucs_discovery])
    @unittest.skip("Skipping 'test_api_redfish_chassis' bug RAC-5358")
    def test_api_redfish_chassis(self):
        """
        Tests the redfish/chassis routes with UCS nodes
        :return:
        """
        ucsEnclList = self.get_ucs_encl_id_list()
        errUrls = ''

        api_data = fit_common.rackhdapi('/redfish/v1/Chassis')
        self.assertEqual(
            api_data['status'], 200,
            'Incorrect HTTP return code, expected 200, got:' +
            str(api_data['status']))
        for chassis in api_data['json']['Members']:
            url = chassis['@odata.id']
            id = url[len('/redfish/v1/Chassis/'):]
            if id in ucsEnclList:
                ucsEnclList.remove(id)
                api_data = fit_common.rackhdapi(url)
                if api_data['status'] != 200:
                    errUrls += url + ' returned status ' + str(
                        api_data['status']) + ',\n'
        self.assertEqual(len(ucsEnclList), 0,
                         'not all UCS chassis were listed under /chassis')
        self.assertEqual(len(errUrls), 0, errUrls)

    @depends(after=[test_api_20_ucs_catalog])
    def test_api_20_ucs_discover_and_catalog_all(self):
        """
        Tests the UCS Discovery and Catalon All workflow in rackHD
        :return:
        """

        # delete all previously discovered nodes and catalogs
        self.assertTrue(restore_node_utility(), "failed to restore nodes")
        self.assertTrue(restore_obms_utility(), "failed to restore obms")

        initialNodeCount = len(self.get_ucs_node_list())
        expected_ucs_logical_nodes = self.get_service_profile_count()
        expected_ucs_physical_nodes = self.get_physical_server_count()

        data_payload = {
            "name": "Graph.Ucs.Discovery",
            "options": {
                "defaults": {
                    "username": UCSM_USER,
                    "password": UCSM_PASS,
                    "ucs": UCSM_IP,
                    "uri": UCS_SERVICE_URI
                },
                "when-discover-physical-ucs": {
                    "discoverPhysicalServers": "true",
                },
                "when-discover-logical-ucs": {
                    "discoverLogicalServer": "true"
                },
                "when-catalog-ucs": {
                    "autoCatalogUcs": "true"
                }
            }
        }

        header = {"Content-Type": "application/json"}
        api_data = fit_common.rackhdapi("/api/2.0/workflows",
                                        action="post",
                                        headers=header,
                                        payload=data_payload)
        id = api_data["json"]["context"]["graphId"]
        self.assertEqual(
            api_data['status'], 201,
            'Incorrect HTTP return code, expected 201, got:' +
            str(api_data['status']))
        status = self.wait_utility(str(id), 0, "Discovery", 240)
        self.assertEqual(status, 'succeeded',
                         'Discovery graph returned status {}'.format(status))

        newNodeCount = len(self.get_ucs_node_list())

        logs.info_1("Found {0} Nodes after cataloging the UCS".format(
            len(api_data['json'])))

        self.assertEqual(
            newNodeCount - initialNodeCount,
            expected_ucs_physical_nodes + expected_ucs_logical_nodes,
            'Expected to discover {0} UCS nodes, got: {1}'.format(
                expected_ucs_physical_nodes + expected_ucs_logical_nodes,
                newNodeCount - initialNodeCount))
コード例 #17
0
class rackhd20_ucs_catalogs(unittest.TestCase):
    NODELIST = []
    RACK_NODELIST = []
    CHASSIS_NODELIST = []
    BLADE_NODELIST = []
    CATALOGS = {}

    @classmethod
    def setUpClass(cls):
        if not ucs_common.get_nodes_utility():
            raise Exception("error getting node list")
        if not ucs_common.get_obms_utility():
            raise Exception("error getting obms list")

    @classmethod
    def tearDownClass(cls):
        if not ucs_common.restore_node_utility():
            raise Exception("error restoring node list")
        if not ucs_common.restore_obms_utility():
            raise Exception("error restoring obms list")

    def get_ucs_node_list(self):
        api_data = fit_common.rackhdapi('/api/2.0/nodes')
        self.assertEqual(
            api_data['status'], 200,
            'Incorrect HTTP return code, expected 200, got:' +
            str(api_data['status']))
        for node in api_data['json']:
            if node["obms"] != [] and node["obms"][0][
                    "service"] == "ucs-obm-service":
                self.NODELIST.append(node["id"])
                node_name = node["name"].split("/")[-1]
                if "rack" in node_name:
                    self.RACK_NODELIST.append(node["id"])
                elif "blade" in node_name:
                    self.BLADE_NODELIST.append(node["id"])
                elif "chassis" in node_name:
                    self.CHASSIS_NODELIST.append(node["id"])

    @unittest.skipUnless("ucsm_ip" in fit_common.fitcfg(), "")
    def test_check_ucs_params(self):
        if not ucs_common.is_ucs_valid():
            raise unittest.SkipTest(
                "Ucs parameters are not valid or UCSPE emulator is not ready, skipping all UCS tests"
            )

    @depends(after=[test_check_ucs_params])
    def test_api_20_workflow_ucs_catalogs(self):
        """
        Tests the UCS Poller workflow in rackHD
        :return:
        """
        data_payload = {
            "name": "Graph.Ucs.Discovery",
            "options": {
                "defaults": {
                    "username": ucs_common.UCSM_USER,
                    "password": ucs_common.UCSM_PASS,
                    "ucs": ucs_common.UCSM_IP,
                    "uri": ucs_common.UCS_SERVICE_URI
                },
                "when-discover-physical-ucs": {
                    "discoverPhysicalServers": "true",
                },
                "when-discover-logical-ucs": {
                    "discoverLogicalServer": "false"
                },
                "when-catalog-ucs": {
                    "autoCatalogUcs": "false"
                }
            }
        }

        header = {"Content-Type": "application/json"}
        api_data = fit_common.rackhdapi("/api/2.0/workflows",
                                        action="post",
                                        headers=header,
                                        payload=data_payload)
        self.assertEqual(
            api_data['status'], 201,
            'Incorrect HTTP return code, expected 201, got:' +
            str(api_data['status']))
        id = api_data["json"]["context"]["graphId"]
        status = ucs_common.wait_utility(str(id), 0, "Ucs Discovery")
        self.assertEqual(
            status, 'succeeded',
            'Ucs Discovery graph returned status {}'.format(status))

        self.get_ucs_node_list()
        errNodes = ''
        errGraphs = ''

        for node in self.NODELIST:
            postUrl = '/api/2.0/nodes/' + node + "/workflows?name=Graph.Ucs.Catalog"
            header = {"Content-Type": "application/json"}
            api_data = fit_common.rackhdapi(postUrl,
                                            headers=header,
                                            action="post",
                                            payload={})
            if api_data['status'] != 201:
                errNodes += 'POST for node {} returned {}, '.format(
                    node, api_data['status'])
            status = ucs_common.wait_utility(api_data["json"]["instanceId"], 0,
                                             "Catalog")
            if status != 'succeeded':
                errGraphs += 'graph id {} finished with status: {}, '.format(
                    api_data["json"]["instanceId"], status)

            logs.info_1("Posted URL: {0} with status: {1}".format(
                postUrl, api_data['status']))

        self.assertEqual(len(errNodes), 0, errNodes)
        self.assertEqual(len(errGraphs), 0, errGraphs)

    @depends(after=[test_api_20_workflow_ucs_catalogs])
    def test_api_20_get_catalogs(self):
        msg = "Description: Check catalogs data per node."
        logs.info_2("\t{0}".format(msg))

        for node in self.NODELIST:
            api_data = fit_common.rackhdapi("/api/2.0/nodes/" + node +
                                            "/catalogs")
            self.assertEqual(
                api_data['status'], 200,
                "Incorrect HTTP return code, expected 200, got:{0}".format(
                    str(api_data['status'])))
            self.CATALOGS[node] = api_data['json']
            for item in api_data['json']:
                for subitem in ['node', 'id', 'source', 'data']:
                    self.assertIn(subitem, item, subitem + ' field error')

    @depends(after=[test_api_20_get_catalogs])
    def test_api_20_verify_catalogs_source(self):
        msg = "Description: Check source of catalogs created for node"
        logs.info_2("\t{0}".format(msg))
        for node in self.NODELIST:
            sources = []
            for item in self.CATALOGS[node]:
                sources.append(item['source'])
            logs.info_5("Node {0} contains source: {1}".format(node, sources))
            self.assertIn("UCS", sources,
                          node + " catalogs doesn't contain UCS source")
        for node in self.RACK_NODELIST + self.BLADE_NODELIST:
            sources = []
            for item in self.CATALOGS[node]:
                sources.append(item['source'])
            self.assertIn("UCS:board", sources,
                          node + " catalogs doesn't contain UCS:board source")

    @depends(after=[test_api_20_get_catalogs])
    def test_api_20_vefify_catalogs_source_data(self):
        msg = "Description: Check source data of catalogs created for node"
        logs.info_2("\t{0}".format(msg))
        for node in self.NODELIST:
            for item in self.CATALOGS[node]:
                logs.info_2("Checking source:{0}".format(item['source']))
                self.assertNotEqual(item, '', 'Empty JSON Field')
                sourcedata = fit_common.rackhdapi("/api/2.0/nodes/" + node +
                                                  "/catalogs/" +
                                                  item['source'])
                self.assertGreater(len(sourcedata['json']['id']), 0,
                                   'id field error')
                self.assertGreater(len(sourcedata['json']['node']), 0,
                                   'node field error')
                self.assertGreater(len(sourcedata['json']['source']), 0,
                                   'source field error')
                self.assertGreater(len(sourcedata['json']['updatedAt']), 0,
                                   'updatedAt field error')
                self.assertGreater(len(sourcedata['json']['createdAt']), 0,
                                   'createdAt field error')
コード例 #18
0
class ucs_api(unittest.TestCase):

    UCS_IP = fit_common.fitcfg().get("ucs_ip")
    UCS_PORT = fit_common.fitcfg().get("ucs_port")
    RACKHD_IP = fit_common.fitcfg().get("rackhd_host")

    def ucs_url_factory(self, api, identifier=None):
        """
        returns a fully qualified UCS API
        :param api:UCS API
        :param identifier: identify the ucs element in the catalog API
        :return:
        """
        ucs_service = self.RACKHD_IP + ":" + self.UCS_PORT + "/"
        ucs_manager = self.UCS_IP
        if identifier is None:
            url = "https://" + ucs_service + api
        else:
            url = "https://" + ucs_service + api + "?identifier=" + identifier
        headers = {"ucs-user": "******",
                   "ucs-password": "******",
                   "ucs-host": ucs_manager}
        return (url, headers)

    @unittest.skipUnless("ucs_ip" in fit_common.fitcfg(), "")
    def test_check_ucs_params(self):
        self.assertNotEqual(self.UCS_IP, None, "Expected value for UCS_IP other then None and found {0}"
                            .format(self.UCS_IP))
        self.assertNotEqual(self.UCS_PORT, None, "Expected value for UCS_PORT other then None and found {0}"
                            .format(self.UCS_IP))

    @depends(after=test_check_ucs_params)
    def test_ucs_log_in(self):
        """
        Test the /logIn ucs API
        :return:
        """
        url, headers = self.ucs_url_factory("login")
        api_data = fit_common.restful(url, rest_headers=headers)
        self.assertEqual(api_data['status'], 200,
                         'Incorrect HTTP return code, expected 200, got:' + str(api_data['status']))

        self.assertNotEqual(api_data["json"], None, "Expected a token to be returned on login and received None")
        self.assertNotEqual(type(api_data["json"]), "unicode", "Unexpected Token was received on Login")

    @depends(after=test_check_ucs_params)
    def test_ucs_get_sys(self):
        """
        Test the /sys ucs API
        :return:
        """
        url, headers = self.ucs_url_factory("sys")
        api_data = fit_common.restful(url, rest_headers=headers)
        self.assertEqual(api_data['status'], 200,
                         'Incorrect HTTP return code, expected 200, got:' + str(api_data['status']))

        self.assertEqual(len(api_data["json"]["Fabric Interconnects"]), 2,
                         "Expected 2 Fabric Interconnects but found {0}"
                         .format(len(api_data["json"]["Fabric Interconnects"])))
        self.assertEqual(len(api_data["json"]["Servers"]), 7, "Expected 7 Servers but found {0}"
                         .format(len(api_data["json"]["Servers"])))
        self.assertEqual(len(api_data["json"]["FEX"]), 2, "Expected 2 FEX but found {0}"
                         .format(len(api_data["json"]["FEX"])))
        self.assertEqual(len(api_data["json"]["Chassis"]), 4, "Expected 2 Chassis but found {0}"
                         .format(len(api_data["json"]["Chassis"])))

    @depends(after=test_check_ucs_params)
    def test_ucs_get_rackmount(self):
        """
        Test the /rackmount ucs API
        :return:
        """
        url, headers = self.ucs_url_factory("rackmount")
        api_data = fit_common.restful(url, rest_headers=headers)
        self.assertEqual(api_data['status'], 200,
                         'Incorrect HTTP return code, expected 200, got:' + str(api_data['status']))
        self.assertGreaterEqual(len(api_data["json"]), 1, "Expected 1  or more Rackmounts but found {0}".
                                format(len(api_data["json"])))
        # TO DO more in depth testing for the returned content such as mac validation, etc...

    @depends(after=test_check_ucs_params)
    def test_ucs_get_chassis(self):
        """
            Test the /chassis ucs API
            :return:
            """
        url, headers = self.ucs_url_factory("chassis")
        api_data = fit_common.restful(url, rest_headers=headers)
        self.assertEqual(api_data['status'], 200,
                         'Incorrect HTTP return code, expected 200, got:' + str(api_data['status']))
        self.assertGreaterEqual(len(api_data["json"]), 4, "Expected 4 chassis or more but found {0}".
                                format(len(api_data["json"])))
        # TO DO more in depth testing for the returned content such as mac validation, etc...

    @depends(after=test_check_ucs_params)
    def test_api_20_ucs_get_catalog(self):
        """
        Test the /sys ucs API
        :return:
        """
        url, headers = self.ucs_url_factory("sys")
        api_data = fit_common.restful(url, rest_headers=headers)
        self.assertEqual(api_data['status'], 200,
                         'Incorrect HTTP return code, expected 200, got:' + str(api_data['status']))
        total_elements = 0
        for elementTypes in api_data["json"]:
            for element in api_data["json"][str(elementTypes)]:
                url, headers = self.ucs_url_factory("catalog", identifier=element["relative_path"].split("/")[-1])
                api_data_c = fit_common.restful(url, rest_headers=headers)
                self.assertEqual(api_data['status'], 200,
                                 'Incorrect HTTP return code, expected 200, got:' + str(api_data_c['status']))
                total_elements += 1
        self.assertGreaterEqual(total_elements, 15, "Expected at least 15 elements but found {0}"
                                .format(total_elements))
コード例 #19
0
class ucs_api(unittest.TestCase):

    def ucs_url_factory(self, api, identifier=None):
        """
        returns a fully qualified UCS API
        :param api:UCS API
        :param identifier: identify the ucs element in the catalog API
        :return:
        """

        if identifier is None:
            url = UCS_SERVICE_URI + "/" + api
        else:
            url = UCS_SERVICE_URI + "/" + api + "?identifier=" + identifier
        headers = {"ucs-user": UCSM_USER,
                   "ucs-password": UCSM_PASS,
                   "ucs-host": UCSM_IP}
        return (url, headers)

    @unittest.skipUnless("ucsm_ip" in fit_common.fitcfg(), "")
    def test_check_ucs_params(self):
        self.assertNotEqual(UCSM_IP, None, "Expected value for UCSM_IP other then None and found {0}"
                            .format(UCSM_IP))
        self.assertNotEqual(UCS_SERVICE_URI, None,
                            "Expected value for UCS_SERVICE_URI other then None and found {0}"
                            .format(UCS_SERVICE_URI))

    @depends(after=test_check_ucs_params)
    def test_ucs_log_in(self):
        """
        Test the /logIn ucs API
        :return:
        """
        url, headers = self.ucs_url_factory("login")
        api_data = fit_common.restful(url, rest_headers=headers)
        self.assertEqual(api_data['status'], 200,
                         'Incorrect HTTP return code, expected 200, got:' + str(api_data['status']))

        self.assertNotEqual(api_data["json"], None, "Expected a token to be returned on login and received None")
        self.assertNotEqual(type(api_data["json"]), "unicode", "Unexpected Token was received on Login")

    @depends(after=test_check_ucs_params)
    def test_ucs_get_sys(self):
        """
        Test the /sys ucs API
        :return:
        """
        url, headers = self.ucs_url_factory("sys")
        api_data = fit_common.restful(url, rest_headers=headers)
        self.assertEqual(api_data['status'], 200,
                         'Incorrect HTTP return code, expected 200, got:' + str(api_data['status']))

        self.assertEqual(len(api_data["json"]["Fabric Interconnects"]), 2,
                         "Expected 2 Fabric Interconnects but found {0}"
                         .format(len(api_data["json"]["Fabric Interconnects"])))
        self.assertEqual(len(api_data["json"]["Servers"]), 7, "Expected 7 Servers but found {0}"
                         .format(len(api_data["json"]["Servers"])))
        self.assertEqual(len(api_data["json"]["FEX"]), 2, "Expected 2 FEX but found {0}"
                         .format(len(api_data["json"]["FEX"])))
        self.assertEqual(len(api_data["json"]["Chassis"]), 4, "Expected 2 Chassis but found {0}"
                         .format(len(api_data["json"]["Chassis"])))

    @depends(after=test_check_ucs_params)
    def test_ucs_get_rackmount(self):
        """
        Test the /rackmount ucs API
        :return:
        """
        url, headers = self.ucs_url_factory("rackmount")
        api_data = fit_common.restful(url, rest_headers=headers)
        self.assertEqual(api_data['status'], 200,
                         'Incorrect HTTP return code, expected 200, got:' + str(api_data['status']))
        self.assertEqual(len(api_data["json"]), 7, "Expected 7 Rackmounts but found {0}".
                                format(len(api_data["json"])))
        # TO DO more in depth testing for the returned content such as mac validation, etc...

    @depends(after=test_check_ucs_params)
    def test_ucs_get_chassis(self):
        """
        Test the /chassis ucs API
        :return:
        """
        url, headers = self.ucs_url_factory("chassis")
        api_data = fit_common.restful(url, rest_headers=headers)
        self.assertEqual(api_data['status'], 200,
                         'Incorrect HTTP return code, expected 200, got:' + str(api_data['status']))
        self.assertEqual(len(api_data["json"]), 4, "Expected 4 chassis but found {0}".
                                format(len(api_data["json"])))
        # TO DO more in depth testing for the returned content such as mac validation, etc...

    @depends(after=test_ucs_get_chassis)
    def test_ucs_get_serviceProfile(self):
        """
        Test the /serviceProfile ucs API
        :return:
        """
        url, headers = self.ucs_url_factory("serviceProfile")
        api_data = fit_common.restful(url, rest_headers=headers)
        self.assertEqual(api_data['status'], 200,
                         'Incorrect HTTP return code, expected 200, got:' + str(api_data['status']))
        self.assertEqual(len(api_data["json"]["ServiceProfile"]["members"]), 18,
                         "Expected 18 chassis or more but found {0}"
                         .format(len(api_data["json"]["ServiceProfile"]["members"])))
        # TO DO more in depth testing for the returned content such as mac validation, etc...

    @depends(after=test_check_ucs_params)
    def test_api_20_ucs_get_catalog(self):
        """
        Test the /sys ucs API
        :return:
        """
        url, headers = self.ucs_url_factory("sys")
        api_data = fit_common.restful(url, rest_headers=headers)
        self.assertEqual(api_data['status'], 200,
                         'Incorrect HTTP return code, expected 200, got:' + str(api_data['status']))
        total_elements = 0
        for elementTypes in api_data["json"]:
            for element in api_data["json"][str(elementTypes)]:
                url, headers = self.ucs_url_factory("catalog", identifier=element["relative_path"].split("/")[-1])
                api_data_c = fit_common.restful(url, rest_headers=headers)
                self.assertEqual(api_data_c['status'], 200,
                                 'Incorrect HTTP return code, expected 200, got:' + str(api_data_c['status']))
                total_elements += 1
        self.assertEqual(total_elements, 15, "Expected 15 elements but found {0}"
                                .format(total_elements))
        # TO DO: deeper check on the catalog data

    def check_all_server_power_state(self, state):
        """
        Test to see if all Associated servers are in the specified state
        :return: True or False
        """

        url, headers = self.ucs_url_factory("serviceProfile")
        api_data = fit_common.restful(url, rest_headers=headers)
        self.assertEqual(api_data['status'], 200,
                         'Incorrect HTTP return code, expected 200, got:' + str(api_data['status']))
        total_elements = 0
        for server in api_data["json"]["ServiceProfile"]["members"]:
            url, headers = self.ucs_url_factory("power", identifier=str(server["path"]))
            api_data_c = fit_common.restful(url, rest_headers=headers)
            self.assertEqual(api_data_c['status'], 200,
                             'Incorrect HTTP return code, expected 200, got:' + str(api_data_c['status']))
            self.assertEqual(api_data_c["json"]["serverState"], state,
                             'Server ' + str(server["path"]) + ' reported power state ' +
                             str(api_data_c["json"]["serverState"]) + ' expected: ' + state)
            total_elements += 1
        self.assertEqual(total_elements, 18, "Expected 18 elements but found {0}"
                         .format(total_elements))

    def set_all_server_power_state(self, state):
        """
        Use the POST /power ucs API to set the state of all servers
        :return:
        """

        url, headers = self.ucs_url_factory("serviceProfile")
        api_data = fit_common.restful(url, rest_headers=headers)
        self.assertEqual(api_data['status'], 200,
                         'Incorrect HTTP return code, expected 200, got:' + str(api_data['status']))
        total_elements = 0
        for server in api_data["json"]["ServiceProfile"]["members"]:
            url, headers = self.ucs_url_factory("power", identifier=str(server["path"]))
            api_data_c = fit_common.restful(url + "&action=" + state, rest_headers=headers, rest_action='post')
            self.assertEqual(api_data_c['status'], 200,
                             'Incorrect HTTP return code, expected 200, got:' + str(api_data_c['status']))
            total_elements += 1
        self.assertEqual(total_elements, 18, "Expected 18 elements but found {0}"
                         .format(total_elements))

    @depends(after=test_check_ucs_params)
    def test_api_20_ucs_power(self):
        """
        Test the GET and POST api for server power state
        :return:
        """

        # first power off all servers
        self.set_all_server_power_state("off")
        # verify power state is down
        self.check_all_server_power_state("down")
        # now power on the servers
        self.set_all_server_power_state("on")
        # verify power state is up
        self.check_all_server_power_state("up")
コード例 #20
0
'''

import fit_path  # NOQA: unused import
from common import fit_common
import time
import flogging
from ucsmsdk import ucshandle
from ucsmsdk.utils.ucsbackup import import_ucs_backup
import os

logs = flogging.get_loggers()

INITIAL_NODES = {}
INITIAL_OBMS = {}
MAX_WAIT = 240
UCSM_IP = fit_common.fitcfg().get('ucsm_ip')
UCSM_USER = fit_common.fitcfg().get('ucsm_user')
UCSM_PASS = fit_common.fitcfg().get('ucsm_pass')
EXPECTED_UCS_PHYSICAL_NODES = 22
if fit_common.fitcfg().get('physical_nodes_count') is not None:
    EXPECTED_UCS_PHYSICAL_NODES = int(
        fit_common.fitcfg().get('physical_nodes_count'))
UCS_SERVICE_URI = fit_common.fitcfg().get('ucs_service_uri')


def get_nodes_utility():
    """
    Takes inventory of the nodes available before discovering the UCS nodes.
    We will restore the nodes collection to this snapshot
    :return: return False on failure, or True otherwise
    """