def soap_login(options):
	run_delay(options)

	if options.has_key("--ssl") or options.has_key("--ssl-secure") or options.has_key("--ssl-insecure"):
		if options.has_key("--ssl-insecure"):
			verify = False
		else:
			verify = True
		url = "https://"
	else:
		verify = False
		url = "http://"

	url += options["--ip"] + ":" + str(options["--ipport"]) + "/sdk"

	tmp_dir = tempfile.mkdtemp()
	tempfile.tempdir = tmp_dir
	atexit.register(remove_tmp_dir, tmp_dir)

	try:
		headers = {"Content-Type" : "text/xml;charset=UTF-8", "SOAPAction" : ""}
		conn = Client(url + "/vimService.wsdl", location=url, transport=RequestsTransport(verify=verify), headers=headers)

		mo_ServiceInstance = Property('ServiceInstance')
		mo_ServiceInstance._type = 'ServiceInstance'
		ServiceContent = conn.service.RetrieveServiceContent(mo_ServiceInstance)
		mo_SessionManager = Property(ServiceContent.sessionManager.value)
		mo_SessionManager._type = 'SessionManager'

		conn.service.Login(mo_SessionManager, options["--username"], options["--password"])
	except requests.exceptions.SSLError, ex:
		fail_usage("Server side certificate verification failed")
Beispiel #2
0
def get_reservation_key(options, dev):
	cmd = options["--sg_persist-path"] + " -n -i -r -d " + dev
	out = run_cmd(options, cmd)
	if out["err"]:
		fail_usage("Cannot get reservation key")
	match = re.search(r"\s+key=0x(\S+)\s+", out["out"], re.IGNORECASE)
	return match.group(1) if match else None
Beispiel #3
0
def get_key():
	file_path = STORE_PATH + ".key"
	try:
		f = open(file_path, "r")
	except IOError:
		fail_usage("Failed: Cannot open file \""+ file_path + "\"")
	return f.readline().strip().lower()
Beispiel #4
0
def vmware_get_outlets_vi(options, add_vm_name):
	outlets = {}

	if add_vm_name:
		all_machines = vmware_run_command(options, True,
				("--operation status --vmname '%s'"% (quote_for_run(options["--plug"]))), 0)
	else:
		all_machines = vmware_run_command(options, True, "--operation list", int(options["--power-timeout"]))

	all_machines_array = all_machines.splitlines()

	for machine in all_machines_array:
		machine_array = dsv_split(machine)
		if len(machine_array) == 4:
			if machine_array[0] in outlets:
				fail_usage("Failed. More machines with same name %s found!"%(machine_array[0]))

			if vmware_disconnected_hack:
				outlets[machine_array[0]] = ("", (
						((machine_array[2].lower() in ["poweredon"]) and
						 (machine_array[3].lower() == "connected"))
						and "on" or "off"))
			else:
				outlets[machine_array[0]] = ("", ((machine_array[2].lower() in ["poweredon"]) and "on" or "off"))
	return outlets
Beispiel #5
0
def get_power_status(conn, options):
	start_communication(conn, options)

	conn.send_eol("ldm ls")

	conn.log_expect(options, COMMAND_PROMPT_REG, int(options["--shell-timeout"]))

	result = {}

	#This is status of mini finite automata. 0 = we didn't found NAME and STATE, 1 = we did
	fa_status = 0

	for line in conn.before.splitlines():
		domain = re.search(r"^(\S+)\s+(\S+)\s+.*$", line)

		if domain != None:
			if fa_status == 0 and domain.group(1) == "NAME" and domain.group(2) == "STATE":
				fa_status = 1
			elif fa_status == 1:
				result[domain.group(1)] = ("", (domain.group(2).lower()=="bound" and "off" or "on"))

	if not options["--action"] in ['monitor','list']:
		if not options["--plug"] in result:
			fail_usage("Failed: You have to enter existing logical domain!")
		else:
			return result[options["--plug"]][1]
	else:
		return result
Beispiel #6
0
def main():
	atexit.register(atexit_handler)

	device_opt = [ "ipaddr", "no_login", "passwd", "boot_option", "no_port",
		"sudo", "amttool_path", "method" ]

	define_new_opts()

	options = check_input(device_opt, process_input(device_opt))

	docs = { }
	docs["shortdesc"] = "Fence agent for AMT"
	docs["longdesc"] = "fence_amt is an I/O Fencing agent \
which can be used with Intel AMT. This agent calls support software amttool\
(http://www.kraxel.org/cgit/amtterm/)."
	docs["vendorurl"] = "http://www.intel.com/"
	show_docs(options, docs)

	run_delay(options)

	if not is_executable(options["--amttool-path"]):
		fail_usage("Amttool not found or not accessible")

	result = fence_action(None, options, set_power_status, get_power_status, None, reboot_cycle)

	sys.exit(result)
Beispiel #7
0
def get_lpar_list(conn, options):
	outlets = {}
	if options["--hmc-version"] == "3":
		conn.send("query_partition_names -m " + options["--managed"] + "\n")
		conn.log_expect(options["--command-prompt"], int(options["--power-timeout"]))

		## We have to remove first 3 lines (command + header) and last line (part of new prompt)
		####
		res = re.search("^.+?\n(.+?\n){2}(.*)\n.*$", conn.before, re.S)

		if res == None:
			fail_usage("Unable to parse output of list command")

		lines = res.group(2).split("\n")
		for outlet_line in lines:
			outlets[outlet_line.rstrip()] = ("", "")
	elif options["--hmc-version"] == "4":
		conn.send("lssyscfg -r lpar -m " + options["--managed"] +
			" -F name:state\n")
		conn.log_expect(options["--command-prompt"], int(options["--power-timeout"]))

		## We have to remove first line (command) and last line (part of new prompt)
		####
		res = re.search("^.+?\n(.*)\n.*$", conn.before, re.S)

		if res == None:
			fail_usage("Unable to parse output of list command")

		lines = res.group(1).split("\n")
		for outlet_line in lines:
			(port, status) = outlet_line.split(":")
			outlets[port] = ("", status)

	return outlets
Beispiel #8
0
def main():
	device_opt = ["ipaddr", "login", "passwd", "secure", "cmd_prompt", \
	                "port", "managed", "hmc_version"]

	atexit.register(atexit_handler)

	define_new_opts()

	all_opt["login_timeout"]["default"] = "15"
	all_opt["secure"]["default"] = "1"
	all_opt["cmd_prompt"]["default"] = [r":~>", r"]\$", r"\$ "]

	options = check_input(device_opt, process_input(device_opt), other_conditions = True)

	docs = {}
	docs["shortdesc"] = "Fence agent for IBM LPAR"
	docs["longdesc"] = ""
	docs["vendorurl"] = "http://www.ibm.com"
	show_docs(options, docs)

	if "--managed" not in options:
		fail_usage("Failed: You have to enter name of managed system")

	if options["--action"] == "validate-all":
		sys.exit(0)

	##
	## Operate the fencing device
	####
	conn = fence_login(options)
	result = fence_action(conn, options, set_power_status, get_power_status, get_lpar_list)
	fence_logout(conn, "quit\r\n")
	sys.exit(result)
Beispiel #9
0
def main():
	conn = None

	device_opt = ["port", "no_password", "zone", "project"]

	atexit.register(atexit_handler)

	define_new_opts()

	all_opt["power_timeout"]["default"] = "60"

	options = check_input(device_opt, process_input(device_opt))

	docs = {}
	docs["shortdesc"] = "Fence agent for GCE (Google Cloud Engine)"
	docs["longdesc"] = "fence_gce is an I/O Fencing agent for GCE (Google Cloud " \
			   "Engine). It uses the googleapiclient library to connect to GCE.\n" \
			   "googleapiclient can be configured with Google SDK CLI or by " \
			   "executing 'gcloud auth application-default login'.\n" \
			   "For instructions see: https://cloud.google.com/compute/docs/tutorials/python-guide"
	docs["vendorurl"] = "http://cloud.google.com"
	show_docs(options, docs)

	run_delay(options)

	try:
		credentials = GoogleCredentials.get_application_default()
		conn = discovery.build('compute', 'v1', credentials=credentials)
	except:
		fail_usage("Failed: Unable to connect to GCE. Check your configuration.")

	# Operate the fencing device
	result = fence_action(conn, options, set_power_status, get_power_status, get_nodes_list)
	sys.exit(result)
