diff --git a/RHEL-65025-fence_ibm_powervs-add-private-endpoint-and-token-file-support.patch b/RHEL-65025-fence_ibm_powervs-add-private-endpoint-and-token-file-support.patch new file mode 100644 index 0000000..af3ea5f --- /dev/null +++ b/RHEL-65025-fence_ibm_powervs-add-private-endpoint-and-token-file-support.patch @@ -0,0 +1,120 @@ +--- a/agents/ibm_powervs/fence_ibm_powervs.py 2024-10-18 10:30:40.651200620 +0200 ++++ b/agents/ibm_powervs/fence_ibm_powervs.py 2024-10-18 10:30:35.157070713 +0200 +@@ -1,13 +1,14 @@ + #!@PYTHON@ -tt + + import sys +-import pycurl, io, json ++import pycurl ++import io ++import json + import logging + import atexit +-import time ++ + sys.path.append("@FENCEAGENTSLIBDIR@") +-from fencing import * +-from fencing import fail, run_delay, EC_LOGIN_DENIED, EC_STATUS ++from fencing import all_opt, atexit_handler, check_input, process_input, show_docs, fence_action, fail, run_delay, EC_STATUS + + state = { + "ACTIVE": "on", +@@ -18,15 +19,35 @@ + } + + def get_token(conn, options): +- try: +- command = "identity/token" +- action = "grant_type=urn%3Aibm%3Aparams%3Aoauth%3Agrant-type%3Aapikey&apikey={}".format(options["--token"]) +- res = send_command(conn, command, "POST", action, printResult=False) +- except Exception as e: +- logging.debug("Failed: {}".format(e)) +- return "TOKEN_IS_MISSING_OR_WRONG" +- +- return res["access_token"] ++ try: ++ if options["--token"][0] == '@': ++ key_file = options["--token"][1:] ++ try: ++ # read the API key from a file ++ with open(key_file, "r") as f: ++ try: ++ keys = json.loads(f.read()) ++ # data seems to be in json format ++ # return the value of the item with the key 'Apikey' ++ api_key = keys.get("Apikey", "") ++ if not api_key: ++ # backward compatibility: former key name was 'apikey' ++ api_key = keys.get("apikey", "") ++ # data is text, return as is ++ except ValueError: ++ api_key = f.read().strip() ++ except FileNotFoundError: ++ logging.debug("Failed: Cannot open file {}".format(key_file)) ++ return "TOKEN_IS_MISSING_OR_WRONG" ++ else: ++ api_key = options["--token"] ++ command = "identity/token" ++ action = "grant_type=urn%3Aibm%3Aparams%3Aoauth%3Agrant-type%3Aapikey&apikey={}".format(api_key) ++ res = send_command(conn, command, "POST", action, printResult=False) ++ except Exception as e: ++ logging.debug("Failed: {}".format(e)) ++ return "TOKEN_IS_MISSING_OR_WRONG" ++ return res["access_token"] + + def get_list(conn, options): + outlets = {} +@@ -41,7 +62,7 @@ + for r in res["pvmInstances"]: + if options["--verbose-level"] > 1: + logging.debug(json.dumps(r, indent=2)) +- outlets[r["pvmInstanceID"]] = (r["serverName"], state[r["status"]]) ++ outlets[r["pvmInstanceID"]] = (r["serverName"], state.get(r["status"], "unknown")) + + return outlets + +@@ -97,7 +118,7 @@ + else: + logging.debug("Failed: Unable to cycle with {} for {}".format(options["--action"], e)) + fail(EC_STATUS) +- return True ++ return True + + def connect(opt, token): + conn = pycurl.Curl() +@@ -130,7 +151,10 @@ + conn = pycurl.Curl() + + # setup correct URL +- conn.base_url = "https://iam.cloud.ibm.com/" ++ if opt["--api-type"] == "private": ++ conn.base_url = "https://private.iam.cloud.ibm.com/" ++ else: ++ conn.base_url = "https://iam.cloud.ibm.com/" + + if opt["--verbose-level"] > 1: + conn.setopt(pycurl.VERBOSE, 1) +@@ -265,9 +289,9 @@ + define_new_opts() + + all_opt["shell_timeout"]["default"] = "500" +- all_opt["power_timeout"]["default"] = "30" +- all_opt["power_wait"]["default"] = "1" +- all_opt["stonith_status_sleep"]["default"] = "2" ++ all_opt["power_timeout"]["default"] = "120" ++ all_opt["power_wait"]["default"] = "15" ++ all_opt["stonith_status_sleep"]["default"] = "10" + all_opt["api-type"]["default"] = "private" + all_opt["proxy"]["default"] = "" + +@@ -275,8 +299,8 @@ + + docs = {} + docs["shortdesc"] = "Fence agent for IBM PowerVS" +- docs["longdesc"] = """fence_ibm_powervs is a Power Fencing agent which can be \ +-used with IBM PowerVS to fence virtual machines.""" ++ docs["longdesc"] = """fence_ibm_powervs is a power fencing agent for \ ++IBM Power Virtual Server (IBM PowerVS) to fence virtual server instances.""" + docs["vendorurl"] = "https://www.ibm.com" + show_docs(options, docs) + diff --git a/fence-agents.spec b/fence-agents.spec index 23a611b..b3cfea2 100644 --- a/fence-agents.spec +++ b/fence-agents.spec @@ -87,7 +87,7 @@ Name: fence-agents Summary: Set of unified programs capable of host isolation ("fencing") Version: 4.2.1 -Release: 129%{?alphatag:.%{alphatag}}%{?dist}.7 +Release: 129%{?alphatag:.%{alphatag}}%{?dist}.8 License: GPLv2+ and LGPLv2+ Group: System Environment/Base URL: https://github.com/ClusterLabs/fence-agents @@ -315,6 +315,7 @@ Patch142: RHEL-14343-fence_zvmip-2-fix-manpage-formatting.patch Patch143: RHEL-7734-fence_eps-add-fence_epsr2-for-ePowerSwitch-R2-and-newer.patch Patch144: RHEL-56840-fence_scsi-only-preempt-once-for-mpath-devices.patch Patch145: RHEL-76492-fence_azure_arm-use-azure-identity.patch +Patch146: RHEL-65025-fence_ibm_powervs-add-private-endpoint-and-token-file-support.patch ### HA support libs/utils ### # all archs @@ -549,6 +550,7 @@ BuildRequires: python3-google-api-client python3-pip python3-wheel python3-jinja %patch -p1 -P 143 -F1 %patch -p1 -P 144 %patch -p1 -P 145 +%patch -p1 -P 146 # prevent compilation of something that won't get used anyway sed -i.orig 's|FENCE_ZVM=1|FENCE_ZVM=0|' configure.ac @@ -1595,6 +1597,10 @@ Fence agent for IBM z/VM over IP. %endif %changelog +* Fri Apr 25 2025 Oyvind Albrigtsen - 4.2.1-129.8 +- fence_ibm_powervs: add private endpoint and token file support + Resolves: RHEL-65025 + * Thu Jan 30 2025 Oyvind Albrigtsen - 4.2.1-129.7 - fence_azure_arm: use azure-identity instead of msrestazure, which has been deprecated