def test_check_selEntries_poller(self):
        # """Test: Checking that the selEntries pollers have started for all of the compute nodes"""
        node_id = self.__get_run_context('node_id')

        Api().nodes_get_pollers_by_id(identifier=node_id)
        pollers = self.__get_data()
        for poller in pollers:
            if get_by_string(poller, 'config.command') == "selEntries":
                self.__set_run_context('poller_id', poller['id'])
                break
        self.assertIsNotNone(self.__get_run_context('poller_id'),
                             msg='SelEntries poller not found for node {}'.format(node_id))
    def test_check_selEntries_poller(self):
        # """Test: Checking that the selEntries pollers have started for all of the compute nodes"""
        node_id = self.__get_run_context('node_id')

        Api().nodes_get_pollers_by_id(identifier=node_id)
        pollers = self.__get_data()
        for poller in pollers:
            if get_by_string(poller, 'config.command') == "selEntries":
                self.__set_run_context('poller_id', poller['id'])
                break
        self.assertIsNotNone(
            self.__get_run_context('poller_id'),
            msg='SelEntries poller not found for node {}'.format(node_id))
    def __generate_tar_ball(self, node_dmi_catalog, original_sku_id):
        # This function genetare a skupack tarball with a cutome rule

        if os.path.isdir(self.__rootDir):
            shutil.rmtree(self.__rootDir)
        os.mkdir(self.__rootDir)
        tarballDirs = ["profiles", "static", "tasks", "templates", "workflows"]
        for dir in tarballDirs:
            os.mkdir(self.__rootDir + dir)
        name = TEST_SKU_PACK_NAME
        self.__config_json = {
            "name":
            name,
            "rules": [{
                "path": "dmi.Base Board Information.Serial Number",
                "contains": " "
            }],
            "skuConfig": {
                "value1": {
                    "value": "value"
                },
                "sel": {
                    "alerts": [{
                        "Event Type Code": "01",
                        "Description": "/.+Non-critical going.+/",
                        "action": "warning"
                    }, {
                        "Event Type Code":
                        "01",
                        "Description":
                        "/(.+Critical going.+)|(Lower Non-recoverable going low)"
                        + "|(Upper Non-recoverable going high)/",
                        "action":
                        "critical"
                    }, {
                        "Sensor Type Code": "07",
                        "Event Type Code": "6f",
                        "Event Data": "/050000|080000|0a0000/",
                        "action": "warning"
                    }, {
                        "Sensor Type Code": "07",
                        "Event Type Code": "6f",
                        "Event Data":
                        "/000000|010000|020000|030000|040000|060000|0b0000/",
                        "action": "critical"
                    }, {
                        "Event Data": "00ffff",
                        "action": "warning"
                    }, {
                        "Sensor Type Code": "14",
                        "Event Type Code": "6f",
                        "Event Data": "/000000|020000|010000|030000|040000/",
                        "action": "warning"
                    }, {
                        "Sensor Type": "Event Logging Disabled",
                        "Description": "Log full",
                        "Event Direction": "Assertion Event",
                        "action": "warning"
                    }]
                }
            },
            "workflowRoot":
            "workflows",
            "taskRoot":
            "tasks",
            "httpProfileRoot":
            "profiles",
            "httpTemplateRoot":
            "templates",
            "httpStaticRoot":
            "static"
        }

        # fill in mock sku using the provided node_dmi_catalog
        node_serial_number = get_by_string(
            node_dmi_catalog,
            'data.Base Board Information.Serial Number').split(" ")[0]
        logs.info('Node serial number is: %s', node_serial_number)
        self.__config_json['rules'][0]['contains'] = node_serial_number

        # if there is no sku associated with this node, skip copy
        if original_sku_id:
            # copy the rules from the original sku into the mock sku
            Api().skus_id_get(identifier=original_sku_id)
            result = self.__client.last_response
            data = loads(self.__client.last_response.data)
            self.assertEqual(200, result.status, msg=result.reason)
            rules = get_by_string(data, 'rules')
            self.__config_json['rules'].extend(rules)
            logs.info("Sku rules are: \n%s\n",
                      dumps(self.__config_json['rules'], indent=4))

        with open(self.__rootDir + 'config.json', 'w') as f:
            dump(self.__config_json, f)
        f.close()

        os.chdir(self.__rootDir)
        with tarfile.open(self.__rootDir + "mytest.tar.gz", mode="w:gz") as f:
            for name in [
                    "config.json", "profiles", "static", "tasks", "templates",
                    "workflows"
            ]:
                f.add(name)
    def test_post_skupacks(self):
        # """Test posting skupacks that starts the sel alert poller"""
        # In order for the sel alert poller to be created there should be a
        # skupack posted  with the alerts in the config.json file
        # The code below dynamically creates the skupack  rule for each node based on their catalog

        Api().nodes_get_all()
        all_nodes = self.__get_data()

        # get the catalog of the node
        node_id, original_sku_id = self.__find_node_with_sku(all_nodes)
        self.assertIsNotNone(node_id, 'No node with with SKU and OBMs found')
        logs.info("node Id: %s  original sku id: %s", node_id, original_sku_id)

        # get the node BMC IP address
        Api().nodes_get_catalog_source_by_id(identifier=node_id, source='bmc')
        node_bmc = self.__get_data()
        node_bmc_mac = get_by_string(node_bmc, 'data.MAC Address')
        logs.info("bmc MAC address: %s", node_bmc_mac)

        Api().lookups_get(q=node_bmc_mac)
        dhcp_entry = self.__get_data()
        bmc_ip = dhcp_entry[0].get('ipAddress')
        logs.info("SLE object: %s", bmc_ip)

        self.__run_ipmitool_command(bmc_ip, "sel clear")

        Api().nodes_get_catalog_source_by_id(identifier=node_id, source='dmi')
        node_dmi_catalog = self.__get_data()

        if len(node_dmi_catalog) > 0:

            # Find the size of the SEL and how many entries can it handles
            available_sel_entries = self.__get_available_sel_entries(bmc_ip)

            # Deleting the sku pack
            self.__delete_skus(sku_name=TEST_SKU_PACK_NAME)

            # Generate and post the skupack with the updated rule
            self.__generate_tar_ball(node_dmi_catalog, original_sku_id)
            self.__file = {'file': open(self.__skuPackTarball, 'rb')}
            URL = config.host + config.api_root + '/skus/pack'
            logs.info("URL {0}".format(URL))
            requests.adapters.DEFAULT_RETRIES = 3
            sku_id = None
            for n in range(0, 5):
                try:
                    logs.info(
                        "Number of attempt to post  the skupack :  {0}".format(
                            n))
                    res = requests.post(URL, files=self.__file)
                    sku_id = loads(res.text).get('id')
                    break
                except requests.ConnectionError as e:
                    logs.info("Request Error {0}: ".format(e))

            self.assertIsNotNone(res,
                                 msg='Connection could not be established')
            self.assertEqual(201, res.status_code, msg=res.reason)
            self.assertIsNotNone(sku_id, msg='Sku ID not found')

            # Wait fot the POSTed sku to attach
            self.__wait_for_sku_to_attach(node_id, sku_id)

            self.__set_run_context("node_id", node_id)
            self.__set_run_context("bmc_ip", bmc_ip)
            self.__set_run_context("sku_id", sku_id)
            self.__set_run_context("original_sku_id", original_sku_id)
            self.__set_run_context("available_sel_entries",
                                   available_sel_entries)
        else:
            logs.warning('selInfoDuct we have none in a row!!!')
    def test_get_sku_nodes(self):
        # """Test GET /api/2.0/skus/:identifier/nodes"""
        mock_sku = {
            "name":
            "mytestsku",
            "rules": [{
                "path": "dmi.Base Board Information.Serial Number",
                "contains": " "
            }]
        }

        # get current node list
        Api().nodes_get_all()
        nodes = loads(self.__client.last_response.data)

        # find node with sku attached
        node_id, original_sku_id = self.find_node_with_sku(nodes)
        self.assertIsNotNone(node_id, msg=("No compute nodes found"))

        # get the dmi catalog for node and fill in mock sku
        Api().nodes_get_catalog_source_by_id(identifier=node_id, source='dmi')
        node_catalog_data = loads(self.__client.last_response.data)
        self.assertGreater(len(node_catalog_data),
                           0,
                           msg=("Node %s dmi catalog has zero length" %
                                node_id))
        node_serial_number = get_by_string(
            node_catalog_data,
            'data.Base Board Information.Serial Number').split(" ")[0]
        logs.info('Node serial number is: %s', node_serial_number)
        mock_sku['rules'][0]['contains'] = node_serial_number

        # if there is no sku associated with this node, skip copy
        if original_sku_id:
            # copy the rules from the original sku into the mock sku
            Api().skus_id_get(identifier=original_sku_id)
            result = self.__client.last_response
            data = loads(self.__client.last_response.data)
            self.assertEqual(200, result.status, msg=result.reason)
            rules = get_by_string(data, 'rules')
            mock_sku['rules'].extend(rules)
            logs.info("Sku rules are: \n%s\n",
                      dumps(mock_sku['rules'], indent=4))

        # POST the new sku
        logs.info("posting SKU : \n%s\n", (dumps(mock_sku, indent=4)))
        Api().skus_post(mock_sku)
        result = self.__client.last_response
        data = loads(self.__client.last_response.data)
        sku_id = data['id']
        logs.info("ID of the posted sku is: %s", sku_id)
        self.assertEqual(201, result.status, msg=result.reason)

        # Wait fot the POSTed sku to attach
        self.wait_for_sku_to_attach(node_id, sku_id)

        # validate the /api/2.0/skus/:id/nodes works
        Api().skus_id_get_nodes(sku_id)
        result = self.__client.last_response
        data = loads(self.__client.last_response.data)
        self.assertEqual(200, result.status, msg=result.reason)
        flag = False
        for item in data:
            if item["id"] == node_id:
                flag = True
                break
        self.assertTrue(flag, msg='Node id {} not found'.format(node_id))

        # delete the sku that where created
        logs.info(" Deleting the added sku of %s", sku_id)
        Api().skus_id_delete(identifier=sku_id)
        result = self.__client.last_response
        self.assertEqual(204, result.status, msg=result.reason)

        # if there is no sku_id, skip re-attachment tests
        if original_sku_id:
            # Wait for the original sku to re-attach
            self.wait_for_sku_to_attach(node_id, original_sku_id)

            # validate the /api/2.0/skus/:id/nodes works
            Api().skus_id_get_nodes(original_sku_id)
            result = self.__client.last_response
            data = loads(self.__client.last_response.data)
            self.assertEqual(200, result.status, msg=result.reason)
            flag = False
            for item in data:
                if item["id"] == node_id:
                    flag = True
                    break
            self.assertTrue(
                flag,
                msg='Node id {} is not assocaited the original sku id {}'.
                format(node_id, original_sku_id))
    def test_get_sku_nodes(self):
        # """Test GET /api/2.0/skus/:identifier/nodes"""
        mock_sku = {
            "name": "mytestsku",
            "rules": [
                {
                    "path": "dmi.Base Board Information.Serial Number",
                    "contains": " "
                }
            ]
        }

        # get current node list
        Api().nodes_get_all()
        nodes = loads(self.__client.last_response.data)

        # find node with sku attached
        node_id, original_sku_id = self.find_node_with_sku(nodes)
        self.assertIsNotNone(node_id, msg=("No compute nodes found"))

        # get the dmi catalog for node and fill in mock sku
        Api().nodes_get_catalog_source_by_id(identifier=node_id, source='dmi')
        node_catalog_data = loads(self.__client.last_response.data)
        self.assertGreater(len(node_catalog_data), 0, msg=("Node %s dmi catalog has zero length" % node_id))
        node_serial_number = get_by_string(node_catalog_data, 'data.Base Board Information.Serial Number').split(" ")[0]
        logs.info('Node serial number is: %s', node_serial_number)
        mock_sku['rules'][0]['contains'] = node_serial_number

        # if there is no sku associated with this node, skip copy
        if original_sku_id:
            # copy the rules from the original sku into the mock sku
            Api().skus_id_get(identifier=original_sku_id)
            result = self.__client.last_response
            data = loads(self.__client.last_response.data)
            self.assertEqual(200, result.status, msg=result.reason)
            rules = get_by_string(data, 'rules')
            mock_sku['rules'].extend(rules)
            logs.info("Sku rules are: \n%s\n", dumps(mock_sku['rules'], indent=4))

        # POST the new sku
        logs.info("posting SKU : \n%s\n", (dumps(mock_sku, indent=4)))
        Api().skus_post(mock_sku)
        result = self.__client.last_response
        data = loads(self.__client.last_response.data)
        sku_id = data['id']
        logs.info("ID of the posted sku is: %s", sku_id)
        self.assertEqual(201, result.status, msg=result.reason)

        # Wait fot the POSTed sku to attach
        self.wait_for_sku_to_attach(node_id, sku_id)

        # validate the /api/2.0/skus/:id/nodes works
        Api().skus_id_get_nodes(sku_id)
        result = self.__client.last_response
        data = loads(self.__client.last_response.data)
        self.assertEqual(200, result.status, msg=result.reason)
        flag = False
        for item in data:
            if item["id"] == node_id:
                flag = True
                break
        self.assertTrue(flag, msg='Node id {} not found'.format(node_id))

        # delete the sku that where created
        logs.info(" Deleting the added sku of %s", sku_id)
        Api().skus_id_delete(identifier=sku_id)
        result = self.__client.last_response
        self.assertEqual(204, result.status, msg=result.reason)

        # if there is no sku_id, skip re-attachment tests
        if original_sku_id:
            # Wait for the original sku to re-attach
            self.wait_for_sku_to_attach(node_id, original_sku_id)

            # validate the /api/2.0/skus/:id/nodes works
            Api().skus_id_get_nodes(original_sku_id)
            result = self.__client.last_response
            data = loads(self.__client.last_response.data)
            self.assertEqual(200, result.status, msg=result.reason)
            flag = False
            for item in data:
                if item["id"] == node_id:
                    flag = True
                    break
            self.assertTrue(flag, msg='Node id {} is not assocaited the original sku id {}'.format(node_id, original_sku_id))
    def __generate_tar_ball(self, node_dmi_catalog, original_sku_id):
        # This function genetare a skupack tarball with a cutome rule

        if os.path.isdir(self.__rootDir):
            shutil.rmtree(self.__rootDir)
        os.mkdir(self.__rootDir)
        tarballDirs = ["profiles", "static", "tasks", "templates", "workflows"]
        for dir in tarballDirs:
            os.mkdir(self.__rootDir + dir)
        name = TEST_SKU_PACK_NAME
        self.__config_json = {
            "name": name,
            "rules": [
                {
                    "path": "dmi.Base Board Information.Serial Number",
                    "contains": " "
                }
            ],
            "skuConfig": {
                "value1": {
                    "value": "value"
                },
                "sel": {
                    "alerts": [
                        {
                            "Event Type Code": "01",
                            "Description": "/.+Non-critical going.+/",
                            "action": "warning"
                        },
                        {
                            "Event Type Code": "01",
                            "Description": "/(.+Critical going.+)|(Lower Non-recoverable going low)" +
                                           "|(Upper Non-recoverable going high)/",
                            "action": "critical"
                        },
                        {
                            "Sensor Type Code": "07",
                            "Event Type Code": "6f",
                            "Event Data": "/050000|080000|0a0000/",
                            "action": "warning"
                        },
                        {
                            "Sensor Type Code": "07",
                            "Event Type Code": "6f",
                            "Event Data": "/000000|010000|020000|030000|040000|060000|0b0000/",
                            "action": "critical"
                        },
                        {
                            "Event Data": "00ffff",
                            "action": "warning"
                        },
                        {
                            "Sensor Type Code": "14",
                            "Event Type Code": "6f",
                            "Event Data": "/000000|020000|010000|030000|040000/",
                            "action": "warning"
                        },
                        {
                            "Sensor Type": "Event Logging Disabled",
                            "Description": "Log full",
                            "Event Direction": "Assertion Event",
                            "action": "warning"
                        }
                    ]
                }
            },
            "workflowRoot": "workflows",
            "taskRoot": "tasks",
            "httpProfileRoot": "profiles",
            "httpTemplateRoot": "templates",
            "httpStaticRoot": "static"
        }

        # fill in mock sku using the provided node_dmi_catalog
        node_serial_number = get_by_string(node_dmi_catalog, 'data.Base Board Information.Serial Number').split(" ")[0]
        logs.info('Node serial number is: %s', node_serial_number)
        self.__config_json['rules'][0]['contains'] = node_serial_number

        # if there is no sku associated with this node, skip copy
        if original_sku_id:
            # copy the rules from the original sku into the mock sku
            Api().skus_id_get(identifier=original_sku_id)
            result = self.__client.last_response
            data = loads(self.__client.last_response.data)
            self.assertEqual(200, result.status, msg=result.reason)
            rules = get_by_string(data, 'rules')
            self.__config_json['rules'].extend(rules)
            logs.info("Sku rules are: \n%s\n", dumps(self.__config_json['rules'], indent=4))

        with open(self.__rootDir + 'config.json', 'w') as f:
            dump(self.__config_json, f)
        f.close()

        os.chdir(self.__rootDir)
        with tarfile.open(self.__rootDir + "mytest.tar.gz", mode="w:gz") as f:
            for name in ["config.json", "profiles", "static", "tasks", "templates", "workflows"]:
                f.add(name)
    def test_post_skupacks(self):
        # """Test posting skupacks that starts the sel alert poller"""
        # In order for the sel alert poller to be created there should be a
        # skupack posted  with the alerts in the config.json file
        # The code below dynamically creates the skupack  rule for each node based on their catalog

        Api().nodes_get_all()
        all_nodes = self.__get_data()

        # get the catalog of the node
        node_id, original_sku_id = self.__find_node_with_sku(all_nodes)
        self.assertIsNotNone(node_id, 'No node with with SKU and OBMs found')
        logs.info("node Id: %s  original sku id: %s", node_id, original_sku_id)

        # get the node BMC IP address
        Api().nodes_get_catalog_source_by_id(identifier=node_id, source='bmc')
        node_bmc = self.__get_data()
        node_bmc_mac = get_by_string(node_bmc, 'data.MAC Address')
        logs.info("bmc MAC address: %s", node_bmc_mac)

        Api().lookups_get(q=node_bmc_mac)
        dhcp_entry = self.__get_data()
        bmc_ip = dhcp_entry[0].get('ipAddress')
        logs.info("SLE object: %s", bmc_ip)

        self.__run_ipmitool_command(bmc_ip, "sel clear")

        Api().nodes_get_catalog_source_by_id(identifier=node_id, source='dmi')
        node_dmi_catalog = self.__get_data()

        if len(node_dmi_catalog) > 0:

            # Find the size of the SEL and how many entries can it handles
            available_sel_entries = self.__get_available_sel_entries(bmc_ip)

            # Deleting the sku pack
            self.__delete_skus(sku_name=TEST_SKU_PACK_NAME)

            # Generate and post the skupack with the updated rule
            self.__generate_tar_ball(node_dmi_catalog, original_sku_id)
            self.__file = {'file': open(self.__skuPackTarball, 'rb')}
            URL = config.host + config.api_root + '/skus/pack'
            logs.info("URL {0}".format(URL))
            requests.adapters.DEFAULT_RETRIES = 3
            sku_id = None
            for n in range(0, 5):
                try:
                    logs.info("Number of attempt to post  the skupack :  {0}".format(n))
                    res = requests.post(URL, files=self.__file)
                    sku_id = loads(res.text).get('id')
                    break
                except requests.ConnectionError as e:
                    logs.info("Request Error {0}: ".format(e))

            self.assertIsNotNone(res, msg='Connection could not be established')
            self.assertEqual(201, res.status_code, msg=res.reason)
            self.assertIsNotNone(sku_id, msg='Sku ID not found')

            # Wait fot the POSTed sku to attach
            self.__wait_for_sku_to_attach(node_id, sku_id)

            self.__set_run_context("node_id", node_id)
            self.__set_run_context("bmc_ip", bmc_ip)
            self.__set_run_context("sku_id", sku_id)
            self.__set_run_context("original_sku_id", original_sku_id)
            self.__set_run_context("available_sel_entries", available_sel_entries)
        else:
            logs.warning('selInfoDuct we have none in a row!!!')