Пример #1
0
 def get_nodes(self):
     """
     Get all defined nodes
     """
     result = NodeAddressesList()
     for node in self.config.findall("./clusternodes/clusternode"):
         altname = node.find("altname")
         result.append(NodeAddresses(
             ring0=node.get("name"),
             ring1=altname.get("name") if altname is not None else None,
             name=None,
             id=node.get("nodeid")
         ))
     return result
Пример #2
0
    def test_one_node_down_forced(self, mock_corosync_live):
        conf_text = "test conf text"
        nodes = ["node1", "node2"]
        node_addrs_list = NodeAddressesList(
            [NodeAddresses(addr) for addr in nodes])
        mock_corosync_live.set_remote_corosync_conf = mock.MagicMock()

        def raiser(comm, node, conf):
            if node.ring0 == nodes[1]:
                raise NodeAuthenticationException(nodes[1], "command",
                                                  "HTTP error: 401")

        mock_corosync_live.set_remote_corosync_conf.side_effect = raiser

        lib.distribute_corosync_conf(self.mock_communicator,
                                     self.mock_reporter,
                                     node_addrs_list,
                                     conf_text,
                                     skip_offline_nodes=True)

        corosync_live_calls = [
            mock.call.set_remote_corosync_conf("mock node communicator",
                                               nodes[0], conf_text),
            mock.call.set_remote_corosync_conf("mock node communicator",
                                               nodes[1], conf_text),
        ]
        self.assertEqual(len(corosync_live_calls),
                         len(mock_corosync_live.mock_calls))
        mock_corosync_live.set_remote_corosync_conf.assert_has_calls(
            [
                mock.call("mock node communicator", node_addrs_list[0],
                          conf_text),
                mock.call("mock node communicator", node_addrs_list[1],
                          conf_text),
            ],
            any_order=True)

        assert_report_item_list_equal(self.mock_reporter.report_item_list, [
            (severity.INFO, report_codes.COROSYNC_CONFIG_DISTRIBUTION_STARTED,
             {}),
            (severity.INFO, report_codes.COROSYNC_CONFIG_ACCEPTED_BY_NODE, {
                "node": nodes[0]
            }),
            (severity.WARNING,
             report_codes.NODE_COMMUNICATION_ERROR_NOT_AUTHORIZED, {
                 "node": nodes[1],
                 "command": "command",
                 "reason": "HTTP error: 401",
             }),
            (severity.WARNING,
             report_codes.COROSYNC_CONFIG_DISTRIBUTION_NODE_ERROR, {
                 "node": nodes[1],
             }),
        ])
Пример #3
0
 def get_nodes(self):
     """
     Get all defined nodes
     """
     result = NodeAddressesList()
     for nodelist in self.config.get_sections("nodelist"):
         for node in nodelist.get_sections("node"):
             node_data = {
                 "ring0_addr": None,
                 "ring1_addr": None,
                 "name": None,
                 "nodeid": None,
             }
             for attr_name, attr_value in node.get_attributes():
                 if attr_name in node_data:
                     node_data[attr_name] = attr_value
             result.append(
                 NodeAddresses(node_data["ring0_addr"],
                               node_data["ring1_addr"], node_data["name"],
                               node_data["nodeid"]))
     return result