Beispiel #10
0
def get_power_status(_, options):
	global override_status

	status = "unknown"
	logging.debug("get action: " + options["--action"])

	if len(override_status):
		logging.debug("Pretending we're " + override_status)
		return override_status

	if nova:
		try:
			services = nova.services.list(host=options["--plug"])
		except Exception, e:
			fail_usage(str(e))

		for service in services:
			if service.binary == "nova-compute":
				if service.state == "up":
					status = "on"
				elif service.state == "down":
					status = "off"
				else:
					logging.debug("Unknown status detected from nova: " + service.state)
				break
Beispiel #11
0
def get_power_status_fail(conn, options):
	outlets = get_outlets_fail(conn, options)

	if len(outlets) == 0 or "--plug" not in options:
		fail_usage("Failed: You have to enter existing machine!")
	else:
		return outlets[options["--plug"]][0]
Beispiel #12
0
def apc_resolv_port_id(conn, options):
	global port_id, switch_id

	if device == None:
		apc_set_device(conn)

	# Now we resolv port_id/switch_id
	if (options["--plug"].isdigit()) and ((not device.has_switches) or (options["--switch"].isdigit())):
		port_id = int(options["--plug"])

		if device.has_switches:
			switch_id = int(options["--switch"])
	else:
		table = conn.walk(device.outlet_table_oid, 30)

		for x in table:
			if x[1].strip('"') == options["--plug"]:
				t = x[0].split('.')
				if device.has_switches:
					port_id = int(t[len(t)-1])
					switch_id = int(t[len(t)-3])
				else:
					port_id = int(t[len(t)-1])

	if port_id == None:
		fail_usage("Can't find port with name %s!"%(options["--plug"]))
def cisco_port2oid(port):
	port = port.lower()

	nums = re.match(r'^fc(\d+)/(\d+)$', port)

	if nums and len(nums.groups()) == 2:
		return "%s.%d.%d"% (PORT_ADMIN_STATUS_OID, int(nums.group(1))+21, int(nums.group(2))-1)
	else:
		fail_usage("Mangled port number: %s"%(port))
Beispiel #14
0
def get_key(fail=True):
    file_path = STORE_PATH + ".key"
    try:
        f = open(file_path, "r")
    except IOError:
        if fail:
            fail_usage('Failed: Cannot open file "' + file_path + '"')
        else:
            return None
    return f.readline().strip().lower()
Beispiel #15
0
def set_key(options):
	file_path = options["store_path"] + ".key"
	if not os.path.isdir(os.path.dirname(options["store_path"])):
		os.makedirs(os.path.dirname(options["store_path"]))
	try:
		f = open(file_path, "w")
	except IOError:
		fail_usage("Failed: Cannot open file \""+ file_path + "\"")
	f.write(options["--key"].lower() + "\n")
	f.close()
Beispiel #16
0
def dev_read():
	file_path = STORE_PATH + ".dev"
	try:
		f = open(file_path, "r")
	except IOError:
		fail_usage("Failed: Cannot open file \"" + file_path + "\"")
	# get not empty lines from file
	devs = [line.strip() for line in f if line.strip()]
	f.close()
	return devs
Beispiel #17
0
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",
    ]

    define_new_opts()

    options = check_input(device_opt, process_input(device_opt), other_conditions=True)

    docs = {}
    docs["shortdesc"] = "Fence agent for multipath persistent reservation"
    docs[
        "longdesc"
    ] = 'fence_mpath is an I/O fencing agent that uses SCSI-3 \
persistent reservations to control access multipath devices. Underlying \
devices must support SCSI-3 persistent reservations (SPC-3 or greater) as \
well as the "preempt-and-abort" subcommand.\nThe fence_mpath agent works by \
having a unique key for each node that has to be set in /etc/multipath.conf. \
Once registered, a single node will become the reservation holder \
by creating a "write exclusive, registrants only" reservation on the \
device(s). The result is that only registered nodes may write to the \
device(s). When a node failure occurs, the fence_mpath agent will remove the \
key belonging to the failed node from the device(s). The failed node will no \
longer be able to write to the device(s). A manual reboot is required.'
    docs["vendorurl"] = "https://www.sourceware.org/dm/"
    show_docs(options, docs)

    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"]:
        fail_usage("Failed: No devices found")
        # Input control END

    result = fence_action(None, options, set_status, get_status)
    sys.exit(result)
Beispiel #18
0
def set_power_status(conn, options):
	try:
		if (options["--action"]=="off"):
			conn.instances().stop(project=options["--project"], zone=options["--zone"],
							instance=options["--plug"]).execute()
		elif (options["--action"]=="on"):
			conn.instances().start(project=options["--project"], zone=options["--zone"],
							instance=options["--plug"]).execute()
	# TODO: check which Exceptions it can throw
	except :
		fail_usage("Failed: Unable to connect to GCE. Check your configuration.")
Beispiel #19
0
def get_nodes_list(conn, options):
	result = {}
	try:
		for instance in conn.instances.all():
			result[instance.id] = ("", None)
	except ClientError:
		fail_usage("Failed: Incorrect Access Key or Secret Key.")
	except EndpointConnectionError:
		fail_usage("Failed: Incorrect Region.")

	return result
Beispiel #20
0
def get_registration_keys(options, dev):
	keys = []
	cmd = options["--sg_persist-path"] + " -n -i -k -d " + dev
	out = run_cmd(options, cmd)
	if out["err"]:
		fail_usage("Cannot get registration keys")
	for line in out["out"].split("\n"):
		match = re.search(r"\s+0x(\S+)\s*", line)
		if match:
			keys.append(match.group(1))
	return keys
Beispiel #21
0
def dev_read(options):
	dev_key = {}
	file_path = options["--store-path"] + "/mpath.devices"
	try:
		store_fh = open(file_path, "r")
	except IOError:
		fail_usage("Failed: Cannot open file \"" + file_path + "\"")
	# get not empty lines from file
	for (device, key) in [line.strip().split() for line in store_fh if line.strip()]:
		dev_key[device] = key
	store_fh.close()
	return dev_key
Beispiel #22
0
def get_nodes_list(compute_client, options):
    result = {}
    if compute_client:
        rgName = options["--resourceGroup"]
        vms = compute_client.virtual_machines.list(rgName)
        try:
            for vm in vms:
                result[vm.name] = ("", None)
        except Exception as e:
            fail_usage("Failed: %s" % e)

    return result
Beispiel #23
0
def dev_write(dev, options):
	file_path = options["store_path"] + ".dev"
	if not os.path.isdir(os.path.dirname(options["store_path"])):
		os.makedirs(os.path.dirname(options["store_path"]))
	try:
		f = open(file_path, "a+")
	except IOError:
		fail_usage("Failed: Cannot open file \""+ file_path + "\"")
	out = f.read()
	if not re.search(r"^" + dev + "\s+", out):
		f.write(dev + "\n")
	f.close()
