Ejemplo n.º 1
0
    def run(self, context):
        """Returns the parameters for fencing controller nodes"""
        hostmap = nodes.generate_hostmap(self.get_baremetal_client(context),
                                         self.get_compute_client(context))
        fence_params = {"EnableFencing": True, "FencingConfig": {}}
        devices = []

        for node in self.nodes_json:
            node_data = {}
            params = {}
            if "ports" in node:
                # Not all Ironic drivers present a MAC address, so we only
                # capture it if it's present
                mac_addr = node['ports'][0]['address'].lower()
                node_data["host_mac"] = mac_addr

                # If the MAC isn't in the hostmap, this node hasn't been
                # provisioned, so no fencing parameters are necessary
                if hostmap and mac_addr not in hostmap:
                    continue

            # Build up fencing parameters based on which Ironic driver this
            # node is using
            try:
                # Deprecated classic drivers (pxe_ipmitool, etc)
                driver_proto = node['pm_type'].split('_')[1]
            except IndexError:
                # New-style hardware types (ipmi, etc)
                driver_proto = node['pm_type']

            if driver_proto in {'ipmi', 'ipmitool', 'drac', 'idrac', 'ilo'}:
                # IPMI fencing driver
                node_data["agent"] = "fence_ipmilan"
                params["ipaddr"] = node["pm_addr"]
                params["passwd"] = node["pm_password"]
                params["login"] = node["pm_user"]
                if hostmap:
                    params["pcmk_host_list"] = \
                        hostmap[mac_addr]["compute_name"]
                if "pm_port" in node:
                    params["ipport"] = node["pm_port"]
                if self.ipmi_lanplus:
                    params["lanplus"] = self.ipmi_lanplus
                if self.delay:
                    params["delay"] = self.delay
                if self.ipmi_cipher:
                    params["cipher"] = self.ipmi_cipher
                if self.ipmi_level:
                    params["privlvl"] = self.ipmi_level
            else:
                error = ("Unable to generate fencing parameters for %s" %
                         node["pm_type"])
                raise ValueError(error)

            node_data["params"] = params
            devices.append(node_data)

        fence_params["FencingConfig"]["devices"] = devices
        return {"parameter_defaults": fence_params}
Ejemplo n.º 2
0
    def test_generate_hostmap(self):

        # two instances in 'nova list'.
        # vm1 with id=123 and vm2 with id=234
        server1 = mock.MagicMock()
        server1.id = 123
        server1.name = 'vm1'

        server2 = mock.MagicMock()
        server2.id = 234
        server2.name = 'vm2'

        servers = mock.MagicMock()
        servers = [server1, server2]

        compute_client = mock.MagicMock()
        compute_client.servers.list.side_effect = (servers, )

        # we assume instance id=123 has been provisioned using bm node 'bm1'
        # while instance id=234 is in error state, so no bm node has been used

        def side_effect(args):
            if args == 123:
                return bm1
            if args == 234:
                raise ironicexceptions.NotFound

        baremetal_client = mock.MagicMock()
        baremetal_client.node.get_by_instance_uuid = mock.MagicMock(
            side_effect=side_effect)

        # bm server with name='bm1' and uuid='9876'
        bm1 = mock.MagicMock()
        bm1.uuid = 9876
        bm1.name = 'bm1'

        # 'bm1' has a single port with mac='aa:bb:cc:dd:ee:ff'
        port1 = mock.MagicMock()
        port1.address = 'aa:bb:cc:dd:ee:ff'

        def side_effect2(node, *args):
            if node == 9876:
                return [port1, ]
            raise ironicexceptions.NotFound

        baremetal_client.port.list = mock.MagicMock(side_effect=side_effect2)

        expected_hostmap = {
            'aa:bb:cc:dd:ee:ff': {
                'compute_name': 'vm1',
                'baremetal_name': 'bm1'
                }
            }

        result = nodes.generate_hostmap(baremetal_client, compute_client)
        self.assertEqual(result, expected_hostmap)
