Blame SOURCES/bz1387590-compute-fix-plug-domain-name-nova-force-down.patch

217e50
--- a/fence/agents/compute/fence_compute.py	2016-11-10 18:03:41.473498575 +1100
bf1da4
+++ b/fence/agents/compute/fence_compute.py	2016-11-10 12:45:28.766603941 +1100
bf1da4
@@ -45,7 +45,7 @@ def get_power_status(_, options):
bf1da4
 					else:
bf1da4
 						logging.debug("Unknown status detected from nova: " + service.state)
bf1da4
 					break
bf1da4
-		except ConnectionError as (err):
bf1da4
+		except ConnectionError as err:
bf1da4
 			logging.warning("Nova connection failed: " + str(err))
bf1da4
 	return status
bf1da4
 
bf1da4
@@ -160,7 +160,7 @@ def set_power_status(_, options):
bf1da4
 		return
bf1da4
 
bf1da4
 	if options["--action"] == "on":
bf1da4
-		if get_power_status(_, options) == "on":
bf1da4
+		if get_power_status(_, options) != "on":
bf1da4
 			# Forcing the service back up in case it was disabled
bf1da4
 			nova.services.enable(options["--plug"], 'nova-compute')
bf1da4
 			try:
bf1da4
@@ -168,7 +168,7 @@ def set_power_status(_, options):
bf1da4
 				nova.services.force_down(
bf1da4
 					options["--plug"], "nova-compute", force_down=False)
bf1da4
 			except Exception as e:
bf1da4
-				# In theory, if foce_down=False fails, that's for the exact
bf1da4
+				# In theory, if force_down=False fails, that's for the exact
bf1da4
 				# same possible reasons that below with force_down=True
bf1da4
 				# eg. either an incompatible version or an old client.
bf1da4
 				# Since it's about forcing back to a default value, there is
bf1da4
@@ -202,7 +202,7 @@ def set_power_status(_, options):
bf1da4
 			#
bf1da4
 			# Some callers (such as Pacemaker) will have a timer
bf1da4
 			# running and kill us if necessary
bf1da4
-			logging.debug("Waiting for nova to update it's internal state for %s" % options["--plug"])
bf1da4
+			logging.debug("Waiting for nova to update its internal state for %s" % options["--plug"])
bf1da4
 			time.sleep(1)
bf1da4
 
bf1da4
 	if not _host_evacuate(options):
bf1da4
@@ -236,49 +236,45 @@ def fix_domain(options):
bf1da4
 				# One hopes they don't appear interleaved as A.com B.com A.com B.com
bf1da4
 				logging.debug("Calculated the same domain from: %s" % hypervisor.hypervisor_hostname)
bf1da4
 
bf1da4
-			elif options.has_key("--domain") and options["--domain"] == calculated:
bf1da4
+			elif "--domain" in options and options["--domain"] == calculated:
bf1da4
 				# Supplied domain name is valid 
bf1da4
 				return
bf1da4
 
bf1da4
-			elif options.has_key("--domain"):
bf1da4
+			elif "--domain" in options:
bf1da4
 				# Warn in case nova isn't available at some point
bf1da4
 				logging.warning("Supplied domain '%s' does not match the one calculated from: %s"
bf1da4
 					      % (options["--domain"], hypervisor.hypervisor_hostname))
bf1da4
 
bf1da4
 			last_domain = calculated
bf1da4
 
bf1da4
-	if len(domains) == 0 and not options.has_key("--domain"):
bf1da4
+	if len(domains) == 0 and "--domain" not in options:
bf1da4
 		logging.error("Could not calculate the domain names used by compute nodes in nova")
bf1da4
 
bf1da4
-	elif len(domains) == 1 and not options.has_key("--domain"):
bf1da4
+	elif len(domains) == 1 and "--domain" not in options:
bf1da4
 		options["--domain"] = last_domain
bf1da4
-		return options["--domain"]
bf1da4
 
bf1da4
 	elif len(domains) == 1:
bf1da4
 		logging.error("Overriding supplied domain '%s' does not match the one calculated from: %s"
bf1da4
 			      % (options["--domain"], hypervisor.hypervisor_hostname))