Beispiel #24
0
def main():
	atexit.register(atexit_handler)

	device_opt = ["ipaddr", "login", "no_login", "no_password", "passwd",
		"diag", "lanplus", "auth", "cipher", "privlvl", "sudo",
		"ipmitool_path", "method", "target", "hexadecimal_kg"]
	define_new_opts()

	all_opt["power_wait"]["default"] = 2
	if os.path.basename(sys.argv[0]) == "fence_ilo3":
		all_opt["power_wait"]["default"] = "4"
		all_opt["method"]["default"] = "cycle"
		all_opt["lanplus"]["default"] = "1"
	elif os.path.basename(sys.argv[0]) == "fence_ilo4":
		all_opt["lanplus"]["default"] = "1"

	all_opt["ipport"]["default"] = "623"
	if all_opt["method"]["default"] == "cycle":
		all_opt["method"]["help"] = "-m, --method=[method]          Method to fence (onoff|cycle) (Default: cycle)\n" \
				    "WARNING! This fence agent might report success before the node is powered off. " \
				    "You should use -m/method onoff if your fence device works correctly with that option."

	options = check_input(device_opt, process_input(device_opt))

	docs = {}
	docs["shortdesc"] = "Fence agent for IPMI"
	docs["longdesc"] = "fence_ipmilan is an I/O Fencing agent\
which can be used with machines controlled by IPMI.\
This agent calls support software ipmitool (http://ipmitool.sf.net/). \
WARNING! This fence agent might report success before the node is powered off. \
You should use -m/method onoff if your fence device works correctly with that option."
	docs["vendorurl"] = ""
	docs["symlink"] = [("fence_ilo3", "Fence agent for HP iLO3"),
		("fence_ilo4", "Fence agent for HP iLO4"),
		("fence_imm", "Fence agent for IBM Integrated Management Module"),
		("fence_idrac", "Fence agent for Dell iDRAC")]
	show_docs(options, docs)

	run_delay(options)

	if not is_executable(options["--ipmitool-path"]):
		fail_usage("Ipmitool not found or not accessible")

	reboot_fn = reboot_cycle
	if options["--action"] == "diag":
		# Diag is a special action that can't be verified so we will reuse reboot functionality
		# to minimize impact on generic library
		options["--action"] = "reboot"
		options["--method"] = "cycle"
		reboot_fn = reboot_diag

	result = fence_action(None, options, set_power_status, get_power_status, None, reboot_fn)
	sys.exit(result)
def get_power_status(conn, options):
	prefix = SUDO_PATH + " " if options.has_key("--use-sudo") else ""
	conn.sendline(prefix + "virsh domstate %s" % (get_name_or_uuid(options)))
	conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"]))

	for line in conn.before.splitlines():
		if line.strip() in ["running", "blocked", "idle", "no state", "paused"]:
			return "on"
		if "error:" in line.strip():
			fail_usage("Failed: You have to enter existing name/UUID of virtual machine!")

	return "off"
Beispiel #26
0
def main():
    compute_client = None

    device_opt = ["resourceGroup", "login", "passwd", "tenantId", "subscriptionId","port"]

    atexit.register(atexit_handler)

    define_new_opts()

    all_opt["power_timeout"]["default"] = "150"

    all_opt["login"]["help"] = "-l, --username=[appid]         Application ID"
    all_opt["passwd"]["help"] = "-p, --password=[authkey]       Authentication key"

    options = check_input(device_opt, process_input(device_opt))

    docs = {}
    docs["shortdesc"] = "Fence agent for Azure Resource Manager"
    docs["longdesc"] = "Used to deallocate virtual machines and to report power state of virtual machines running in Azure. It uses Azure SDK for Python to connect to Azure.\
\n.P\n\
For instructions to setup credentials see: https://docs.microsoft.com/en-us/azure/azure-resource-manager/resource-group-create-service-principal-portal\
\n.P\n\
Username and password are application ID and authentication key from \"App registrations\"."
    docs["vendorurl"] = "http://www.microsoft.com"
    show_docs(options, docs)

    run_delay(options)

    try:
        from azure.common.credentials import ServicePrincipalCredentials
        from azure.mgmt.compute import ComputeManagementClient

        tenantid = options["--tenantId"]
        servicePrincipal = options["--username"]
        spPassword = options["--password"]
        subscriptionId = options["--subscriptionId"]
        credentials = ServicePrincipalCredentials(
            client_id = servicePrincipal,
            secret = spPassword,
            tenant = tenantid
        )
        compute_client = ComputeManagementClient(
            credentials,
            subscriptionId
        )
    except ImportError:
        fail_usage("Azure Resource Manager Python SDK not found or not accessible")
    except Exception as e:
        fail_usage("Failed: %s" % re.sub("^, ", "", str(e)))

    # Operate the fencing device
    result = fence_action(compute_client, options, set_power_status, get_power_status, get_nodes_list)
    sys.exit(result)
Beispiel #27
0
def main():
	device_opt = ["ipaddr", "login", "passwd", "secure",
		       "exec", "vmware_type", "vmware_datacenter"]

	atexit.register(atexit_handler)

	all_opt["secure"]["default"] = "1"
	all_opt["vmware_type"]["default"] = VMWARE_DEFAULT_TYPE

	options = check_input(device_opt, process_input(device_opt))

	docs = {}
	docs["shortdesc"] = "Fence agent for VMWare"
	docs["longdesc"] = "fence_vmware is an I/O Fencing agent \
which can be used with the VMware ESX, VMware ESXi or VMware Server \
to fence virtual machines.\
\n.P\n\
Before you can use this agent, it must be installed VI Perl Toolkit or \
vmrun command on every node you want to make fencing.\
\n.P\n\
VI Perl Toolkit is preferred for VMware ESX/ESXi and Virtual Center. Vmrun \
command is only solution for VMware Server 1/2 (this command will works against \
ESX/ESXi 3.5 up2 and VC up2 too, but not cluster aware!) and is available as part \
of VMware VIX API SDK package. VI Perl and VIX API SDK are both available from \
VMware web pages (not int RHEL repository!). \
\n.P\n\
You can specify type of VMware you are connecting to with \\fB-d\\fP switch \
(or \\fIvmware_type\\fR for stdin). Possible values are esx, server2 and server1.\
Default value is esx, which will use VI Perl. With server1 and server2, vmrun \
command is used.\
\n.P\n\
After you have successfully installed VI Perl Toolkit or VIX API, you should \
be able to run fence_vmware_helper (part of this agent) or vmrun command. \
This agent supports only vmrun from version 2.0.0 (VIX API 1.6.0)."
	docs["vendorurl"] = "http://www.vmware.com"
	show_docs(options, docs)

	run_delay(options)

	# Check vmware type and set path
	vmware_check_vmware_type(options)

	# Test user vmrun command version
	if vmware_internal_type == VMWARE_TYPE_SERVER1 or vmware_internal_type == VMWARE_TYPE_SERVER2:
		if not vmware_is_supported_vmrun_version(options):
			fail_usage("Unsupported version of vmrun command! You must use at least version %d!" %
					(VMRUN_MINIMUM_REQUIRED_VERSION))

	# Operate the fencing device
	result = fence_action(None, options, set_power_status, get_power_status, get_outlets_status)

	sys.exit(result)
Beispiel #28
0
def dev_read(fail=True):
    file_path = STORE_PATH + ".dev"
    try:
        f = open(file_path, "r")
    except IOError:
        if fail:
            fail_usage('Failed: Cannot open file "' + file_path + '"')
        else:
            return None
            # get not empty lines from file
    devs = [line.strip() for line in f if line.strip()]
    f.close()
    return devs
Beispiel #29
0
def get_power_status(conn, options):
	try:
		instance = conn.instances().get(project=options["--project"], zone=options["--zone"],
						instance=options["--plug"]).execute()
		if instance["status"] == "RUNNING":
			return "on"
		elif instance["status"] == "TERMINATED":
			return "off"
		else:
			return "unknown"
	# TODO: check which Exceptions it can throw
	except:
		fail_usage("Failed: Unable to connect to GCE. Check your configuration.")
Beispiel #30
0
def get_power_status(conn, options):
	if vmware_internal_type == VMWARE_TYPE_ESX:
		outlets = vmware_get_outlets_vi(options, True)
	else:
		outlets = get_outlets_status(conn, options)

	if vmware_internal_type == VMWARE_TYPE_SERVER2 or vmware_internal_type == VMWARE_TYPE_ESX:
		if not options["--plug"] in outlets:
			fail_usage("Failed: You have to enter existing name of virtual machine!")
		else:
			return outlets[options["--plug"]][1]
	elif vmware_internal_type == VMWARE_TYPE_SERVER1:
		return (options["--plug"] in outlets) and "on" or "off"
