Blob Blame History Raw
From db91fd68f1baa7b19f06dc8156822430decce4e7 Mon Sep 17 00:00:00 2001
From: Miroslav Lisik <mlisik@redhat.com>
Date: Thu, 2 Sep 2021 10:29:59 +0200
Subject: [PATCH 1/2] update

---
 Makefile.am                                   |   9 +-
 configure.ac                                  |   5 +
 pcs/config.py                                 |  13 +-
 pcs/lib/communication/corosync.py             |   8 +-
 pcs/utils.py                                  |   4 +-
 pcs_test/suite.py                             |  70 ++
 .../cluster/test_add_nodes_validation.py      |  18 +-
 .../test_stonith_update_scsi_devices.py       |  11 +-
 pcs_test/tier0/lib/test_env_corosync.py       | 618 ++++++++--------
 pcs_test/tier1/legacy/test_constraints.py     |  76 +-
 pcs_test/tier1/legacy/test_resource.py        |  48 +-
 pcs_test/tier1/legacy/test_stonith.py         |  71 +-
 .../tools/command_env/config_http_corosync.py |  23 +-
 pcs_test/tools/fixture_cib.py                 |  65 ++
 pcsd/Makefile.am                              |   1 -
 pcsd/capabilities.xml                         |   7 -
 pcsd/fenceagent.rb                            |  59 --
 pcsd/pcs.rb                                   |  15 -
 pcsd/pcsd.rb                                  | 671 +-----------------
 pcsd/remote.rb                                | 559 +--------------
 pcsd/resource.rb                              |   3 -
 pcsd/rserver.rb                               |   1 -
 pcsd/test/test_resource.rb                    |   4 -
 23 files changed, 634 insertions(+), 1725 deletions(-)
 delete mode 100644 pcsd/fenceagent.rb

diff --git a/Makefile.am b/Makefile.am
index 6aede970..34692969 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -188,8 +188,13 @@ endif
 
 pylint:
 if DEV_TESTS
+if PARALLEL_PYLINT
+pylint_options = --jobs=0
+else
+pylint_options = 
+endif
 	export PYTHONPATH=${abs_top_builddir}/${PCS_BUNDLED_DIR_LOCAL}/packages && \
-		$(TIME) $(PYTHON) -m pylint --rcfile pylintrc --persistent=n --reports=n --score=n --disable similarities ${PCS_PYTHON_PACKAGES}
+		$(TIME) $(PYTHON) -m pylint --rcfile pylintrc --persistent=n --reports=n --score=n --disable similarities ${pylint_options} ${PCS_PYTHON_PACKAGES}
 endif
 
 
@@ -213,7 +218,7 @@ endif
 
 tests_tier0:
 	export PYTHONPATH=${abs_top_builddir}/${PCS_BUNDLED_DIR_LOCAL}/packages && \
-		$(PYTHON) ${abs_builddir}/pcs_test/suite.py $(python_test_options) --tier0
+		$(PYTHON) ${abs_builddir}/pcs_test/suite.py ${python_test_options} --tier0
 
 tests_tier1:
 if EXECUTE_TIER1_TESTS
diff --git a/configure.ac b/configure.ac
index f7b9d1ad..75d65616 100644
--- a/configure.ac
+++ b/configure.ac
@@ -148,6 +148,11 @@ AC_ARG_ENABLE([parallel-tests],
 	      [parallel_tests="yes"])
 AM_CONDITIONAL([PARALLEL_TESTS], [test "x$parallel_tests" = "xyes"])
 
+AC_ARG_ENABLE([parallel-pylint],
+	      [AS_HELP_STRING([--enable-parallel-pylint], [Enable running pylint in multiple threads (default: no)])],
+	      [parallel_pylint="yes"])
+AM_CONDITIONAL([PARALLEL_PYLINT], [test "x$parallel_pylint" = "xyes"])
+
 AC_ARG_ENABLE([local-build],
 	      [AS_HELP_STRING([--enable-local-build], [Download and install all dependencies as user / bundles])],
 	      [local_build="yes"])
diff --git a/pcs/config.py b/pcs/config.py
index a0290499..a3e7e164 100644
--- a/pcs/config.py
+++ b/pcs/config.py
@@ -345,12 +345,13 @@ def config_restore_remote(infile_name, infile_obj):
                 err_msgs.append(output)
                 continue
             _status = json.loads(output)