Пример #4
0
    def test_errors_forced(self):
        nodes = ["node1", "node2"]
        node_addrs_list = NodeAddressesList(
            [NodeAddresses(addr) for addr in nodes]
        )
        def side_effect(node, request, data):
            if node.ring0 == nodes[1]:
                raise NodeAuthenticationException(
                    nodes[1], "command", "HTTP error: 401"
                )
            return '{' # invalid json
        self.mock_communicator.call_node.side_effect = side_effect

        lib.check_corosync_offline_on_nodes(
            self.mock_communicator,
            self.mock_reporter,
            node_addrs_list,
            skip_offline_nodes=True
        )

        assert_report_item_list_equal(
            self.mock_reporter.report_item_list,
            [
                (
                    severity.INFO,
                    report_codes.COROSYNC_NOT_RUNNING_CHECK_STARTED,
                    {}
                ),
                (
                    severity.WARNING,
                    report_codes.COROSYNC_NOT_RUNNING_CHECK_NODE_ERROR,
                    {
                        "node": nodes[0],
                    }
                ),
                (
                    severity.WARNING,
                    report_codes.NODE_COMMUNICATION_ERROR_NOT_AUTHORIZED,
                    {
                        "node": nodes[1],
                        "command": "command",
                        "reason" : "HTTP error: 401",
                    }
                ),
                (
                    severity.WARNING,
                    report_codes.COROSYNC_NOT_RUNNING_CHECK_NODE_ERROR,
                    {
                        "node": nodes[1],
                    }
                )
            ]
        )
Пример #5
0
    def test_success(self, mock_corosync_live):
        conf_text = "test conf text"
        nodes = ["node1", "node2"]
        node_addrs_list = NodeAddressesList(
            [NodeAddresses(addr) for addr in nodes]
        )
        mock_corosync_live.set_remote_corosync_conf = mock.MagicMock()

        lib.distribute_corosync_conf(
            self.mock_communicator,
            self.mock_reporter,
            node_addrs_list,
            conf_text
        )

        corosync_live_calls = [
            mock.call.set_remote_corosync_conf(
                "mock node communicator", node_addrs_list[0], conf_text
            ),
            mock.call.set_remote_corosync_conf(
                "mock node communicator", node_addrs_list[1], conf_text
            ),
        ]
        self.assertEqual(
            len(corosync_live_calls),
            len(mock_corosync_live.mock_calls)
        )
        mock_corosync_live.set_remote_corosync_conf.assert_has_calls(
            corosync_live_calls,
            any_order=True
        )

        assert_report_item_list_equal(
            self.mock_reporter.report_item_list,
            [
                (
                    severity.INFO,
                    report_codes.COROSYNC_CONFIG_DISTRIBUTION_STARTED,
                    {}
                ),
                (
                    severity.INFO,
                    report_codes.COROSYNC_CONFIG_ACCEPTED_BY_NODE,
                    {"node": nodes[0]}
                ),
                (
                    severity.INFO,
                    report_codes.COROSYNC_CONFIG_ACCEPTED_BY_NODE,
                    {"node": nodes[1]}
                ),
            ]
        )
Пример #6
0
    def setUp(self):
        self.mock_env = mock.MagicMock(spec_set=LibraryEnvironment)
        self.mock_log = mock.MagicMock(spec_set=logging.Logger)
        self.mock_env.logger = self.mock_log
        self.mock_com = mock.MagicMock(spec_set=NodeCommunicator)
        self.mock_env.node_communicator.return_value = self.mock_com
        self.mock_run = mock.MagicMock(spec_set=CommandRunner)
        self.mock_env.cmd_runner.return_value = self.mock_run
        self.mock_rep = MockLibraryReportProcessor()
        self.mock_env.report_processor = self.mock_rep

        self.node_list = NodeAddressesList(
            [NodeAddresses("node" + str(i)) for i in range(3)])
Пример #7
0
 def setUp(self):
     self.env_assistant, self.config = get_env_tools(self)
     self.corosync_conf_facade = mock.MagicMock(CorosyncConfigFacade)
     self.corosync_conf_text = "corosync conf"
     self.corosync_conf_facade.config.export.return_value = (
         self.corosync_conf_text
     )
     self.corosync_conf_facade.get_nodes.return_value = NodeAddressesList([
         NodeAddresses("node-1"),
         NodeAddresses("node-2"),
     ])
     self.corosync_conf_facade.need_stopped_cluster = False
     self.corosync_conf_facade.need_qdevice_reload = False
     self.node_labels = ["node-1", "node-2"]