Beispiel #31
0
def main():
    """Main function
    """
    # We need to define "no_password" otherwise we will be ask about it if
    # we don't provide any password.
    device_opt = ["no_password", "devices", "port", "method", "sbd_path"]

    # close stdout if we get interrupted
    atexit.register(atexit_handler)

    define_new_opts()

    all_opt["method"]["default"] = "cycle"
    all_opt["method"][
        "help"] = "-m, --method=[method]          Method to fence (onoff|cycle) (Default: cycle)"

    options = check_input(device_opt, process_input(device_opt))

    # fill the needed variables to generate metadata and help text output
    docs = {}
    docs["shortdesc"] = "Fence agent for sbd"
    docs["longdesc"] = "fence_sbd is I/O Fencing agent \
which can be used in environments where sbd can be used (shared storage)."

    docs["vendorurl"] = ""
    show_docs(options, docs)

    # We need to check if --devices is given and not empty.
    if "--devices" not in options:
        fail_usage("No SBD devices specified. \
                At least one SBD device is required.")

    run_delay(options)

    # We need to check if the provided sbd_devices exists. We need to do
    # that for every given device.
    for device_path in parse_sbd_devices(options):
        logging.debug("check device \"%s\"", device_path)

        return_code = check_sbd_device(options, device_path)
        if PATH_NOT_EXISTS == return_code:
            logging.error("\"%s\" does not exist", device_path)
        elif PATH_NOT_BLOCK == return_code:
            logging.error("\"%s\" is not a valid block device", device_path)
        elif DEVICE_NOT_INIT == return_code:
            logging.error("\"%s\" is not initialized", device_path)
        elif DEVICE_INIT != return_code:
            logging.error("UNKNOWN error while checking \"%s\"", device_path)

        # If we get any error while checking the device we need to exit at this
        # point.
        if DEVICE_INIT != return_code:
            exit(return_code)

    # we check against the defined timeouts. If the pacemaker timeout is smaller
    # then that defined within sbd we should report this.
    power_timeout = int(options["--power-timeout"])
    sbd_msg_timeout = get_msg_timeout(options)
    if power_timeout <= sbd_msg_timeout:
        logging.warn("power timeout needs to be \
                greater then sbd message timeout")

    result = fence_action(\
                None, \
                options, \
                set_power_status, \
                get_power_status, \
                get_node_list, \
                reboot_cycle)

    sys.exit(result)
Beispiel #32
0
def create_nova_connection(options):
    nova = None

    try:
        from novaclient import client
        from novaclient.exceptions import NotAcceptable
    except ImportError:
        fail_usage("Nova not found or not accessible")

    from keystoneauth1 import loading
    from keystoneauth1 import session
    from keystoneclient import discover

    # Prefer the oldest and strip the leading 'v'
    keystone_versions = discover.available_versions(options["--auth-url"])
    keystone_version = keystone_versions[0]['id'][1:]
    kwargs = dict(auth_url=options["--auth-url"],
                  username=options["--username"],
                  password=options["--password"])

    if discover.version_match("2", keystone_version):
        kwargs["tenant_name"] = options["--tenant-name"]

    elif discover.version_match("3", keystone_version):
        kwargs["project_name"] = options["--tenant-name"]
        kwargs["user_domain_name"] = options["--user-domain"]
        kwargs["project_domain_name"] = options["--project-domain"]

    loader = loading.get_plugin_loader('password')
    keystone_auth = loader.load_from_options(**kwargs)
    keystone_session = session.Session(auth=keystone_auth,
                                       verify=not "--insecure" in options)

    versions = ["2.11", "2"]
    for version in versions:
        clientargs = inspect.getargspec(client.Client).varargs

        # Some versions of Openstack prior to Ocata only
        # supported positional arguments for username,
        # password, and tenant.
        #
        # Versions since Ocata only support named arguments.
        #
        # So we need to use introspection to figure out how to
        # create a Nova client.
        #
        # Happy days
        #
        if clientargs:
            # OSP < 11
            # ArgSpec(args=['version', 'username', 'password', 'project_id', 'auth_url'],
            #	 varargs=None,
            #	 keywords='kwargs', defaults=(None, None, None, None))
            nova = client.Client(
                version,
                None,  # User
                None,  # Password
                None,  # Tenant
                None,  # Auth URL
                insecure="--insecure" in options,
                region_name=options["--region-name"],
                endpoint_type=options["--endpoint-type"],
                session=keystone_session,
                auth=keystone_auth,
                http_log_debug="--verbose" in options)
        else:
            # OSP >= 11
            # ArgSpec(args=['version'], varargs='args', keywords='kwargs', defaults=None)
            nova = client.Client(version,
                                 region_name=options["--region-name"],
                                 endpoint_type=options["--endpoint-type"],
                                 session=keystone_session,
                                 auth=keystone_auth,
                                 http_log_debug="--verbose" in options)

        try:
            nova.hypervisors.list()
            return nova

        except NotAcceptable as e:
            logging.warning(e)

        except Exception as e:
            logging.warning("Nova connection failed. %s: %s" %
                            (e.__class__.__name__, e))

    logging.warning(
        "Couldn't obtain a supported connection to nova, tried: %s\n" %
        repr(versions))
    return None
Beispiel #33
0
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", "port", "no_port"]

	define_new_opts()

	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 \
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())
	elif os.path.basename(sys.argv[0]) == "fence_mpath_check_hardreboot":
		sys.exit(mpath_check(hardreboot=True))

	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 "--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"
	docs["longdesc"] = "fence_mpath is an I/O fencing agent that uses SCSI-3 \
persistent reservations to control access multipath devices. Underlying \
devices must support SCSI-3 persistent reservations (SPC-3 or greater) as \
well as the \"preempt-and-abort\" subcommand.\nThe fence_mpath agent works by \
having a unique key for each node that has to be set in /etc/multipath.conf. \
Once registered, a single node will become the reservation holder \
by creating a \"write exclusive, registrants only\" reservation on the \
device(s). The result is that only registered nodes may write to the \
device(s). When a node failure occurs, the fence_mpath agent will remove the \
key belonging to the failed node from the device(s). The failed node will no \
longer be able to write to the device(s). A manual reboot is required."
	docs["vendorurl"] = "https://www.sourceware.org/dm/"
	show_docs(options, docs)

	run_delay(options)

	# Input control BEGIN
	if options["--action"] == "validate-all":
		sys.exit(0)

	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)
	sys.exit(result)
Beispiel #34
0
def main():
    conn = None

    device_opt = [
        "login",
        "passwd",
        "auth-url",
        "project-name",
        "user-domain-name",
        "project-domain-name",
        "port",
        "no_port",
        "uuid",
        "cacert",
        "apitimeout",
    ]

    atexit.register(atexit_handler)

    define_new_opts()

    all_opt["port"]["required"] = "0"
    all_opt["port"][
        "help"] = "-n, --plug=[UUID]              UUID of the node to be fenced"
    all_opt["port"]["shortdesc"] = "UUID of the node to be fenced."
    all_opt["power_timeout"]["default"] = "60"

    options = check_input(device_opt, process_input(device_opt))

    # workaround to avoid regressions
    if "--uuid" in options:
        options["--plug"] = options["--uuid"]
        del options["--uuid"]
    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 OpenStack's Nova service"
    docs["longdesc"] = "fence_openstack is a Fencing agent \
which can be used with machines controlled by the Openstack's Nova service. \
This agent calls the python-novaclient and it is mandatory to be installed "

    docs["vendorurl"] = "https://wiki.openstack.org/wiki/Nova"
    show_docs(options, docs)

    run_delay(options)

    username = options["--username"]
    password = options["--password"]
    projectname = options["--project-name"]
    auth_url = None
    try:
        auth_url = options["--auth-url"]
    except KeyError:
        fail_usage(
            "Failed: You have to set the Keystone service endpoint for authorization"
        )
    user_domain_name = options["--user-domain-name"]
    project_domain_name = options["--project-domain-name"]
    cacert = options["--cacert"]
    apitimeout = options["--apitimeout"]
    try:
        conn = nova_login(
            username,
            password,
            projectname,
            auth_url,
            user_domain_name,
            project_domain_name,
            cacert,
            apitimeout,
        )
    except Exception as e:
        fail_usage("Failed: Unable to connect to Nova: " + str(e))

    # Operate the fencing device
    result = fence_action(conn, options, set_power_status, get_power_status,
                          get_nodes_list)
    sys.exit(result)