bf1da4
 		options["--domain"] = last_domain
bf1da4
-		return options["--domain"]
bf1da4
 
bf1da4
 	elif len(domains) > 1:
bf1da4
 		logging.error("The supplied domain '%s' did not match any used inside nova: %s"
bf1da4
 			      % (options["--domain"], repr(domains)))
bf1da4
 		sys.exit(1)
bf1da4
 
bf1da4
-	return None
bf1da4
-
bf1da4
 def fix_plug_name(options):
bf1da4
 	if options["--action"] == "list":
bf1da4
 		return
bf1da4
 
bf1da4
-	if not options.has_key("--plug"):
bf1da4
+	if "--plug" not in options:
bf1da4
 		return
bf1da4
 
bf1da4
-	calculated = fix_domain(options)
bf1da4
+	fix_domain(options)
bf1da4
 	short_plug = options["--plug"].split('.')[0]
bf1da4
-	logging.debug("Checking target '%s' against calculated domain '%s'"% (options["--plug"], calculated))
bf1da4
+	logging.debug("Checking target '%s' against calculated domain '%s'"% (options["--plug"], options["--domain"]))
bf1da4
 
bf1da4
-	if not options.has_key("--domain"):
bf1da4
+	if "--domain" not in options:
bf1da4
 		# Nothing supplied and nova not available... what to do... nothing
bf1da4
 		return
bf1da4
 
bf1da4
@@ -286,7 +282,7 @@ def fix_plug_name(options):
bf1da4
 		# Ensure any domain is stripped off since nova isn't using FQDN
bf1da4
 		options["--plug"] = short_plug
bf1da4
 
bf1da4
-	elif options["--plug"].find(options["--domain"]):
bf1da4
+	elif options["--domain"] in options["--plug"]:
bf1da4
 		# Plug already contains the domain, don't re-add 
bf1da4
 		return
bf1da4
 
bf1da4
@@ -306,6 +302,37 @@ def get_plugs_list(_, options):
bf1da4
 			result[shorthost] = ("", None)
bf1da4
 	return result
bf1da4
 
bf1da4
+def create_nova_connection(options):
bf1da4
+	global nova
bf1da4
+
bf1da4
+	try:
bf1da4
+		from novaclient import client
bf1da4
+		from novaclient.exceptions import NotAcceptable
bf1da4
+	except ImportError:
bf1da4
+		fail_usage("Nova not found or not accessible")
bf1da4
+
bf1da4
+	versions = [ "2.11", "2" ]
bf1da4
+	for version in versions:
bf1da4
+		nova = client.Client(version,
bf1da4
+				     options["--username"],
bf1da4
+				     options["--password"],
bf1da4
+				     options["--tenant-name"],
bf1da4
+				     options["--auth-url"],
bf1da4
+				     insecure=options["--insecure"],
bf1da4
+				     region_name=options["--region-name"],
bf1da4
+				     endpoint_type=options["--endpoint-type"],
bf1da4
+				     http_log_debug=options.has_key("--verbose"))
bf1da4
+		try:
bf1da4
+			nova.hypervisors.list()
bf1da4
+			return
bf1da4
+
bf1da4
+		except NotAcceptable as e:
bf1da4
+			logging.warning(e)
bf1da4
+
bf1da4
+		except Exception as e:
bf1da4
+			logging.warning("Nova connection failed. %s: %s" % (e.__class__.__name__, e))
bf1da4
+			
217e50
+	logging.warning("Couldn't obtain a supported connection to nova, tried: %s\n" % repr(versions))
bf1da4
 
bf1da4
 def define_new_opts():