Пример #8
0
 def get_nodes(self):
     """
     Get all defined nodes
     """
     result = NodeAddressesList()
     for nodelist in self.config.get_sections("nodelist"):
         for node in nodelist.get_sections("node"):
             node_data = {
                 "ring0_addr": None,
                 "ring1_addr": None,
                 "name": None,
                 "nodeid": None,
             }
             for attr_name, attr_value in node.get_attributes():
                 if attr_name in node_data:
                     node_data[attr_name] = attr_value
             result.append(NodeAddresses(
                 node_data["ring0_addr"],
                 node_data["ring1_addr"],
                 node_data["name"],
                 node_data["nodeid"]
             ))
     return result
Пример #9
0
    def test_one_node_running(self):
        nodes = ["node1", "node2"]
        node_addrs_list = NodeAddressesList(
            [NodeAddresses(addr) for addr in nodes])
        self.mock_communicator.call_node.side_effect = [
            '{"corosync": false}',
            '{"corosync": true}',
        ]

        assert_raise_library_error(
            lambda: lib.check_corosync_offline_on_nodes(
                self.mock_communicator, self.mock_reporter, node_addrs_list),
            (severity.ERROR, report_codes.COROSYNC_RUNNING_ON_NODE, {
                "node": nodes[1],
            }))
Пример #10
0
    def test_one_node_running(self):
        node_responses = {
            "node1": '{"corosync": false}',
            "node2": '{"corosync": true}',
        }
        node_addrs_list = NodeAddressesList(
            [NodeAddresses(addr) for addr in node_responses.keys()])

        self.mock_communicator.call_node.side_effect = (
            lambda node, request, data: node_responses[node.label])

        assert_raise_library_error(
            lambda: lib.check_corosync_offline_on_nodes(
                self.mock_communicator, self.mock_reporter, node_addrs_list),
            (severity.ERROR, report_codes.COROSYNC_RUNNING_ON_NODE, {
                "node": "node2",
            }))
Пример #11
0
def _share_authkey(env,
                   current_nodes,
                   candidate_node_addresses,
                   allow_incomplete_distribution=False):
    if env.pacemaker.has_authkey:
        authkey_content = env.pacemaker.get_authkey_content()
        node_addresses_list = NodeAddressesList([candidate_node_addresses])
    else:
        authkey_content = generate_key()
        node_addresses_list = current_nodes + [candidate_node_addresses]

    nodes_task.distribute_files(
        env.node_communicator(),
        env.report_processor,
        node_communication_format.pcmk_authkey_file(authkey_content),
        node_addresses_list,
        allow_incomplete_distribution,
        description="remote node configuration files")
Пример #12
0
    def test_json_error(self):
        nodes = ["node1", "node2"]
        node_addrs_list = NodeAddressesList(
            [NodeAddresses(addr) for addr in nodes])
        self.mock_communicator.call_node.side_effect = [
            '{}',  # missing key
            '{',  # not valid json
        ]

        assert_raise_library_error(
            lambda: lib.check_corosync_offline_on_nodes(
                self.mock_communicator, self.mock_reporter, node_addrs_list),
            (severity.ERROR,
             report_codes.COROSYNC_NOT_RUNNING_CHECK_NODE_ERROR, {
                 "node": nodes[0],
             }, report_codes.SKIP_OFFLINE_NODES),
            (severity.ERROR,
             report_codes.COROSYNC_NOT_RUNNING_CHECK_NODE_ERROR, {
                 "node": nodes[1],
             }, report_codes.SKIP_OFFLINE_NODES))
