- fence_vmware_rest: add token-based authentication
Resolves: RHEL-193739
This commit is contained in:
parent
7dbf04cad2
commit
48e610d7b9
@ -0,0 +1,171 @@
|
||||
From 1a943d5c131ae65b01bdd44a816f3903cb878b87 Mon Sep 17 00:00:00 2001
|
||||
From: Arslan Ahmad <arahmad@redhat.com>
|
||||
Date: Wed, 8 Jul 2026 21:51:53 +0530
|
||||
Subject: [PATCH] fence_vmware_rest: add token-based authentication support
|
||||
|
||||
This introduces `--token` and `--token-script` parameters to allow secure,
|
||||
passwordless authentication with the vCenter REST API. This avoids the
|
||||
need to store static passwords or short-lived session IDs in the cluster
|
||||
configuration.
|
||||
|
||||
- Adds dynamic bypass of core credential validation when a token is used.
|
||||
- Adds a `fail_usage` check if neither authentication method is provided.
|
||||
- Streamlines `connect()` to cleanly handle both token and credential
|
||||
workflows.
|
||||
|
||||
Signed-off-by: Arslan Ahmad <arahmad@redhat.com>
|
||||
---
|
||||
agents/vmware_rest/fence_vmware_rest.py | 49 ++++++++++++++++++-----
|
||||
tests/data/metadata/fence_vmware_rest.xml | 14 ++++++-
|
||||
2 files changed, 51 insertions(+), 12 deletions(-)
|
||||
|
||||
diff --git a/agents/vmware_rest/fence_vmware_rest.py b/agents/vmware_rest/fence_vmware_rest.py
|
||||
index 9dc9a12f4..fb9d42861 100644
|
||||
--- a/agents/vmware_rest/fence_vmware_rest.py
|
||||
+++ b/agents/vmware_rest/fence_vmware_rest.py
|
||||
@@ -6,7 +6,7 @@
|
||||
import atexit
|
||||
sys.path.append("@FENCEAGENTSLIBDIR@")
|
||||
from fencing import *
|
||||
-from fencing import fail, run_delay, EC_LOGIN_DENIED, EC_STATUS
|
||||
+from fencing import fail, fail_usage, run_command, run_delay, EC_LOGIN_DENIED, EC_STATUS
|
||||
|
||||
if sys.version_info[0] > 2: import urllib.parse as urllib
|
||||
else: import urllib
|
||||
@@ -69,6 +69,8 @@ def get_list(conn, options):
|
||||
return outlets
|
||||
|
||||
def connect(opt):
|
||||
+ if "--token" not in opt and ("--username" not in opt or "--password" not in opt):
|
||||
+ fail_usage("Failed: You must provide either a token, a token-script, or a username/password.")
|
||||
conn = pycurl.Curl()
|
||||
|
||||
## setup correct URL
|
||||
@@ -88,9 +90,6 @@ def connect(opt):
|
||||
"Accept: application/json",
|
||||
])
|
||||
|
||||
- conn.setopt(pycurl.HTTPAUTH, pycurl.HTTPAUTH_BASIC)
|
||||
- conn.setopt(pycurl.USERPWD, opt["--username"] + ":" + opt["--password"])
|
||||
-
|
||||
conn.setopt(pycurl.TIMEOUT, int(opt["--shell-timeout"]))
|
||||
|
||||
if "--ssl-secure" in opt:
|
||||
@@ -100,16 +99,22 @@ def connect(opt):
|
||||
conn.setopt(pycurl.SSL_VERIFYPEER, 0)
|
||||
conn.setopt(pycurl.SSL_VERIFYHOST, 0)
|
||||
|
||||
- try:
|
||||
- result = send_command(conn, "com/vmware/cis/session", "POST")
|
||||
- except Exception as e:
|
||||
- logging.debug("Failed: {}".format(e))
|
||||
- fail(EC_LOGIN_DENIED)
|
||||
+ if "--token" not in opt:
|
||||
+ conn.setopt(pycurl.HTTPAUTH, pycurl.HTTPAUTH_BASIC)
|
||||
+ conn.setopt(pycurl.USERPWD, opt["--username"] + ":" + opt["--password"])
|
||||
+
|
||||
+ try:
|
||||
+ result = send_command(conn, "com/vmware/cis/session", "POST")
|
||||
+ except Exception as e:
|
||||
+ logging.debug("Failed: {}".format(e))
|
||||
+ fail(EC_LOGIN_DENIED)
|
||||
+
|
||||
+ conn.setopt(pycurl.HTTPAUTH, pycurl.HTTPAUTH_NONE)
|
||||
|
||||
# set session id for later requests
|
||||
conn.setopt(pycurl.HTTPHEADER, [
|
||||
"Accept: application/json",
|
||||
- "vmware-api-session-id: {}".format(result["value"]),
|
||||
+ "vmware-api-session-id: {}".format(opt["--token"] if "--token" in opt else result["value"]),
|
||||
])
|
||||
|
||||
return conn
|
||||
@@ -182,6 +187,20 @@ def define_new_opts():
|
||||
"shortdesc" : "Filter to only return relevant VMs. It can be used to avoid "
|
||||
"the agent failing when more than 1000 VMs should be returned.",
|
||||
"order" : 2}
|
||||
+ all_opt["token"] = {
|
||||
+ "getopt" : ":",
|
||||
+ "longopt" : "token",
|
||||
+ "help" : "--token=[token] API Token",
|
||||
+ "required" : "0",
|
||||
+ "shortdesc" : "API Token",
|
||||
+ "order" : 2}
|
||||
+ all_opt["token_script"] = {
|
||||
+ "getopt" : ":",
|
||||
+ "longopt" : "token-script",
|
||||
+ "help" : "--token-script=[script] Script to retrieve a token",
|
||||
+ "required" : "0",
|
||||
+ "shortdesc" : "Script to retrieve a token",
|
||||
+ "order" : 2}
|
||||
|
||||
|
||||
def main():
|
||||
@@ -190,11 +209,15 @@ def main():
|
||||
"api_path",
|
||||
"login",
|
||||
"passwd",
|
||||
+ "no_login",
|
||||
+ "no_password",
|
||||
"ssl",
|
||||
"notls",
|
||||
"web",
|
||||
"port",
|
||||
"filter",
|
||||
+ "token",
|
||||
+ "token_script",
|
||||
]
|
||||
|
||||
atexit.register(atexit_handler)
|
||||
@@ -204,6 +227,12 @@ def main():
|
||||
all_opt["power_wait"]["default"] = "1"
|
||||
|
||||
options = check_input(device_opt, process_input(device_opt))
|
||||
+ if "--token-script" in options:
|
||||
+ try:
|
||||
+ options["--token"] = run_command(options, options["--token-script"])[1].strip()
|
||||
+ except Exception as e:
|
||||
+ logging.error("Failed to execute token script: {}".format(e))
|
||||
+ sys.exit(EC_LOGIN_DENIED)
|
||||
|
||||
docs = {}
|
||||
docs["shortdesc"] = "Fence agent for VMware REST API"
|
||||
diff --git a/tests/data/metadata/fence_vmware_rest.xml b/tests/data/metadata/fence_vmware_rest.xml
|
||||
index 672769d99..72fc22533 100644
|
||||
--- a/tests/data/metadata/fence_vmware_rest.xml
|
||||
+++ b/tests/data/metadata/fence_vmware_rest.xml
|
||||
@@ -25,7 +25,7 @@ NOTE: If there's more than 1000 VMs there is a filter parameter to work around t
|
||||
<content type="integer" default="80" />
|
||||
<shortdesc lang="en">TCP/UDP port to use for connection with device</shortdesc>
|
||||
</parameter>
|
||||
- <parameter name="login" unique="0" required="1" deprecated="1">
|
||||
+ <parameter name="login" unique="0" required="0" deprecated="1">
|
||||
<getopt mixed="-l, --username=[name]" />
|
||||
<content type="string" />
|
||||
<shortdesc lang="en">Login name</shortdesc>
|
||||
@@ -80,7 +80,7 @@ NOTE: If there's more than 1000 VMs there is a filter parameter to work around t
|
||||
<content type="boolean" />
|
||||
<shortdesc lang="en">Use SSL connection with verifying certificate</shortdesc>
|
||||
</parameter>
|
||||
- <parameter name="username" unique="0" required="1" obsoletes="login">
|
||||
+ <parameter name="username" unique="0" required="0" obsoletes="login">
|
||||
<getopt mixed="-l, --username=[name]" />
|
||||
<content type="string" />
|
||||
<shortdesc lang="en">Login name</shortdesc>
|
||||
@@ -94,6 +94,16 @@ NOTE: If there's more than 1000 VMs there is a filter parameter to work around t
|
||||
<content type="string" />
|
||||
<shortdesc lang="en">Filter to only return relevant VMs. It can be used to avoid the agent failing when more than 1000 VMs should be returned.</shortdesc>
|
||||
</parameter>
|
||||
+ <parameter name="token" unique="0" required="0">
|
||||
+ <getopt mixed="--token=[token]" />
|
||||
+ <content type="string" />
|
||||
+ <shortdesc lang="en">API Token</shortdesc>
|
||||
+ </parameter>
|
||||
+ <parameter name="token_script" unique="0" required="0">
|
||||
+ <getopt mixed="--token-script=[script]" />
|
||||
+ <content type="string" />
|
||||
+ <shortdesc lang="en">Script to retrieve a token</shortdesc>
|
||||
+ </parameter>
|
||||
<parameter name="quiet" unique="0" required="0">
|
||||
<getopt mixed="-q, --quiet" />
|
||||
<content type="boolean" />
|
||||
@ -47,7 +47,7 @@
|
||||
Name: fence-agents
|
||||
Summary: Set of unified programs capable of host isolation ("fencing")
|
||||
Version: 4.10.0
|
||||
Release: 116%{?alphatag:.%{alphatag}}%{?dist}
|
||||
Release: 117%{?alphatag:.%{alphatag}}%{?dist}
|
||||
License: GPLv2+ and LGPLv2+
|
||||
URL: https://github.com/ClusterLabs/fence-agents
|
||||
Source0: https://fedorahosted.org/releases/f/e/fence-agents/%{name}-%{version}.tar.gz
|
||||
@ -221,6 +221,7 @@ Patch76: RHEL-145088-fence_ibm_vpc-fix-missing-statuses.patch
|
||||
Patch77: RHEL-146216-fence_kubevirt-report-Succeeded-and-Failed-as-OFF.patch
|
||||
Patch78: RHEL-183892-fence_ibm_vpc-set-proxy-when-token-is-expired-as-well.patch
|
||||
Patch79: RHEL-154985-fence_openstack-fix-list-action-to-avoid-timeout-with-large-number-of-VMs.patch
|
||||
Patch80: RHEL-193739-fence_vmware_rest-add-token-based-authentication.patch
|
||||
|
||||
### HA support libs/utils ###
|
||||
# all archs
|
||||
@ -424,6 +425,7 @@ BuildRequires: %{systemd_units}
|
||||
%patch -p1 -P 77
|
||||
%patch -p1 -P 78
|
||||
%patch -p1 -P 79
|
||||
%patch -p1 -P 80
|
||||
|
||||
# prevent compilation of something that won't get used anyway
|
||||
sed -i.orig 's|FENCE_ZVM=1|FENCE_ZVM=0|' configure.ac
|
||||
@ -1522,6 +1524,10 @@ are located on corosync cluster nodes.
|
||||
%endif
|
||||
|
||||
%changelog
|
||||
* Thu Jul 09 2026 Arslan Ahmad <arahmad@redhat.com> - 4.10.0-117
|
||||
- fence_vmware_rest: add token-based authentication
|
||||
Resolves: RHEL-193739
|
||||
|
||||
* Wed Jun 17 2026 Arslan Ahmad <arahmad@redhat.com> - 4.10.0-116
|
||||
- fence_openstack: fix list-action to avoid timeout when
|
||||
there are 100+ VMs on the hypervisor
|
||||
|
||||
Loading…
Reference in New Issue
Block a user