bf1da4
 	all_opt["endpoint-type"] = {
bf1da4
@@ -329,12 +356,30 @@ def define_new_opts():
bf1da4
 	all_opt["auth-url"] = {
bf1da4
 		"getopt" : "k:",
bf1da4
 		"longopt" : "auth-url",
bf1da4
-		"help" : "-k, --auth-url=[tenant]        Keystone Admin Auth URL",
bf1da4
+		"help" : "-k, --auth-url=[url]           Keystone Admin Auth URL",
bf1da4
 		"required" : "0",
bf1da4
 		"shortdesc" : "Keystone Admin Auth URL",
bf1da4
 		"default" : "",
bf1da4
 		"order": 1,
bf1da4
 	}
bf1da4
+	all_opt["region-name"] = {
bf1da4
+		"getopt" : "",
bf1da4
+		"longopt" : "region-name",
bf1da4
+		"help" : "--region-name=[region]         Region Name",
bf1da4
+		"required" : "0",
bf1da4
+		"shortdesc" : "Region Name",
bf1da4
+		"default" : "",
bf1da4
+		"order": 1,
bf1da4
+	}
bf1da4
+	all_opt["insecure"] = {
bf1da4
+		"getopt" : "",
bf1da4
+		"longopt" : "insecure",
bf1da4
+		"help" : "--insecure                     Explicitly allow agent to perform \"insecure\" TLS (https) requests",
bf1da4
+		"required" : "0",
bf1da4
+		"shortdesc" : "Allow Insecure TLS Requests",
bf1da4
+		"default" : "False",
bf1da4
+		"order": 2,
bf1da4
+	}
bf1da4
 	all_opt["domain"] = {
bf1da4
 		"getopt" : "d:",
bf1da4
 		"longopt" : "domain",
bf1da4
@@ -373,12 +418,11 @@ def define_new_opts():
bf1da4
 
bf1da4
 def main():
bf1da4
 	global override_status
bf1da4
-	global nova
bf1da4
 	atexit.register(atexit_handler)
bf1da4
 
bf1da4
 	device_opt = ["login", "passwd", "tenant-name", "auth-url", "fabric_fencing", "on_target",
bf1da4
 		"no_login", "no_password", "port", "domain", "no-shared-storage", "endpoint-type",
bf1da4
-		"record-only", "instance-filtering"]
bf1da4
+		"record-only", "instance-filtering", "insecure", "region-name"]
bf1da4
 	define_new_opts()
bf1da4
 	all_opt["shell_timeout"]["default"] = "180"
bf1da4
 
bf1da4
@@ -391,19 +435,15 @@ def main():
bf1da4
 
bf1da4
 	show_docs(options, docs)
bf1da4
 
bf1da4
+	if options["--record-only"] in [ "2", "Disabled", "disabled" ]:
bf1da4
+		sys.exit(0)
bf1da4
+
bf1da4
 	run_delay(options)
bf1da4
 
bf1da4
-	try:
bf1da4
-		from novaclient import client as nova_client
bf1da4
-	except ImportError:
bf1da4
-		fail_usage("nova not found or not accessible")
bf1da4
+	create_nova_connection(options)
bf1da4
 
bf1da4
 	fix_plug_name(options)
bf1da4
-
bf1da4
-	if options["--record-only"] in [ "2", "Disabled", "disabled" ]:
bf1da4
-		sys.exit(0)
bf1da4
-
bf1da4
-	elif options["--record-only"] in [ "1", "True", "true", "Yes", "yes"]:
bf1da4
+	if options["--record-only"] in [ "1", "True", "true", "Yes", "yes"]:
bf1da4
 		if options["--action"] == "on":
bf1da4
 			set_attrd_status(options["--plug"], "no", options)
bf1da4
 			sys.exit(0)
bf1da4
@@ -412,17 +452,9 @@ def main():
bf1da4
 			set_attrd_status(options["--plug"], "yes", options)
bf1da4
 			sys.exit(0)
bf1da4
 
bf1da4
-		elif options["--action"] in ["monitor"]:
bf1da4
+		elif options["--action"] in ["monitor", "status"]:
bf1da4
 			sys.exit(0)
bf1da4
 
bf1da4
-	# The first argument is the Nova client version
bf1da4
-	nova = nova_client.Client('2',
bf1da4
-		options["--username"],
bf1da4
-		options["--password"],
bf1da4
-		options["--tenant-name"],
bf1da4
-		options["--auth-url"],
bf1da4
-		endpoint_type=options["--endpoint-type"])
bf1da4
-
bf1da4
 	if options["--action"] in ["off", "reboot"]:
bf1da4
 		# Pretend we're 'on' so that the fencing library will always call set_power_status(off)
bf1da4
 		override_status = "on"