Beispiel #35
0
def is_block_device(dev):
    if not os.path.exists(dev):
        fail_usage("Failed: device \"" + dev + "\" does not exist")
    if not stat.S_ISBLK(os.stat(dev).st_mode):
        fail_usage("Failed: device \"" + dev + "\" is not a block device")
Beispiel #36
0
def main():
    compute_client = None
    network_client = None

    device_opt = [
        "login", "passwd", "port", "resourceGroup", "tenantId",
        "subscriptionId", "network-fencing", "msi", "cloud"
    ]

    atexit.register(atexit_handler)

    define_new_opts()

    all_opt["power_timeout"]["default"] = "150"

    all_opt["login"]["help"] = "-l, --username=[appid]         Application ID"
    all_opt["passwd"][
        "help"] = "-p, --password=[authkey]       Authentication key"

    options = check_input(device_opt, process_input(device_opt))

    docs = {}
    docs["shortdesc"] = "Fence agent for Azure Resource Manager"
    docs[
        "longdesc"] = "fence_azure_arm is an I/O Fencing agent for Azure Resource Manager. It uses Azure SDK for Python to connect to Azure.\
\n.P\n\
For instructions to setup credentials see: https://docs.microsoft.com/en-us/azure/azure-resource-manager/resource-group-create-service-principal-portal\
\n.P\n\
Username and password are application ID and authentication key from \"App registrations\".\
\n.P\n\
NOTE: NETWORK FENCING\n.br\n\
Network fencing requires an additional Subnet named \"fence-subnet\" for the Virtual Network using a Network Security Group with the following rules:\n.br\n\
+-----------+-----+-------------------------+------+------+-----+-----+--------+\n.br\n\
| DIRECTION | PRI | NAME                    | PORT | PROT | SRC | DST | ACTION |\n.br\n\
+-----------+-----+-------------------------+------+------+-----+-----+--------+\n.br\n\
| Inbound   | 100 | FENCE_DENY_ALL_INBOUND  | Any  | Any  | Any | Any | Deny   |\n.br\n\
| Outbound  | 100 | FENCE_DENY_ALL_OUTBOUND | Any  | Any  | Any | Any | Deny   |\n.br\n\
+-----------+-----+-------------------------+------+------+-----+-----+--------+\
\n.P\n\
When using network fencing the reboot-action will cause a quick-return once the network has been fenced (instead of waiting for the off-action to succeed). It will check the status during the monitor-action, and request power-on when the shutdown operation is complete."

    docs["vendorurl"] = "http://www.microsoft.com"
    show_docs(options, docs)

    run_delay(options)

    try:
        config = azure_fence.get_azure_config(options)
        compute_client = azure_fence.get_azure_compute_client(config)
        if "--network-fencing" in options:
            network_client = azure_fence.get_azure_network_client(config)
    except ImportError:
        fail_usage(
            "Azure Resource Manager Python SDK not found or not accessible")
    except Exception as e:
        fail_usage("Failed: %s" % re.sub("^, ", "", str(e)))

    if "--network-fencing" in options:
        # use  off-action to quickly return off once network is fenced instead of
        # waiting for vm state to change
        if options["--action"] == "reboot":
            options["--action"] = "off"
        # check for devices to unfence in monitor-action
        elif options["--action"] == "monitor":
            check_unfence([compute_client, network_client], options)

    # Operate the fencing device
    result = fence_action([compute_client, network_client], options,
                          set_power_status, get_power_status, get_nodes_list)
    sys.exit(result)
Beispiel #37
0
def main():

	atexit.register(atexit_handler)

	device_opt = ["no_login", "no_password", "devices", "nodename", "key",\
	"aptpl", "fabric_fencing", "on_target", "corosync-cmap_path",\
	"sg_persist_path", "sg_turs_path", "logfile", "vgs_path", "force_on"]

	define_new_opts()

	all_opt["delay"]["getopt"] = "H:"

	#fence_scsi_check
	if os.path.basename(sys.argv[0]) == "fence_scsi_check":
		sys.exit(scsi_check())
	elif os.path.basename(sys.argv[0]) == "fence_scsi_check_hardreboot":
		sys.exit(scsi_check(True))

	options = check_input(device_opt, process_input(device_opt), other_conditions=True)

	docs = {}
	docs["shortdesc"] = "Fence agent for SCSI persistent reservation"
	docs["longdesc"] = "fence_scsi is an I/O fencing agent that uses SCSI-3 \
persistent reservations to control access to shared storage devices. These \
devices must support SCSI-3 persistent reservations (SPC-3 or greater) as \
well as the \"preempt-and-abort\" subcommand.\nThe fence_scsi agent works by \
having each node in the cluster register a unique key with the SCSI \
device(s). Once registered, a single node will become the reservation holder \
by creating a \"write exclusive, registrants only\" reservation on the \
device(s). The result is that only registered nodes may write to the \
device(s). When a node failure occurs, the fence_scsi agent will remove the \
key belonging to the failed node from the device(s). The failed node will no \
longer be able to write to the device(s). A manual reboot is required."
	docs["vendorurl"] = ""
	show_docs(options, docs)

	run_delay(options)

	# backward compatibility layer BEGIN
	if "--logfile" in options:
		try:
			logfile = open(options["--logfile"], 'w')
			sys.stderr = logfile
			sys.stdout = logfile
		except IOError:
			fail_usage("Failed: Unable to create file " + options["--logfile"])
	# backward compatibility layer END

	options["store_path"] = STORE_PATH

	# Input control BEGIN
	stop_after_error = False if options["--action"] == "validate-all" else True

	if options["--action"] == "monitor":
		sys.exit(do_action_monitor(options))

	if not (("--nodename" in options and options["--nodename"])\
	or ("--key" in options and options["--key"])):
		fail_usage("Failed: nodename or key is required", stop_after_error)

	if not ("--key" in options and options["--key"]):
		options["--key"] = generate_key(options)

	if options["--key"] == "0" or not options["--key"]:
		fail_usage("Failed: key cannot be 0", stop_after_error)

	if options["--action"] == "validate-all":
		sys.exit(0)

	options["--key"] = options["--key"].lstrip('0')

	if not ("--devices" in options and options["--devices"].split(",")):
		options["devices"] = get_clvm_devices(options)
	else:
		options["devices"] = options["--devices"].split(",")

	if not options["devices"]:
		fail_usage("Failed: No devices found")
	# Input control END

	result = fence_action(None, options, set_status, get_status)
	sys.exit(result)
Beispiel #38
0
def get_cluster_id(options):
    cmd = options["--corosync-cmap-path"] + " totem.cluster_name"

    match = re.search(r"\(str\) = (\S+)\n", run_cmd(options, cmd)["out"])
    return hashlib.md5(match.group(1)).hexdigest() if match else fail_usage(
        "Failed: cannot get cluster name")
Beispiel #39
0
def get_node_id(options):
	cmd = options["--corosync-cmap-path"] + " nodelist."

	match = re.search(r".(\d).ring._addr \(str\) = " + options["--nodename"] + "\n", run_cmd(options, cmd)["out"])
	return match.group(1) if match else fail_usage("Failed: unable to parse output of corosync-cmapctl or node does not exist")