Ejemplo n.º 3
0
    def run(self, context):
        """Returns the parameters for fencing controller nodes"""
        hostmap = nodes.generate_hostmap(self.get_baremetal_client(context),
                                         self.get_compute_client(context))
        fence_params = {"EnableFencing": True, "FencingConfig": {}}
        devices = []

        for node in self.nodes_json:
            node_data = {}
            params = {}
            if "mac" in node:
                # Not all Ironic drivers present a MAC address, so we only
                # capture it if it's present
                mac_addr = node["mac"][0]
                node_data["host_mac"] = mac_addr

                # If the MAC isn't in the hostmap, this node hasn't been
                # provisioned, so no fencing parameters are necessary
                if mac_addr not in hostmap:
                    continue

            # Build up fencing parameters based on which Ironic driver this
            # node is using
            if node["pm_type"] == "pxe_ssh":
                # Ironic fencing driver
                node_data["agent"] = "fence_ironic"
                if self.fence_action:
                    params["action"] = self.fence_action
                params["auth_url"] = self.os_auth["auth_url"]
                params["login"] = self.os_auth["login"]
                params["passwd"] = self.os_auth["passwd"]
                params["tenant_name"] = self.os_auth["tenant_name"]
                params["pcmk_host_map"] = "%(compute_name)s:%(bm_name)s" % (
                    {
                        "compute_name": hostmap[mac_addr]["compute_name"],
                        "bm_name": hostmap[mac_addr]["baremetal_name"]
                    })
                if self.delay:
                    params["delay"] = self.delay
            elif (node['pm_type'] == 'ipmi' or node["pm_type"].split('_')[1]
                  in ("ipmitool", "ilo", "drac")):
                # IPMI fencing driver
                node_data["agent"] = "fence_ipmilan"
                if self.fence_action:
                    params["action"] = self.fence_action
                params["ipaddr"] = node["pm_addr"]
                params["passwd"] = node["pm_password"]
                params["login"] = node["pm_user"]
                params["pcmk_host_list"] = hostmap[mac_addr]["compute_name"]
                if "pm_port" in node:
                    params["ipport"] = node["pm_port"]
                if self.ipmi_lanplus:
                    params["lanplus"] = self.ipmi_lanplus
                if self.delay:
                    params["delay"] = self.delay
                if self.ipmi_cipher:
                    params["cipher"] = self.ipmi_cipher
                if self.ipmi_level:
                    params["privlvl"] = self.ipmi_level
            else:
                error = ("Unable to generate fencing parameters for %s" %
                         node["pm_type"])
                raise ValueError(error)

            node_data["params"] = params
            devices.append(node_data)

        fence_params["FencingConfig"]["devices"] = devices
        return {"parameter_defaults": fence_params}
Ejemplo n.º 4
0
    def run(self, context):
        """Returns the parameters for fencing controller nodes"""
        hostmap = nodes.generate_hostmap(self.get_baremetal_client(context),
                                         self.get_compute_client(context))
        fence_params = {"EnableFencing": True, "FencingConfig": {}}
        devices = []

        for node in self.nodes_json:
            node_data = {}
            params = {}
            if "mac" in node:
                # Not all Ironic drivers present a MAC address, so we only
                # capture it if it's present
                mac_addr = node["mac"][0]
                node_data["host_mac"] = mac_addr

                # If the MAC isn't in the hostmap, this node hasn't been
                # provisioned, so no fencing parameters are necessary
                if mac_addr not in hostmap:
                    continue

            # Build up fencing parameters based on which Ironic driver this
            # node is using
            if node["pm_type"] == "pxe_ssh":
                # Ironic fencing driver
                node_data["agent"] = "fence_ironic"
                if self.fence_action:
                    params["action"] = self.fence_action
                params["auth_url"] = self.os_auth["auth_url"]
                params["login"] = self.os_auth["login"]
                params["passwd"] = self.os_auth["passwd"]
                params["tenant_name"] = self.os_auth["tenant_name"]
                params["pcmk_host_map"] = "%(compute_name)s:%(bm_name)s" % (
                    {"compute_name": hostmap[mac_addr]["compute_name"],
                     "bm_name": hostmap[mac_addr]["baremetal_name"]})
                if self.delay:
                    params["delay"] = self.delay
            elif (node['pm_type'] == 'ipmi' or node["pm_type"].split('_')[1] in
                  ("ipmitool", "ilo", "drac")):
                # IPMI fencing driver
                node_data["agent"] = "fence_ipmilan"
                if self.fence_action:
                    params["action"] = self.fence_action
                params["ipaddr"] = node["pm_addr"]
                params["passwd"] = node["pm_password"]
                params["login"] = node["pm_user"]
                params["pcmk_host_list"] = hostmap[mac_addr]["compute_name"]
                if "pm_port" in node:
                    params["ipport"] = node["pm_port"]
                if self.ipmi_lanplus:
                    params["lanplus"] = self.ipmi_lanplus
                if self.delay:
                    params["delay"] = self.delay
                if self.ipmi_cipher:
                    params["cipher"] = self.ipmi_cipher
                if self.ipmi_level:
                    params["privlvl"] = self.ipmi_level
            else:
                error = ("Unable to generate fencing parameters for %s" %
                         node["pm_type"])
                raise ValueError(error)

            node_data["params"] = params
            devices.append(node_data)

        fence_params["FencingConfig"]["devices"] = devices
        return {"parameter_defaults": fence_params}