-            if (
-                _status["corosync"]
-                or _status["pacemaker"]
-                or
-                # not supported by older pcsd, do not fail if not present
-                _status.get("pacemaker_remote", False)
+            if any(
+                _status["node"]["services"][service_name]["running"]
+                for service_name in (
+                    "corosync",
+                    "pacemaker",
+                    "pacemaker_remote",
+                )
             ):
                 err_msgs.append(
                     "Cluster is currently running on node %s. You need to stop "
diff --git a/pcs/lib/communication/corosync.py b/pcs/lib/communication/corosync.py
index fab8e38f..e2a2949c 100644
--- a/pcs/lib/communication/corosync.py
+++ b/pcs/lib/communication/corosync.py
@@ -28,7 +28,7 @@ class CheckCorosyncOffline(
             self._set_skip_offline(skip_offline_targets)
 
     def _get_request_data(self):
-        return RequestData("remote/status")
+        return RequestData("remote/status", [("version", "2")])
 
     def _process_response(self, response):
         report_item = self._get_response_report(response)
@@ -53,7 +53,7 @@ class CheckCorosyncOffline(
             return
         try:
             status = response.data
-            if not json.loads(status)["corosync"]:
+            if not json.loads(status)["node"]["corosync"]:
                 report_item = ReportItem.info(
                     reports.messages.CorosyncNotRunningOnNode(node_label),
                 )
@@ -94,7 +94,7 @@ class GetCorosyncOnlineTargets(
         self._corosync_online_target_list = []
 
     def _get_request_data(self):
-        return RequestData("remote/status")
+        return RequestData("remote/status", [("version", "2")])
 
     def _process_response(self, response):
         report_item = self._get_response_report(response)
@@ -103,7 +103,7 @@ class GetCorosyncOnlineTargets(
             return
         try:
             status = response.data
-            if json.loads(status)["corosync"]:
+            if json.loads(status)["node"]["corosync"]:
                 self._corosync_online_target_list.append(
                     response.request.target
                 )
diff --git a/pcs/utils.py b/pcs/utils.py
index ef778b52..7774016e 100644
--- a/pcs/utils.py
+++ b/pcs/utils.py
@@ -186,7 +186,9 @@ def checkStatus(node):
     Commandline options:
       * --request-timeout - timeout for HTTP requests
     """
-    return sendHTTPRequest(node, "remote/status", None, False, False)
+    return sendHTTPRequest(
+        node, "remote/status", urlencode({"version": "2"}), False, False
+    )
 
 
 # Check and see if we're authorized (faster than a status check)
diff --git a/pcs_test/suite.py b/pcs_test/suite.py
index 75ab66cd..bd98b8b0 100644
--- a/pcs_test/suite.py
+++ b/pcs_test/suite.py
@@ -1,6 +1,8 @@
 import importlib
 import os
 import sys
+from threading import Thread
+import time
 import unittest
 
 try:
@@ -84,6 +86,67 @@ def discover_tests(
     return unittest.TestLoader().loadTestsFromNames(explicitly_enumerated_tests)
 
 
+def tier1_fixtures_needed(test_list):
+    for test_name in tests_from_suite(test_list):
+        if test_name.startswith("pcs_test.tier1.legacy."):
+            return True
+    return False
+
+
+def run_tier1_fixtures(run_concurrently=True):
+    # pylint: disable=import-outside-toplevel
+    from pcs_test.tier1.legacy.test_constraints import (
+        CONSTRAINT_TEST_CIB_FIXTURE,
+    )
+    from pcs_test.tier1.legacy.test_resource import RESOURCE_TEST_CIB_FIXTURE
+    from pcs_test.tier1.legacy.test_stonith import (
+        STONITH_LEVEL_TEST_CIB_FIXTURE,
+    )
+
+    fixture_instances = [
+        CONSTRAINT_TEST_CIB_FIXTURE,
+        RESOURCE_TEST_CIB_FIXTURE,
+        STONITH_LEVEL_TEST_CIB_FIXTURE,
+    ]
+    print("Preparing tier1 fixtures...")
+    time_start = time.time()
+    if run_concurrently:
+        thread_list = []
+        for instance in fixture_instances:
+            thread = Thread(target=instance.set_up)
+            thread.daemon = True
+            thread.start()
+            thread_list.append(thread)
+        timeout_counter = 30  # 30 * 10s = 5min
+        while thread_list:
+            if timeout_counter < 0:
+                raise AssertionError("Fixture threads seem to be stuck :(")
+            for thread in thread_list:
+                thread.join(timeout=10)
+                sys.stdout.write(".")
+                sys.stdout.flush()
+                timeout_counter -= 1
+                if not thread.is_alive():
+                    thread_list.remove(thread)
+                    continue
+
+    else:
+        for instance in fixture_instances:
+            instance.set_up()
+    time_stop = time.time()
+    time_taken = time_stop - time_start
+    sys.stdout.write("Tier1 fixtures prepared in %.3fs\n" % (time_taken))
+    sys.stdout.flush()
+
+    def cleanup():
+        print("Cleaning tier1 fixtures...", end=" ")
+        for instance in fixture_instances:
+            instance.clean_up()
+        print("done")
+
+    return cleanup
+
+
 def main():
     # pylint: disable=import-outside-toplevel
     if "BUNDLED_LIB_LOCATION" in os.environ:
@@ -141,6 +204,11 @@ def main():
         sys.exit()
 
     tests_to_run = discovered_tests
+    tier1_fixtures_cleanup = None
+    if tier1_fixtures_needed(tests_to_run):
+        tier1_fixtures_cleanup = run_tier1_fixtures(
+            run_concurrently=run_concurrently
+        )
     if run_concurrently:
         tests_to_run = ConcurrentTestSuite(
             discovered_tests,
@@ -174,6 +242,8 @@ def main():
         verbosity=2 if "-v" in sys.argv else 1, resultclass=ResultClass
     )
     test_result = test_runner.run(tests_to_run)
+    if tier1_fixtures_cleanup:
+        tier1_fixtures_cleanup()
     if not test_result.wasSuccessful():
         sys.exit(1)
 
diff --git a/pcs_test/tier0/lib/commands/cluster/test_add_nodes_validation.py b/pcs_test/tier0/lib/commands/cluster/test_add_nodes_validation.py
index c66a5dff..69cdeed2 100644
--- a/pcs_test/tier0/lib/commands/cluster/test_add_nodes_validation.py
+++ b/pcs_test/tier0/lib/commands/cluster/test_add_nodes_validation.py
@@ -14,6 +14,9 @@ from pcs_test.tier0.lib.commands.cluster.test_add_nodes import (
 )
 from pcs_test.tools import fixture
 from pcs_test.tools.command_env import get_env_tools
+from pcs_test.tools.command_env.config_http_corosync import (
+    corosync_running_check_response,
+)
 from pcs_test.tools.custom_mock import patch_getaddrinfo
 
 from pcs import settings
@@ -1170,7 +1173,10 @@ class ClusterStatus(TestCase):
             .local.read_sbd_config(name_sufix="_2")
             .http.corosync.check_corosync_offline(
                 communication_list=[
-                    {"label": "node1", "output": '{"corosync":true}'},
+                    {
+                        "label": "node1",
+                        "output": corosync_running_check_response(True),
+                    },
                     {"label": "node2", "output": "an error"},
                     {
                         "label": "node3",
@@ -1178,8 +1184,14 @@ class ClusterStatus(TestCase):
                         "errno": 7,
                         "error_msg": "an error",
                     },
-                    {"label": "node4", "output": '{"corosync":true}'},
-                    {"label": "node5", "output": '{"corosync":false}'},
+                    {
+                        "label": "node4",
+                        "output": corosync_running_check_response(True),
+                    },
+                    {
+                        "label": "node5",
+                        "output": corosync_running_check_response(False),
+                    },
                 ]
             )
             .local.get_host_info(new_nodes)
diff --git a/pcs_test/tier0/lib/commands/test_stonith_update_scsi_devices.py b/pcs_test/tier0/lib/commands/test_stonith_update_scsi_devices.py
index 3bc51325..593757d8 100644
--- a/pcs_test/tier0/lib/commands/test_stonith_update_scsi_devices.py
+++ b/pcs_test/tier0/lib/commands/test_stonith_update_scsi_devices.py
@@ -4,6 +4,9 @@ from unittest import mock, TestCase
 
 from pcs_test.tools import fixture
 from pcs_test.tools.command_env import get_env_tools
+from pcs_test.tools.command_env.config_http_corosync import (
+    corosync_running_check_response,
+)
 from pcs_test.tools.misc import get_test_resource as rc
 
 from pcs import settings
@@ -1013,7 +1016,7 @@ class TestUpdateScsiDevicesFailures(TestCase):
             communication_list=[
                 dict(
                     label=self.existing_nodes[0],
-                    output='{"corosync":true}',
+                    output=corosync_running_check_response(True),
                 ),
             ]
             + [
@@ -1052,11 +1055,11 @@ class TestUpdateScsiDevicesFailures(TestCase):
             communication_list=[
                 dict(
                     label=self.existing_nodes[0],
-                    output='{"corosync":true}',
+                    output=corosync_running_check_response(True),
                 ),
                 dict(
                     label=self.existing_nodes[1],
-                    output='{"corosync":false}',
+                    output=corosync_running_check_response(False),
                 ),
                 dict(
                     label=self.existing_nodes[2],
@@ -1122,7 +1125,7 @@ class TestUpdateScsiDevicesFailures(TestCase):
                 ),
                 dict(
                     label=self.existing_nodes[2],
-                    output='{"corosync":false}',
+                    output=corosync_running_check_response(False),
                 ),
             ]
         )
diff --git a/pcs_test/tier0/lib/test_env_corosync.py b/pcs_test/tier0/lib/test_env_corosync.py
index dafc63a0..7063ee80 100644
--- a/pcs_test/tier0/lib/test_env_corosync.py
+++ b/pcs_test/tier0/lib/test_env_corosync.py
@@ -14,6 +14,9 @@ from pcs.lib.corosync.config_parser import (
 from pcs_test.tools import fixture
 from pcs_test.tools.assertions import assert_raise_library_error
 from pcs_test.tools.command_env import get_env_tools
+from pcs_test.tools.command_env.config_http_corosync import (
+    corosync_running_check_response,
+)
 
 
 class PushCorosyncConfLiveBase(TestCase):
@@ -92,12 +95,11 @@ class PushCorosyncConfLiveNoQdeviceTest(PushCorosyncConfLiveBase):
         )
 
     def test_dont_need_stopped_cluster(self):
-        (
-            self.config.http.corosync.set_corosync_conf(
-                self.corosync_conf_text, node_labels=self.node_labels
-            ).http.corosync.reload_corosync_conf(
-                node_labels=self.node_labels[:1]
-            )
+        self.config.http.corosync.set_corosync_conf(
+            self.corosync_conf_text, node_labels=self.node_labels
+        )
+        self.config.http.corosync.reload_corosync_conf(
+            node_labels=self.node_labels[:1]
         )
         self.env_assistant.get_env().push_corosync_conf(
             self.corosync_conf_facade
@@ -114,26 +116,19 @@ class PushCorosyncConfLiveNoQdeviceTest(PushCorosyncConfLiveBase):
                     node="node-2",
                 ),
                 fixture.info(
-                    report_codes.COROSYNC_CONFIG_RELOADED, node="node-1"
+                    report_codes.COROSYNC_CONFIG_RELOADED,
+                    node="node-1",
                 ),
             ]
         )
 
     def test_dont_need_stopped_cluster_error(self):
-        (
-            self.config.http.corosync.set_corosync_conf(
-                self.corosync_conf_text,
-                communication_list=[
-                    {
-                        "label": "node-1",
-                    },
-                    {
-                        "label": "node-2",
-                        "response_code": 400,
-                        "output": "Failed",
-                    },
-                ],
-            )
+        self.config.http.corosync.set_corosync_conf(
+            self.corosync_conf_text,
+            communication_list=[
+                {"label": "node-1"},
+                {"label": "node-2", "response_code": 400, "output": "Failed"},
+            ],
         )
         env = self.env_assistant.get_env()
         self.env_assistant.assert_raise_library_error(
@@ -162,35 +157,28 @@ class PushCorosyncConfLiveNoQdeviceTest(PushCorosyncConfLiveBase):
         )
 
     def test_dont_need_stopped_cluster_error_skip_offline(self):
-        (
-            self.config.http.corosync.set_corosync_conf(
-                self.corosync_conf_text,
-                communication_list=[
+        self.config.http.corosync.set_corosync_conf(
+            self.corosync_conf_text,
+            communication_list=[
+                {
+                    "label": "node-1",
+                    "response_code": 400,
+                    "output": "Failed",
+                },
+                {"label": "node-2"},
+            ],
+        )
+        self.config.http.corosync.reload_corosync_conf(
+            communication_list=[
+                [
                     {
-                        "label": "node-1",
+                        "label": self.node_labels[0],
                         "response_code": 400,
                         "output": "Failed",
                     },
-                    {
-                        "label": "node-2",
-                    },
                 ],
-            ).http.corosync.reload_corosync_conf(
-                communication_list=[
-                    [
-                        {
-                            "label": self.node_labels[0],
-                            "response_code": 400,
-                            "output": "Failed",
-                        },
-                    ],
-                    [
-                        {
-                            "label": self.node_labels[1],
-                        },
-                    ],
-                ]
-            )
+                [{"label": self.node_labels[1]}],
+            ]
         )
         self.env_assistant.get_env().push_corosync_conf(
             self.corosync_conf_facade, skip_offline_nodes=True
@@ -219,33 +207,29 @@ class PushCorosyncConfLiveNoQdeviceTest(PushCorosyncConfLiveBase):
                     reason="Failed",
                 ),
                 fixture.info(
-                    report_codes.COROSYNC_CONFIG_RELOADED, node="node-2"
+                    report_codes.COROSYNC_CONFIG_RELOADED,
+                    node="node-2",
                 ),
             ]
         )
 
     def test_reload_on_another_node(self):
-        (
-            self.config.http.corosync.set_corosync_conf(
-                self.corosync_conf_text, node_labels=self.node_labels
-            ).http.corosync.reload_corosync_conf(
-                communication_list=[
-                    [
-                        {
-                            "label": self.node_labels[0],
-                            "response_code": 200,
-                            "output": json.dumps(
-                                dict(code="not_running", message="not running")
-                            ),
-                        },
-                    ],
-                    [
-                        {
-                            "label": self.node_labels[1],
-                        },
-                    ],
-                ]
-            )
+        self.config.http.corosync.set_corosync_conf(
+            self.corosync_conf_text, node_labels=self.node_labels
+        )
+        self.config.http.corosync.reload_corosync_conf(
+            communication_list=[
+                [
+                    {
+                        "label": self.node_labels[0],
+                        "response_code": 200,
+                        "output": json.dumps(
+                            dict(code="not_running", message="not running")
+                        ),
+                    },
+                ],
+                [{"label": self.node_labels[1]}],
+            ]
         )
         self.env_assistant.get_env().push_corosync_conf(
             self.corosync_conf_facade
@@ -266,35 +250,35 @@ class PushCorosyncConfLiveNoQdeviceTest(PushCorosyncConfLiveBase):
                     node="node-1",
                 ),
                 fixture.info(
-                    report_codes.COROSYNC_CONFIG_RELOADED, node="node-2"
+                    report_codes.COROSYNC_CONFIG_RELOADED,
+                    node="node-2",
                 ),
             ]
         )
 
     def test_reload_not_successful(self):
-        (
-            self.config.http.corosync.set_corosync_conf(
-                self.corosync_conf_text, node_labels=self.node_labels
-            ).http.corosync.reload_corosync_conf(
-                communication_list=[
-                    [
-                        {
-                            "label": self.node_labels[0],
-                            "response_code": 200,
-                            "output": json.dumps(
-                                dict(code="not_running", message="not running")
-                            ),
-                        },
-                    ],
-                    [
-                        {
-                            "label": self.node_labels[1],
-                            "response_code": 200,
-                            "output": "not a json",
-                        },
-                    ],
-                ]
-            )
+        self.config.http.corosync.set_corosync_conf(
+            self.corosync_conf_text, node_labels=self.node_labels
+        )
+        self.config.http.corosync.reload_corosync_conf(
+            communication_list=[
+                [
+                    {
+                        "label": self.node_labels[0],
+                        "response_code": 200,
+                        "output": json.dumps(
+                            dict(code="not_running", message="not running")
+                        ),
+                    },
+                ],
+                [
+                    {
+                        "label": self.node_labels[1],
+                        "response_code": 200,
+                        "output": "not a json",
+                    },
+                ],
+            ]
         )
         self.env_assistant.assert_raise_library_error(
             lambda: self.env_assistant.get_env().push_corosync_conf(
@@ -318,7 +302,8 @@ class PushCorosyncConfLiveNoQdeviceTest(PushCorosyncConfLiveBase):
                     node="node-1",
                 ),
                 fixture.warn(
-                    report_codes.INVALID_RESPONSE_FORMAT, node="node-2"
+                    report_codes.INVALID_RESPONSE_FORMAT,
+                    node="node-2",
                 ),
                 fixture.error(
                     report_codes.UNABLE_TO_PERFORM_OPERATION_ON_ANY_NODE
@@ -327,23 +312,22 @@ class PushCorosyncConfLiveNoQdeviceTest(PushCorosyncConfLiveBase):
         )
 
     def test_reload_corosync_not_running_anywhere(self):
-        (
-            self.config.http.corosync.set_corosync_conf(
-                self.corosync_conf_text, node_labels=self.node_labels
-            ).http.corosync.reload_corosync_conf(
-                communication_list=[
-                    [
-                        {
-                            "label": node,
-                            "response_code": 200,
-                            "output": json.dumps(
-                                dict(code="not_running", message="not running")
-                            ),
-                        },
-                    ]
-                    for node in self.node_labels
+        self.config.http.corosync.set_corosync_conf(
+            self.corosync_conf_text, node_labels=self.node_labels
+        )
+        self.config.http.corosync.reload_corosync_conf(
+            communication_list=[
+                [
+                    {
+                        "label": node,
+                        "response_code": 200,
+                        "output": json.dumps(
+                            dict(code="not_running", message="not running")
+                        ),
+                    },
                 ]
-            )
+                for node in self.node_labels
+            ]
         )
         self.env_assistant.get_env().push_corosync_conf(
             self.corosync_conf_facade
@@ -372,12 +356,11 @@ class PushCorosyncConfLiveNoQdeviceTest(PushCorosyncConfLiveBase):
 
     def test_need_stopped_cluster(self):
         self.corosync_conf_facade.need_stopped_cluster = True
-        (
-            self.config.http.corosync.check_corosync_offline(
-                node_labels=self.node_labels
-            ).http.corosync.set_corosync_conf(
-                self.corosync_conf_text, node_labels=self.node_labels
-            )
+        self.config.http.corosync.check_corosync_offline(
+            node_labels=self.node_labels
+        )
+        self.config.http.corosync.set_corosync_conf(
+            self.corosync_conf_text, node_labels=self.node_labels
         )
         self.env_assistant.get_env().push_corosync_conf(
             self.corosync_conf_facade
@@ -407,21 +390,14 @@ class PushCorosyncConfLiveNoQdeviceTest(PushCorosyncConfLiveBase):
 
     def test_need_stopped_cluster_not_stopped(self):
         self.corosync_conf_facade.need_stopped_cluster = True
-        (
-            self.config.http.corosync.check_corosync_offline(
-                communication_list=[
-                    {
-                        "label": self.node_labels[0],
-                        "output": '{"corosync":true}',
-                    }
-                ]
-                + [
-                    {
-                        "label": node,
-                    }
-                    for node in self.node_labels[1:]
-                ]
-            )
+        self.config.http.corosync.check_corosync_offline(
+            communication_list=[
+                {
+                    "label": self.node_labels[0],
+                    "output": corosync_running_check_response(True),
+                }
+            ]
+            + [{"label": node} for node in self.node_labels[1:]]
         )
         env = self.env_assistant.get_env()
         self.env_assistant.assert_raise_library_error(
@@ -445,18 +421,14 @@ class PushCorosyncConfLiveNoQdeviceTest(PushCorosyncConfLiveBase):
         # If we know for sure that corosync is running, skip_offline doesn't
         # matter.
         self.corosync_conf_facade.need_stopped_cluster = True
-        (
-            self.config.http.corosync.check_corosync_offline(
-                communication_list=[
-                    dict(
-                        label="node-1",
-                        output='{"corosync":true}',
-                    ),
-                    dict(
-                        label="node-2",
-                    ),
-                ]
-            )
+        self.config.http.corosync.check_corosync_offline(
+            communication_list=[
+                dict(
+                    label="node-1",
+                    output=corosync_running_check_response(True),
+                ),
+                dict(label="node-2"),
+            ]
         )
         env = self.env_assistant.get_env()
         self.env_assistant.assert_raise_library_error(
@@ -481,19 +453,17 @@ class PushCorosyncConfLiveNoQdeviceTest(PushCorosyncConfLiveBase):
 
     def test_need_stopped_cluster_json_error(self):
         self.corosync_conf_facade.need_stopped_cluster = True
-        (
-            self.config.http.corosync.check_corosync_offline(
-                communication_list=[
-                    dict(label="node-1", output="{"),  # not valid json
-                    dict(
-                        label="node-2",
-                        # The expected key (/corosync) is missing, we don't
-                        # care about version 2 status key
-                        # (/services/corosync/running)
-                        output='{"services":{"corosync":{"running":true}}}',
-                    ),
-                ]
-            )
+        self.config.http.corosync.check_corosync_offline(
+            communication_list=[
+                dict(label="node-1", output="{"),  # not valid json
+                dict(
+                    label="node-2",
+                    # The expected key (/corosync) is missing, tested code
+                    # doesn't care about a new key added in version 2 status
+                    # (/services/corosync/running)
+                    output='{"services":{"corosync":{"running":true}}}',
+                ),
+            ]
         )
         env = self.env_assistant.get_env()
         self.env_assistant.assert_raise_library_error(
@@ -517,19 +487,15 @@ class PushCorosyncConfLiveNoQdeviceTest(PushCorosyncConfLiveBase):
 
     def test_need_stopped_cluster_comunnication_failure(self):
         self.corosync_conf_facade.need_stopped_cluster = True
-        (
-            self.config.http.corosync.check_corosync_offline(
-                communication_list=[
-                    dict(
-                        label="node-1",
-                    ),
-                    dict(
-                        label="node-2",
-                        response_code=401,
-                        output="""{"notauthorized":"true"}""",
-                    ),
-                ]
-            )
+        self.config.http.corosync.check_corosync_offline(
+            communication_list=[
+                dict(label="node-1"),
+                dict(
+                    label="node-2",
+                    response_code=401,
+                    output='{"notauthorized":"true"}',
+                ),
+            ]
         )
         env = self.env_assistant.get_env()
         self.env_assistant.assert_raise_library_error(
@@ -560,29 +526,26 @@ class PushCorosyncConfLiveNoQdeviceTest(PushCorosyncConfLiveBase):
     def test_need_stopped_cluster_comunnication_failures_skip_offline(self):
         # If we don't know if corosync is running, skip_offline matters.
         self.corosync_conf_facade.need_stopped_cluster = True
-        (
-            self.config.http.corosync.check_corosync_offline(
-                communication_list=[
-                    dict(
-                        label="node-1",
-                        response_code=401,
-                        output="""{"notauthorized":"true"}""",
-                    ),
-                    dict(label="node-2", output="{"),  # not valid json
-                ]
-            ).http.corosync.set_corosync_conf(
-                self.corosync_conf_text,
-                communication_list=[
-                    dict(
-                        label="node-1",
-                        response_code=401,
-                        output="""{"notauthorized":"true"}""",
-                    ),
-                    dict(
-                        label="node-2",
-                    ),
-                ],
-            )
+        self.config.http.corosync.check_corosync_offline(
+            communication_list=[
+                dict(
+                    label="node-1",
+                    response_code=401,
+                    output='{"notauthorized":"true"}',
+                ),
+                dict(label="node-2", output="{"),  # not valid json
+            ]
+        )
+        self.config.http.corosync.set_corosync_conf(
+            self.corosync_conf_text,
+            communication_list=[
+                dict(
+                    label="node-1",
+                    response_code=401,
+                    output='{"notauthorized":"true"}',
+                ),
+                dict(label="node-2"),
+            ],
         )
         self.env_assistant.get_env().push_corosync_conf(
             self.corosync_conf_facade, skip_offline_nodes=True
@@ -662,15 +625,17 @@ class PushCorosyncConfLiveWithQdeviceTest(PushCorosyncConfLiveBase):
 
     def test_qdevice_reload(self):
         self.corosync_conf_facade.need_qdevice_reload = True
-        (
-            self.config.http.corosync.set_corosync_conf(
-                self.corosync_conf_text, node_labels=self.node_labels
-            )
-            .http.corosync.reload_corosync_conf(
-                node_labels=self.node_labels[:1]
-            )
-            .http.corosync.qdevice_client_stop(node_labels=self.node_labels)
-            .http.corosync.qdevice_client_start(node_labels=self.node_labels)
+        self.config.http.corosync.set_corosync_conf(
+            self.corosync_conf_text, node_labels=self.node_labels
+        )
+        self.config.http.corosync.reload_corosync_conf(
+            node_labels=self.node_labels[:1]
+        )
+        self.config.http.corosync.qdevice_client_stop(
+            node_labels=self.node_labels
+        )
+        self.config.http.corosync.qdevice_client_start(
+            node_labels=self.node_labels
         )
 
         self.env_assistant.get_env().push_corosync_conf(
@@ -689,7 +654,8 @@ class PushCorosyncConfLiveWithQdeviceTest(PushCorosyncConfLiveBase):
                     node="node-2",
                 ),
                 fixture.info(
-                    report_codes.COROSYNC_CONFIG_RELOADED, node="node-1"
+                    report_codes.COROSYNC_CONFIG_RELOADED,
+                    node="node-1",
                 ),
                 fixture.info(report_codes.QDEVICE_CLIENT_RELOAD_STARTED),
                 fixture.info(
@@ -725,34 +691,34 @@ class PushCorosyncConfLiveWithQdeviceTest(PushCorosyncConfLiveBase):
 
     def test_qdevice_reload_corosync_stopped(self):
         self.corosync_conf_facade.need_qdevice_reload = True
-        (
-            self.config.http.corosync.set_corosync_conf(
-                self.corosync_conf_text, node_labels=self.node_labels
-            )
-            .http.corosync.reload_corosync_conf(
-                communication_list=[
-                    [
-                        {
-                            "label": label,
-                            "response_code": 200,
-                            "output": json.dumps(
-                                dict(code="not_running", message="")
-                            ),
-                        },
-                    ]
-                    for label in self.node_labels
-                ]
-            )
-            .http.corosync.qdevice_client_stop(node_labels=self.node_labels)
-            .http.corosync.qdevice_client_start(
-                communication_list=[
+        self.config.http.corosync.set_corosync_conf(
+            self.corosync_conf_text, node_labels=self.node_labels
+        )
+        self.config.http.corosync.reload_corosync_conf(
+            communication_list=[
+                [
                     {
                         "label": label,
-                        "output": "corosync is not running, skipping",
-                    }
-                    for label in self.node_labels
+                        "response_code": 200,
+                        "output": json.dumps(
+                            dict(code="not_running", message="")
+                        ),
+                    },
                 ]
-            )
+                for label in self.node_labels
+            ]
+        )
+        self.config.http.corosync.qdevice_client_stop(
+            node_labels=self.node_labels
+        )
+        self.config.http.corosync.qdevice_client_start(
+            communication_list=[
+                {
+                    "label": label,
+                    "output": "corosync is not running, skipping",
+                }
+                for label in self.node_labels
+            ]
         )
 
         self.env_assistant.get_env().push_corosync_conf(
@@ -816,38 +782,28 @@ class PushCorosyncConfLiveWithQdeviceTest(PushCorosyncConfLiveBase):
         # This also tests that failing to stop qdevice on a node doesn't prevent
         # starting qdevice on the same node.
         self.corosync_conf_facade.need_qdevice_reload = True
-        (
-            self.config.http.corosync.set_corosync_conf(
-                self.corosync_conf_text, node_labels=self.node_labels
-            )
-            .http.corosync.reload_corosync_conf(
-                node_labels=self.node_labels[:1]
-            )
-            .http.corosync.qdevice_client_stop(
-                communication_list=[
-                    dict(
-                        label="node-1",
-                    ),
-                    dict(
-                        label="node-2",
-                        response_code=400,
-                        output="error",
-                    ),
-                ]
-            )
-            .http.corosync.qdevice_client_start(
-                communication_list=[
-                    dict(
-                        label="node-1",
-                        errno=8,
-                        error_msg="failure",
-                        was_connected=False,
-                    ),
-                    dict(
-                        label="node-2",
-                    ),
-                ]
-            )
+        self.config.http.corosync.set_corosync_conf(
+            self.corosync_conf_text, node_labels=self.node_labels
+        )
+        self.config.http.corosync.reload_corosync_conf(
+            node_labels=self.node_labels[:1]
+        )
+        self.config.http.corosync.qdevice_client_stop(
+            communication_list=[
+                dict(label="node-1"),
+                dict(label="node-2", response_code=400, output="error"),
+            ]
+        )
+        self.config.http.corosync.qdevice_client_start(
+            communication_list=[
+                dict(
+                    label="node-1",
+                    errno=8,
+                    error_msg="failure",
+                    was_connected=False,
+                ),
+                dict(label="node-2"),
+            ]
         )
 
         env = self.env_assistant.get_env()
@@ -867,7 +823,8 @@ class PushCorosyncConfLiveWithQdeviceTest(PushCorosyncConfLiveBase):
                     node="node-2",
                 ),
                 fixture.info(
-                    report_codes.COROSYNC_CONFIG_RELOADED, node="node-1"
+                    report_codes.COROSYNC_CONFIG_RELOADED,
+                    node="node-1",
                 ),
                 fixture.info(report_codes.QDEVICE_CLIENT_RELOAD_STARTED),
                 fixture.info(
@@ -903,62 +860,46 @@ class PushCorosyncConfLiveWithQdeviceTest(PushCorosyncConfLiveBase):
 
     def test_qdevice_reload_failures_skip_offline(self):
         self.corosync_conf_facade.need_qdevice_reload = True
-        (
-            self.config.http.corosync.set_corosync_conf(
-                self.corosync_conf_text,
-                communication_list=[
-                    dict(
-                        label="node-1",
-                    ),
-                    dict(
-                        label="node-2",
-                        errno=8,
-                        error_msg="failure",
-                        was_connected=False,
-                    ),
+        self.config.http.corosync.set_corosync_conf(
+            self.corosync_conf_text,
+            communication_list=[
+                dict(label="node-1"),
+                dict(
+                    label="node-2",
+                    errno=8,
+                    error_msg="failure",
+                    was_connected=False,
+                ),
+            ],
+        )
+        self.config.http.corosync.reload_corosync_conf(
+            communication_list=[
+                [
+                    {
+                        "label": self.node_labels[0],
+                        "response_code": 400,
+                        "output": "Failed",
+                    },
                 ],
-            )
-            .http.corosync.reload_corosync_conf(
-                communication_list=[
-                    [
-                        {
-                            "label": self.node_labels[0],
-                            "response_code": 400,
-                            "output": "Failed",
-                        },
-                    ],
-                    [
-                        {
-                            "label": self.node_labels[1],
-                        },
-                    ],
-                ]
-            )
-            .http.corosync.qdevice_client_stop(
-                communication_list=[
-                    dict(
-                        label="node-1",
-                    ),
-                    dict(
-                        label="node-2",
-                        response_code=400,
-                        output="error",
-                    ),
-                ]
-            )
-            .http.corosync.qdevice_client_start(
-                communication_list=[
-                    dict(
-                        label="node-1",
-                        errno=8,
-                        error_msg="failure",
-                        was_connected=False,
-                    ),
-                    dict(
-                        label="node-2",
-                    ),
-                ]
-            )
+                [{"label": self.node_labels[1]}],
+            ]
+        )
+        self.config.http.corosync.qdevice_client_stop(
+            communication_list=[
+                dict(label="node-1"),
+                dict(label="node-2", response_code=400, output="error"),
+            ]
+        )
+        self.config.http.corosync.qdevice_client_start(
+            communication_list=[
+                dict(
+                    label="node-1",
+                    errno=8,
+                    error_msg="failure",
+                    was_connected=False,
+                ),
+                dict(label="node-2"),
+            ]
         )
 
         env = self.env_assistant.get_env()
@@ -990,7 +931,8 @@ class PushCorosyncConfLiveWithQdeviceTest(PushCorosyncConfLiveBase):
                     reason="Failed",
                 ),
                 fixture.info(
-                    report_codes.COROSYNC_CONFIG_RELOADED, node="node-2"
+                    report_codes.COROSYNC_CONFIG_RELOADED,
+                    node="node-2",
                 ),
                 fixture.info(report_codes.QDEVICE_CLIENT_RELOAD_STARTED),
                 fixture.info(
@@ -1024,29 +966,28 @@ class PushCorosyncConfLiveWithQdeviceTest(PushCorosyncConfLiveBase):
 
     def test_reload_not_successful(self):
         self.corosync_conf_facade.need_qdevice_reload = True
-        (
-            self.config.http.corosync.set_corosync_conf(
-                self.corosync_conf_text, node_labels=self.node_labels
-            ).http.corosync.reload_corosync_conf(
-                communication_list=[
-                    [
-                        {
-                            "label": self.node_labels[0],
-                            "response_code": 200,
-                            "output": json.dumps(
-                                dict(code="not_running", message="not running")
-                            ),
-                        },
-                    ],
-                    [
-                        {
-                            "label": self.node_labels[1],
-                            "response_code": 200,
-                            "output": "not a json",
-                        },
-                    ],
-                ]
-            )
+        self.config.http.corosync.set_corosync_conf(
+            self.corosync_conf_text, node_labels=self.node_labels
+        )
+        self.config.http.corosync.reload_corosync_conf(
+            communication_list=[
+                [
+                    {
+                        "label": self.node_labels[0],
+                        "response_code": 200,
+                        "output": json.dumps(
+                            dict(code="not_running", message="not running")
+                        ),
+                    },
+                ],
+                [
+                    {
+                        "label": self.node_labels[1],
+                        "response_code": 200,
+                        "output": "not a json",
+                    },
+                ],
+            ]
         )
         self.env_assistant.assert_raise_library_error(
             lambda: self.env_assistant.get_env().push_corosync_conf(
@@ -1070,7 +1011,8 @@ class PushCorosyncConfLiveWithQdeviceTest(PushCorosyncConfLiveBase):
                     node="node-1",
                 ),
                 fixture.warn(
-                    report_codes.INVALID_RESPONSE_FORMAT, node="node-2"
+                    report_codes.INVALID_RESPONSE_FORMAT,
+                    node="node-2",
                 ),
                 fixture.error(
                     report_codes.UNABLE_TO_PERFORM_OPERATION_ON_ANY_NODE
diff --git a/pcs_test/tier1/legacy/test_constraints.py b/pcs_test/tier1/legacy/test_constraints.py
index 36924925..49b413a8 100644
--- a/pcs_test/tier1/legacy/test_constraints.py
+++ b/pcs_test/tier1/legacy/test_constraints.py
@@ -13,9 +13,11 @@ from pcs_test.tools.assertions import (
 from pcs_test.tools.bin_mock import get_mock_settings
 from pcs_test.tools.cib import get_assert_pcs_effect_mixin
 from pcs_test.tools.fixture_cib import (
+    CachedCibFixture,
     fixture_master_xml,
     fixture_to_cib,
     wrap_element_by_master,
+    wrap_element_by_master_file,
 )
 from pcs_test.tools.misc import (
     get_test_resource as rc,
@@ -23,7 +25,6 @@ from pcs_test.tools.misc import (
     skip_unless_crm_rule,
     outdent,
     ParametrizedTestMetaClass,
-    write_data_to_tmpfile,
     write_file_to_tmpfile,
 )
 from pcs_test.tools.pcs_runner import pcs, PcsRunner
@@ -54,70 +55,63 @@ empty_cib = rc("cib-empty-3.7.xml")
 large_cib = rc("cib-large.xml")
 
 
-@skip_unless_crm_rule()
-class ConstraintTest(unittest.TestCase):
-    def setUp(self):
-        self.temp_cib = get_tmp_file("tier1_constraints")
-        write_file_to_tmpfile(empty_cib, self.temp_cib)
-        self.temp_corosync_conf = None
-
-    def tearDown(self):
-        self.temp_cib.close()
-        if self.temp_corosync_conf:
-            self.temp_corosync_conf.close()
-
-    def fixture_resources(self):
-        write_data_to_tmpfile(self.fixture_cib_cache(), self.temp_cib)
-
-    def fixture_cib_cache(self):
-        if not hasattr(self.__class__, "cib_cache"):
-            self.__class__.cib_cache = self.fixture_cib()
-        return self.__class__.cib_cache
-
-    def fixture_cib(self):
-        write_file_to_tmpfile(empty_cib, self.temp_cib)
-        self.setupClusterA()
-        self.temp_cib.flush()
-        self.temp_cib.seek(0)
-        cib_content = self.temp_cib.read()
-        self.temp_cib.seek(0)
-        write_file_to_tmpfile(empty_cib, self.temp_cib)
-        return cib_content
-
-    # Sets up a cluster with Resources, groups, master/slave resource and clones
-    def setupClusterA(self):
+class ConstraintTestCibFixture(CachedCibFixture):
+    def _setup_cib(self):
         line = "resource create D1 ocf:heartbeat:Dummy".split()
-        output, returnVal = pcs(self.temp_cib.name, line)
+        output, returnVal = pcs(self.cache_path, line)
         assert returnVal == 0 and output == ""
 
         line = "resource create D2 ocf:heartbeat:Dummy".split()
-        output, returnVal = pcs(self.temp_cib.name, line)
+        output, returnVal = pcs(self.cache_path, line)
         assert returnVal == 0 and output == ""
 
         line = "resource create D3 ocf:heartbeat:Dummy".split()
-        output, returnVal = pcs(self.temp_cib.name, line)
+        output, returnVal = pcs(self.cache_path, line)
         assert returnVal == 0 and output == ""
 
         line = "resource create D4 ocf:heartbeat:Dummy".split()
-        output, returnVal = pcs(self.temp_cib.name, line)
+        output, returnVal = pcs(self.cache_path, line)
         assert returnVal == 0 and output == ""
 
         line = "resource create D5 ocf:heartbeat:Dummy".split()
-        output, returnVal = pcs(self.temp_cib.name, line)
+        output, returnVal = pcs(self.cache_path, line)
         assert returnVal == 0 and output == ""
 
         line = "resource create D6 ocf:heartbeat:Dummy".split()
-        output, returnVal = pcs(self.temp_cib.name, line)
+        output, returnVal = pcs(self.cache_path, line)
         assert returnVal == 0 and output == ""
 
         line = "resource clone D3".split()
-        output, returnVal = pcs(self.temp_cib.name, line)
+        output, returnVal = pcs(self.cache_path, line)
         assert returnVal == 0 and output == ""
 
         # pcs no longer allows turning resources into masters but supports
         # existing ones. In order to test it, we need to put a master in the
         # CIB without pcs.
-        wrap_element_by_master(self.temp_cib, "D4", master_id="Master")
+        wrap_element_by_master_file(self.cache_path, "D4", master_id="Master")
+
+
+CONSTRAINT_TEST_CIB_FIXTURE = ConstraintTestCibFixture(
+    "fixture_tier1_constraints", empty_cib
+)
+
+
+@skip_unless_crm_rule()
+class ConstraintTest(unittest.TestCase):
+    def setUp(self):
+        self.temp_cib = get_tmp_file("tier1_constraints")
+        write_file_to_tmpfile(empty_cib, self.temp_cib)
+        self.temp_corosync_conf = None
+
+    def tearDown(self):
+        self.temp_cib.close()
+        if self.temp_corosync_conf:
+            self.temp_corosync_conf.close()
+
+    def fixture_resources(self):
+        write_file_to_tmpfile(
+            CONSTRAINT_TEST_CIB_FIXTURE.cache_path, self.temp_cib
+        )
 
     def testConstraintRules(self):
         self.fixture_resources()
diff --git a/pcs_test/tier1/legacy/test_resource.py b/pcs_test/tier1/legacy/test_resource.py
index 8b043260..ecf0d23d 100644
--- a/pcs_test/tier1/legacy/test_resource.py
+++ b/pcs_test/tier1/legacy/test_resource.py
@@ -12,8 +12,10 @@ from pcs_test.tools.assertions import (
 from pcs_test.tools.bin_mock import get_mock_settings
 from pcs_test.tools.cib import get_assert_pcs_effect_mixin
 from pcs_test.tools.fixture_cib import (
+    CachedCibFixture,
     fixture_master_xml,
     fixture_to_cib,
+    wrap_element_by_master_file,
     wrap_element_by_master,
 )
 from pcs_test.tools.misc import (
@@ -154,21 +156,8 @@ class ResourceDescribe(TestCase, AssertPcsMixin):
         )
 
 
-class Resource(TestCase, AssertPcsMixin):
-    def setUp(self):
-        self.temp_cib = get_tmp_file("tier1_resource")
-        self.temp_large_cib = get_tmp_file("tier1_resource_large")
-        write_file_to_tmpfile(empty_cib, self.temp_cib)
-        write_file_to_tmpfile(large_cib, self.temp_large_cib)
-        self.pcs_runner = PcsRunner(self.temp_cib.name)
-        self.pcs_runner.mock_settings = get_mock_settings("crm_resource_binary")
-
-    def tearDown(self):
-        self.temp_cib.close()
-        self.temp_large_cib.close()
-
-    # Setups up a cluster with Resources, groups, master/slave resource & clones
-    def setupClusterA(self):
+class ResourceTestCibFixture(CachedCibFixture):
+    def _setup_cib(self):
         self.assert_pcs_success(
             (
                 "resource create --no-default-ops ClusterIP ocf:heartbeat:IPaddr2"
@@ -215,7 +204,34 @@ class Resource(TestCase, AssertPcsMixin):
         # pcs no longer allows turning resources into masters but supports
         # existing ones. In order to test it, we need to put a master in the
         # CIB without pcs.
-        wrap_element_by_master(self.temp_cib, "ClusterIP5", master_id="Master")
+        wrap_element_by_master_file(
+            self.cache_path, "ClusterIP5", master_id="Master"
+        )
+
+
+RESOURCE_TEST_CIB_FIXTURE = ResourceTestCibFixture(
+    "fixture_tier1_resource", empty_cib
+)
+
+
+class Resource(TestCase, AssertPcsMixin):
+    def setUp(self):
+        self.temp_cib = get_tmp_file("tier1_resource")
+        self.temp_large_cib = get_tmp_file("tier1_resource_large")
+        write_file_to_tmpfile(empty_cib, self.temp_cib)
+        write_file_to_tmpfile(large_cib, self.temp_large_cib)
+        self.pcs_runner = PcsRunner(self.temp_cib.name)
+        self.pcs_runner.mock_settings = get_mock_settings("crm_resource_binary")
+
+    def tearDown(self):
+        self.temp_cib.close()
+        self.temp_large_cib.close()
+
+    # Setups up a cluster with Resources, groups, master/slave resource & clones
+    def setupClusterA(self):
+        write_file_to_tmpfile(
+            RESOURCE_TEST_CIB_FIXTURE.cache_path, self.temp_cib
+        )
 
     def testCaseInsensitive(self):
         o, r = pcs(
diff --git a/pcs_test/tier1/legacy/test_stonith.py b/pcs_test/tier1/legacy/test_stonith.py
index b3def2d4..f6b93f01 100644
--- a/pcs_test/tier1/legacy/test_stonith.py
+++ b/pcs_test/tier1/legacy/test_stonith.py
@@ -8,6 +8,7 @@ from pcs.common.str_tools import indent
 from pcs_test.tier1.cib_resource.common import ResourceTest
 from pcs_test.tools.assertions import AssertPcsMixin
 from pcs_test.tools.bin_mock import get_mock_settings
+from pcs_test.tools.fixture_cib import CachedCibFixture
 from pcs_test.tools.misc import (
     get_test_resource as rc,
     get_tmp_file,
@@ -840,6 +841,46 @@ _fixture_stonith_level_cache = None
 _fixture_stonith_level_cache_lock = Lock()
 
 
+class StonithLevelTestCibFixture(CachedCibFixture):
+    def _fixture_stonith_resource(self, name):
+        self.assert_pcs_success(
+            [
+                "stonith",
+                "create",
+                name,
+                "fence_apc",
+                "pcmk_host_list=rh7-1 rh7-2",
+                "ip=i",
+                "username=u",
+            ]
+        )
+
+    def _setup_cib(self):
+        self._fixture_stonith_resource("F1")
+        self._fixture_stonith_resource("F2")
+        self._fixture_stonith_resource("F3")
+
+        self.assert_pcs_success("stonith level add 1 rh7-1 F1".split())
+        self.assert_pcs_success("stonith level add 2 rh7-1 F2".split())
+        self.assert_pcs_success("stonith level add 2 rh7-2 F1".split())
+        self.assert_pcs_success("stonith level add 1 rh7-2 F2".split())
+        self.assert_pcs_success("stonith level add 4 regexp%rh7-\\d F3".split())
+        self.assert_pcs_success(
+            "stonith level add 3 regexp%rh7-\\d F2 F1".split()
+        )
+        self.assert_pcs_success(
+            "stonith level add 5 attrib%fencewith=levels1 F3 F2".split()
+        )
+        self.assert_pcs_success(
+            "stonith level add 6 attrib%fencewith=levels2 F3 F1".split()
+        )
+
+
+STONITH_LEVEL_TEST_CIB_FIXTURE = StonithLevelTestCibFixture(
+    "fixture_tier1_stonith_level_tests", rc("cib-empty-withnodes.xml")
+)
+
+
 class LevelTestsBase(TestCase, AssertPcsMixin):
     def setUp(self):
         self.temp_cib = get_tmp_file("tier1_test_stonith_level")
@@ -877,26 +918,11 @@ class LevelTestsBase(TestCase, AssertPcsMixin):
                 _fixture_stonith_level_cache = self.fixture_cib_config()
             return _fixture_stonith_level_cache
 
-    def fixture_cib_config(self):
-        self.fixture_stonith_resource("F1")
-        self.fixture_stonith_resource("F2")
-        self.fixture_stonith_resource("F3")
-
-        self.assert_pcs_success("stonith level add 1 rh7-1 F1".split())
-        self.assert_pcs_success("stonith level add 2 rh7-1 F2".split())
-        self.assert_pcs_success("stonith level add 2 rh7-2 F1".split())
-        self.assert_pcs_success("stonith level add 1 rh7-2 F2".split())
-        self.assert_pcs_success("stonith level add 4 regexp%rh7-\\d F3".split())
-        self.assert_pcs_success(
-            "stonith level add 3 regexp%rh7-\\d F2 F1".split()
-        )
-        self.assert_pcs_success(
-            "stonith level add 5 attrib%fencewith=levels1 F3 F2".split()
-        )
-        self.assert_pcs_success(
-            "stonith level add 6 attrib%fencewith=levels2 F3 F1".split()
-        )
-
+    @staticmethod
+    def fixture_cib_config():
+        cib_content = ""
+        with open(STONITH_LEVEL_TEST_CIB_FIXTURE.cache_path, "r") as cib_file:
+            cib_content = cib_file.read()
         config = outdent(
             """\
             Target: rh7-1
@@ -914,12 +940,7 @@ class LevelTestsBase(TestCase, AssertPcsMixin):
               Level 6 - F3,F1
             """
         )
-
         config_lines = config.splitlines()
-        self.temp_cib.flush()
-        self.temp_cib.seek(0)
-        cib_content = self.temp_cib.read()
-        self.temp_cib.seek(0)
         return cib_content, config, config_lines
 
 
diff --git a/pcs_test/tools/command_env/config_http_corosync.py b/pcs_test/tools/command_env/config_http_corosync.py
index cdaf65ff..7f84f406 100644
--- a/pcs_test/tools/command_env/config_http_corosync.py
+++ b/pcs_test/tools/command_env/config_http_corosync.py
@@ -6,6 +6,23 @@ from pcs_test.tools.command_env.mock_node_communicator import (
 )
 
 
+def corosync_running_check_response(running):
+    return json.dumps(
+        {
+            "node": {
+                "corosync": running,
+                "services": {
+                    "corosync": {
+                        "installed": True,
+                        "enabled": not running,
+                        "running": running,
+                    }
+                },
+            }
+        }
+    )
+
+
 class CorosyncShortcuts:
     def __init__(self, calls):
         self.__calls = calls
@@ -29,7 +46,8 @@ class CorosyncShortcuts:
             node_labels,
             communication_list,
             action="remote/status",
-            output='{"corosync":false}',
+            param_list=[("version", "2")],
+            output=corosync_running_check_response(False),
         )
 
     def get_corosync_online_targets(
@@ -51,7 +69,8 @@ class CorosyncShortcuts:
             node_labels,
             communication_list,
             action="remote/status",
-            output='{"corosync":true}',
+            param_list=[("version", "2")],
+            output=corosync_running_check_response(True),
         )
 
     def get_corosync_conf(
diff --git a/pcs_test/tools/fixture_cib.py b/pcs_test/tools/fixture_cib.py
index 730b0e33..602491c8 100644
--- a/pcs_test/tools/fixture_cib.py
+++ b/pcs_test/tools/fixture_cib.py
@@ -3,7 +3,14 @@ import os
 from unittest import mock
 from lxml import etree
 
+from pcs_test.tools.assertions import AssertPcsMixin
 from pcs_test.tools.custom_mock import MockLibraryReportProcessor
+from pcs_test.tools.misc import (
+    get_test_resource,
+    get_tmp_file,
+    write_file_to_tmpfile,
+)
+from pcs_test.tools.pcs_runner import PcsRunner
 from pcs_test.tools.xml import etree_to_str
 
 from pcs import settings
@@ -12,6 +19,54 @@ from pcs.lib.external import CommandRunner
 # pylint: disable=line-too-long
 
 
+class CachedCibFixture(AssertPcsMixin):
+    def __init__(self, cache_name, empty_cib_path):
+        self._empty_cib_path = empty_cib_path
+        self._cache_name = cache_name
+        self._cache_path = None
+        self._pcs_runner = None
+
+    def _setup_cib(self):
+        raise NotImplementedError()
+
+    def set_up(self):
+        fixture_dir = get_test_resource("temp_fixtures")
+        os.makedirs(fixture_dir, exist_ok=True)
+        self._cache_path = os.path.join(fixture_dir, self._cache_name)
+        self._pcs_runner = PcsRunner(self._cache_path)
+
+        with open(self._empty_cib_path, "r") as template_file, open(
+            self.cache_path, "w"
+        ) as cache_file:
+            cache_file.write(template_file.read())
+        self._setup_cib()
+
+    def clean_up(self):
+        if os.path.isfile(self.cache_path):
+            os.unlink(self.cache_path)
+
+    @property
+    def cache_path(self):
+        if self._cache_path is None:
+            raise AssertionError("Cache has not been initiialized")
+        return self._cache_path
+
+    # methods for supporting assert_pcs_success
+    @property
+    def pcs_runner(self):
+        if self._pcs_runner is None:
+            raise AssertionError("Cache has not been initialized")
+        return self._pcs_runner
+
+    def assertEqual(self, first, second, msg=None):
+        # pylint: disable=invalid-name
+        # pylint: disable=no-self-use
+        if first != second:
+            raise AssertionError(
+                f"{msg}\n{first} != {second}" if msg else f"{first} != {second}"
+            )
+
+
 def wrap_element_by_master(cib_file, resource_id, master_id=None):
     cib_file.seek(0)
     cib_tree = etree.parse(cib_file, etree.XMLParser(huge_tree=True)).getroot()
@@ -49,6 +104,16 @@ def wrap_element_by_master(cib_file, resource_id, master_id=None):
     )
 
 
+def wrap_element_by_master_file(filepath, resource_id, master_id=None):
+    cib_tmp = get_tmp_file("wrap_by_master")
+    write_file_to_tmpfile(filepath, cib_tmp)
+    wrap_element_by_master(cib_tmp, resource_id, master_id=master_id)
+    cib_tmp.seek(0)
+    with open(filepath, "w") as target:
+        target.write(cib_tmp.read())
+    cib_tmp.close()
+
+
 def fixture_master_xml(name, all_ops=True, meta_dict=None):
     default_ops = f"""
             <op id="{name}-notify-interval-0s" interval="0s" name="notify"
diff --git a/pcsd/Makefile.am b/pcsd/Makefile.am
index 066ae8b6..a16917f5 100644
--- a/pcsd/Makefile.am
+++ b/pcsd/Makefile.am
@@ -50,7 +50,6 @@ dist_pcsd_DATA		= \
 			  cluster.rb \
 			  config.rb \
 			  corosyncconf.rb \
-			  fenceagent.rb \
 			  pcsd_action_command.rb \
 			  pcsd-cli-main.rb \
 			  pcsd_exchange_format.rb \
diff --git a/pcsd/capabilities.xml b/pcsd/capabilities.xml
index 745b05ad..f9dd8891 100644
--- a/pcsd/capabilities.xml
+++ b/pcsd/capabilities.xml
@@ -561,13 +561,6 @@
         pcs commands: cluster kill
       </description>
     </capability>
-    <capability id="node.restart" in-pcs="0" in-pcsd="1">
-      <description>
-        Restart one host machine or the local host machine if no host specified.
-
-        daemon urls: node_restart
-      </description>
-    </capability>
 
 
 
diff --git a/pcsd/fenceagent.rb b/pcsd/fenceagent.rb
deleted file mode 100644
index 4a3ba07d..00000000
--- a/pcsd/fenceagent.rb
+++ /dev/null
@@ -1,59 +0,0 @@
-def getFenceAgents(auth_user)
-  fence_agent_list = {}
-  stdout, stderr, retval = run_cmd(
-    auth_user, PCS, "stonith", "list", "--nodesc"
-  )
-  if retval != 0
-    $logger.error("Error running 'pcs stonith list --nodesc")
-    $logger.error(stdout + stderr)
-    return {}
-  end
-
-  agents = stdout
-  agents.each { |a|
-    fa = FenceAgent.new
-    fa.name = a.chomp
-    fence_agent_list[fa.name] = fa
-  }
-  return fence_agent_list
-end
-
-class FenceAgent
-  attr_accessor :name, :resource_class, :required_options, :optional_options, :advanced_options, :info
-  def initialize(name=nil, required_options={}, optional_options={}, resource_class=nil, advanced_options={})
-    @name = name
-    @required_options = {}
-    @optional_options = {}
-    @required_options = required_options
-    @optional_options = optional_options
-    @advanced_options = advanced_options
-    @resource_class = nil
-  end
-
-  def type
-    name
-  end
-
-  def to_json(options = {})
-    JSON.generate({
-      :full_name => "stonith:#{name}",
-      :class => 'stonith',
-      :provider => nil,
-      :type => name,
-    })
-  end
-
-  def long_desc
-    if info && info.length >= 2
-      return info[1]
-    end
-    return ""
-  end
-
-  def short_desc
-    if info && info.length >= 1
-      return info[0]
-    end
-    return ""
-  end
-end
diff --git a/pcsd/pcs.rb b/pcsd/pcs.rb
index 9e26c607..1507bdf5 100644
--- a/pcsd/pcs.rb
+++ b/pcsd/pcs.rb
@@ -1514,21 +1514,6 @@ def allowed_for_superuser(auth_user)
   return true
 end
 
-def get_default_overview_node_list(clustername)
-  nodes = get_cluster_nodes clustername
-  node_list = []
-  nodes.each { |node|
-    node_list << {
-      'error_list' => [],
-      'warning_list' => [],
-      'status' => 'unknown',
-      'quorum' => false,
-      'name' => node
-    }
-  }
-  return node_list
-end
-
 def enable_service(service)
   result = run_pcs_internal(
     PCSAuth.getSuperuserAuth(),
diff --git a/pcsd/pcsd.rb b/pcsd/pcsd.rb
index bf91e906..3297fc5e 100644
--- a/pcsd/pcsd.rb
+++ b/pcsd/pcsd.rb
@@ -11,7 +11,6 @@ require 'cgi'
 require 'bootstrap.rb'
 require 'resource.rb'
 require 'remote.rb'
-require 'fenceagent.rb'
 require 'cluster.rb'
 require 'config.rb'
 require 'pcs.rb'
@@ -54,14 +53,14 @@ end
 before do
   # nobody is logged in yet
   @auth_user = nil
-  @tornado_session_username = Thread.current[:tornado_username]
-  @tornado_session_groups = Thread.current[:tornado_groups]
-  @tornado_is_authenticated = Thread.current[:tornado_is_authenticated]
 
   if(request.path.start_with?('/remote/') and request.path != "/remote/auth") or request.path == '/run_pcs' or request.path.start_with?('/api/')
     # Sets @auth_user to a hash containing info about logged in user or halts
     # the request processing if login credentials are incorrect.
-    protect_by_token!
+    @auth_user = PCSAuth.loginByToken(request.cookies)
+    unless @auth_user
+      halt [401, '{"notauthorized":"true"}']
+    end
   else
     # Set a sane default: nobody is logged in, but we do not need to check both
     # for nil and empty username (if auth_user and auth_user[:username])
@@ -120,37 +119,6 @@ def run_cfgsync
   end
 end
 
-helpers do
-  def is_ajax?
-    return request.env['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest'
-  end
-
-  def protect_by_token!
-    @auth_user = PCSAuth.loginByToken(request.cookies)
-    unless @auth_user
-      halt [401, '{"notauthorized":"true"}']
-    end
-  end
-
-  def getParamList(params)
-    param_line = []
-    meta_options = []
-    params.each { |param, val|
-      if param.start_with?("_res_paramne_") or (param.start_with?("_res_paramempty_") and val != "")
-        myparam = param.sub(/^_res_paramne_/,"").sub(/^_res_paramempty_/,"")
-        param_line << "#{myparam}=#{val}"
-      end
-      if param == "disabled"
-        meta_options << 'meta' << 'target-role=Stopped'
-      end
-      if param == "force" and val
-        param_line << "--force"
-      end
-    }
-    return param_line + meta_options
-  end
-end
-
 get '/remote/?:command?' do
   return remote(params, request, @auth_user)
 end
@@ -675,10 +643,6 @@ post '/manage/auth_gui_against_nodes' do
   ]
 end
 
-get '/clusters_overview' do
-  clusters_overview(params, request, getAuthUser())
-end
-
 get '/imported-cluster-list' do
   imported_cluster_list(params, request, getAuthUser())
 end
@@ -693,190 +657,11 @@ post '/managec/:cluster/permissions_save/?' do
   )
 end
 
-get '/managec/:cluster/status_all' do
-  auth_user = getAuthUser()
-  status_all(params, request, auth_user, get_cluster_nodes(params[:cluster]))
-end
-
 get '/managec/:cluster/cluster_status' do
   auth_user = getAuthUser()
   cluster_status_gui(auth_user, params[:cluster])
 end
 
-get '/managec/:cluster/cluster_properties' do
-  auth_user = getAuthUser()
-  cluster = params[:cluster]
-  unless cluster
-    return 200, {}
-  end
-  code, out = send_cluster_request_with_token(auth_user, cluster, 'get_cib')
-  if code == 403
-    return [403, 'Permission denied']
-  elsif code != 200
-    return [400, 'getting CIB failed']
-  end
-  begin
-    properties = getAllSettings(nil, REXML::Document.new(out))
-    code, out = send_cluster_request_with_token(
-      auth_user, cluster, 'get_cluster_properties_definition'
-    )
-
-    if code == 403
-      return [403, 'Permission denied']
-    elsif code == 404
-      definition = {
-        'batch-limit' => {
-          'name' => 'batch-limit',
-          'source' => 'pacemaker-schedulerd',
-          'default' => '0',
-          'type' => 'integer',
-          'shortdesc' => 'The number of jobs that pacemaker is allowed to execute in parallel.',
-          'longdesc' => 'The "correct" value will depend on the speed and load of your network and cluster nodes.',
-          'readable_name' => 'Batch Limit',
-          'advanced' => false
-        },
-        'no-quorum-policy' => {
-          'name' => 'no-quorum-policy',
-          'source' => 'pacemaker-schedulerd',
-          'default' => 'stop',
-          'type' => 'enum',
-          'enum' => ['stop', 'freeze', 'ignore', 'suicide'],
-          'shortdesc' => 'What to do when the cluster does not have quorum.',
-          'longdesc' => 'Allowed values:
-  * ignore - continue all resource management
-  * freeze - continue resource management, but don\'t recover resources from nodes not in the affected partition
-  * stop - stop all resources in the affected cluster partition
-  * suicide - fence all nodes in the affected cluster partition',
-          'readable_name' => 'No Quorum Policy',
-          'advanced' => false
-        },
-        'symmetric-cluster' => {
-          'name' => 'symmetric-cluster',
-          'source' => 'pacemaker-schedulerd',
-          'default' => 'true',
-          'type' => 'boolean',
-          'shortdesc' => 'All resources can run anywhere by default.',
-          'longdesc' => 'All resources can run anywhere by default.',
-          'readable_name' => 'Symmetric',
-          'advanced' => false
-        },
-        'stonith-enabled' => {
-          'name' => 'stonith-enabled',
-          'source' => 'pacemaker-schedulerd',
-          'default' => 'true',
-          'type' => 'boolean',
-          'shortdesc' => 'Failed nodes are STONITH\'d',
-          'longdesc' => 'Failed nodes are STONITH\'d',
-          'readable_name' => 'Stonith Enabled',
-          'advanced' => false
-        },
-        'stonith-action' => {
-          'name' => 'stonith-action',
-          'source' => 'pacemaker-schedulerd',
-          'default' => 'reboot',
-          'type' => 'enum',
-          'enum' => ['reboot', 'poweroff', 'off'],
-          'shortdesc' => 'Action to send to STONITH device',
-          'longdesc' => 'Action to send to STONITH device Allowed values: reboot, poweroff, off',
-          'readable_name' => 'Stonith Action',
-          'advanced' => false
-        },
-        'cluster-delay' => {
-          'name' => 'cluster-delay',
-          'source' => 'pacemaker-schedulerd',
-          'default' => '60s',
-          'type' => 'time',
-          'shortdesc' => 'Round trip delay over the network (excluding action execution)',
-          'longdesc' => 'The "correct" value will depend on the speed and load of your network and cluster nodes.',
-          'readable_name' => 'Cluster Delay',
-          'advanced' => false
-        },
-        'stop-orphan-resources' => {
-          'name' => 'stop-orphan-resources',
-          'source' => 'pacemaker-schedulerd',
-          'default' => 'true',
-          'type' => 'boolean',
-          'shortdesc' => 'Should deleted resources be stopped',
-          'longdesc' => 'Should deleted resources be stopped',
-          'readable_name' => 'Stop Orphan Resources',
-          'advanced' => false
-        },
-        'stop-orphan-actions' => {
-          'name' => 'stop-orphan-actions',
-          'source' => 'pacemaker-schedulerd',
-          'default' => 'true',
-          'type' => 'boolean',
-          'shortdesc' => 'Should deleted actions be cancelled',
-          'longdesc' => 'Should deleted actions be cancelled',
-          'readable_name' => 'Stop Orphan Actions',
-          'advanced' => false
-        },
-        'start-failure-is-fatal' => {
-          'name' => 'start-failure-is-fatal',
-          'source' => 'pacemaker-schedulerd',
-          'default' => 'true',
-          'type' => 'boolean',
-          'shortdesc' => 'Always treat start failures as fatal',
-          'longdesc' => 'This was the old default. However when set to FALSE, the cluster will instead use the resource\'s failcount and value for resource-failure-stickiness',
-          'readable_name' => 'Start Failure is Fatal',
-          'advanced' => false
-        },
-        'pe-error-series-max' => {
-          'name' => 'pe-error-series-max',
-          'source' => 'pacemaker-schedulerd',
-          'default' => '-1',
-          'type' => 'integer',
-          'shortdesc' => 'The number of PE inputs resulting in ERRORs to save',
-          'longdesc' => 'Zero to disable, -1 to store unlimited.',
-          'readable_name' => 'PE Error Storage',
-          'advanced' => false
-        },
-        'pe-warn-series-max' => {
-          'name' => 'pe-warn-series-max',
-          'source' => 'pacemaker-schedulerd',
-          'default' => '5000',
-          'type' => 'integer',
-          'shortdesc' => 'The number of PE inputs resulting in WARNINGs to save',
-          'longdesc' => 'Zero to disable, -1 to store unlimited.',
-          'readable_name' => 'PE Warning Storage',
-          'advanced' => false
-        },
-        'pe-input-series-max' => {
-          'name' => 'pe-input-series-max',
-          'source' => 'pacemaker-schedulerd',
-          'default' => '4000',
-          'type' => 'integer',
-          'shortdesc' => 'The number of other PE inputs to save',
-          'longdesc' => 'Zero to disable, -1 to store unlimited.',
-          'readable_name' => 'PE Input Storage',
-          'advanced' => false
-        },
-        'enable-acl' => {
-          'name' => 'enable-acl',
-          'source' => 'pacemaker-based',
-          'default' => 'false',
-          'type' => 'boolean',
-          'shortdesc' => 'Enable CIB ACL',
-          'longdesc' => 'Should pacemaker use ACLs to determine access to cluster',
-          'readable_name' => 'Enable ACLs',
-          'advanced' => false
-        },
-      }
-    elsif code != 200
-      return [400, 'getting properties definition failed']
-    else
-      definition = JSON.parse(out)
-    end
-
-    definition.each { |name, prop|
-      prop['value'] = properties[name]
-    }
-    return [200, JSON.generate(definition)]
-  rescue
-    return [400, 'unable to get cluster properties']
-  end
-end
-
 get '/managec/:cluster/get_resource_agent_metadata' do
   auth_user = getAuthUser()
   cluster = params[:cluster]
@@ -888,69 +673,7 @@ get '/managec/:cluster/get_resource_agent_metadata' do
     false,
     {:resource_agent => resource_agent}
   )
-  if code != 404
-    return [code, out]
-  end
-
-  code, out = send_cluster_request_with_token(
-    auth_user,
-    cluster,
-    'resource_metadata',
-    false,
-    {
-      :resourcename => resource_agent,
-      :new => true
-    }
-  )
-  if code != 200
-    return [400, 'Unable to get meta-data of specified resource agent.']
-  end
-  desc_regex = Regexp.new(
-    '<span class="reg[^>]*>(?<short>[^>]*)&nbsp;</span>[^<]*' +
-      '<span title="(?<long>[^"]*)"'
-  )
-  parameters_regex = Regexp.new(
-    '<input type="hidden" name="resource_type"[^>]*>(?<required>[\s\S]*)' +
-      '<div class="bold">Optional Arguments:</div>(?<optional>[\S\s]*)' +
-      '<tr class="stop">'
-  )
-  parameter_regex = Regexp.new(
-    '<tr title="(?<longdesc>[^"]*)"[^>]*>[\s]*<td class="reg">\s*' +
-      '(?<name>[^<\s]*)\s*</td>\s*<td>\s*' +
-      '<input placeholder="(?<shortdesc>[^"]*)"'
-  )
-
-  desc = desc_regex.match(out)
-  unless desc
-    return [400, 'Unable to get meta-data of specified resource agent.']
-  end
-  result = {
-    :name => resource_agent,
-    :shortdesc => html2plain(desc[:short]),
-    :longdesc => html2plain(desc[:long]),
-    :parameters => []
-  }
-
-  parameters = parameters_regex.match(out)
-  parameters[:required].scan(parameter_regex) { |match|
-    result[:parameters] << {
-      :name => html2plain(match[1]),
-      :longdesc => html2plain(match[0]),
-      :shortdesc => html2plain(match[2]),
-      :type => 'string',
-      :required => true
-    }
-  }
-  parameters[:optional].scan(parameter_regex) { |match|
-    result[:parameters] << {
-      :name => html2plain(match[1]),
-      :longdesc => html2plain(match[0]),
-      :shortdesc => html2plain(match[2]),
-      :type => 'string',
-      :required => false
-    }
-  }
-  return [200, JSON.generate(result)]
+  return [code, out]
 end
 
 get '/managec/:cluster/get_fence_agent_metadata' do
@@ -964,90 +687,7 @@ get '/managec/:cluster/get_fence_agent_metadata' do
     false,
     {:fence_agent => fence_agent}
   )
-  if code != 404
-    return [code, out]
-  end
-
-  code, out = send_cluster_request_with_token(
-    auth_user,
-    cluster,
-    'fence_device_metadata',
-    false,
-    {
-      :resourcename => fence_agent.sub('stonith:', ''),
-      :new => true
-    }
-  )
-  if code != 200
-    return [400, 'Unable to get meta-data of specified fence agent.']
-  end
-  desc_regex = Regexp.new(
-    '<span class="reg[^>]*>(?<short>[^>]*)&nbsp;</span>[^<]*' +
-      '<span title="(?<long>[^"]*)"'
-  )
-  parameters_regex = Regexp.new(
-    '<input type="hidden" name="resource_type"[^>]*>(?<required>[\s\S]*)' +
-      '<div class="bold">Optional Arguments:</div>(?<optional>[\S\s]*)' +
-      '<div class="bold">Advanced Arguments:</div>(?<advanced>[\S\s]*)' +
-      '<tr class="stop">'
-  )
-  required_parameter_regex = Regexp.new(
-    '<tr title="(?<longdesc>[^"]*)[^>]*>[\s]*' +
-      '<td class="reg">\s*&nbsp;(?<name>[^<\s]*)\s*</td>\s*<td>\s*' +
-      '<input placeholder="(?<shortdesc>[^"]*)"'
-  )
-  other_parameter_regex = Regexp.new(
-    '<td class="reg">\s*&nbsp;(?<name>[^<\s]*)\s*</td>\s*<td>\s*' +
-      '<input placeholder="(?<shortdesc>[^"]*)"'
-  )
-
-  result = {
-    :name => fence_agent,
-    :shortdesc => '',
-    :longdesc => '',
-    :parameters => []
-  }
-
-  # pcsd in version 0.9.137 (and older) does not provide description for
-  # fence agents
-  desc = desc_regex.match(out)
-  if desc
-    result[:shortdesc] = html2plain(desc[:short])
-    result[:longdesc] = html2plain(desc[:long])
-  end
-
-  parameters = parameters_regex.match(out)
-  parameters[:required].scan(required_parameter_regex) { |match|
-    result[:parameters] << {
-      :name => html2plain(match[1]),
-      :longdesc => html2plain(match[0]),
-      :shortdesc => html2plain(match[2]),
-      :type => 'string',
-      :required => true,
-      :advanced => false
-    }
-  }
-  parameters[:optional].scan(other_parameter_regex) { |match|
-    result[:parameters] << {
-      :name => html2plain(match[0]),
-      :longdesc => '',
-      :shortdesc => html2plain(match[1]),
-      :type => 'string',
-      :required => false,
-      :advanced => false
-    }
-  }
-  parameters[:advanced].scan(other_parameter_regex) { |match|
-    result[:parameters] << {
-      :name => html2plain(match[0]),
-      :longdesc => '',
-      :shortdesc => html2plain(match[1]),
-      :type => 'string',
-      :required => false,
-      :advanced => true
-    }
-  }
-  return [200, JSON.generate(result)]
+  return [code, out]
 end
 
 post '/managec/:cluster/fix_auth_of_cluster' do
@@ -1123,7 +763,6 @@ def pcs_compatibility_layer_known_hosts_add(
   known_hosts = get_known_hosts().select { |name, obj|
     host_list.include?(name)
   }
-  # try the new endpoint provided by pcs-0.10
   known_hosts_request_data = {}
   known_hosts.each { |host_name, host_obj|
     known_hosts_request_data[host_name] = {
@@ -1149,50 +788,14 @@ def pcs_compatibility_layer_known_hosts_add(
     )
   end
 
-  # a remote host supports the endpoint; success
-  if retval == 200
-    return 'success'
-  end
-
-  # a remote host supports the endpoint; error
-  if retval != 404
-    return 'error'
-  end
-
-  # a remote host does not support the endpoint
-  # fallback to the old endpoint provided by pcs-0.9 since 0.9.140
-  request_data = {}
-  known_hosts.each { |host_name, host_obj|
-    addr = host_obj.first_dest()['addr']
-    port = host_obj.first_dest()['port']
-    request_data["node:#{host_name}"] = host_obj.token
-    request_data["port:#{host_name}"] = port
-    request_data["node:#{addr}"] = host_obj.token
-    request_data["port:#{addr}"] = port
-  }
-  if is_cluster_request
-    retval, _out = send_cluster_request_with_token(
-      auth_user, target, '/save_tokens', true, request_data
-    )
-  else
-    retval, _out = send_request_with_token(
-      auth_user, target, '/save_tokens', true, request_data
-    )
-  end
-
-  # a remote host supports the endpoint; success
   if retval == 200
     return 'success'
   end
 
-  # a remote host supports the endpoint; error
-  if retval != 404
-    return 'error'
+  if retval == 404
+    return 'not_supported'
   end
-
-  # a remote host does not support any of the endpoints
-  # there's nothing we can do about it
-  return 'not_supported'
+  return 'error'
 end
 
 def pcs_compatibility_layer_get_cluster_known_hosts(cluster_name, target_node)
@@ -1200,11 +803,9 @@ def pcs_compatibility_layer_get_cluster_known_hosts(cluster_name, target_node)
   known_hosts = []
   auth_user = PCSAuth.getSuperuserAuth()
 
-  # try the new endpoint provided by pcs-0.10
   retval, out = send_request_with_token(
     auth_user, target_node, '/get_cluster_known_hosts'
   )
-  # a remote host supports /get_cluster_known_hosts; data downloaded
   if retval == 200
     begin
       JSON.parse(out).each { |name, data|
@@ -1222,159 +823,21 @@ def pcs_compatibility_layer_get_cluster_known_hosts(cluster_name, target_node)
         "cannot get authentication info from cluster '#{cluster_name}'"
       )
     end
-    return known_hosts, warning_messages
-  end
-
-  # a remote host supports /get_cluster_known_hosts; an error occured
-  if retval != 404
+  elsif retval == 404
     warning_messages << (
       "Unable to automatically authenticate against cluster nodes: " +
-      "cannot get authentication info from cluster '#{cluster_name}'"
+      "cluster '#{cluster_name}' is running an old version of pcs/pcsd"
     )
-    return known_hosts, warning_messages
-  end
-
-  # a remote host does not support /get_cluster_known_hosts
-  # fallback to the old endpoint provided by pcs-0.9 since 0.9.140
-  retval, out = send_request_with_token(
-    auth_user, target_node, '/get_cluster_tokens', false, {'with_ports' => '1'}
-  )
-
-  # a remote host supports /get_cluster_tokens; data downloaded
-  if retval == 200
-    begin
-      data = JSON.parse(out)
-      expected_keys = ['tokens', 'ports']
-      if expected_keys.all? {|i| data.has_key?(i) and data[i].class == Hash}
-        # new format
-        new_tokens = data["tokens"] || {}
-        new_ports = data["ports"] || {}
-      else
-        # old format
-        new_tokens = data
-        new_ports = {}
-      end
-      new_tokens.each { |name_addr, token|
-        known_hosts << PcsKnownHost.new(
-          name_addr,
-          token,
-          [
-            {
-              'addr' => name_addr,
-              'port' => (new_ports[name_addr] || PCSD_DEFAULT_PORT),
-            }
-          ]
-        )
-      }
-    rescue => e
-      $logger.error "Unable to parse the response of /get_cluster_tokens: #{e}"
-      known_hosts = []
-      warning_messages << (
-        "Unable to automatically authenticate against cluster nodes: " +
-        "cannot get authentication info from cluster '#{cluster_name}'"
-      )
-    end
-    return known_hosts, warning_messages
-  end
-
-  # a remote host supports /get_cluster_tokens; an error occured
-  if retval != 404
+  else
     warning_messages << (
       "Unable to automatically authenticate against cluster nodes: " +
       "cannot get authentication info from cluster '#{cluster_name}'"
     )
-    return known_hosts, warning_messages
   end
 
-  # a remote host does not support /get_cluster_tokens
-  # there's nothing we can do about it
-  warning_messages << (
-    "Unable to automatically authenticate against cluster nodes: " +
-    "cluster '#{cluster_name}' is running an old version of pcs/pcsd"
-  )
   return known_hosts, warning_messages
 end
 
-def pcs_0_9_142_resource_change_group(auth_user, params)
-  parameters = {
-    :resource_id => params[:resource_id],
-    :resource_group => '',
-    :_orig_resource_group => '',
-  }
-  parameters[:resource_group] = params[:group_id] if params[:group_id]
-  if params[:old_group_id]
-    parameters[:_orig_resource_group] = params[:old_group_id]
-  end
-  return send_cluster_request_with_token(
-    auth_user, params[:cluster], 'update_resource', true, parameters
-  )
-end
-
-def pcs_0_9_142_resource_clone(auth_user, params)
-  parameters = {
-    :resource_id => params[:resource_id],
-    :resource_clone => true,
-    :_orig_resource_clone => 'false',
-  }
-  return send_cluster_request_with_token(
-    auth_user, params[:cluster], 'update_resource', true, parameters
-  )
-end
-
-def pcs_0_9_142_resource_unclone(auth_user, params)
-  parameters = {
-    :resource_id => params[:resource_id],
-    :resource_clone => nil,
-    :_orig_resource_clone => 'true',
-  }
-  return send_cluster_request_with_token(
-    auth_user, params[:cluster], 'update_resource', true, parameters
-  )
-end
-
-def pcs_0_9_142_resource_master(auth_user, params)
-  parameters = {
-    :resource_id => params[:resource_id],
-    :resource_ms => true,
-    :_orig_resource_ms => 'false',
-  }
-  return send_cluster_request_with_token(
-    auth_user, params[:cluster], 'update_resource', true, parameters
-  )
-end
-
-# There is a bug in pcs-0.9.138 and older in processing the standby and
-# unstandby request. JS of that pcsd always sent nodename in "node"
-# parameter, which caused pcsd daemon to run the standby command locally with
-# param["node"] as node name. This worked fine if the local cluster was
-# managed from JS, as pacemaker simply put the requested node into standby.
-# However it didn't work for managing non-local clusters, as the command was
-# run on the local cluster everytime. Pcsd daemon would send the request to a
-# remote cluster if the param["name"] variable was set, and that never
-# happened. That however wouldn't work either, as then the required parameter
-# "node" wasn't sent in the request causing an exception on the receiving
-# node. This is fixed in commit 053f63ca109d9ef9e7f0416e90aab8e140480f5b
-#
-# In order to be able to put nodes running pcs-0.9.138 into standby, the
-# nodename must be sent in "node" param, and the "name" must not be sent.
-def pcs_0_9_138_node_standby(auth_user, params)
-  translated_params = {
-    'node' => params[:name],
-  }
-  return send_cluster_request_with_token(
-    auth_user, params[:cluster], 'node_standby', true, translated_params
-  )
-end
-
-def pcs_0_9_138_node_unstandby(auth_user, params)
-  translated_params = {
-    'node' => params[:name],
-  }
-  return send_cluster_request_with_token(
-    auth_user, params[:cluster], 'node_unstandby', true, translated_params
-  )
-end
-
 def pcs_0_10_6_get_avail_resource_agents(code, out)
   if code != 200
     return code, out
@@ -1421,99 +884,9 @@ post '/managec/:cluster/?*' do
   if params[:cluster]
     request = "/" + params[:splat].join("/")
 
-    # backward compatibility layer BEGIN
-    translate_for_version = {
-      '/node_standby' => [
-        [[0, 9, 138], method(:pcs_0_9_138_node_standby)],
-      ],
-      '/node_unstandby' => [
-        [[0, 9, 138], method(:pcs_0_9_138_node_unstandby)],
-      ],
-    }
-    if translate_for_version.key?(request)
-      target_pcsd_version = [0, 0, 0]
-      version_code, version_out = send_cluster_request_with_token(
-        auth_user, params[:cluster], 'get_sw_versions'
-      )
-      if version_code == 200
-        begin
-          versions = JSON.parse(version_out)
-          target_pcsd_version = versions['pcs'] if versions['pcs']
-        rescue JSON::ParserError
-        end
-      end
-      translate_function = nil
-      translate_for_version[request].each { |pair|
-        if (target_pcsd_version <=> pair[0]) != 1 # target <= pair
-          translate_function = pair[1]
-          break
-        end
-      }
-    end
-    # backward compatibility layer END
-
-    if translate_function
-      code, out = translate_function.call(auth_user, params)
-    else
-      code, out = send_cluster_request_with_token(
-        auth_user, params[:cluster], request, true, params, true, raw_data
-      )
-    end
-
-    # backward compatibility layer BEGIN
-    if code == 404
-      case request
-        # supported since pcs-0.9.143 (tree view of resources)
-        when '/resource_change_group', 'resource_change_group'
-          code, out =  pcs_0_9_142_resource_change_group(auth_user, params)
-        # supported since pcs-0.9.143 (tree view of resources)
-        when '/resource_clone', 'resource_clone'
-          code, out = pcs_0_9_142_resource_clone(auth_user, params)
-        # supported since pcs-0.9.143 (tree view of resources)
-        when '/resource_unclone', 'resource_unclone'
-          code, out = pcs_0_9_142_resource_unclone(auth_user, params)
-        # supported since pcs-0.9.143 (tree view of resources)
-        when '/resource_master', 'resource_master'
-          # defaults to true for old pcsds without capabilities defined
-          supports_resource_master = true
-          capabilities_code, capabilities_out = send_cluster_request_with_token(
-            auth_user, params[:cluster], 'capabilities'
-          )
-          if capabilities_code == 200
-            begin
-              capabilities_json = JSON.parse(capabilities_out)
-              supports_resource_master = capabilities_json[:pcsd_capabilities].include?(
-                'pcmk.resource.master'
-              )
-            rescue JSON::ParserError
-            end
-          end
-          if supports_resource_master
-            code, out = pcs_0_9_142_resource_master(auth_user, params)
-          end
-        else
-          redirection = {
-            # constraints removal for pcs-0.9.137 and older
-            "/remove_constraint_remote" => "/resource_cmd/rm_constraint",
-            # constraints removal for pcs-0.9.137 and older
-            "/remove_constraint_rule_remote" => "/resource_cmd/rm_constraint_rule"
-          }
-          if redirection.key?(request)
-            code, out = send_cluster_request_with_token(
-              auth_user,
-              params[:cluster],
-              redirection[request],
-              true,
-              params,
-              false,
-              raw_data
-            )
-          end
-      end
-    end
-    # backward compatibility layer END
-
-    return code, out
+    return send_cluster_request_with_token(
+      auth_user, params[:cluster], request, true, params, true, raw_data
+    )
   end
 end
 
@@ -1548,17 +921,3 @@ get '*' do
   redirect "Bad URL"
   call(env.merge("PATH_INFO" => '/nodes'))
 end
-
-def html2plain(text)
-  return CGI.unescapeHTML(text).gsub(/<br[^>]*>/, "\n")
-end
-
-helpers do
-  def h(text)
-    Rack::Utils.escape_html(text)
-  end
-
-  def nl2br(text)
-    text.gsub(/\n/, "<br>")
-  end
-end
diff --git a/pcsd/remote.rb b/pcsd/remote.rb
index 1c019e98..e36f651f 100644
--- a/pcsd/remote.rb
+++ b/pcsd/remote.rb
@@ -25,14 +25,14 @@ def remote(params, request, auth_user)
   remote_cmd_without_pacemaker = {
       :capabilities => method(:capabilities),
       :status => method(:node_status),
-      :status_all => method(:status_all),
       :cluster_status => method(:cluster_status_remote),
       :cluster_status_plaintext => method(:cluster_status_plaintext),
       :auth => method(:auth),
       :check_auth => method(:check_auth),
+      # lib api:
+      # /api/v1/cluster-setup/v1
       :cluster_setup => method(:cluster_setup),
       :get_quorum_info => method(:get_quorum_info),
-      :get_cib => method(:get_cib),
       :get_corosync_conf => method(:get_corosync_conf_remote),
       :set_corosync_conf => method(:set_corosync_conf),
       :get_sync_capabilities => method(:get_sync_capabilities),
@@ -45,14 +45,6 @@ def remote(params, request, auth_user)
       :cluster_start => method(:cluster_start),
       :cluster_stop => method(:cluster_stop),
       :config_restore => method(:config_restore),
-      # TODO deprecated, remove, not used anymore
-      :node_restart => method(:node_restart),
-      # lib api:
-      # /api/v1/node-standby-unstandby/v1
-      :node_standby => method(:node_standby),
-      # lib api:
-      # /api/v1/node-standby-unstandby/v1
-      :node_unstandby => method(:node_unstandby),
       :cluster_enable => method(:cluster_enable),
       :cluster_disable => method(:cluster_disable),
       :get_sw_versions => method(:get_sw_versions),
@@ -69,12 +61,6 @@ def remote(params, request, auth_user)
       :sbd_enable => method(:sbd_enable),
       :remove_stonith_watchdog_timeout=> method(:remove_stonith_watchdog_timeout),
       :set_stonith_watchdog_timeout_to_zero => method(:set_stonith_watchdog_timeout_to_zero),
-      # lib api:
-      # /api/v1/sbd-enable-sbd/v1
-      :remote_enable_sbd => method(:remote_enable_sbd),
-      # lib api:
-      # /api/v1/sbd-disable-sbd/v1
-      :remote_disable_sbd => method(:remote_disable_sbd),
       :qdevice_net_get_ca_certificate => method(:qdevice_net_get_ca_certificate),
       # lib api:
       # /api/v1/qdevice-qdevice-net-sign-certificate-request/v1
@@ -100,9 +86,6 @@ def remote(params, request, auth_user)
       # lib api:
       # /api/v1/resource-agent-list-agents/v1
       :get_avail_resource_agents => method(:get_avail_resource_agents),
-      # lib api:
-      # /api/v1/stonith-agent-list-agents/v1
-      :get_avail_fence_agents => method(:get_avail_fence_agents),
   }
   remote_cmd_with_pacemaker = {
       :pacemaker_node_status => method(:remote_pacemaker_node_status),
@@ -159,18 +142,6 @@ def remote(params, request, auth_user)
       :get_fence_agent_metadata => method(:get_fence_agent_metadata),
       :manage_resource => method(:manage_resource),
       :unmanage_resource => method(:unmanage_resource),
-      # lib api:
-      # /api/v1/alert-create-alert/v1
-      :create_alert => method(:create_alert),
-      # lib api:
-      # /api/v1/alert-update-alert/v1
-      :update_alert => method(:update_alert),
-      :create_recipient => method(:create_recipient),
-      :update_recipient => method(:update_recipient),
-      # lib api:
-      # /api/v1/alert-remove-alert/v1
-      # /api/v1/alert-remove-recipient/v1
-      :remove_alerts_and_recipients => method("remove_alerts_and_recipients"),
   }
 
   command = params[:command].to_sym
@@ -193,6 +164,24 @@ def remote(params, request, auth_user)
   end
 end
 
+def _get_param_list(params)
+  param_line = []
+  meta_options = []
+  params.each { |param, val|
+    if param.start_with?("_res_paramne_") or (param.start_with?("_res_paramempty_") and val != "")
+      myparam = param.sub(/^_res_paramne_/,"").sub(/^_res_paramempty_/,"")
+      param_line << "#{myparam}=#{val}"
+    end
+    if param == "disabled"
+      meta_options << 'meta' << 'target-role=Stopped'
+    end
+    if param == "force" and val
+      param_line << "--force"
+    end
+  }
+  return param_line + meta_options
+end
+
 def capabilities(params, request, auth_user)
   return JSON.generate({
     :pcsd_capabilities => CAPABILITIES_PCSD,
@@ -394,53 +383,6 @@ def config_restore(params, request, auth_user)
   end
 end
 
-# TODO deprecated, remove, not used anymore
-def node_restart(params, request, auth_user)
-  if params[:name]
-    code, response = send_request_with_token(
-      auth_user, params[:name], 'node_restart', true
-    )
-  else
-    if not allowed_for_local_cluster(auth_user, Permissions::WRITE)
-      return 403, 'Permission denied'
-    end
-    $logger.info "Restarting Node"
-    output =  `/sbin/reboot`
-    $logger.debug output
-    return output
-  end
-end
-
-def node_standby(params, request, auth_user)
-  if params[:name]
-    code, response = send_request_with_token(
-      auth_user, params[:name], 'node_standby', true
-    )
-  else
-    if not allowed_for_local_cluster(auth_user, Permissions::WRITE)
-      return 403, 'Permission denied'
-    end
-    $logger.info "Standby Node"
-    stdout, stderr, retval = run_cmd(auth_user, PCS, "node", "standby")
-    return stdout
-  end
-end
-
-def node_unstandby(params, request, auth_user)
-  if params[:name]
-    code, response = send_request_with_token(
-      auth_user, params[:name], 'node_unstandby', true
-    )
-  else
-    if not allowed_for_local_cluster(auth_user, Permissions::WRITE)
-      return 403, 'Permission denied'
-    end
-    $logger.info "Unstandby Node"
-    stdout, stderr, retval = run_cmd(auth_user, PCS, "node", "unstandby")
-    return stdout
-  end
-end
-
 def cluster_enable(params, request, auth_user)
   if params[:name]
     code, response = send_request_with_token(
@@ -491,21 +433,6 @@ def get_quorum_info(params, request, auth_user)
   end
 end
 
-def get_cib(params, request, auth_user)
-  if not allowed_for_local_cluster(auth_user, Permissions::READ)
-    return 403, 'Permission denied'
-  end
-  cib, stderr, retval = run_cmd(auth_user, CIBADMIN, "-Ql")
-  if retval != 0
-    if not pacemaker_running?
-      return [400, '{"pacemaker_not_running":true}']
-    end
-    return [500, "Unable to get CIB: " + cib.to_s + stderr.to_s]
-  else
-    return [200, cib]
-  end
-end
-
 def get_corosync_conf_remote(params, request, auth_user)
   if not allowed_for_local_cluster(auth_user, Permissions::READ)
     return 403, 'Permission denied'
@@ -912,66 +839,6 @@ def node_status(params, request, auth_user)
   return [400, "Unsupported version '#{version}' of status requested"]
 end
 
-def status_all(params, request, auth_user, nodes=[], dont_update_config=false)
-  if nodes == nil
-    return JSON.generate({"error" => "true"})
-  end
-
-  final_response = {}
-  threads = []
-  forbidden_nodes = {}
-  nodes.each {|node|
-    threads << Thread.new(Thread.current[:pcsd_logger_container]) { |logger|
-      Thread.current[:pcsd_logger_container] = logger
-      code, response = send_request_with_token(auth_user, node, 'status')
-      if 403 == code
-        forbidden_nodes[node] = true
-      end
-      begin
-        final_response[node] = JSON.parse(response)
-      rescue JSON::ParserError => e
-        final_response[node] = {"bad_json" => true}
-        $logger.info("ERROR: Parse Error when parsing status JSON from #{node}")
-      end
-      if final_response[node] and final_response[node]["notoken"] == true
-        $logger.error("ERROR: bad token for #{node}")
-      end
-    }
-  }
-  threads.each { |t| t.join }
-  if forbidden_nodes.length > 0
-    return 403, 'Permission denied'
-  end
-
-  # Get full list of nodes and see if we need to update the configuration
-  node_list = []
-  final_response.each { |fr,n|
-    node_list += n["corosync_offline"] if n["corosync_offline"]
-    node_list += n["corosync_online"] if n["corosync_online"]
-    node_list += n["pacemaker_offline"] if n["pacemaker_offline"]
-    node_list += n["pacemaker_online"] if n["pacemaker_online"]
-  }
-
-  node_list.uniq!
-  if node_list.length > 0
-    config = PCSConfig.new(Cfgsync::PcsdSettings.from_file().text())
-    old_node_list = config.get_nodes(params[:cluster])
-    if !(dont_update_config or config.cluster_nodes_equal?(params[:cluster], node_list))
-      $logger.info("Updating node list for: #{params[:cluster]} #{old_node_list}->#{node_list}")
-      config.update_cluster(params[:cluster], node_list)
-      sync_config = Cfgsync::PcsdSettings.from_text(config.text())
-      # on version conflict just go on, config will be corrected eventually
-      # by displaying the cluster in the web UI
-      Cfgsync::save_sync_new_version(
-        sync_config, get_corosync_nodes_names(), $cluster_name, true
-      )
-      return status_all(params, request, auth_user, node_list, true)
-    end
-  end
-  $logger.debug("NODE LIST: " + node_list.inspect)
-  return JSON.generate(final_response)
-end
-
 def imported_cluster_list(params, request, auth_user)
   config = PCSConfig.new(Cfgsync::PcsdSettings.from_file().text())
   imported_clusters = {"cluster_list" => []}
@@ -981,173 +848,6 @@ def imported_cluster_list(params, request, auth_user)
   return JSON.generate(imported_clusters)
 end
 
-def clusters_overview(params, request, auth_user)
-  cluster_map = {}
-  forbidden_clusters = {}
-  threads = []
-  config = PCSConfig.new(Cfgsync::PcsdSettings.from_file().text())
-  config.clusters.each { |cluster|
-    threads << Thread.new(Thread.current[:pcsd_logger_container]) { |logger|
-      Thread.current[:pcsd_logger_container] = logger
-      cluster_map[cluster.name] = {
-        'cluster_name' => cluster.name,
-        'error_list' => [
-          {'message' => 'Unable to connect to the cluster. Request timeout.'}
-        ],
-        'warning_list' => [],
-        'status' => 'unknown',
-        'node_list' => get_default_overview_node_list(cluster.name),
-        'resource_list' => []
-      }
-      overview_cluster = nil
-      online, offline, not_authorized_nodes = is_auth_against_nodes(
-        auth_user,
-        get_cluster_nodes(cluster.name),
-        3
-      )
-      not_supported = false
-      forbidden = false
-      cluster_nodes_auth = (online + offline).uniq
-      cluster_nodes_all = (cluster_nodes_auth + not_authorized_nodes).uniq
-      nodes_not_in_cluster = []
-      for node in cluster_nodes_auth
-        code, response = send_request_with_token(
-          auth_user, node, 'cluster_status', true, {}, true, nil, 8
-        )
-        if code == 404
-          not_supported = true
-          next
-        end
-        if 403 == code
-          forbidden = true
-          forbidden_clusters[cluster.name] = true
-          break
-        end
-        begin
-          parsed_response = JSON.parse(response)
-          if parsed_response['noresponse'] or parsed_response['pacemaker_not_running']
-            next
-          elsif parsed_response['notoken'] or parsed_response['notauthorized']
-            next
-          elsif parsed_response['cluster_name'] != cluster.name
-            # queried node is not in the cluster (any more)
-            nodes_not_in_cluster << node
-            next
-          else
-            overview_cluster = parsed_response
-            break
-          end
-        rescue JSON::ParserError
-        end
-      end
-
-      if cluster_nodes_all.sort == nodes_not_in_cluster.sort
-        overview_cluster = {
-          'cluster_name' => cluster.name,
-          'error_list' => [],
-          'warning_list' => [],
-          'status' => 'unknown',
-          'node_list' => [],
-          'resource_list' => []
-        }
-      end
-
-      if not overview_cluster
-        overview_cluster = {
-          'cluster_name' => cluster.name,
-          'error_list' => [],
-          'warning_list' => [],
-          'status' => 'unknown',
-          'node_list' => get_default_overview_node_list(cluster.name),
-          'resource_list' => []
-        }
-        if not_supported
-          overview_cluster['warning_list'] = [
-            {
-              'message' => 'Cluster is running an old version of pcs/pcsd which does not provide data for the dashboard.',
-            },
-          ]
-        else
-          if forbidden
-            overview_cluster['error_list'] = [
-              {
-                'message' => 'You do not have permissions to view the cluster.',
-                'type' => 'forbidden',
-              },
-            ]
-            overview_cluster['node_list'] = []
-          else
-            overview_cluster['error_list'] = [
-              {
-                'message' => 'Unable to connect to the cluster.',
-              },
-            ]
-          end
-        end
-      end
-      if not_authorized_nodes.length > 0
-        overview_cluster['warning_list'] << {
-          'message' => 'GUI is not authorized against node(s) '\
-            + not_authorized_nodes.join(', '),
-          'type' => 'nodes_not_authorized',
-          'node_list' => not_authorized_nodes,
-        }
-      end
-
-      overview_cluster['node_list'].each { |node|
-        if node['status_version'] == '1'
-          overview_cluster['warning_list'] << {
-            :message => 'Some nodes are running old version of pcs/pcsd.'
-          }
-          break
-        end
-      }
-
-      cluster_map[cluster.name] = overview_cluster
-    }
-  }
-
-  begin
-    Timeout::timeout(18) {
-      threads.each { |t| t.join }
-    }
-  rescue Timeout::Error
-    threads.each { |t| t.exit }
-  end
-
-  # update clusters in PCSConfig
-  not_current_data = false
-  config = PCSConfig.new(Cfgsync::PcsdSettings.from_file().text())
-  cluster_map.each { |cluster, values|
-    next if forbidden_clusters[cluster]
-    nodes = []
-    values['node_list'].each { |node|
-      nodes << node['name']
-    }
-    if !config.cluster_nodes_equal?(cluster, nodes)
-      $logger.info("Updating node list for: #{cluster} #{config.get_nodes(cluster)}->#{nodes}")
-      config.update_cluster(cluster, nodes)
-      not_current_data = true
-    end
-  }
-  if not_current_data
-    sync_config = Cfgsync::PcsdSettings.from_text(config.text())
-    # on version conflict just go on, config will be corrected eventually
-    # by displaying the cluster in the web UI
-    Cfgsync::save_sync_new_version(
-      sync_config, get_corosync_nodes_names(), $cluster_name, true
-    )
-  end
-
-  overview = {
-    'not_current_data' => not_current_data,
-    'cluster_list' => cluster_map.values.sort { |a, b|
-      a['clustername'] <=> b['clustername']
-    }
-  }
-  return JSON.generate(overview)
-end
-
 def auth(params, request, auth_user)
   # User authentication using username and password is done in python part of
   # pcsd. We will get here only if credentials are correct, so we just need to
@@ -1220,7 +920,7 @@ def update_resource (params, request, auth_user)
     return 403, 'Permission denied'
   end
 
-  param_line = getParamList(params)
+  param_line = _get_param_list(params)
   if not params[:resource_id]
     cmd = [PCS, "resource", "create", params[:name], params[:resource_type]]
     cmd += param_line
@@ -1320,7 +1020,7 @@ def update_fence_device(params, request, auth_user)
 
   $logger.info "Updating fence device"
   $logger.info params
-  param_line = getParamList(params)
+  param_line = _get_param_list(params)
   $logger.info param_line
 
   if not params[:resource_id]
@@ -1353,14 +1053,6 @@ def get_avail_resource_agents(params, request, auth_user)
   return JSON.generate(getResourceAgents(auth_user).map{|a| [a, get_resource_agent_name_structure(a)]}.to_h)
 end
 
-def get_avail_fence_agents(params, request, auth_user)
-  if not allowed_for_local_cluster(auth_user, Permissions::READ)
-    return 403, 'Permission denied'
-  end
-  agents = getFenceAgents(auth_user)
-  return JSON.generate(agents)
-end
-
 def remove_resource(params, request, auth_user)
   if not allowed_for_local_cluster(auth_user, Permissions::WRITE)
     return 403, 'Permission denied'
@@ -1740,18 +1432,6 @@ def update_cluster_settings(params, request, auth_user)
   to_update = []
   current = getAllSettings(auth_user)
 
-  # We need to be able to set cluster properties also from older version GUI.
-  # This code handles proper processing of checkboxes.
-  # === backward compatibility layer start ===
-  params['hidden'].each { |prop, val|
-    next if prop == 'hidden_input'
-    unless properties.include?(prop)
-      properties[prop] = val
-      to_update << prop
-    end
-  }
-  # === backward compatibility layer end ===
-
   properties.each { |prop, val|
     val.strip!
     if not current.include?(prop) and val != '' # add
@@ -2236,62 +1916,6 @@ def set_stonith_watchdog_timeout_to_zero(param, request, auth_user)
   end
 end
 
-def remote_enable_sbd(params, request, auth_user)
-  unless allowed_for_local_cluster(auth_user, Permissions::WRITE)
-    return 403, 'Permission denied'
-  end
-
-  arg_list = []
-
-  if ['true', '1', 'on'].include?(params[:ignore_offline_nodes])
-    arg_list << '--skip-offline'
-  end
-
-  params[:watchdog].each do |node, watchdog|
-    unless watchdog.strip.empty?
-      arg_list << "watchdog=#{watchdog.strip}@#{node}"
-    end
-  end
-
-  params[:config].each do |option, value|
-    unless value.empty?
-      arg_list << "#{option}=#{value}"
-    end
-  end
-
-  _, stderr, retcode = run_cmd(
-    auth_user, PCS, 'stonith', 'sbd', 'enable', *arg_list
-  )
-
-  if retcode != 0
-    return [400, "Unable to enable sbd in cluster:\n#{stderr.join('')}"]
-  end
-
-  return [200, 'Sbd has been enabled.']
-end
-
-def remote_disable_sbd(params, request, auth_user)
-  unless allowed_for_local_cluster(auth_user, Permissions::WRITE)
-    return 403, 'Permission denied'
-  end
-
-  arg_list = []
-
-  if ['true', '1', 'on'].include?(params[:ignore_offline_nodes])
-    arg_list << '--skip-offline'
-  end
-
-  _, stderr, retcode = run_cmd(
-    auth_user, PCS, 'stonith', 'sbd', 'disable', *arg_list
-  )
-
-  if retcode != 0
-    return [400, "Unable to disable sbd in cluster:\n#{stderr.join('')}"]
-  end
-
-  return [200, 'Sbd has been disabled.']
-end
-
 def qdevice_net_get_ca_certificate(params, request, auth_user)
   unless allowed_for_local_cluster(auth_user, Permissions::READ)
     return 403, 'Permission denied'
@@ -2697,145 +2321,6 @@ def manage_services(params, request, auth_user)
   end
 end
 
-def _hash_to_argument_list(hash)
-  result = []
-  if hash.kind_of?(Hash)
-    hash.each {|key, value|
-      value = '' if value.nil?
-      result << "#{key}=#{value}"
-    }
-  end
-  return result
-end
-
-def create_alert(params, request, auth_user)
-  unless allowed_for_local_cluster(auth_user, Permissions::WRITE)
-    return 403, 'Permission denied'
-  end
-  path = params[:path]
-  unless path
-    return [400, 'Missing required parameter: path']
-  end
-  alert_id = params[:alert_id]
-  description = params[:description]
-  meta_attr_list = _hash_to_argument_list(params[:meta_attr])
-  instance_attr_list = _hash_to_argument_list(params[:instance_attr])
-  cmd = [PCS, 'alert', 'create', "path=#{path}"]
-  cmd << "id=#{alert_id}" if alert_id and alert_id != ''
-  cmd << "description=#{description}" if description and description != ''
-  cmd += ['options', *instance_attr_list] if instance_attr_list.any?
-  cmd += ['meta', *meta_attr_list] if meta_attr_list.any?
-  output, stderr, retval = run_cmd(auth_user, *cmd)
-  if retval != 0
-    return [400, "Unable to create alert: #{stderr.join("\n")}"]
-  end
-  return [200, 'Alert created']
-end
-
-def update_alert(params, request, auth_user)
-  unless allowed_for_local_cluster(auth_user, Permissions::WRITE)
-    return 403, 'Permission denied'
-  end
-  alert_id = params[:alert_id]
-  unless alert_id
-    return [400, 'Missing required parameter: alert_id']
-  end
-  path = params[:path]
-  description = params[:description]
-  meta_attr_list = _hash_to_argument_list(params[:meta_attr])
-  instance_attr_list = _hash_to_argument_list(params[:instance_attr])
-  cmd = [PCS, 'alert', 'update', alert_id]
-  cmd << "path=#{path}" if path
-  cmd << "description=#{description}" if description
-  cmd += ['options', *instance_attr_list] if instance_attr_list.any?
-  cmd += ['meta', *meta_attr_list] if meta_attr_list.any?
-  output, stderr, retval = run_cmd(auth_user, *cmd)
-  if retval != 0
-    return [400, "Unable to update alert: #{stderr.join("\n")}"]
-  end
-  return [200, 'Alert updated']
-end
-
-def remove_alerts_and_recipients(params, request, auth_user)
-  unless allowed_for_local_cluster(auth_user, Permissions::WRITE)
-    return 403, 'Permission denied'
-  end
-  alert_list = params[:alert_list]
-  recipient_list = params[:recipient_list]
-  if recipient_list.kind_of?(Array) and recipient_list.any?
-    output, stderr, retval = run_cmd(
-      auth_user, PCS, 'alert', 'recipient', 'remove', *recipient_list
-    )
-    if retval != 0
-      return [400, "Unable to remove recipients: #{stderr.join("\n")}"]
-    end
-  end
-  if alert_list.kind_of?(Array) and alert_list.any?
-    output, stderr, retval = run_cmd(
-      auth_user, PCS, 'alert', 'remove', *alert_list
-    )
-    if retval != 0
-      return [400, "Unable to remove alerts: #{stderr.join("\n")}"]
-    end
-  end
-  return [200, 'All removed']
-end
-
-def create_recipient(params, request, auth_user)
-  unless allowed_for_local_cluster(auth_user, Permissions::WRITE)
-    return 403, 'Permission denied'
-  end
-  alert_id = params[:alert_id]
-  if not alert_id or alert_id.strip! == ''
-    return [400, 'Missing required paramter: alert_id']
-  end
-  value = params[:value]
-  if not value or value == ''
-    return [400, 'Missing required paramter: value']
-  end
-  recipient_id = params[:recipient_id]
-  description = params[:description]
-  meta_attr_list = _hash_to_argument_list(params[:meta_attr])
-  instance_attr_list = _hash_to_argument_list(params[:instance_attr])
-  cmd = [PCS, 'alert', 'recipient', 'add', alert_id, "value=#{value}"]
-  cmd << "id=#{recipient_id}" if recipient_id and recipient_id != ''
-  cmd << "description=#{description}" if description and description != ''
-  cmd += ['options', *instance_attr_list] if instance_attr_list.any?
-  cmd += ['meta', *meta_attr_list] if meta_attr_list.any?
-  output, stderr, retval = run_cmd(auth_user, *cmd)
-  if retval != 0
-    return [400, "Unable to create recipient: #{stderr.join("\n")}"]
-  end
-  return [200, 'Recipient created']
-end
-
-def update_recipient(params, request, auth_user)
-  unless allowed_for_local_cluster(auth_user, Permissions::WRITE)
-    return 403, 'Permission denied'
-  end
-  recipient_id = params[:recipient_id]
-  if not recipient_id or recipient_id.strip! == ''
-    return [400, 'Missing required paramter: recipient_id']
-  end
-  value = params[:value]
-  if value and value.strip! == ''
-    return [400, 'Parameter value canot be empty string']
-  end
-  description = params[:description]
-  meta_attr_list = _hash_to_argument_list(params[:meta_attr])
-  instance_attr_list = _hash_to_argument_list(params[:instance_attr])
-  cmd = [PCS, 'alert', 'recipient', 'update', recipient_id]
-  cmd << "value=#{value}" if value
-  cmd << "description=#{description}" if description
-  cmd += ['options', *instance_attr_list] if instance_attr_list.any?
-  cmd += ['meta', *meta_attr_list] if meta_attr_list.any?
-  output, stderr, retval = run_cmd(auth_user, *cmd)
-  if retval != 0
-    return [400, "Unable to update recipient: #{stderr.join("\n")}"]
-  end
-  return [200, 'Recipient updated']
-end
-
 def pcsd_success(msg)
   $logger.info(msg)
   return [200, msg]
diff --git a/pcsd/resource.rb b/pcsd/resource.rb
index e49422f8..27894cc9 100644
--- a/pcsd/resource.rb
+++ b/pcsd/resource.rb
@@ -103,11 +103,8 @@ def get_resource_agent_name_structure(agent_name)
     match = expression.match(agent_name)
     if match
       provider = match.names.include?('provider') ? match[:provider] : nil
-      class_provider = provider.nil? ? match[:standard] : "#{match[:standard]}:#{provider}"
       return {
         :full_name => agent_name,
-        # TODO remove, this is only used by the old web UI
-        :class_provider => class_provider,
         :class => match[:standard],
         :provider => provider,
         :type => match[:type],
diff --git a/pcsd/rserver.rb b/pcsd/rserver.rb
index c37f9df4..e2c5e2a1 100644
--- a/pcsd/rserver.rb
+++ b/pcsd/rserver.rb
@@ -26,7 +26,6 @@ class TornadoCommunicationMiddleware
           session = JSON.parse(Base64.strict_decode64(env["HTTP_X_PCSD_PAYLOAD"]))
           Thread.current[:tornado_username] = session["username"]
           Thread.current[:tornado_groups] = session["groups"]
-          Thread.current[:tornado_is_authenticated] = session["is_authenticated"]
         end
 
         status, headers, body = @app.call(env)
diff --git a/pcsd/test/test_resource.rb b/pcsd/test/test_resource.rb
index 1eb0d3aa..97679eca 100644
--- a/pcsd/test/test_resource.rb
+++ b/pcsd/test/test_resource.rb
@@ -8,7 +8,6 @@ class GetResourceAgentNameStructure < Test::Unit::TestCase
       get_resource_agent_name_structure('standard:provider:type'),
       {
         :full_name => 'standard:provider:type',
-        :class_provider => 'standard:provider',
         :class => 'standard',
         :provider => 'provider',
         :type => 'type',
@@ -21,7 +20,6 @@ class GetResourceAgentNameStructure < Test::Unit::TestCase
       get_resource_agent_name_structure('standard:type'),
       {
         :full_name => 'standard:type',
-        :class_provider => 'standard',
         :class => 'standard',
         :provider => nil,
         :type => 'type',
@@ -34,7 +32,6 @@ class GetResourceAgentNameStructure < Test::Unit::TestCase
       get_resource_agent_name_structure('systemd:service@instance:name'),
       {
         :full_name => 'systemd:service@instance:name',
-        :class_provider => 'systemd',
         :class => 'systemd',
         :provider => nil,
         :type => 'service@instance:name',
@@ -47,7 +44,6 @@ class GetResourceAgentNameStructure < Test::Unit::TestCase
       get_resource_agent_name_structure('service:service@instance:name'),
       {
         :full_name => 'service:service@instance:name',
-        :class_provider => 'service',
         :class => 'service',
         :provider => nil,
         :type => 'service@instance:name',
-- 
2.31.1