import fence-agents-4.2.1-50.el8

This commit is contained in:
CentOS Sources 2020-07-28 06:37:25 -04:00 committed by Stepan Oksanichenko
parent bd862936eb
commit 46220d305b
17 changed files with 1587 additions and 5 deletions

View File

@ -0,0 +1,79 @@
From f1f8fe7791d0bf439f7caf1365c371153f9819ff Mon Sep 17 00:00:00 2001
From: Oyvind Albrigtsen <oalbrigt@redhat.com>
Date: Thu, 14 May 2020 15:41:52 +0200
Subject: [PATCH] fence_scsi: add readonly parameter
---
agents/scsi/fence_scsi.py | 21 ++++++++++++++++++---
tests/data/metadata/fence_scsi.xml | 5 +++++
2 files changed, 23 insertions(+), 3 deletions(-)
diff --git a/agents/scsi/fence_scsi.py b/agents/scsi/fence_scsi.py
index 9b6af556..77817f35 100644
--- a/agents/scsi/fence_scsi.py
+++ b/agents/scsi/fence_scsi.py
@@ -150,7 +150,10 @@ def reserve_dev(options, dev):
def get_reservation_key(options, dev):
reset_dev(options,dev)
- cmd = options["--sg_persist-path"] + " -n -i -r -d " + dev
+ opts = ""
+ if "--readonly" in options:
+ opts = "-y "
+ cmd = options["--sg_persist-path"] + " -n -i " + opts + "-r -d " + dev
out = run_cmd(options, cmd)
if out["err"]:
fail_usage("Cannot get reservation key")
@@ -161,7 +164,10 @@ def get_reservation_key(options, dev):
def get_registration_keys(options, dev, fail=True):
reset_dev(options,dev)
keys = []
- cmd = options["--sg_persist-path"] + " -n -i -k -d " + dev
+ opts = ""
+ if "--readonly" in options:
+ opts = "-y "
+ cmd = options["--sg_persist-path"] + " -n -i " + opts + "-k -d " + dev
out = run_cmd(options, cmd)
if out["err"]:
fail_usage("Cannot get registration keys", fail)
@@ -342,6 +348,14 @@ def define_new_opts():
"shortdesc" : "Use the APTPL flag for registrations. This option is only used for the 'on' action.",
"order": 1
}
+ all_opt["readonly"] = {
+ "getopt" : "",
+ "longopt" : "readonly",
+ "help" : "--readonly Open DEVICE read-only. May be useful with PRIN commands if there are unwanted side effects with the default read-write open.",
+ "required" : "0",
+ "shortdesc" : "Open DEVICE read-only.",
+ "order": 4
+ }
all_opt["logfile"] = {
"getopt" : ":",
"longopt" : "logfile",
@@ -464,7 +478,8 @@ def main():
device_opt = ["no_login", "no_password", "devices", "nodename", "port",\
"no_port", "key", "aptpl", "fabric_fencing", "on_target", "corosync_cmap_path",\
- "sg_persist_path", "sg_turs_path", "logfile", "vgs_path", "force_on", "key_value"]
+ "sg_persist_path", "sg_turs_path", "readonly", "logfile", "vgs_path",\
+ "force_on", "key_value"]
define_new_opts()
diff --git a/tests/data/metadata/fence_scsi.xml b/tests/data/metadata/fence_scsi.xml
index b840f3cf..d0818b0d 100644
--- a/tests/data/metadata/fence_scsi.xml
+++ b/tests/data/metadata/fence_scsi.xml
@@ -36,6 +36,11 @@ When used as a watchdog device you can define e.g. retry=1, retry-sleep=2 and ve
<content type="string" />
<shortdesc lang="en">Name of the node to be fenced. The node name is used to generate the key value used for the current operation. This option will be ignored when used with the -k option.</shortdesc>
</parameter>
+ <parameter name="readonly" unique="0" required="0">
+ <getopt mixed="--readonly" />
+ <content type="boolean" />
+ <shortdesc lang="en">Open DEVICE read-only.</shortdesc>
+ </parameter>
<parameter name="logfile" unique="0" required="0">
<getopt mixed="-f, --logfile" />
<content type="string" />

View File

@ -0,0 +1,197 @@
From d866e11213ebeab8da280b41371a968ae12410bd Mon Sep 17 00:00:00 2001
From: Oyvind Albrigtsen <oalbrigt@redhat.com>
Date: Fri, 13 Sep 2019 12:48:46 +0200
Subject: [PATCH] fence_mpath: use -n/--plug/port parameter to be able to use
pcmk_host_map
---
agents/mpath/fence_mpath.py | 63 +++++++++++++++++------------
tests/data/metadata/fence_mpath.xml | 12 +++++-
2 files changed, 49 insertions(+), 26 deletions(-)
diff --git a/agents/mpath/fence_mpath.py b/agents/mpath/fence_mpath.py
index e4f59836..dfc5657b 100644
--- a/agents/mpath/fence_mpath.py
+++ b/agents/mpath/fence_mpath.py
@@ -16,11 +16,11 @@ def get_status(conn, options):
status = "off"
for dev in options["devices"]:
is_block_device(dev)
- if options["--key"] in get_registration_keys(options, dev):
+ if options["--plug"] in get_registration_keys(options, dev):
status = "on"
else:
logging.debug("No registration for key "\
- + options["--key"] + " on device " + dev + "\n")
+ + options["--plug"] + " on device " + dev + "\n")
if options["--action"] == "monitor":
dev_read(options)
@@ -36,10 +36,10 @@ def set_status(conn, options):
is_block_device(dev)
register_dev(options, dev)
- if options["--key"] not in get_registration_keys(options, dev):
+ if options["--plug"] not in get_registration_keys(options, dev):
count += 1
logging.debug("Failed to register key "\
- + options["--key"] + "on device " + dev + "\n")
+ + options["--plug"] + "on device " + dev + "\n")
continue
dev_write(options, dev)
@@ -48,7 +48,7 @@ def set_status(conn, options):
and get_reservation_key(options, dev) is None:
count += 1
logging.debug("Failed to create reservation (key="\
- + options["--key"] + ", device=" + dev + ")\n")
+ + options["--plug"] + ", device=" + dev + ")\n")
else:
dev_keys = dev_read(options)
@@ -56,14 +56,14 @@ def set_status(conn, options):
for dev in options["devices"]:
is_block_device(dev)
- if options["--key"] in get_registration_keys(options, dev):
+ if options["--plug"] in get_registration_keys(options, dev):
preempt_abort(options, dev_keys[dev], dev)
for dev in options["devices"]:
- if options["--key"] in get_registration_keys(options, dev):
+ if options["--plug"] in get_registration_keys(options, dev):
count += 1
logging.debug("Failed to remove key "\
- + options["--key"] + " on device " + dev + "\n")
+ + options["--plug"] + " on device " + dev + "\n")
continue
if not get_reservation_key(options, dev):
@@ -97,16 +97,16 @@ def is_block_device(dev):
# cancel registration
def preempt_abort(options, host, dev):
- cmd = options["--mpathpersist-path"] + " -o --preempt-abort --prout-type=5 --param-rk=" + host +" --param-sark=" + options["--key"] +" -d " + dev
+ cmd = options["--mpathpersist-path"] + " -o --preempt-abort --prout-type=5 --param-rk=" + host +" --param-sark=" + options["--plug"] +" -d " + dev
return not bool(run_cmd(options, cmd)["err"])
def register_dev(options, dev):
- cmd = options["--mpathpersist-path"] + " -o --register --param-sark=" + options["--key"] + " -d " + dev
+ cmd = options["--mpathpersist-path"] + " -o --register --param-sark=" + options["--plug"] + " -d " + dev
#cmd return code != 0 but registration can be successful
return not bool(run_cmd(options, cmd)["err"])
def reserve_dev(options, dev):
- cmd = options["--mpathpersist-path"] + " -o --reserv --prout-type=5 --param-rk=" + options["--key"] + " -d " + dev
+ cmd = options["--mpathpersist-path"] + " -o --reserv --prout-type=5 --param-rk=" + options["--plug"] + " -d " + dev
return not bool(run_cmd(options, cmd)["err"])
def get_reservation_key(options, dev):
@@ -141,7 +141,7 @@ def dev_write(options, dev):
fail_usage("Failed: Cannot open file \""+ file_path + "\"")
out = store_fh.read()
if not re.search(r"^" + dev + r"\s+", out):
- store_fh.write(dev + "\t" + options["--key"] + "\n")
+ store_fh.write(dev + "\t" + options["--plug"] + "\n")
store_fh.close()
def dev_read(options, fail=True):
@@ -209,12 +209,9 @@ def define_new_opts():
all_opt["key"] = {
"getopt" : "k:",
"longopt" : "key",
- "help" : "-k, --key=[key] Key to use for the current operation",
- "required" : "1",
- "shortdesc" : "Key to use for the current operation. This key should be \
-unique to a node and have to be written in /etc/multipath.conf. For the \"on\" action, the key specifies the key use to \
-register the local node. For the \"off\" action, this key specifies the key to \
-be removed from the device(s).",
+ "help" : "-k, --key=[key] Replaced by -n, --plug",
+ "required" : "0",
+ "shortdesc" : "Replaced by -n, --plug",
"order": 1
}
all_opt["mpathpersist_path"] = {
@@ -240,10 +237,18 @@ def main():
atexit.register(atexit_handler)
device_opt = ["no_login", "no_password", "devices", "key", "sudo", \
- "fabric_fencing", "on_target", "store_path", "mpathpersist_path", "force_on"]
+ "fabric_fencing", "on_target", "store_path", \
+ "mpathpersist_path", "force_on", "port", "no_port"]
define_new_opts()
+ all_opt["port"]["help"] = "Key to use for the current operation"
+ all_opt["port"]["shortdesc"] = "Key to use for the current operation. \
+This key should be unique to a node and have to be written in \
+/etc/multipath.conf. For the \"on\" action, the key specifies the key use to \
+register the local node. For the \"off\" action, this key specifies the key to \
+be removed from the device(s)."
+
# fence_mpath_check
if os.path.basename(sys.argv[0]) == "fence_mpath_check":
sys.exit(mpath_check())
@@ -252,6 +257,17 @@ def main():
options = check_input(device_opt, process_input(device_opt), other_conditions=True)
+ # hack to remove list/list-status actions which are not supported
+ options["device_opt"] = [ o for o in options["device_opt"] if o != "separator" ]
+
+ # workaround to avoid regressions
+ if "--key" in options:
+ options["--plug"] = options["--key"]
+ del options["--key"]
+ elif options["--action"] in ["off", "on", "reboot", "status"] \
+ and "--plug" not in options:
+ fail_usage("Failed: You have to enter plug number or machine identification", stop)
+
docs = {}
docs["shortdesc"] = "Fence agent for multipath persistent reservation"
docs["longdesc"] = "fence_mpath is an I/O fencing agent that uses SCSI-3 \
@@ -271,16 +287,13 @@ def main():
run_delay(options)
# Input control BEGIN
- if not "--key" in options:
- fail_usage("Failed: key is required")
-
if options["--action"] == "validate-all":
sys.exit(0)
- options["devices"] = options["--devices"].split(",")
-
- if not options["devices"]:
+ if not ("--devices" in options and options["--devices"]):
fail_usage("Failed: No devices found")
+
+ options["devices"] = options["--devices"].split(",")
# Input control END
result = fence_action(None, options, set_status, get_status)
diff --git a/tests/data/metadata/fence_mpath.xml b/tests/data/metadata/fence_mpath.xml
index bbe9ad2b..fe9378df 100644
--- a/tests/data/metadata/fence_mpath.xml
+++ b/tests/data/metadata/fence_mpath.xml
@@ -14,9 +14,19 @@ The fence_mpath agent works by having a unique key for each node that has to be
<content type="string" />
<shortdesc lang="en">List of devices to use for current operation. Devices can be comma-separated list of device-mapper multipath devices (eg. /dev/mapper/3600508b400105df70000e00000ac0000 or /dev/mapper/mpath1). Each device must support SCSI-3 persistent reservations.</shortdesc>
</parameter>
- <parameter name="key" unique="0" required="1">
+ <parameter name="key" unique="0" required="0">
<getopt mixed="-k, --key=[key]" />
<content type="string" />
+ <shortdesc lang="en">Replaced by -n, --plug</shortdesc>
+ </parameter>
+ <parameter name="plug" unique="0" required="1" obsoletes="port">
+ <getopt mixed="Key to use for the current operation" />
+ <content type="string" />
+ <shortdesc lang="en">Key to use for the current operation. This key should be unique to a node and have to be written in /etc/multipath.conf. For the "on" action, the key specifies the key use to register the local node. For the "off" action, this key specifies the key to be removed from the device(s).</shortdesc>
+ </parameter>
+ <parameter name="port" unique="0" required="1" deprecated="1">
+ <getopt mixed="Key to use for the current operation" />
+ <content type="string" />
<shortdesc lang="en">Key to use for the current operation. This key should be unique to a node and have to be written in /etc/multipath.conf. For the "on" action, the key specifies the key use to register the local node. For the "off" action, this key specifies the key to be removed from the device(s).</shortdesc>
</parameter>
<parameter name="quiet" unique="0" required="0">

