Skip to content

Commit

Permalink
Configuration of DRclusters to enable fencing (red-hat-storage#7978)
Browse files Browse the repository at this point in the history
* Configure drcluster for fencing

Signed-off-by: Parikshith <[email protected]>
  • Loading branch information
parikshithb authored Jul 25, 2023
1 parent fdc1275 commit 00d24a4
Show file tree
Hide file tree
Showing 3 changed files with 99 additions and 1 deletion.
6 changes: 6 additions & 0 deletions ocs_ci/deployment/deployment.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
from ocs_ci.deployment.helpers.lso_helpers import setup_local_storage
from ocs_ci.deployment.disconnected import prepare_disconnected_ocs_deployment
from ocs_ci.framework import config, merge_dict
from ocs_ci.helpers.dr_helpers import configure_drcluster_for_fencing
from ocs_ci.ocs import constants, ocp, defaults, registry
from ocs_ci.ocs.cluster import (
validate_cluster_on_pvc,
Expand Down Expand Up @@ -91,6 +92,7 @@
enable_console_plugin,
get_all_acm_indexes,
get_active_acm_index,
enable_mco_console_plugin,
)
from ocs_ci.utility.deployment import create_external_secret
from ocs_ci.utility.flexy import load_cluster_info
Expand Down Expand Up @@ -2655,10 +2657,14 @@ def deploy(self):
for i in acm_indexes:
config.switch_ctx(i)
self.deploy_dr_multicluster_orchestrator()
# Enable MCO console plugin
enable_mco_console_plugin()
# Configure mirror peer
self.configure_mirror_peer()
# Deploy dr policy
self.deploy_dr_policy()
# Configure DRClusters for fencing automation
configure_drcluster_for_fencing()

# Enable cluster backup on both ACMs
for i in acm_indexes:
Expand Down
72 changes: 71 additions & 1 deletion ocs_ci/helpers/dr_helpers.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""
Helper functions specific for DR
"""
import json
import logging
import tempfile

Expand All @@ -12,7 +13,11 @@
from ocs_ci.ocs.resources.pv import get_all_pvs
from ocs_ci.ocs.resources.pvc import get_all_pvc_objs
from ocs_ci.ocs.node import gracefully_reboot_nodes
from ocs_ci.ocs.utils import get_non_acm_cluster_config, get_active_acm_index
from ocs_ci.ocs.utils import (
get_non_acm_cluster_config,
get_active_acm_index,
get_primary_cluster_config,
)
from ocs_ci.utility import version, templating
from ocs_ci.utility.utils import TimeoutSampler, CommandFailed, run_cmd

Expand Down Expand Up @@ -662,6 +667,41 @@ def get_all_drpolicy():
return drpolicy_list


def get_managed_cluster_node_ips():
"""
Gets node ips of individual managed clusters for enabling fencing on MDR DRCluster configuration
Returns:
cluster (list): Returns list of managed cluster, indexes and their node IPs
"""
primary_index = get_primary_cluster_config().MULTICLUSTER["multicluster_index"]
secondary_index = [
s.MULTICLUSTER["multicluster_index"]
for s in get_non_acm_cluster_config()
if s.MULTICLUSTER["multicluster_index"] != primary_index
][0]
cluster_name_primary = config.clusters[primary_index].ENV_DATA["cluster_name"]
cluster_name_secondary = config.clusters[secondary_index].ENV_DATA["cluster_name"]
cluster_data = [
[cluster_name_primary, primary_index],
[cluster_name_secondary, secondary_index],
]
for cluster in cluster_data:
config.switch_ctx(cluster[1])
logger.info(f"Getting node IPs on managed cluster: {cluster[0]}")
node_obj = ocp.OCP(kind=constants.NODE).get()
external_ips = []
for node in node_obj.get("items"):
addresses = node.get("status").get("addresses")
for address in addresses:
if address.get("type") == "ExternalIP":
external_ips.append(address.get("address"))
external_ips_with_cidr = [f"{ip}/32" for ip in external_ips]
cluster.append(external_ips_with_cidr)
return cluster_data


def enable_fence(drcluster_name):
"""
Once the managed cluster is fenced, all communication
Expand All @@ -685,6 +725,36 @@ def enable_fence(drcluster_name):
config.switch_ctx(restore_index)


def configure_drcluster_for_fencing():
"""
Configures DRClusters for enabling fencing
"""
old_ctx = config.cur_index
cluster_ip_list = get_managed_cluster_node_ips()
config.switch_acm_ctx()
for cluster in cluster_ip_list:
fence_ip_data = json.dumps({"spec": {"cidrs": cluster[2]}})
fence_ip_cmd = (
f"oc patch drcluster {cluster[0]} --type merge -p '{fence_ip_data}'"
)
logger.info(f"Patching DRCluster: {cluster[0]} to add node IP addresses")
run_cmd(fence_ip_cmd)

fence_annotation_data = """{"metadata": {"annotations": {
"drcluster.ramendr.openshift.io/storage-clusterid": "openshift-storage",
"drcluster.ramendr.openshift.io/storage-driver": "openshift-storage.rbd.csi.ceph.com",
"drcluster.ramendr.openshift.io/storage-secret-name": "rook-csi-rbd-provisioner",
"drcluster.ramendr.openshift.io/storage-secret-namespace": "openshift-storage" } } }"""
fencing_annotation_cmd = (
f"oc patch drcluster {cluster[0]} --type merge -p '{fence_annotation_data}'"
)
logger.info(f"Patching DRCluster: {cluster[0]} to add fencing annotations")
run_cmd(fencing_annotation_cmd)

config.switch_ctx(old_ctx)


def enable_unfence(drcluster_name):
"""
The OpenShift cluster to be Unfenced is the one where applications
Expand Down
22 changes: 22 additions & 0 deletions ocs_ci/ocs/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -1538,6 +1538,28 @@ def get_all_acm_indexes():
return acm_indexes


def enable_mco_console_plugin():
"""
Enables console plugin for MCO
"""
if (
"odf-multicluster-console"
in OCP(kind="console.operator", resource_name="cluster").get()["spec"][
"plugins"
]
):
log.info("MCO console plugin is enabled")
else:
patch = '\'[{"op": "add", "path": "/spec/plugins/-", "value": "odf-multicluster-console"}]\''
patch_cmd = (
f"patch console.operator cluster -n openshift-console"
f" --type json -p {patch}"
)
log.info("Enabling MCO console plugin")
ocp_obj = OCP()
ocp_obj.exec_oc_cmd(command=patch_cmd)


def get_active_acm_index():
"""
Get index of active acm cluster
Expand Down

0 comments on commit 00d24a4

Please sign in to comment.