def validate_options(required_options_list, options):
    for required_option in required_options_list:
        if required_option not in options:
            fail_usage("Failed: %s option must be provided" % required_option)
Beispiel #41
0
def main():
	global override_status
	global nova
	atexit.register(atexit_handler)

	device_opt = ["login", "passwd", "tenant-name", "auth-url", "fabric_fencing", "on_target",
		"no_login", "no_password", "port", "domain", "no-shared-storage", "endpoint-type",
		"record-only", "instance-filtering", "insecure", "region-name"]
	define_new_opts()
	all_opt["shell_timeout"]["default"] = "180"

	options = check_input(device_opt, process_input(device_opt))

	docs = {}
	docs["shortdesc"] = "Fence agent for the automatic resurrection of OpenStack compute instances"
	docs["longdesc"] = "Used to tell Nova that compute nodes are down and to reschedule flagged instances"
	docs["vendorurl"] = ""

	show_docs(options, docs)

	run_delay(options)

	try:
		from novaclient import client as nova_client
	except ImportError:
		fail_usage("nova not found or not accessible")

	fix_plug_name(options)

	if options["--record-only"] in [ "2", "Disabled", "disabled" ]:
		sys.exit(0)

	elif options["--record-only"] in [ "1", "True", "true", "Yes", "yes"]:
		if options["--action"] == "on":
			set_attrd_status(options["--plug"], "no", options)
			sys.exit(0)

		elif options["--action"] in ["off", "reboot"]:
			set_attrd_status(options["--plug"], "yes", options)
			sys.exit(0)

		elif options["--action"] in ["monitor", "status"]:
			sys.exit(0)

	# The first argument is the Nova client version
	nova = nova_client.Client('2',
		options["--username"],
		options["--password"],
		options["--tenant-name"],
		options["--auth-url"],
		insecure=options["--insecure"],
		region_name=options["--region-name"],
		endpoint_type=options["--endpoint-type"])

	if options["--action"] in ["off", "reboot"]:
		# Pretend we're 'on' so that the fencing library will always call set_power_status(off)
		override_status = "on"

	if options["--action"] == "on":
		# Pretend we're 'off' so that the fencing library will always call set_power_status(on)
		override_status = "off"

	result = fence_action(None, options, set_power_status, get_power_status, get_plugs_list, None)
	sys.exit(result)
Beispiel #42
0
def fail_fence_agent(options, message):
    run_on_fail(options)
    fail_usage(message)
Beispiel #43
0
def main():
    conn = None

    device_opt = [
        "port", "no_password", "zone", "project", "stackdriver-logging",
        "method", "baremetalsolution", "apitimeout", "retries", "retrysleep",
        "serviceaccount", "proxyhost", "proxyport"
    ]

    atexit.register(atexit_handler)

    define_new_opts()

    all_opt["power_timeout"]["default"] = "60"

    options = check_input(device_opt, process_input(device_opt))

    docs = {}
    docs["shortdesc"] = "Fence agent for GCE (Google Cloud Engine)"
    docs["longdesc"] = "fence_gce is an I/O Fencing agent for GCE (Google Cloud " \
         "Engine). It uses the googleapiclient library to connect to GCE.\n" \
         "googleapiclient can be configured with Google SDK CLI or by " \
         "executing 'gcloud auth application-default login'.\n" \
         "For instructions see: https://cloud.google.com/compute/docs/tutorials/python-guide"
    docs["vendorurl"] = "http://cloud.google.com"
    show_docs(options, docs)

    run_delay(options)

    # Prepare logging
    if options.get('--verbose') is None:
        logging.getLogger('googleapiclient').setLevel(logging.ERROR)
        logging.getLogger('oauth2client').setLevel(logging.ERROR)
    if options.get('--stackdriver-logging') is not None and options.get(
            '--plug'):
        try:
            import google.cloud.logging.handlers
            client = google.cloud.logging.Client()
            handler = google.cloud.logging.handlers.CloudLoggingHandler(
                client, name=options['--plug'])
            handler.setLevel(logging.INFO)
            formatter = logging.Formatter('gcp:stonith "%(message)s"')
            handler.setFormatter(formatter)
            root_logger = logging.getLogger()
            if options.get('--verbose') is None:
                root_logger.setLevel(logging.INFO)
            root_logger.addHandler(handler)
        except ImportError:
            logging.error('Couldn\'t import google.cloud.logging, '
                          'disabling Stackdriver-logging support')

# if apitimeout is defined we set the socket timeout, if not we keep the
# socket default which is 60s
    if options.get("--apitimeout"):
        socket.setdefaulttimeout(options["--apitimeout"])

    # Prepare cli
    try:
        if options.get("--serviceaccount"):
            scope = ['https://www.googleapis.com/auth/cloud-platform']
            credentials = ServiceAccountCredentials.from_json_keyfile_name(
                options.get("--serviceaccount"), scope)
            logging.debug("using credentials from service account")
        else:
            try:
                from googleapiclient import _auth
                credentials = _auth.default_credentials()
            except:
                credentials = GoogleCredentials.get_application_default()
            logging.debug("using application default credentials")

        if options.get("--proxyhost") and options.get("--proxyport"):
            proxy_info = httplib2.ProxyInfo(
                proxy_type=socks.PROXY_TYPE_HTTP,
                proxy_host=options.get("--proxyhost"),
                proxy_port=int(options.get("--proxyport")))
            http = credentials.authorize(httplib2.Http(proxy_info=proxy_info))
            conn = googleapiclient.discovery.build('compute',
                                                   'v1',
                                                   http=http,
                                                   cache_discovery=False)
        else:
            conn = googleapiclient.discovery.build('compute',
                                                   'v1',
                                                   credentials=credentials,
                                                   cache_discovery=False)
    except Exception as err:
        fail_usage("Failed: Create GCE compute v1 connection: {}".format(
            str(err)))

    # Get project and zone
    if not options.get("--project"):
        try:
            options["--project"] = get_metadata('project/project-id')
        except Exception as err:
            fail_usage(
                "Failed retrieving GCE project. Please provide --project option: {}"
                .format(str(err)))

    if "--baremetalsolution" in options:
        options["--zone"] = "none"
    if not options.get("--zone"):
        try:
            options["--zone"] = get_zone(conn, options)
        except Exception as err:
            fail_usage(
                "Failed retrieving GCE zone. Please provide --zone option: {}".
                format(str(err)))

    # Operate the fencing device
    result = fence_action(conn, options, set_power_status, get_power_status,
                          get_nodes_list, power_cycle)
    sys.exit(result)
Beispiel #44
0
def main():
    conn = None

    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"

    options = check_input(device_opt, process_input(device_opt))

    docs = {}
    docs["shortdesc"] = "Fence agent for AWS (Amazon Web Services)"
    docs["longdesc"] = "fence_aws is an I/O Fencing agent for AWS (Amazon Web\
Services). It uses the boto3 library to connect to AWS.\
\n.P\n\
boto3 can be configured with AWS CLI or by creating ~/.aws/credentials.\n\
For instructions see: https://boto3.readthedocs.io/en/latest/guide/quickstart.html#configuration"

    docs["vendorurl"] = "http://www.amazon.com"
    show_docs(options, docs)

    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)

    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
        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")
    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)
    sys.exit(result)