Пример #13
0
    def test_success(self):
        nodes = ["node1", "node2"]
        node_addrs_list = NodeAddressesList(
            [NodeAddresses(addr) for addr in nodes])
        self.mock_communicator.call_node.return_value = '{"corosync": false}'

        lib.check_corosync_offline_on_nodes(self.mock_communicator,
                                            self.mock_reporter,
                                            node_addrs_list)

        assert_report_item_list_equal(self.mock_reporter.report_item_list, [
            (severity.INFO, report_codes.COROSYNC_NOT_RUNNING_CHECK_STARTED,
             {}),
            (severity.INFO, report_codes.COROSYNC_NOT_RUNNING_ON_NODE, {
                "node": nodes[0]
            }),
            (severity.INFO, report_codes.COROSYNC_NOT_RUNNING_ON_NODE, {
                "node": nodes[1]
            }),
        ])
Пример #14
0
def _share_authkey(env,
                   current_nodes,
                   candidate_node_addresses,
                   skip_offline_nodes=False,
                   allow_incomplete_distribution=False):
    if env.pacemaker.has_authkey:
        authkey_content = env.pacemaker.get_authkey_content()
        node_addresses_list = NodeAddressesList([candidate_node_addresses])
    else:
        authkey_content = generate_key()
        node_addresses_list = current_nodes + [candidate_node_addresses]

    com_cmd = DistributeFiles(
        env.report_processor,
        node_communication_format.pcmk_authkey_file(authkey_content),
        skip_offline_targets=skip_offline_nodes,
        allow_fails=allow_incomplete_distribution,
        description="remote node configuration files",
    )
    com_cmd.set_targets(
        env.get_node_target_factory().get_target_list(node_addresses_list))
    run_and_raise(env.get_node_communicator(), com_cmd)
Пример #15
0
    def test_success(self, mock_remote_start, mock_remote_stop):
        nodes = ["node1", "node2"]
        node_addrs_list = NodeAddressesList(
            [NodeAddresses(addr) for addr in nodes])

        lib.qdevice_reload_on_nodes(self.mock_communicator, self.mock_reporter,
                                    node_addrs_list)

        node_calls = [
            mock.call(self.mock_reporter, self.mock_communicator,
                      node_addrs_list[0]),
            mock.call(self.mock_reporter, self.mock_communicator,
                      node_addrs_list[1]),
        ]
        self.assertEqual(len(node_calls), len(mock_remote_stop.mock_calls))
        self.assertEqual(len(node_calls), len(mock_remote_start.mock_calls))
        mock_remote_stop.assert_has_calls(node_calls, any_order=True)
        mock_remote_start.assert_has_calls(node_calls, any_order=True)

        assert_report_item_list_equal(self.mock_reporter.report_item_list, [
            (severity.INFO, report_codes.QDEVICE_CLIENT_RELOAD_STARTED, {}),
        ])
Пример #16
0
    def test_node_down(self):
        nodes = ["node1", "node2"]
        node_addrs_list = NodeAddressesList(
            [NodeAddresses(addr) for addr in nodes]
        )
        def side_effect(node, request, data):
            if node.ring0 == nodes[1]:
                raise NodeAuthenticationException(
                    nodes[1], "command", "HTTP error: 401"
                )
            return '{"corosync": false}'
        self.mock_communicator.call_node.side_effect = side_effect

        assert_raise_library_error(
            lambda: lib.check_corosync_offline_on_nodes(
                self.mock_communicator,
                self.mock_reporter,
                node_addrs_list
            ),
            (
                severity.ERROR,
                report_codes.NODE_COMMUNICATION_ERROR_NOT_AUTHORIZED,
                {
                    "node": nodes[1],
                    "command": "command",
                    "reason" : "HTTP error: 401",
                },
                report_codes.SKIP_OFFLINE_NODES
            ),
            (
                severity.ERROR,
                report_codes.COROSYNC_NOT_RUNNING_CHECK_NODE_ERROR,
                {
                    "node": nodes[1],
                },
                report_codes.SKIP_OFFLINE_NODES
            )
        )
Пример #17
0
 def setUp(self):
     self.mock_communicator = mock.MagicMock(spec_set=NodeCommunicator)
     self.mock_reporter = MockLibraryReportProcessor()
     self.node_list = NodeAddressesList(
         [NodeAddresses("node" + str(i) for i in range(5))])
