|
|
21d5fd |
From a4e8b77ac51a0e4a6de489823ee1be47cbc7eb18 Mon Sep 17 00:00:00 2001
|
|
|
21d5fd |
From: Oyvind Albrigtsen <oalbrigt@redhat.com>
|
|
|
21d5fd |
Date: Thu, 9 May 2019 12:09:48 +0200
|
|
|
21d5fd |
Subject: [PATCH] fence_rhevm: add RHEV v4 API support and auto-detection
|
|
|
21d5fd |
|
|
|
21d5fd |
---
|
|
|
21d5fd |
agents/rhevm/fence_rhevm.py | 44 +++++++++++++++++++++++------
|
|
|
21d5fd |
tests/data/metadata/fence_rhevm.xml | 7 ++++-
|
|
|
21d5fd |
2 files changed, 41 insertions(+), 10 deletions(-)
|
|
|
21d5fd |
|
|
|
21d5fd |
diff --git a/agents/rhevm/fence_rhevm.py b/agents/rhevm/fence_rhevm.py
|
|
|
21d5fd |
index a1cdaf605..6012c4239 100644
|
|
|
21d5fd |
--- a/agents/rhevm/fence_rhevm.py
|
|
|
21d5fd |
+++ b/agents/rhevm/fence_rhevm.py
|
|
|
21d5fd |
@@ -9,7 +9,8 @@
|
|
|
21d5fd |
from fencing import fail, EC_FETCH_VM_UUID, run_delay
|
|
|
21d5fd |
|
|
|
21d5fd |
RE_GET_ID = re.compile("
|
|
|
21d5fd |
-RE_STATUS = re.compile("<state>(.*?)</state>", re.IGNORECASE)
|
|
|
21d5fd |
+RE_STATUS = re.compile("<status>(.*?)</status>", re.IGNORECASE)
|
|
|
21d5fd |
+RE_STATE = re.compile("<state>(.*?)</state>", re.IGNORECASE)
|
|
|
21d5fd |
RE_GET_NAME = re.compile("<name>(.*?)</name>", re.IGNORECASE)
|
|
|
21d5fd |
|
|
|
21d5fd |
def get_power_status(conn, options):
|
|
|
21d5fd |
@@ -25,7 +26,10 @@ def get_power_status(conn, options):
|
|
|
21d5fd |
|
|
|
21d5fd |
options["id"] = result.group(2)
|
|
|
21d5fd |
|
|
|
21d5fd |
- result = RE_STATUS.search(res)
|
|
|
21d5fd |
+ if tuple(map(int, options["--api-version"].split(".")))[0] > 3:
|
|
|
21d5fd |
+ result = RE_STATUS.search(res)
|
|
|
21d5fd |
+ else:
|
|
|
21d5fd |
+ result = RE_STATE.search(res)
|
|
|
21d5fd |
if result == None:
|
|
|
21d5fd |
# We were able to parse ID so output is correct
|
|
|
21d5fd |
# in some cases it is possible that RHEV-M output does not
|
|
|
21d5fd |
@@ -59,7 +63,10 @@ def get_list(conn, options):
|
|
|
21d5fd |
lines = res.split("
|
|
|
21d5fd |
for i in range(1, len(lines)):
|
|
|
21d5fd |
name = RE_GET_NAME.search(lines[i]).group(1)
|
|
|
21d5fd |
- status = RE_STATUS.search(lines[i]).group(1)
|
|
|
21d5fd |
+ if tuple(map(int, options["--api-version"].split(".")))[0] > 3:
|
|
|
21d5fd |
+ status = RE_STATUS.search(lines[i]).group(1)
|
|
|
21d5fd |
+ else:
|
|
|
21d5fd |
+ status = RE_STATE.search(lines[i]).group(1)
|
|
|
21d5fd |
outlets[name] = ("", status)
|
|
|
21d5fd |
except AttributeError:
|
|
|
21d5fd |
return {}
|
|
|
21d5fd |
@@ -69,6 +76,13 @@ def get_list(conn, options):
|
|
|
21d5fd |
return outlets
|
|
|
21d5fd |
|
|
|
21d5fd |
def send_command(opt, command, method="GET"):
|
|
|
21d5fd |
+ if opt["--api-version"] == "auto":
|
|
|
21d5fd |
+ opt["--api-version"] = "4"
|
|
|
21d5fd |
+ res = send_command(opt, "")
|
|
|
21d5fd |
+ if re.search("<title>Error</title>", res):
|
|
|
21d5fd |
+ opt["--api-version"] = "3"
|
|
|
21d5fd |
+ logging.debug("auto-detected API version: " + opt["--api-version"])
|
|
|
21d5fd |
+
|
|
|
21d5fd |
## setup correct URL
|
|
|
21d5fd |
if "--ssl" in opt or "--ssl-secure" in opt or "--ssl-insecure" in opt:
|
|
|
21d5fd |
url = "https:"
|
|
|
21d5fd |
@@ -90,7 +104,7 @@ def send_command(opt, command, method="GET"):
|
|
|
21d5fd |
web_buffer = io.BytesIO()
|
|
|
21d5fd |
conn.setopt(pycurl.URL, url.encode("UTF-8"))
|
|
|
21d5fd |
conn.setopt(pycurl.HTTPHEADER, [
|
|
|
21d5fd |
- "Version: 3",
|
|
|
21d5fd |
+ "Version: {}".format(opt["--api-version"]),
|
|
|
21d5fd |
"Content-type: application/xml",
|
|
|
21d5fd |
"Accept: application/xml",
|
|
|
21d5fd |
"Prefer: persistent-auth",
|
|
|
21d5fd |
@@ -130,8 +144,9 @@ def send_command(opt, command, method="GET"):
|
|
|
21d5fd |
|
|
|
21d5fd |
result = web_buffer.getvalue().decode("UTF-8")
|
|
|
21d5fd |
|
|
|
21d5fd |
- logging.debug("%s\n", command)
|
|
|
21d5fd |
- logging.debug("%s\n", result)
|
|
|
21d5fd |
+ logging.debug("url: %s\n", url)
|
|
|
21d5fd |
+ logging.debug("command: %s\n", command)
|
|
|
21d5fd |
+ logging.debug("result: %s\n", result)
|
|
|
21d5fd |
|
|
|
21d5fd |
return result
|
|
|
21d5fd |
|
|
|
21d5fd |
@@ -151,6 +166,15 @@ def define_new_opts():
|
|
|
21d5fd |
"required" : "0",
|
|
|
21d5fd |
"shortdesc" : "Reuse cookies for authentication",
|
|
|
21d5fd |
"order" : 1}
|
|
|
21d5fd |
+ all_opt["api_version"] = {
|
|
|
21d5fd |
+ "getopt" : ":",
|
|
|
21d5fd |
+ "longopt" : "api-version",
|
|
|
21d5fd |
+ "help" : "--api-version "
|
|
|
21d5fd |
+ "Version of RHEV API (default: auto)",
|
|
|
21d5fd |
+ "required" : "0",
|
|
|
21d5fd |
+ "order" : 2,
|
|
|
21d5fd |
+ "default" : "auto",
|
|
|
21d5fd |
+ }
|
|
|
21d5fd |
all_opt["api_path"] = {
|
|
|
21d5fd |
"getopt" : ":",
|
|
|
21d5fd |
"longopt" : "api-path",
|
|
|
21d5fd |
@@ -158,20 +182,19 @@ def define_new_opts():
|
|
|
21d5fd |
"default" : "/ovirt-engine/api",
|
|
|
21d5fd |
"required" : "0",
|
|
|
21d5fd |
"shortdesc" : "The path part of the API URL",
|
|
|
21d5fd |
- "order" : 2}
|
|
|
21d5fd |
+ "order" : 3}
|
|
|
21d5fd |
all_opt["disable_http_filter"] = {
|
|
|
21d5fd |
"getopt" : "",
|
|
|
21d5fd |
"longopt" : "disable-http-filter",
|
|
|
21d5fd |
"help" : "--disable-http-filter Set HTTP Filter header to false",
|
|
|
21d5fd |
"required" : "0",
|
|
|
21d5fd |
"shortdesc" : "Set HTTP Filter header to false",
|
|
|
21d5fd |
- "order" : 3}
|
|
|
21d5fd |
+ "order" : 4}
|
|
|
21d5fd |
|
|
|
21d5fd |
|
|
|
21d5fd |
def main():
|
|
|
21d5fd |
device_opt = [
|
|
|
21d5fd |
"ipaddr",
|
|
|
21d5fd |
- "api_path",
|
|
|
21d5fd |
"login",
|
|
|
21d5fd |
"passwd",
|
|
|
21d5fd |
"ssl",
|
|
|
21d5fd |
@@ -179,6 +202,8 @@ def main():
|
|
|
21d5fd |
"web",
|
|
|
21d5fd |
"port",
|
|
|
21d5fd |
"use_cookies",
|
|
|
21d5fd |
+ "api_version",
|
|
|
21d5fd |
+ "api_path",
|
|
|
21d5fd |
"disable_http_filter",
|
|
|
21d5fd |
]
|
|
|
21d5fd |
|
|
|
21d5fd |
@@ -186,6 +211,7 @@ def main():
|
|
|
21d5fd |
define_new_opts()
|
|
|
21d5fd |
|
|
|
21d5fd |
all_opt["power_wait"]["default"] = "1"
|
|
|
21d5fd |
+ all_opt["shell_timeout"]["default"] = "5"
|
|
|
21d5fd |
|
|
|
21d5fd |
options = check_input(device_opt, process_input(device_opt))
|
|
|
21d5fd |
|
|
|
21d5fd |
diff --git a/tests/data/metadata/fence_rhevm.xml b/tests/data/metadata/fence_rhevm.xml
|
|
|
21d5fd |
index 6344db79f..c56cf64b6 100644
|
|
|
21d5fd |
--- a/tests/data/metadata/fence_rhevm.xml
|
|
|
21d5fd |
+++ b/tests/data/metadata/fence_rhevm.xml
|
|
|
21d5fd |
@@ -98,6 +98,11 @@
|
|
|
21d5fd |
<content type="string" />
|
|
|
21d5fd |
<shortdesc lang="en">Login name</shortdesc>
|
|
|
21d5fd |
</parameter>
|
|
|
21d5fd |
+ <parameter name="api_version" unique="0" required="0">
|
|
|
21d5fd |
+ <getopt mixed="--api-version" />
|
|
|
21d5fd |
+ <content type="string" default="auto" />
|
|
|
21d5fd |
+ <shortdesc lang="en">Version of RHEV API (default: auto)</shortdesc>
|
|
|
21d5fd |
+ </parameter>
|
|
|
21d5fd |
<parameter name="api_path" unique="0" required="0">
|
|
|
21d5fd |
<getopt mixed="--api-path=[path]" />
|
|
|
21d5fd |
<shortdesc lang="en">The path part of the API URL</shortdesc>
|
|
|
21d5fd |
@@ -164,7 +169,7 @@
|
|
|
21d5fd |
</parameter>
|
|
|
21d5fd |
<parameter name="shell_timeout" unique="0" required="0">
|
|
|
21d5fd |
<getopt mixed="--shell-timeout=[seconds]" />
|
|
|
21d5fd |
- <content type="second" default="3" />
|
|
|
21d5fd |
+ <content type="second" default="5" />
|
|
|
21d5fd |
<shortdesc lang="en">Wait X seconds for cmd prompt after issuing command</shortdesc>
|
|
|
21d5fd |
</parameter>
|
|
|
21d5fd |
<parameter name="retry_on" unique="0" required="0">
|