Beispiel #45
0
def main():
    atexit.register(atexit_handler)

    all_opt["pve_node_auto"] = {
        "getopt": "A",
        "longopt": "pve-node-auto",
        "help": "-A, --pve-node-auto            "
        "Automatically select proxmox node",
        "required": "0",
        "shortdesc": "Automatically select proxmox node. "
        "(This option overrides --pve-node)",
        "type": "boolean",
        "order": 2
    }
    all_opt["pve_node"] = {
        "getopt": "N:",
        "longopt": "pve-node",
        "help": "-N, --pve-node=[node_name]     "
        "Proxmox node name on which machine is located",
        "required": "0",
        "shortdesc": "Proxmox node name on which machine is located. "
        "(Must be specified if not using --pve-node-auto)",
        "order": 2
    }
    all_opt["node_name"] = {
        "getopt": ":",
        "longopt": "nodename",
        "help": "--nodename                     "
        "Replaced by --pve-node",
        "required": "0",
        "shortdesc": "Replaced by --pve-node",
        "order": 3
    }
    all_opt["vmtype"] = {
        "getopt": ":",
        "longopt": "vmtype",
        "default": "qemu",
        "help": "--vmtype                       "
        "Virtual machine type lxc or qemu (default: qemu)",
        "required": "1",
        "shortdesc": "Virtual machine type lxc or qemu. "
        "(Default: qemu)",
        "order": 2
    }

    device_opt = [
        "ipaddr", "login", "passwd", "ssl", "web", "port", "pve_node",
        "pve_node_auto", "node_name", "vmtype", "method"
    ]

    all_opt["login"]["required"] = "0"
    all_opt["login"]["default"] = "root@pam"
    all_opt["ipport"]["default"] = "8006"
    all_opt["ssl"]["default"] = "1"
    all_opt["port"]["shortdesc"] = "Id of the virtual machine."
    all_opt["ipaddr"]["shortdesc"] = "IP Address or Hostname of a node " +\
     "within the Proxmox cluster."

    options = check_input(device_opt, process_input(device_opt))
    docs = {}
    docs["shortdesc"] = "Fencing agent for the Proxmox Virtual Environment"
    docs["longdesc"] = "The fence_pve agent can be used to fence virtual \
machines acting as nodes in a virtualized cluster."

    docs["vendorurl"] = "http://www.proxmox.com/"

    show_docs(options, docs)

    run_delay(options)

    if "--pve-node-auto" in options:
        # Force pve-node to None to allow autodiscovery
        options["--pve-node"] = None
    elif "--pve-node" in options and options["--pve-node"]:
        # Leave pve-node alone
        pass
    elif "--nodename" in options and options["--nodename"]:
        # map nodename into pve-node to support legacy implementations
        options["--pve-node"] = options["--nodename"]
    else:
        fail_usage(
            "At least one of pve-node-auto or pve-node must be supplied")

    if options["--vmtype"] != "qemu":
        # For vmtypes other than qemu, only the onoff method is valid
        options["--method"] = "onoff"

    options["url"] = "https://" + options["--ip"] + ":" + str(
        options["--ipport"]) + "/api2/json/"

    options["auth"] = get_ticket(options)
    if options["auth"] is None:
        fail(EC_LOGIN_DENIED)

    # Workaround for unsupported API call on some Proxmox hosts
    outlets = get_outlet_list(
        None, options)  # Unsupported API-Call will result in value: None
    if outlets is None:
        result = fence_action(None, options, set_power_status,
                              get_power_status, None, reboot_cycle)
        sys.exit(result)

    result = fence_action(None, options, set_power_status, get_power_status,
                          get_outlet_list, reboot_cycle)

    sys.exit(result)
Beispiel #46
0
# under the License.
#

import sys
import atexit
import logging
sys.path.append("@FENCEAGENTSLIBDIR@")
from fencing import *
from fencing import run_delay, fail_usage, fail, EC_STATUS

from xml.etree import ElementTree

try:
    import pywsman
except ImportError:
    fail_usage("pywsman not found or not accessible")


#BEGIN_VERSION_GENERATION
RELEASE_VERSION="Fence agent for Intel AMT (WS)"
REDHAT_COPYRIGHT=""
BUILD_DATE=""
#END_VERSION_GENERATION

POWER_ON='2'
POWER_OFF='8'
POWER_CYCLE='10'

RET_SUCCESS = '0'