View File

@ -0,0 +1,73 @@
From 868c494d17952eecc6736683c6df04aa9d3a3199 Mon Sep 17 00:00:00 2001
From: Oyvind Albrigtsen <oalbrigt@redhat.com>
Date: Fri, 20 Sep 2019 12:06:55 +0200
Subject: [PATCH] fence_mpath: fix fail_usage() issue and a couple of other
minor issues w/the newly added plug/port parameter
---
agents/mpath/fence_mpath.py | 12 +++++++-----
tests/data/metadata/fence_mpath.xml | 10 +++++-----
2 files changed, 12 insertions(+), 10 deletions(-)
diff --git a/agents/mpath/fence_mpath.py b/agents/mpath/fence_mpath.py
index 25aeb052..73517851 100644
--- a/agents/mpath/fence_mpath.py
+++ b/agents/mpath/fence_mpath.py
@@ -213,7 +213,7 @@ def define_new_opts():
"longopt" : "key",
"help" : "-k, --key=[key] Replaced by -n, --plug",
"required" : "0",
- "shortdesc" : "Replaced by -n, --plug",
+ "shortdesc" : "Replaced by port/-n/--plug",
"order": 1
}
all_opt["mpathpersist_path"] = {
@@ -244,7 +244,8 @@ def main():
define_new_opts()
- all_opt["port"]["help"] = "Key to use for the current operation"
+ all_opt["port"]["required"] = "0"
+ all_opt["port"]["help"] = "-n, --plug=[key] Key to use for the current operation"
all_opt["port"]["shortdesc"] = "Key to use for the current operation. \
This key should be unique to a node and have to be written in \
/etc/multipath.conf. For the \"on\" action, the key specifies the key use to \
@@ -266,9 +267,10 @@ def main():
if "--key" in options:
options["--plug"] = options["--key"]
del options["--key"]
- elif options["--action"] in ["off", "on", "reboot", "status"] \
- and "--plug" not in options:
- fail_usage("Failed: You have to enter plug number or machine identification", stop)
+ elif "--help" not in options and options["--action"] in ["off", "on", \
+ "reboot", "status", "validate-all"] and "--plug" not in options:
+ stop_after_error = False if options["--action"] == "validate-all" else True
+ fail_usage("Failed: You have to enter plug number or machine identification", stop_after_error)
docs = {}
docs["shortdesc"] = "Fence agent for multipath persistent reservation"
diff --git a/tests/data/metadata/fence_mpath.xml b/tests/data/metadata/fence_mpath.xml
index fe9378df..f5e60823 100644
--- a/tests/data/metadata/fence_mpath.xml
+++ b/tests/data/metadata/fence_mpath.xml
@@ -17,15 +17,15 @@ The fence_mpath agent works by having a unique key for each node that has to be
<parameter name="key" unique="0" required="0">
<getopt mixed="-k, --key=[key]" />
<content type="string" />
- <shortdesc lang="en">Replaced by -n, --plug</shortdesc>
+ <shortdesc lang="en">Replaced by port/-n/--plug</shortdesc>
</parameter>
- <parameter name="plug" unique="0" required="1" obsoletes="port">
- <getopt mixed="Key to use for the current operation" />
+ <parameter name="plug" unique="0" required="0" obsoletes="port">
+ <getopt mixed="-n, --plug=[key]" />
<content type="string" />
<shortdesc lang="en">Key to use for the current operation. This key should be unique to a node and have to be written in /etc/multipath.conf. For the "on" action, the key specifies the key use to register the local node. For the "off" action, this key specifies the key to be removed from the device(s).</shortdesc>
</parameter>
- <parameter name="port" unique="0" required="1" deprecated="1">
- <getopt mixed="Key to use for the current operation" />
+ <parameter name="port" unique="0" required="0" deprecated="1">
+ <getopt mixed="-n, --plug=[key]" />
<content type="string" />
<shortdesc lang="en">Key to use for the current operation. This key should be unique to a node and have to be written in /etc/multipath.conf. For the "on" action, the key specifies the key use to register the local node. For the "off" action, this key specifies the key to be removed from the device(s).</shortdesc>
</parameter>

View File

@ -0,0 +1,130 @@
From 7ac16fb281fa8cfc51a31f672014c614c81aec82 Mon Sep 17 00:00:00 2001
From: Oyvind Albrigtsen <oalbrigt@redhat.com>
Date: Fri, 31 Jan 2020 15:53:47 +0100
Subject: [PATCH] fence_aws: improve logging and metadata/usage text
---
agents/aws/fence_aws.py | 36 +++++++++++++++++++------------
tests/data/metadata/fence_aws.xml | 6 +++---
2 files changed, 25 insertions(+), 17 deletions(-)
diff --git a/agents/aws/fence_aws.py b/agents/aws/fence_aws.py
index 647b66fc..74321e8e 100644
--- a/agents/aws/fence_aws.py
+++ b/agents/aws/fence_aws.py
@@ -5,7 +5,7 @@
import atexit
sys.path.append("@FENCEAGENTSLIBDIR@")
from fencing import *
-from fencing import fail, fail_usage, EC_TIMED_OUT, run_delay
+from fencing import fail, fail_usage, run_delay, EC_STATUS
import boto3
from botocore.exceptions import ClientError, EndpointConnectionError, NoRegionError
@@ -19,6 +19,8 @@ def get_nodes_list(conn, options):
fail_usage("Failed: Incorrect Access Key or Secret Key.")
except EndpointConnectionError:
fail_usage("Failed: Incorrect Region.")
+ except Exception as e:
+ logging.error("Failed to get node list: %s", e)
return result
@@ -38,20 +40,26 @@ def get_power_status(conn, options):
except EndpointConnectionError:
fail_usage("Failed: Incorrect Region.")
except IndexError:
- return "fail"
+ fail(EC_STATUS)
+ except Exception as e:
+ logging.error("Failed to get power status: %s", e)
+ fail(EC_STATUS)
def set_power_status(conn, options):
- if (options["--action"]=="off"):
- conn.instances.filter(InstanceIds=[options["--plug"]]).stop(Force=True)
- elif (options["--action"]=="on"):
- conn.instances.filter(InstanceIds=[options["--plug"]]).start()
-
+ try:
+ if (options["--action"]=="off"):
+ conn.instances.filter(InstanceIds=[options["--plug"]]).stop(Force=True)
+ elif (options["--action"]=="on"):
+ conn.instances.filter(InstanceIds=[options["--plug"]]).start()
+ except Exception as e:
+ logging.error("Failed to power %s %s: %s", \
+ options["--action"], options["--plug"], e)
def define_new_opts():
all_opt["region"] = {
"getopt" : "r:",
"longopt" : "region",
- "help" : "-r, --region=[name] Region, e.g. us-east-1",
+ "help" : "-r, --region=[region] Region, e.g. us-east-1",
"shortdesc" : "Region.",
"required" : "0",
"order" : 2
@@ -59,7 +67,7 @@ def define_new_opts():
all_opt["access_key"] = {
"getopt" : "a:",
"longopt" : "access-key",
- "help" : "-a, --access-key=[name] Access Key",
+ "help" : "-a, --access-key=[key] Access Key",
"shortdesc" : "Access Key.",
"required" : "0",
"order" : 3
@@ -67,7 +75,7 @@ def define_new_opts():
all_opt["secret_key"] = {
"getopt" : "s:",
"longopt" : "secret-key",
- "help" : "-s, --secret-key=[name] Secret Key",
+ "help" : "-s, --secret-key=[key] Secret Key",
"shortdesc" : "Secret Key.",
"required" : "0",
"order" : 4
@@ -107,16 +115,16 @@ def main():
conn = boto3.resource('ec2', region_name=region,
aws_access_key_id=access_key,
aws_secret_access_key=secret_key)
- except:
- fail_usage("Failed: Unable to connect to AWS. Check your configuration.")
+ except Exception as e:
+ fail_usage("Failed: Unable to connect to AWS: " + str(e))
else:
# If setup with "aws configure" or manually in
# ~/.aws/credentials
try:
conn = boto3.resource('ec2')
- except:
+ except Exception as e:
# If any of region/access/secret are missing
- fail_usage("Failed: Unable to connect to AWS. Check your configuration.")
+ fail_usage("Failed: Unable to connect to AWS: " + str(e))
# Operate the fencing device
result = fence_action(conn, options, set_power_status, get_power_status, get_nodes_list)
diff --git a/tests/data/metadata/fence_aws.xml b/tests/data/metadata/fence_aws.xml
index 4dea4418..5e5d5d99 100644
--- a/tests/data/metadata/fence_aws.xml
+++ b/tests/data/metadata/fence_aws.xml
@@ -22,17 +22,17 @@ For instructions see: https://boto3.readthedocs.io/en/latest/guide/quickstart.ht
<shortdesc lang="en">Physical plug number on device, UUID or identification of machine</shortdesc>
</parameter>
<parameter name="region" unique="0" required="0">
- <getopt mixed="-r, --region=[name]" />
+ <getopt mixed="-r, --region=[region]" />
<content type="string" />
<shortdesc lang="en">Region.</shortdesc>
</parameter>
<parameter name="access_key" unique="0" required="0">
- <getopt mixed="-a, --access-key=[name]" />
+ <getopt mixed="-a, --access-key=[key]" />
<content type="string" />
<shortdesc lang="en">Access Key.</shortdesc>
</parameter>
<parameter name="secret_key" unique="0" required="0">
- <getopt mixed="-s, --secret-key=[name]" />
+ <getopt mixed="-s, --secret-key=[key]" />
<content type="string" />
<shortdesc lang="en">Secret Key.</shortdesc>
</parameter>

View File

@ -0,0 +1,23 @@
From 06cba4aa30322f410b0b2fec5785be39d0953433 Mon Sep 17 00:00:00 2001
From: Oyvind Albrigtsen <oalbrigt@redhat.com>
Date: Wed, 12 Feb 2020 14:21:54 +0100
Subject: [PATCH] fence_vmware_rest: fix encoding to avoid issues with UTF-8
encoded comments
---
agents/vmware_rest/fence_vmware_rest.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/agents/vmware_rest/fence_vmware_rest.py b/agents/vmware_rest/fence_vmware_rest.py
index cd99b4ac..d07bc10d 100644
--- a/agents/vmware_rest/fence_vmware_rest.py
+++ b/agents/vmware_rest/fence_vmware_rest.py
@@ -127,7 +127,7 @@ def send_command(conn, command, method="GET"):
raise Exception(e[1])
rc = conn.getinfo(pycurl.HTTP_CODE)
- result = web_buffer.getvalue().decode()
+ result = web_buffer.getvalue().decode("UTF-8")
web_buffer.close()

View File

@ -0,0 +1,38 @@
From 80aea3942aaca881349230a32b5dcc06c57de98a Mon Sep 17 00:00:00 2001
From: Oyvind Albrigtsen <oalbrigt@redhat.com>
Date: Tue, 19 May 2020 15:10:16 +0200
Subject: [PATCH] fence_vmware_rest: support UTF-8 VM names
---
agents/vmware_rest/fence_vmware_rest.py | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/agents/vmware_rest/fence_vmware_rest.py b/agents/vmware_rest/fence_vmware_rest.py
index 675de246..a038a096 100644
--- a/agents/vmware_rest/fence_vmware_rest.py
+++ b/agents/vmware_rest/fence_vmware_rest.py
@@ -8,11 +8,14 @@
from fencing import *
from fencing import fail, run_delay, EC_LOGIN_DENIED, EC_STATUS
+if sys.version_info[0] > 2: import urllib.parse as urllib
+else: import urllib
+
state = {"POWERED_ON": "on", 'POWERED_OFF': "off", 'SUSPENDED': "off"}
def get_power_status(conn, options):
try:
- res = send_command(conn, "vcenter/vm?filter.names={}".format(options["--plug"]))["value"]
+ res = send_command(conn, "vcenter/vm?filter.names={}".format(urllib.quote(options["--plug"])))["value"]
except Exception as e:
logging.debug("Failed: {}".format(e))
fail(EC_STATUS)
@@ -58,7 +61,7 @@ def get_list(conn, options):
fail(EC_STATUS)
for r in res["value"]:
- outlets[r["name"]] = ("", state[r["power_state"]])
+ outlets[r["name"].encode("UTF-8")] = ("", state[r["power_state"]])
return outlets

View File

@ -0,0 +1,23 @@
From 39e96371ab9ab1318db004c0ddbb1049d1c0f474 Mon Sep 17 00:00:00 2001
From: Oyvind Albrigtsen <oalbrigt@redhat.com>
Date: Thu, 11 Jun 2020 10:25:34 +0200
Subject: [PATCH] fence_vmware_soap: log exception message for SSLError
exception
---
agents/vmware_soap/fence_vmware_soap.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/agents/vmware_soap/fence_vmware_soap.py b/agents/vmware_soap/fence_vmware_soap.py
index 53e8d8f4..f2ab68b0 100644
--- a/agents/vmware_soap/fence_vmware_soap.py
+++ b/agents/vmware_soap/fence_vmware_soap.py
@@ -67,7 +67,7 @@ def soap_login(options):
conn.service.Login(mo_SessionManager, options["--username"], options["--password"])
except requests.exceptions.SSLError as ex:
- fail_usage("Server side certificate verification failed")
+ fail_usage("Server side certificate verification failed: %s" % ex)
except Exception:
fail(EC_LOGIN_DENIED)

View File

@ -0,0 +1,22 @@
From 0d3ff341c5dcff7ded0274ae20460895f35c13d6 Mon Sep 17 00:00:00 2001
From: Oyvind Albrigtsen <oalbrigt@redhat.com>
Date: Thu, 13 Feb 2020 15:40:24 +0100
Subject: [PATCH] fence_mpath: fix --reserve parameter typo
---
agents/mpath/fence_mpath.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/agents/mpath/fence_mpath.py b/agents/mpath/fence_mpath.py
index 73517851..a3d9fe23 100644
--- a/agents/mpath/fence_mpath.py
+++ b/agents/mpath/fence_mpath.py
@@ -106,7 +106,7 @@ def register_dev(options, dev):
return not bool(run_cmd(options, cmd)["err"])
def reserve_dev(options, dev):
- cmd = options["--mpathpersist-path"] + " -o --reserv --prout-type=5 --param-rk=" + options["--plug"] + " -d " + dev
+ cmd = options["--mpathpersist-path"] + " -o --reserve --prout-type=5 --param-rk=" + options["--plug"] + " -d " + dev
return not bool(run_cmd(options, cmd)["err"])
def get_reservation_key(options, dev):

View File

@ -0,0 +1,48 @@
From 1c2f791b6b2be13bcceaa096df52654164b1f6cb Mon Sep 17 00:00:00 2001
From: Oyvind Albrigtsen <oalbrigt@redhat.com>
Date: Thu, 5 Mar 2020 14:10:29 +0100
Subject: [PATCH] fence_aws: improve connect parameter logic, so region can be
specified as parameter, while using role or keys from ~/.aws/config
---
agents/aws/fence_aws.py | 27 +++++++++------------------
1 file changed, 9 insertions(+), 18 deletions(-)
diff --git a/agents/aws/fence_aws.py b/agents/aws/fence_aws.py
index 74321e8e..4a4d9de2 100644
--- a/agents/aws/fence_aws.py
+++ b/agents/aws/fence_aws.py
@@ -107,24 +107,15 @@ def main():
run_delay(options)
- if "--region" in options and "--access-key" in options and "--secret-key" in options:
- region = options["--region"]
- access_key = options["--access-key"]
- secret_key = options["--secret-key"]
- try:
- conn = boto3.resource('ec2', region_name=region,
- aws_access_key_id=access_key,
- aws_secret_access_key=secret_key)
- except Exception as e:
- fail_usage("Failed: Unable to connect to AWS: " + str(e))
- else:
- # If setup with "aws configure" or manually in
- # ~/.aws/credentials
- try:
- conn = boto3.resource('ec2')
- except Exception as e:
- # If any of region/access/secret are missing
- fail_usage("Failed: Unable to connect to AWS: " + str(e))
+ region = options.get("--region")
+ access_key = options.get("--access-key")
+ secret_key = options.get("--secret-key")
+ try:
+ conn = boto3.resource('ec2', region_name=region,
+ aws_access_key_id=access_key,
+ aws_secret_access_key=secret_key)
+ except Exception as e:
+ fail_usage("Failed: Unable to connect to AWS: " + str(e))
# Operate the fencing device
result = fence_action(conn, options, set_power_status, get_power_status, get_nodes_list)

View File

@ -0,0 +1,421 @@
From 1742baf17954c58a84b9c668a617bac78303ce95 Mon Sep 17 00:00:00 2001
From: Guilherme Felix <fguilher@amazon.com>
Date: Tue, 17 Mar 2020 13:18:38 +0000
Subject: [PATCH 1/9] fence_aws: Fix fence race condition by checking local
instance status
---
agents/aws/fence_aws.py | 37 ++++++++++++++++++++++++++++++++++++-
1 file changed, 36 insertions(+), 1 deletion(-)
diff --git a/agents/aws/fence_aws.py b/agents/aws/fence_aws.py
index 4a4d9de2..f37f68d6 100644
--- a/agents/aws/fence_aws.py
+++ b/agents/aws/fence_aws.py
@@ -3,6 +3,7 @@
import sys, re
import logging
import atexit
+import requests
sys.path.append("@FENCEAGENTSLIBDIR@")
from fencing import *
from fencing import fail, fail_usage, run_delay, EC_STATUS
@@ -10,6 +11,17 @@
import boto3
from botocore.exceptions import ClientError, EndpointConnectionError, NoRegionError
+def get_instance_id():
+ try:
+ r = requests.get('http://169.254.169.254/latest/meta-data/instance-id')
+ return r.content
+ except HTTPError as http_err:
+ logging.error('HTTP error occurred while trying to access EC2 metadata server: %s', http_err)
+ except Exception as err:
+ logging.error('A fatal error occurred while trying to access EC2 metadata server: %s', err)
+ return None
+
+
def get_nodes_list(conn, options):
result = {}
try:
@@ -45,10 +57,33 @@ def get_power_status(conn, options):
logging.error("Failed to get power status: %s", e)
fail(EC_STATUS)
+def get_self_power_status(conn, options):
+ try:
+ instance = conn.instances.filter(Filters=[{"Name": "instance-id", "Values": [instance_id]}])
+ state = list(instance)[0].state["Name"]
+ if state == "running":
+ logging.debug("Captured my (%s) state and it %s - returning OK - Proceeding with fencing",instance_id,state.upper())
+ return "ok"
+ else:
+ logging.debug("Captured my (%s) state it is %s - returning Alert - Unable to fence other nodes",instance_id,state.upper())
+ return "alert"
+
+ except ClientError:
+ fail_usage("Failed: Incorrect Access Key or Secret Key.")
+ except EndpointConnectionError:
+ fail_usage("Failed: Incorrect Region.")
+ except IndexError:
+ return "fail"
+
def set_power_status(conn, options):
+ my_instance = get_instance_id()
try:
if (options["--action"]=="off"):
- conn.instances.filter(InstanceIds=[options["--plug"]]).stop(Force=True)
+ if (get_self_power_status(conn,myinstance) == "ok"):
+ logging.info("Called StopInstance API call for %s", options["--plug"])
+ conn.instances.filter(InstanceIds=[options["--plug"]]).stop(Force=True)
+ else:
+ logging.info("Skipping fencing as instance is not in running status")
elif (options["--action"]=="on"):
conn.instances.filter(InstanceIds=[options["--plug"]]).start()
except Exception as e:
From 45e429b3132ebc9e78121c3fbb15f0bf46845a59 Mon Sep 17 00:00:00 2001
From: Guilherme Felix <fguilher@amazon.com>
Date: Tue, 17 Mar 2020 13:28:34 +0000
Subject: [PATCH 2/9] fence_aws: Use local logger and improve logging
experience
---
agents/aws/fence_aws.py | 34 ++++++++++++++++++++++++++--------
1 file changed, 26 insertions(+), 8 deletions(-)
diff --git a/agents/aws/fence_aws.py b/agents/aws/fence_aws.py
index f37f68d6..b0b6685a 100644
--- a/agents/aws/fence_aws.py
+++ b/agents/aws/fence_aws.py
@@ -6,7 +6,7 @@
import requests
sys.path.append("@FENCEAGENTSLIBDIR@")
from fencing import *
-from fencing import fail, fail_usage, run_delay, EC_STATUS
+from fencing import fail, fail_usage, run_delay, EC_STATUS, SyslogLibHandler
import boto3
from botocore.exceptions import ClientError, EndpointConnectionError, NoRegionError
@@ -16,13 +16,14 @@ def get_instance_id():
r = requests.get('http://169.254.169.254/latest/meta-data/instance-id')
return r.content
except HTTPError as http_err:
- logging.error('HTTP error occurred while trying to access EC2 metadata server: %s', http_err)
+ logger.error('HTTP error occurred while trying to access EC2 metadata server: %s', http_err)
except Exception as err:
- logging.error('A fatal error occurred while trying to access EC2 metadata server: %s', err)
+ logger.error('A fatal error occurred while trying to access EC2 metadata server: %s', err)
return None
def get_nodes_list(conn, options):
+ logger.info("Starting monitor operation")
result = {}
try:
for instance in conn.instances.all():
@@ -32,14 +33,16 @@ def get_nodes_list(conn, options):
except EndpointConnectionError:
fail_usage("Failed: Incorrect Region.")
except Exception as e:
- logging.error("Failed to get node list: %s", e)
-
+ logger.error("Failed to get node list: %s", e)
+ logger.debug("Monitor operation OK: %s",result)
return result
def get_power_status(conn, options):
+ logger.debug("Starting status operation")
try:
instance = conn.instances.filter(Filters=[{"Name": "instance-id", "Values": [options["--plug"]]}])
state = list(instance)[0].state["Name"]
+ logger.info("Status operation for EC2 instance %s returned state: %s",options["--plug"],state.upper())
if state == "running":
return "on"
elif state == "stopped":
@@ -80,14 +83,14 @@ def set_power_status(conn, options):
try:
if (options["--action"]=="off"):
if (get_self_power_status(conn,myinstance) == "ok"):
- logging.info("Called StopInstance API call for %s", options["--plug"])
conn.instances.filter(InstanceIds=[options["--plug"]]).stop(Force=True)
+ logger.info("Called StopInstance API call for %s", options["--plug"])
else:
- logging.info("Skipping fencing as instance is not in running status")
+ logger.info("Skipping fencing as instance is not in running status")
elif (options["--action"]=="on"):
conn.instances.filter(InstanceIds=[options["--plug"]]).start()
except Exception as e:
- logging.error("Failed to power %s %s: %s", \
+ logger.error("Failed to power %s %s: %s", \
options["--action"], options["--plug"], e)
def define_new_opts():
@@ -142,6 +145,13 @@ def main():
run_delay(options)
+ if options.get("--verbose") is not None:
+ lh = logging.FileHandler('/var/log/fence_aws_debug.log')
+ logger.addHandler(lh)
+ lhf = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
+ lh.setFormatter(lhf)
+ logger.setLevel(logging.DEBUG)
+
region = options.get("--region")
access_key = options.get("--access-key")
secret_key = options.get("--secret-key")
@@ -157,4 +167,12 @@ def main():
sys.exit(result)
if __name__ == "__main__":
+
+ logger = logging.getLogger("fence_aws")
+ logger.propagate = False
+ logger.setLevel(logging.INFO)
+ logger.addHandler(SyslogLibHandler())
+ logger.getLogger('botocore.vendored').propagate = False
+
+
main()
From 00569921597b8007c67296ab8332747baf1e6fae Mon Sep 17 00:00:00 2001
From: Guilherme Felix <fguilher@amazon.com>
Date: Tue, 17 Mar 2020 13:33:02 +0000
Subject: [PATCH 3/9] fence_aws: Decouple boto3 and botocore debug logging from
local logging
---
agents/aws/fence_aws.py | 26 +++++++++++++++++++++++++-
1 file changed, 25 insertions(+), 1 deletion(-)
diff --git a/agents/aws/fence_aws.py b/agents/aws/fence_aws.py
index b0b6685a..11714315 100644
--- a/agents/aws/fence_aws.py
+++ b/agents/aws/fence_aws.py
@@ -118,18 +118,27 @@ def define_new_opts():
"required" : "0",
"order" : 4
}
+ all_opt["boto3_debug"] = {
+ "getopt" : "b:",
+ "longopt" : "boto3_debug",
+ "help" : "-b, --boto3_debug=on|off Boto3 and Botocore library debug logging",
+ "shortdesc": "Boto Lib debug",
+ "required": "0",
+ "order": 5
+ }
# Main agent method
def main():
conn = None
- device_opt = ["port", "no_password", "region", "access_key", "secret_key"]
+ device_opt = ["port", "no_password", "region", "access_key", "secret_key", "boto3_debug"]
atexit.register(atexit_handler)
define_new_opts()
all_opt["power_timeout"]["default"] = "60"
+ all_opt["boto3_debug"]["default"] = "off"
options = check_input(device_opt, process_input(device_opt))
@@ -151,6 +160,21 @@ def main():
lhf = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
lh.setFormatter(lhf)
logger.setLevel(logging.DEBUG)
+
+ if options["--boto3_debug"] != "on":
+ boto3.set_stream_logger('boto3',logging.INFO)
+ boto3.set_stream_logger('botocore',logging.INFO)
+ logging.getLogger('botocore').propagate = False
+ logging.getLogger('boto3').propagate = False
+ else:
+ log_format = logging.Formatter('%(asctime)s %(name)-12s %(levelname)-8s %(message)s')
+ logging.getLogger('botocore').propagate = False
+ logging.getLogger('boto3').propagate = False
+ fdh = logging.FileHandler('/var/log/fence_aws_boto3.log')
+ fdh.setFormatter(log_format)
+ logging.getLogger('boto3').addHandler(fdh)
+ logging.getLogger('botocore').addHandler(fdh)
+ logging.debug("Boto debug level is %s and sending debug info to /var/log/fence_aws_boto3.log", options["--boto3_debug"])
region = options.get("--region")
access_key = options.get("--access-key")
From ed309bd51dfd5e0fed30156e7a312d5b5a8f4bd4 Mon Sep 17 00:00:00 2001
From: Guilherme Felix <fguilher@amazon.com>
Date: Thu, 19 Mar 2020 16:02:47 +0000
Subject: [PATCH 4/9] fence_aws: Fix typos and variable names
---
agents/aws/fence_aws.py | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/agents/aws/fence_aws.py b/agents/aws/fence_aws.py
index 11714315..207631e8 100644
--- a/agents/aws/fence_aws.py
+++ b/agents/aws/fence_aws.py
@@ -60,7 +60,7 @@ def get_power_status(conn, options):
logging.error("Failed to get power status: %s", e)
fail(EC_STATUS)
-def get_self_power_status(conn, options):
+def get_self_power_status(conn, instance_id):
try:
instance = conn.instances.filter(Filters=[{"Name": "instance-id", "Values": [instance_id]}])
state = list(instance)[0].state["Name"]
@@ -82,7 +82,7 @@ def set_power_status(conn, options):
my_instance = get_instance_id()
try:
if (options["--action"]=="off"):
- if (get_self_power_status(conn,myinstance) == "ok"):
+ if (get_self_power_status(conn,my_instance) == "ok"):
conn.instances.filter(InstanceIds=[options["--plug"]]).stop(Force=True)
logger.info("Called StopInstance API call for %s", options["--plug"])
else:
@@ -196,7 +196,7 @@ def main():
logger.propagate = False
logger.setLevel(logging.INFO)
logger.addHandler(SyslogLibHandler())
- logger.getLogger('botocore.vendored').propagate = False
+ logging.getLogger('botocore.vendored').propagate = False
main()
From 624c652a95a676286af408898186186b7d7fcf55 Mon Sep 17 00:00:00 2001
From: Guilherme Felix <fguilher@amazon.com>
Date: Thu, 19 Mar 2020 16:58:45 +0000
Subject: [PATCH 5/9] fence_aws: Missing brackets on boto3_debug metadata
---
agents/aws/fence_aws.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/agents/aws/fence_aws.py b/agents/aws/fence_aws.py
index 207631e8..8916f4a0 100644
--- a/agents/aws/fence_aws.py
+++ b/agents/aws/fence_aws.py
@@ -121,7 +121,7 @@ def define_new_opts():
all_opt["boto3_debug"] = {
"getopt" : "b:",
"longopt" : "boto3_debug",
- "help" : "-b, --boto3_debug=on|off Boto3 and Botocore library debug logging",
+ "help" : "-b, --boto3_debug=[on|off] Boto3 and Botocore library debug logging",
"shortdesc": "Boto Lib debug",
"required": "0",
"order": 5
From 7c641a6885c4ab67b7739a43892d92d95a6f566c Mon Sep 17 00:00:00 2001
From: Guilherme Felix <fguilher@amazon.com>
Date: Thu, 19 Mar 2020 17:04:31 +0000
Subject: [PATCH 6/9] fence_aws: Fix travis build #1
---
agents/aws/fence_aws.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/agents/aws/fence_aws.py b/agents/aws/fence_aws.py
index 8916f4a0..f41a47e4 100644
--- a/agents/aws/fence_aws.py
+++ b/agents/aws/fence_aws.py
@@ -121,7 +121,7 @@ def define_new_opts():
all_opt["boto3_debug"] = {
"getopt" : "b:",
"longopt" : "boto3_debug",
- "help" : "-b, --boto3_debug=[on|off] Boto3 and Botocore library debug logging",
+ "help" : "-b, --boto3_debug=[option] Boto3 and Botocore library debug logging",
"shortdesc": "Boto Lib debug",
"required": "0",
"order": 5
From 257af7ccc9789646adc7abf1e7dbac744b756071 Mon Sep 17 00:00:00 2001
From: Guilherme Felix <fguilher@amazon.com>
Date: Fri, 20 Mar 2020 10:59:56 +0000
Subject: [PATCH 7/9] fence_aws: Updated metadata XML file
---
tests/data/metadata/fence_aws.xml | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/tests/data/metadata/fence_aws.xml b/tests/data/metadata/fence_aws.xml
index 5e5d5d99..acfebb61 100644
--- a/tests/data/metadata/fence_aws.xml
+++ b/tests/data/metadata/fence_aws.xml
@@ -36,6 +36,11 @@ For instructions see: https://boto3.readthedocs.io/en/latest/guide/quickstart.ht
<content type="string" />
<shortdesc lang="en">Secret Key.</shortdesc>
</parameter>
+ <parameter name="boto3_debug" unique="0" required="0">
+ <getopt mixed="-b, --boto3_debug=[option]" />
+ <content type="string" default="off" />
+ <shortdesc lang="en">Boto Lib debug</shortdesc>
+ </parameter>
<parameter name="quiet" unique="0" required="0">
<getopt mixed="-q, --quiet" />
<content type="boolean" />
From 8f78bc19356b5e07d0021aaf7da3fc4e712e00f0 Mon Sep 17 00:00:00 2001
From: Guilherme Felix <fguilher@amazon.com>
Date: Fri, 20 Mar 2020 12:13:16 +0000
Subject: [PATCH 8/9] fence_aws: Moving logger config next to import statements
for visibility
---
agents/aws/fence_aws.py | 13 ++++++-------
1 file changed, 6 insertions(+), 7 deletions(-)
diff --git a/agents/aws/fence_aws.py b/agents/aws/fence_aws.py
index f41a47e4..72fb8843 100644
--- a/agents/aws/fence_aws.py
+++ b/agents/aws/fence_aws.py
@@ -11,6 +11,12 @@
import boto3
from botocore.exceptions import ClientError, EndpointConnectionError, NoRegionError
+logger = logging.getLogger("fence_aws")
+logger.propagate = False
+logger.setLevel(logging.INFO)
+logger.addHandler(SyslogLibHandler())
+logging.getLogger('botocore.vendored').propagate = False
+
def get_instance_id():
try:
r = requests.get('http://169.254.169.254/latest/meta-data/instance-id')
@@ -192,11 +198,4 @@ def main():
if __name__ == "__main__":
- logger = logging.getLogger("fence_aws")
- logger.propagate = False
- logger.setLevel(logging.INFO)
- logger.addHandler(SyslogLibHandler())
- logging.getLogger('botocore.vendored').propagate = False
-
-
main()
From 570a05c425fe55008c8892ebaad8a73d36143909 Mon Sep 17 00:00:00 2001
From: Guilherme Felix <fguilher@amazon.com>
Date: Fri, 20 Mar 2020 14:17:55 +0000
Subject: [PATCH 9/9] fence_aws: Remove empty line
---
agents/aws/fence_aws.py | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/agents/aws/fence_aws.py b/agents/aws/fence_aws.py
index 72fb8843..ed55f390 100644
--- a/agents/aws/fence_aws.py
+++ b/agents/aws/fence_aws.py
@@ -197,5 +197,4 @@ def main():
sys.exit(result)
if __name__ == "__main__":
-
- main()
+ main()
\ No newline at end of file

View File

@ -0,0 +1,22 @@
From 9758f8c83c44ad6949d4411042c59bcf9365f67e Mon Sep 17 00:00:00 2001
From: Oyvind Albrigtsen <oalbrigt@redhat.com>
Date: Tue, 24 Mar 2020 15:31:13 +0100
Subject: [PATCH] fence_aws: fix Python 3 encoding issue
---
agents/aws/fence_aws.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/agents/aws/fence_aws.py b/agents/aws/fence_aws.py
index ed55f390..17c2fedb 100644
--- a/agents/aws/fence_aws.py
+++ b/agents/aws/fence_aws.py
@@ -20,7 +20,7 @@
def get_instance_id():
try:
r = requests.get('http://169.254.169.254/latest/meta-data/instance-id')
- return r.content
+ return r.content.decode("UTF-8")
except HTTPError as http_err:
logger.error('HTTP error occurred while trying to access EC2 metadata server: %s', http_err)
except Exception as err:

View File

@ -0,0 +1,44 @@
From 020f48a309bcad659dc493960d2b39e8e1243085 Mon Sep 17 00:00:00 2001
From: Thomas Abraham <tabraham@suse.com>
Date: Mon, 20 Apr 2020 20:28:43 -0400
Subject: [PATCH] fence_vmware_rest: improve exception handling in
send_command()
If an exception occurs, simply raise it. pycurl's perform() method can
generate a pycurl.error object, which does not support indexing and
attempting to do so will generate an exception that hides the original
exception.
Also, don't assume that the remote will return a JSON formatted response.
If it doesn't, a exception will occur accessing result which will not
raise the intended exception.
---
agents/vmware_rest/fence_vmware_rest.py | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/agents/vmware_rest/fence_vmware_rest.py b/agents/vmware_rest/fence_vmware_rest.py
index d07bc10d..1505ffe6 100644
--- a/agents/vmware_rest/fence_vmware_rest.py
+++ b/agents/vmware_rest/fence_vmware_rest.py
@@ -124,7 +124,7 @@ def send_command(conn, command, method="GET"):
try:
conn.perform()
except Exception as e:
- raise Exception(e[1])
+ raise(e)
rc = conn.getinfo(pycurl.HTTP_CODE)
result = web_buffer.getvalue().decode("UTF-8")
@@ -135,7 +135,11 @@ def send_command(conn, command, method="GET"):
result = json.loads(result)
if rc != 200:
- raise Exception("{}: {}".format(rc, result["value"]["messages"][0]["default_message"]))
+ if len(result) > 0:
+ raise Exception("{}: {}".format(rc,
+ result["value"]["messages"][0]["default_message"]))
+ else:
+ raise Exception("Remote returned {} for request to {}".format(rc, url))
logging.debug("url: {}".format(url))
logging.debug("method: {}".format(method))

View File

@ -0,0 +1,92 @@
From ab193580dcdd810b7bef69cc04cebef315f4781d Mon Sep 17 00:00:00 2001
From: Oyvind Albrigtsen <oalbrigt@redhat.com>
Date: Thu, 23 Apr 2020 15:55:11 +0200
Subject: [PATCH] fence_vmware_rest: add filter parameter
---
agents/vmware_rest/fence_vmware_rest.py | 24 ++++++++++++++++++++---
tests/data/metadata/fence_vmware_rest.xml | 9 ++++++++-
2 files changed, 29 insertions(+), 4 deletions(-)
diff --git a/agents/vmware_rest/fence_vmware_rest.py b/agents/vmware_rest/fence_vmware_rest.py
index 1505ffe6..6daff121 100644
--- a/agents/vmware_rest/fence_vmware_rest.py
+++ b/agents/vmware_rest/fence_vmware_rest.py
@@ -42,7 +42,10 @@ def get_list(conn, options):
outlets = {}
try:
- res = send_command(conn, "vcenter/vm")
+ command = "vcenter/vm"
+ if "--filter" in options:
+ command = command + "?" + options["--filter"]
+ res = send_command(conn, command)
except:
logging.debug("Failed: {}".format(e))
fail(EC_STATUS)
@@ -157,6 +160,16 @@ def define_new_opts():
"required" : "0",
"shortdesc" : "The path part of the API URL",
"order" : 2}
+ all_opt["filter"] = {
+ "getopt" : ":",
+ "longopt" : "filter",
+ "help" : "--filter=[filter] Filter to only return relevant VMs"
+ " (e.g. \"filter.names=node1&filter.names=node2\").",
+ "default" : "",
+ "required" : "0",
+ "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}
def main():
@@ -169,6 +182,7 @@ def main():
"notls",
"web",
"port",
+ "filter",
]
atexit.register(atexit_handler)
@@ -181,8 +195,12 @@ def main():
docs = {}
docs["shortdesc"] = "Fence agent for VMware REST API"
- docs["longdesc"] = "fence_vmware_rest is an I/O Fencing agent which can be \
-used with VMware API to fence virtual machines."
+ docs["longdesc"] = """fence_vmware_rest is an I/O Fencing agent which can be \
+used with VMware API to fence virtual machines.
+
+NOTE: If there's more than 1000 VMs there is a filter parameter to work around \
+the API limit. See https://code.vmware.com/apis/62/vcenter-management#/VM%20/get_vcenter_vm \
+for full list of filters."""
docs["vendorurl"] = "https://www.vmware.com"
show_docs(options, docs)
diff --git a/tests/data/metadata/fence_vmware_rest.xml b/tests/data/metadata/fence_vmware_rest.xml
index 5b497a6a..d60c8775 100644
--- a/tests/data/metadata/fence_vmware_rest.xml
+++ b/tests/data/metadata/fence_vmware_rest.xml
@@ -1,6 +1,8 @@
<?xml version="1.0" ?>
<resource-agent name="fence_vmware_rest" shortdesc="Fence agent for VMware REST API" >
-<longdesc>fence_vmware_rest is an I/O Fencing agent which can be used with VMware API to fence virtual machines.</longdesc>
+<longdesc>fence_vmware_rest is an I/O Fencing agent which can be used with VMware API to fence virtual machines.
+
+NOTE: If there's more than 1000 VMs there is a filter parameter to work around the API limit. See https://code.vmware.com/apis/62/vcenter-management#/VM%20/get_vcenter_vm for full list of filters.</longdesc>
<vendor-url>https://www.vmware.com</vendor-url>
<parameters>
<parameter name="action" unique="0" required="1">
@@ -87,6 +89,11 @@
<getopt mixed="--api-path=[path]" />
<shortdesc lang="en">The path part of the API URL</shortdesc>
</parameter>
+ <parameter name="filter" unique="0" required="0">
+ <getopt mixed="--filter=[filter]" />
+ <content type="string" default="" />
+ <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="quiet" unique="0" required="0">
<getopt mixed="-q, --quiet" />
<content type="boolean" />

View File

@ -0,0 +1,76 @@
From 0296bc8512e37b8b935bc342b6493ed4fa8aa001 Mon Sep 17 00:00:00 2001
From: Oyvind Albrigtsen <oalbrigt@redhat.com>
Date: Thu, 14 May 2020 13:17:04 +0200
Subject: [PATCH 1/2] fence_vmware_rest: fix exception and remove default value
for filter parameter (which was shown in the manpage)
---
agents/vmware_rest/fence_vmware_rest.py | 3 +--
tests/data/metadata/fence_vmware_rest.xml | 2 +-
2 files changed, 2 insertions(+), 3 deletions(-)
diff --git a/agents/vmware_rest/fence_vmware_rest.py b/agents/vmware_rest/fence_vmware_rest.py
index 6daff121..2635ae07 100644
--- a/agents/vmware_rest/fence_vmware_rest.py
+++ b/agents/vmware_rest/fence_vmware_rest.py
@@ -46,7 +46,7 @@ def get_list(conn, options):
if "--filter" in options:
command = command + "?" + options["--filter"]
res = send_command(conn, command)
- except:
+ except Exception as e:
logging.debug("Failed: {}".format(e))
fail(EC_STATUS)
@@ -165,7 +165,6 @@ def define_new_opts():
"longopt" : "filter",
"help" : "--filter=[filter] Filter to only return relevant VMs"
" (e.g. \"filter.names=node1&filter.names=node2\").",
- "default" : "",
"required" : "0",
"shortdesc" : "Filter to only return relevant VMs. It can be used to avoid "
"the agent failing when more than 1000 VMs should be returned.",
diff --git a/tests/data/metadata/fence_vmware_rest.xml b/tests/data/metadata/fence_vmware_rest.xml
index d60c8775..830b6a21 100644
--- a/tests/data/metadata/fence_vmware_rest.xml
+++ b/tests/data/metadata/fence_vmware_rest.xml
@@ -91,7 +91,7 @@ NOTE: If there's more than 1000 VMs there is a filter parameter to work around t
</parameter>
<parameter name="filter" unique="0" required="0">
<getopt mixed="--filter=[filter]" />
- <content type="string" default="" />
+ <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="quiet" unique="0" required="0">
From 7420cf9f11568be7239956bed4631cdbaa6fb87c Mon Sep 17 00:00:00 2001
From: Oyvind Albrigtsen <oalbrigt@redhat.com>
Date: Thu, 14 May 2020 14:17:03 +0200
Subject: [PATCH 2/2] fence_vmware_rest: dont fail when receiving more than
1000 VM error during monitor-action
---
agents/vmware_rest/fence_vmware_rest.py | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/agents/vmware_rest/fence_vmware_rest.py b/agents/vmware_rest/fence_vmware_rest.py
index 2635ae07..675de246 100644
--- a/agents/vmware_rest/fence_vmware_rest.py
+++ b/agents/vmware_rest/fence_vmware_rest.py
@@ -48,7 +48,14 @@ def get_list(conn, options):
res = send_command(conn, command)
except Exception as e:
logging.debug("Failed: {}".format(e))
- fail(EC_STATUS)
+ if str(e).startswith("400"):
+ if options.get("--original-action") == "monitor":
+ return outlets
+ else:
+ logging.error("More than 1000 VMs returned. Use --filter parameter to limit which VMs to list.")
+ fail(EC_STATUS)
+ else:
+ fail(EC_STATUS)
for r in res["value"]:
outlets[r["name"]] = ("", state[r["power_state"]])

View File

@ -0,0 +1,122 @@
From 8920d2fc7993453e7ad05f807f6ec51745b408a5 Mon Sep 17 00:00:00 2001
From: Oyvind Albrigtsen <oalbrigt@redhat.com>
Date: Mon, 4 May 2020 16:53:55 +0200
Subject: [PATCH] fence_compute/fence_evacuate: fix --insecure parameter
---
agents/compute/fence_compute.py | 10 +++++++---
agents/evacuate/fence_evacuate.py | 10 +++++++---
tests/data/metadata/fence_compute.xml | 2 +-
tests/data/metadata/fence_evacuate.xml | 2 +-
4 files changed, 16 insertions(+), 8 deletions(-)
diff --git a/agents/compute/fence_compute.py b/agents/compute/fence_compute.py
index d0e012e6..f53b97da 100644
--- a/agents/compute/fence_compute.py
+++ b/agents/compute/fence_compute.py
@@ -281,7 +281,7 @@ def create_nova_connection(options):
loader = loading.get_plugin_loader('password')
keystone_auth = loader.load_from_options(**kwargs)
- keystone_session = session.Session(auth=keystone_auth, verify=(not options["--insecure"]))
+ keystone_session = session.Session(auth=keystone_auth, verify=not "--insecure" in options)
nova_versions = [ "2.11", "2" ]
for version in nova_versions:
@@ -307,7 +307,7 @@ def create_nova_connection(options):
None, # Password
None, # Tenant
None, # Auth URL
- insecure=options["--insecure"],
+ insecure="--insecure" in options,
region_name=options["--region-name"],
endpoint_type=options["--endpoint-type"],
session=keystone_session, auth=keystone_auth,
@@ -395,7 +395,6 @@ def define_new_opts():
"help" : "--insecure Explicitly allow agent to perform \"insecure\" TLS (https) requests",
"required" : "0",
"shortdesc" : "Allow Insecure TLS Requests",
- "default" : "False",
"order": 2,
}
all_opt["domain"] = {
@@ -484,6 +483,11 @@ def main():
options["--domain"] = options["--compute-domain"]
del options["--domain"]
+ # Disable insecure-certificate-warning message
+ if "--insecure" in options:
+ import urllib3
+ urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
+
logging.debug("Running "+options["--action"])
connection = create_nova_connection(options)
diff --git a/agents/evacuate/fence_evacuate.py b/agents/evacuate/fence_evacuate.py
index 60bb130e..88837dd8 100644
--- a/agents/evacuate/fence_evacuate.py
+++ b/agents/evacuate/fence_evacuate.py
@@ -217,7 +217,7 @@ def create_nova_connection(options):
loader = loading.get_plugin_loader('password')
keystone_auth = loader.load_from_options(**kwargs)
- keystone_session = session.Session(auth=keystone_auth, verify=(not options["--insecure"]))
+ keystone_session = session.Session(auth=keystone_auth, verify=not "--insecure" in options)
versions = [ "2.11", "2" ]
for version in versions:
@@ -244,7 +244,7 @@ def create_nova_connection(options):
None, # Password
None, # Tenant
None, # Auth URL
- insecure=options["--insecure"],
+ insecure="--insecure" in options,
region_name=options["--region-name"],
endpoint_type=options["--endpoint-type"],
session=keystone_session, auth=keystone_auth,
@@ -332,7 +332,6 @@ def define_new_opts():
"help" : "--insecure Explicitly allow agent to perform \"insecure\" TLS (https) requests",
"required" : "0",
"shortdesc" : "Allow Insecure TLS Requests",
- "default" : "False",
"order": 2,
}
all_opt["domain"] = {
@@ -397,6 +396,11 @@ def main():
del options["--domain"]
+ # Disable insecure-certificate-warning message
+ if "--insecure" in options:
+ import urllib3
+ urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
+
connection = create_nova_connection(options)
# Un-evacuating a server doesn't make sense
diff --git a/tests/data/metadata/fence_compute.xml b/tests/data/metadata/fence_compute.xml
index 99d56af0..2f183268 100644
--- a/tests/data/metadata/fence_compute.xml
+++ b/tests/data/metadata/fence_compute.xml
@@ -70,7 +70,7 @@
</parameter>
<parameter name="insecure" unique="0" required="0">
<getopt mixed="--insecure" />
- <content type="boolean" default="False" />
+ <content type="boolean" />
<shortdesc lang="en">Allow Insecure TLS Requests</shortdesc>
</parameter>
<parameter name="project-domain" unique="0" required="0" deprecated="1">
diff --git a/tests/data/metadata/fence_evacuate.xml b/tests/data/metadata/fence_evacuate.xml
index 8c720b80..95da0e1b 100644
--- a/tests/data/metadata/fence_evacuate.xml
+++ b/tests/data/metadata/fence_evacuate.xml
@@ -70,7 +70,7 @@
</parameter>
<parameter name="insecure" unique="0" required="0">
<getopt mixed="--insecure" />
- <content type="boolean" default="False" />
+ <content type="boolean" />
<shortdesc lang="en">Allow Insecure TLS Requests</shortdesc>
</parameter>
<parameter name="project-domain" unique="0" required="0" deprecated="1">

View File

@ -0,0 +1,95 @@
From be20615859c518b3161b08ee63f5da5213eba91d Mon Sep 17 00:00:00 2001
From: Oyvind Albrigtsen <oalbrigt@redhat.com>
Date: Mon, 25 May 2020 14:03:53 +0200
Subject: [PATCH 1/2] fence_aws: catch ConnectionError and suppress traceback
for caught exceptions
---
agents/aws/fence_aws.py | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/agents/aws/fence_aws.py b/agents/aws/fence_aws.py
index 17c2fedb..191f5de1 100644
--- a/agents/aws/fence_aws.py
+++ b/agents/aws/fence_aws.py
@@ -9,14 +9,14 @@
from fencing import fail, fail_usage, run_delay, EC_STATUS, SyslogLibHandler
import boto3
-from botocore.exceptions import ClientError, EndpointConnectionError, NoRegionError
+from botocore.exceptions import ConnectionError, ClientError, EndpointConnectionError, NoRegionError
logger = logging.getLogger("fence_aws")
logger.propagate = False
logger.setLevel(logging.INFO)
logger.addHandler(SyslogLibHandler())
logging.getLogger('botocore.vendored').propagate = False
-
+
def get_instance_id():
try:
r = requests.get('http://169.254.169.254/latest/meta-data/instance-id')
@@ -38,6 +38,8 @@ def get_nodes_list(conn, options):
fail_usage("Failed: Incorrect Access Key or Secret Key.")
except EndpointConnectionError:
fail_usage("Failed: Incorrect Region.")
+ except ConnectionError as e:
+ fail_usage("Failed: Unable to connect to AWS: " + str(e))
except Exception as e:
logger.error("Failed to get node list: %s", e)
logger.debug("Monitor operation OK: %s",result)
@@ -169,7 +171,7 @@ def main():
if options["--boto3_debug"] != "on":
boto3.set_stream_logger('boto3',logging.INFO)
- boto3.set_stream_logger('botocore',logging.INFO)
+ boto3.set_stream_logger('botocore',logging.CRITICAL)
logging.getLogger('botocore').propagate = False
logging.getLogger('boto3').propagate = False
else:
@@ -197,4 +199,4 @@ def main():
sys.exit(result)
if __name__ == "__main__":
- main()
\ No newline at end of file
+ main()
From 50772024cffa60d05938d328bbd5cffd930f6b42 Mon Sep 17 00:00:00 2001
From: Oyvind Albrigtsen <oalbrigt@redhat.com>
Date: Mon, 25 May 2020 14:07:14 +0200
Subject: [PATCH 2/2] fence_aws: improve boto3_debug boolean handling
---
agents/aws/fence_aws.py | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/agents/aws/fence_aws.py b/agents/aws/fence_aws.py
index 191f5de1..483a2991 100644
--- a/agents/aws/fence_aws.py
+++ b/agents/aws/fence_aws.py
@@ -132,6 +132,7 @@ def define_new_opts():
"help" : "-b, --boto3_debug=[option] Boto3 and Botocore library debug logging",
"shortdesc": "Boto Lib debug",
"required": "0",
+ "default": "False",
"order": 5
}
@@ -146,7 +147,6 @@ def main():
define_new_opts()
all_opt["power_timeout"]["default"] = "60"
- all_opt["boto3_debug"]["default"] = "off"
options = check_input(device_opt, process_input(device_opt))
@@ -169,7 +169,7 @@ def main():
lh.setFormatter(lhf)
logger.setLevel(logging.DEBUG)
- if options["--boto3_debug"] != "on":
+ if options["--boto3_debug"].lower() not in ["1", "yes", "on", "true"]:
boto3.set_stream_logger('boto3',logging.INFO)
boto3.set_stream_logger('botocore',logging.CRITICAL)
logging.getLogger('botocore').propagate = False

View File

@ -29,7 +29,7 @@
Name: fence-agents
Summary: Set of unified programs capable of host isolation ("fencing")
Version: 4.2.1
Release: 39%{?alphatag:.%{alphatag}}%{?dist}
Release: 50%{?alphatag:.%{alphatag}}%{?dist}
License: GPLv2+ and LGPLv2+
Group: System Environment/Base
URL: https://github.com/ClusterLabs/fence-agents
@ -91,14 +91,30 @@ Patch49: bz1773890-fence_scsi-add-hash-key-value-support.patch
Patch50: bz1774458-fence_sbd-stderr-support.patch
Patch51: bz1771594-1-fencing-inetX_only-SSH-fence_zvmip.patch
Patch52: bz1771594-2-fence_redfish-fence_vmware_soap-suppress-warning.patch
Patch53: bz1781357-fence_aws-improve-logging-and-metadata-usage-text.patch
Patch54: bz1753228-fence_mpath-1-add-plug-parameter-support.patch
Patch55: bz1753228-fence_mpath-2-fix-plug-parameter-issues.patch
Patch56: bz1798641-fence_mpath-fix-reserve-parameter-typo.patch
Patch57: bz1810457-fence_aws-improve-parameter-logic.patch
Patch58: bz1816203-fence_aws-1-fix-race-condition.patch
Patch59: bz1816203-fence_aws-2-fix-python3-encoding.patch
Patch60: bz1827559-fence_vmware_rest-improve-exception-handling.patch
Patch61: bz1827652-fence_vmware_rest-1-add-filter-parameter.patch
Patch62: bz1827652-fence_vmware_rest-2-fix-1000-VM-monitor-error.patch
Patch63: bz1830776-fence_compute-fence_evacuate-fix-insecure-parameter.patch
Patch64: bz1750596-fence_scsi-add-readonly-parameter.patch
Patch65: bz1793739-fence_vmware_rest-1-fix-encoding.patch
Patch66: bz1793739-fence_vmware_rest-2-support-utf-8-vm-names.patch
Patch67: bz1839776-fence_aws-catch-connectionerror.patch
Patch68: bz1796654-fence_vmware_soap-log-exception-message-for-SSLError.patch
%if 0%{?fedora} || 0%{?rhel} > 7
%global supportedagents amt_ws apc apc_snmp bladecenter brocade cisco_mds cisco_ucs compute drac5 eaton_snmp emerson eps evacuate hpblade ibmblade ifmib ilo ilo_moonshot ilo_mp ilo_ssh intelmodular ipdu ipmilan mpath kdump redfish rhevm rsa rsb sbd scsi vmware_rest vmware_soap wti
%global supportedagents amt_ws apc apc_snmp bladecenter brocade cisco_mds cisco_ucs compute drac5 eaton_snmp emerson eps evacuate hpblade ibmblade ifmib ilo ilo_moonshot ilo_mp ilo_ssh intelmodular ipdu ipmilan kdump lpar mpath redfish rhevm rsa rsb sbd scsi vmware_rest vmware_soap wti
%ifarch x86_64
%global testagents virsh heuristics_ping aliyun aws azure_arm gce
%endif
%ifarch ppc64le
%global testagents virsh lpar heuristics_ping
%global testagents virsh heuristics_ping
%endif
%ifarch s390x
%global testagents virsh zvm heuristics_ping
@ -221,6 +237,22 @@ BuildRequires: python3-google-api-client
%patch50 -p1
%patch51 -p1
%patch52 -p1
%patch53 -p1
%patch54 -p1
%patch55 -p1
%patch56 -p1
%patch57 -p1
%patch58 -p1
%patch59 -p1
%patch60 -p1 -F1
%patch61 -p1
%patch62 -p1
%patch63 -p1
%patch64 -p1
%patch65 -p1 -F1
%patch66 -p1
%patch67 -p1
%patch68 -p1
# prevent compilation of something that won't get used anyway
sed -i.orig 's|FENCE_ZVM=1|FENCE_ZVM=0|' configure.ac
@ -819,7 +851,6 @@ Fence agent for use with kdump crash recovery service.
%{_mandir}/man8/fence_kdump.8*
%{_mandir}/man8/fence_kdump_send.8*
%ifarch ppc64le
%package lpar
License: GPLv2+ and LGPLv2+
Group: System Environment/Base
@ -833,7 +864,6 @@ Fence agent for IBM LPAR devices that are accessed via telnet or SSH.
%files lpar
%{_sbindir}/fence_lpar
%{_mandir}/man8/fence_lpar.8*
%endif
%package mpath
License: GPLv2+ and LGPLv2+
@ -1014,6 +1044,53 @@ Fence agent for IBM z/VM over IP.
%endif
%changelog
* Thu Jun 11 2020 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.2.1-50
- fence_vmware_soap: log exception message for SSLError exception
Resolves: rhbz#1796654
* Wed May 27 2020 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.2.1-49
- fence_aws: improve logging by catching ConnectionError exception
Resolves: rhbz#1839776
* Wed May 20 2020 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.2.1-48
- fence_vmware_rest: fix encoding issues
Resolves: rhbz#1793739
* Fri May 15 2020 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.2.1-47
- fence_vmware_rest: add filter parameter to avoid 1000 VM API limit
and avoid failing when hitting it during the monitor-action
Resolves: rhbz#1827652
- fence_compute/fence_evacuate: fix --insecure parameter
Resolves: rhbz#1830776
- fence_scsi: add readonly parameter
Resolves: rhbz#1750596
* Tue Apr 28 2020 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.2.1-45
- fence_vmware_rest: improve exception handling
Resolves: rhbz#1827559
* Tue Mar 24 2020 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.2.1-44
- fence_aws: fix possible race condition
Resolves: rhbz#1816203
* Fri Mar 13 2020 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.2.1-42
- fence-agents-lpar: build on non-ppc64le arch's
Resolves: rhbz#1804907
- fence_aws: improve parameter logic to allow setting region parameter
while using credentials from ~/.aws/config
Resolves: rhbz#1810457
* Thu Feb 13 2020 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.2.1-41
- fence_mpath: add plug parameter support to be able to use pcmk_host_map
Resolves: rhbz#1753228
- fence_mpath: fix --reserve parameter typo
Resolves: rhbz#1798641
* Fri Jan 31 2020 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.2.1-40
- fence_aws: improve logging and metadata/usage text
Resolves: rhbz#1781357
* Tue Nov 26 2019 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.2.1-39
- fencing: only use inetX_only parameters for SSH based agents and
fence_zvmip