Пример #18
0
    def test_fail_doesnt_prevent_start(self, mock_remote_start,
                                       mock_remote_stop):
        nodes = ["node1", "node2"]
        node_addrs_list = NodeAddressesList(
            [NodeAddresses(addr) for addr in nodes])

        def raiser(reporter, communicator, node):
            if node.ring0 == nodes[1]:
                raise NodeAuthenticationException(node.label, "command",
                                                  "HTTP error: 401")

        mock_remote_start.side_effect = raiser

        assert_raise_library_error(
            lambda: lib.qdevice_reload_on_nodes(
                self.mock_communicator, self.mock_reporter, node_addrs_list),
            # why the same error twice?
            # 1. Tested piece of code calls a function which puts an error
            # into the reporter. The reporter raises an exception. The
            # exception is caught in the tested piece of code, stored, and
            # later put to reporter again.
            # 2. Mock reporter remembers everything that goes through it
            # and by the machanism described in 1 the error goes througt it
            # twice.
            (severity.ERROR,
             report_codes.NODE_COMMUNICATION_ERROR_NOT_AUTHORIZED, {
                 "node": nodes[1],
                 "command": "command",
                 "reason": "HTTP error: 401",
             }, report_codes.SKIP_OFFLINE_NODES),
            (severity.ERROR,
             report_codes.NODE_COMMUNICATION_ERROR_NOT_AUTHORIZED, {
                 "node": nodes[1],
                 "command": "command",
                 "reason": "HTTP error: 401",
             }, report_codes.SKIP_OFFLINE_NODES))

        node_calls = [
            mock.call(self.mock_reporter, self.mock_communicator,
                      node_addrs_list[0]),
            mock.call(self.mock_reporter, self.mock_communicator,
                      node_addrs_list[1]),
        ]
        self.assertEqual(len(node_calls), len(mock_remote_stop.mock_calls))
        self.assertEqual(len(node_calls), len(mock_remote_start.mock_calls))
        mock_remote_stop.assert_has_calls(node_calls, any_order=True)
        mock_remote_start.assert_has_calls(node_calls, any_order=True)

        assert_report_item_list_equal(
            self.mock_reporter.report_item_list,
            [
                (severity.INFO, report_codes.QDEVICE_CLIENT_RELOAD_STARTED,
                 {}),
                # why the same error twice?
                # 1. Tested piece of code calls a function which puts an error
                # into the reporter. The reporter raises an exception. The
                # exception is caught in the tested piece of code, stored, and
                # later put to reporter again.
                # 2. Mock reporter remembers everything that goes through it
                # and by the machanism described in 1 the error goes througt it
                # twice.
                (severity.ERROR,
                 report_codes.NODE_COMMUNICATION_ERROR_NOT_AUTHORIZED, {
                     "node": nodes[1],
                     "command": "command",
                     "reason": "HTTP error: 401",
                 }, report_codes.SKIP_OFFLINE_NODES),
                (severity.ERROR,
                 report_codes.NODE_COMMUNICATION_ERROR_NOT_AUTHORIZED, {
                     "node": nodes[1],
                     "command": "command",
                     "reason": "HTTP error: 401",
                 }, report_codes.SKIP_OFFLINE_NODES),
            ])
Пример #19
0
 def setUp(self):
     self.node_list = NodeAddressesList([
         NodeAddresses("node1"),
         NodeAddresses("node2"),
         NodeAddresses("node3"),
     ])
Пример #20
0
def get_nodes_remote(tree):
    return NodeAddressesList(remote_node.find_node_list(get_root(tree)))
Пример #21
0
def get_nodes_guest(tree):
    return NodeAddressesList(guest_node.find_node_list(get_root(tree)))
Пример #22
0
 def setUp(self):
     self.node_list = NodeAddressesList(
         [NodeAddresses("node" + str(i)) for i in range(5)]
     )