CIM_PowerManagementService           = ('http://schemas.dmtf.org/wbem/wscim/1/'
Beispiel #47
0
def main():
    conn = None
    sa_file = None

    device_opt = [
        "port", "no_password", "zone", "project", "stackdriver-logging",
        "method"
    ]

    atexit.register(atexit_handler)

    define_new_opts()

    all_opt["power_timeout"]["default"] = "60"
    all_opt["method"]["default"] = "cycle"
    all_opt["method"][
        "help"] = "-m, --method=[method]          Method to fence (onoff|cycle) (Default: cycle)"

    options = check_input(device_opt, process_input(device_opt))

    docs = {}
    docs["shortdesc"] = "Fence agent for GCE (Google Cloud Engine)"
    docs["longdesc"] = "fence_gce is an I/O Fencing agent for GCE (Google Cloud " \
         "Engine). It uses the googleapiclient library to connect to GCE.\n" \
         "googleapiclient can be configured with Google SDK CLI or by " \
         "executing 'gcloud auth application-default login'.\n" \
         "For instructions see: https://cloud.google.com/compute/docs/tutorials/python-guide"
    docs["vendorurl"] = "http://cloud.google.com"
    show_docs(options, docs)

    run_delay(options)

    # Prepare logging
    if options.get('--verbose') is None:
        logging.getLogger('googleapiclient').setLevel(logging.ERROR)
        logging.getLogger('oauth2client').setLevel(logging.ERROR)
    if options.get('--stackdriver-logging') is not None and options.get(
            '--plug'):
        try:
            import google.cloud.logging.handlers
            client = google.cloud.logging.Client()
            handler = google.cloud.logging.handlers.CloudLoggingHandler(
                client, name=options['--plug'])
            handler.setLevel(logging.INFO)
            formatter = logging.Formatter('gcp:stonith "%(message)s"')
            handler.setFormatter(formatter)
            root_logger = logging.getLogger()
            if options.get('--verbose') is None:
                root_logger.setLevel(logging.INFO)
            root_logger.addHandler(handler)
        except ImportError:
            logging.error('Couldn\'t import google.cloud.logging, '
                          'disabling Stackdriver-logging support')

    # Prepare credentials
    # Block added by mbfx
    if options.get('--credentials') is None:
        if os.environ.get('GOOGLE_APPLICATION_CREDENTIALS') is None:
            sa_file = DEFAULT_CREDENTIALS_PATH
        else:
            sa_file = os.environ.get('GOOGLE_APPLICATION_CREDENTIALS')
    elif options.get('--credentials') is not None:
        sa_file = options.get('--credentials')

    # Prepare cli
    # Block changed by erlong15 and mbfx
    try:
        from google.oauth2 import service_account
        credentials = None
        scopes = ['https://www.googleapis.com/auth/cloud-platform']
        credentials = service_account.Credentials.from_service_account_file(
            sa_file, scopes=scopes)
        conn = googleapiclient.discovery.build('compute',
                                               'v1',
                                               credentials=credentials)
    except Exception as err:
        fail_usage("Failed: Create GCE compute v1 connection: {}".format(
            str(err)))

    # Get project and zone
    if not options.get("--project"):
        try:
            options["--project"] = get_metadata('project/project-id')
        except Exception as err:
            fail_usage(
                "Failed retrieving GCE project. Please provide --project option: {}"
                .format(str(err)))

    if not options.get("--zone"):
        try:
            options["--zone"] = get_zone(conn, options['--project'],
                                         options['--plug'])
        except Exception as err:
            fail_usage(
                "Failed retrieving GCE zone. Please provide --zone option: {}".
                format(str(err)))

    # Operate the fencing device
    result = fence_action(conn, options, set_power_status, get_power_status,
                          get_nodes_list, power_cycle)
    sys.exit(result)
def set_network_state(compute_client, network_client, rgName, vmName,
                      operation):
    import msrestazure.azure_exceptions
    logging.info(
        "{set_network_state} Setting state %s for  %s in resource group %s" %
        (operation, vmName, rgName))

    vm = compute_client.virtual_machines.get(rgName, vmName, "instanceView")

    operations = []
    for nicRef in vm.network_profile.network_interfaces:
        for attempt in range(0, MAX_RETRY):
            try:
                nicresource = get_azure_resource(nicRef.id)
                nic = network_client.network_interfaces.get(
                    nicresource.ResourceGroupName, nicresource.ResourceName)

                if not nic.tags and operation == "block":
                    nic.tags = {}

                logging.info(
                    "{set_network_state} Searching for tags required to unfence this virtual machine"
                )
                for ipConfig in nic.ip_configurations:
                    if operation == "block":
                        fenceSubnet = get_fence_subnet_for_config(
                            ipConfig, network_client)
                        testOk = test_fence_subnet(fenceSubnet, nic,
                                                   network_client)
                        if testOk:
                            logging.info(
                                "{set_network_state} Changing subnet of ip config of nic %s"
                                % nic.id)
                            nic.tags[("%s_%s" %
                                      (FENCE_TAG_SUBNET_ID,
                                       ipConfig.name))] = ipConfig.subnet.id
                            nic.tags[(
                                "%s_%s" % (FENCE_TAG_IP_TYPE, ipConfig.name)
                            )] = ipConfig.private_ip_allocation_method
                            nic.tags[("%s_%s" % (FENCE_TAG_IP, ipConfig.name)
                                      )] = ipConfig.private_ip_address
                            ipConfig.subnet = fenceSubnet
                            ipConfig.private_ip_allocation_method = IP_TYPE_DYNAMIC
                        else:
                            fail_usage(
                                "{set_network_state} Network interface id %s does not have a network security group."
                                % nic.id)
                    elif operation == "unblock":
                        if not nic.tags:
                            fail_usage(
                                "{set_network_state} IP configuration %s is missing the required resource tags (empty)"
                                % ipConfig.name)

                        subnetId = nic.tags.pop(
                            "%s_%s" % (FENCE_TAG_SUBNET_ID, ipConfig.name))
                        ipType = nic.tags.pop(
                            "%s_%s" % (FENCE_TAG_IP_TYPE, ipConfig.name))
                        ipAddress = nic.tags.pop("%s_%s" %
                                                 (FENCE_TAG_IP, ipConfig.name))

                        if (subnetId and ipType and
                            (ipAddress or
                             (ipType.lower() == IP_TYPE_DYNAMIC.lower()))):
                            logging.info(
                                "{set_network_state} tags found (subnetId: %s, ipType: %s, ipAddress: %s)"
                                % (subnetId, ipType, ipAddress))

                            subnetResource = get_azure_resource(subnetId)
                            vnet = network_client.virtual_networks.get(
                                subnetResource.ResourceGroupName,
                                subnetResource.ResourceName)
                            logging.info(
                                "{set_network_state} looking for subnet %s" %
                                len(subnetResource.SubResources))
                            oldSubnet = get_subnet(
                                vnet, subnetResource.SubResources[0].Name)
                            if not oldSubnet:
                                fail_usage(
                                    "{set_network_state} subnet %s not found" %
                                    subnetId)

                            ipConfig.subnet = oldSubnet
                            ipConfig.private_ip_allocation_method = ipType
                            if ipAddress:
                                ipConfig.private_ip_address = ipAddress
                        else:
                            fail_usage(
                                "{set_network_state} IP configuration %s is missing the required resource tags(subnetId: %s, ipType: %s, ipAddress: %s)"
                                % (ipConfig.name, subnetId, ipType, ipAddress))

                logging.info("{set_network_state} updating nic %s" % (nic.id))
                op = network_client.network_interfaces.create_or_update(
                    nicresource.ResourceGroupName, nicresource.ResourceName,
                    nic)
                operations.append(op)
                break
            except msrestazure.azure_exceptions.CloudError as cex:
                logging.error(
                    "{set_network_state} CloudError in attempt %s '%s'" %
                    (attempt, cex))
                if cex.error and cex.error.error and cex.error.error.lower(
                ) == "PrivateIPAddressIsBeingCleanedUp":
                    logging.error(
                        "{set_network_state} PrivateIPAddressIsBeingCleanedUp")
                time.sleep(RETRY_WAIT)

            except Exception as ex:
                logging.error("{set_network_state} Exception of type %s: %s" %
                              (type(ex).__name__, ex))
                break
Beispiel #49
0
def main():

	atexit.register(atexit_handler)

	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", "readonly", "logfile", "vgs_path",\
	"force_on", "key_value"]

	define_new_opts()

	all_opt["delay"]["getopt"] = "H:"

	all_opt["port"]["help"] = "-n, --plug=[nodename]          Name of the node to be fenced"
	all_opt["port"]["shortdesc"] = "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."

	#fence_scsi_check
	if os.path.basename(sys.argv[0]) == "fence_scsi_check":
		sys.exit(scsi_check())
	elif os.path.basename(sys.argv[0]) == "fence_scsi_check_hardreboot":
		sys.exit(scsi_check(True))

	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" ]

	docs = {}
	docs["shortdesc"] = "Fence agent for SCSI persistent reservation"
	docs["longdesc"] = "fence_scsi is an I/O fencing agent that uses SCSI-3 \
persistent reservations to control access to shared storage devices. These \
devices must support SCSI-3 persistent reservations (SPC-3 or greater) as \
well as the \"preempt-and-abort\" subcommand.\nThe fence_scsi agent works by \
having each node in the cluster register a unique key with the SCSI \
device(s). Reservation key is generated from \"node id\" (default) or from \
\"node name hash\" (RECOMMENDED) by adjusting \"key_value\" option. \
Using hash is recommended to prevent issues when removing nodes \
from cluster without full cluster restart. \
Once registered, a single node will become the reservation holder \
by creating a \"write exclusive, registrants only\" reservation on the \
device(s). The result is that only registered nodes may write to the \
device(s). When a node failure occurs, the fence_scsi agent will remove the \
key belonging to the failed node from the device(s). The failed node will no \
longer be able to write to the device(s). A manual reboot is required.\
\n.P\n\
When used as a watchdog device you can define e.g. retry=1, retry-sleep=2 and \
verbose=yes parameters in /etc/sysconfig/stonith if you have issues with it \
failing."
	docs["vendorurl"] = ""
	show_docs(options, docs)

	run_delay(options)

	# backward compatibility layer BEGIN
	if "--logfile" in options:
		try:
			logfile = open(options["--logfile"], 'w')
			sys.stderr = logfile
			sys.stdout = logfile
		except IOError:
			fail_usage("Failed: Unable to create file " + options["--logfile"])
	# backward compatibility layer END

	options["store_path"] = STORE_PATH

	# Input control BEGIN
	stop_after_error = False if options["--action"] == "validate-all" else True

	if options["--action"] == "monitor":
		sys.exit(do_action_monitor(options))

	# workaround to avoid regressions
	if "--nodename" in options and options["--nodename"]:
		options["--plug"] = options["--nodename"]
		del options["--nodename"]

	if not (("--plug" in options and options["--plug"])\
	or ("--key" in options and options["--key"])):
		fail_usage("Failed: nodename or key is required", stop_after_error)

	if not ("--key" in options and options["--key"]):
		options["--key"] = generate_key(options)

	if options["--key"] == "0" or not options["--key"]:
		fail_usage("Failed: key cannot be 0", stop_after_error)

	if "--key-value" in options\
	and (options["--key-value"] != "id" and options["--key-value"] != "hash"):
		fail_usage("Failed: key-value has to be 'id' or 'hash'", stop_after_error)

	if options["--action"] == "validate-all":
		sys.exit(0)

	options["--key"] = options["--key"].lstrip('0')

	if not ("--devices" in options and options["--devices"].split(",")):
		options["devices"] = get_clvm_devices(options)
	else:
		options["devices"] = options["--devices"].split(",")

	if not options["devices"]:
		fail_usage("Failed: No devices found")
	# Input control END

	result = fence_action(None, options, set_status, get_status)
	sys.exit(result)