Beispiel #1
0
def main():
    atexit.register(atexit_handler)

    all_opt["node_name"] = {
        "getopt": "N:",
        "longopt": "nodename",
        "help": "-N, --nodename                 "
        "Node on which machine is located",
        "required": "0",
        "shortdesc": "Node on which machine is located. "
        "(Optional, will be automatically determined)",
        "order": 2
    }

    device_opt = ["ipaddr", "login", "passwd", "web", "port", "node_name"]

    all_opt["login"]["required"] = "0"
    all_opt["login"]["default"] = "root@pam"
    all_opt["ipport"]["default"] = "8006"
    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 "--nodename" not in options or not options["--nodename"]:
        options["--nodename"] = None

    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)
        sys.exit(result)

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

    sys.exit(result)
Beispiel #2
0
def main():
    atexit.register(atexit_handler)

    all_opt["tlscert"] = {
        "getopt": ":",
        "longopt": "tlscert",
        "help": "--tlscert                      "
        "Path to client certificate for TLS authentication",
        "required": "0",
        "shortdesc": "Path to client certificate (PEM format) \
for TLS authentication. Required if --ssl option is used.",
        "order": 2
    }

    all_opt["tlskey"] = {
        "getopt": ":",
        "longopt": "tlskey",
        "help": "--tlskey                       "
        "Path to client key for TLS authentication",
        "required": "0",
        "shortdesc": "Path to client key (PEM format) for TLS \
authentication.  Required if --ssl option is used.",
        "order": 2
    }

    all_opt["tlscacert"] = {
        "getopt": ":",
        "longopt": "tlscacert",
        "help": "--tlscacert                    "
        "Path to CA certificate for TLS authentication",
        "required": "0",
        "shortdesc": "Path to CA certificate (PEM format) for \
TLS authentication.  Required if --ssl option is used.",
        "order": 2
    }

    device_opt = [
        "ipaddr", "no_password", "no_login", "port", "method", "web",
        "tlscert", "tlskey", "tlscacert", "ssl"
    ]

    options = check_input(device_opt, process_input(device_opt))

    docs = {}
    docs["shortdesc"] = "Fence agent for Docker"
    docs["longdesc"] = "fence_docker is I/O fencing agent which \
can be used with the Docker Engine containers. You can use this \
fence-agent without any authentication, or you can use TLS authentication \
(use --ssl option, more info about TLS authentication in docker: \
http://docs.docker.com/examples/https/)."

    docs["vendorurl"] = "www.docker.io"
    show_docs(options, docs)

    run_delay(options)

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

    sys.exit(result)
def main():
    device_opt = ["help", "version", "agent", "quiet", "verbose", "debug",
                  "action", "ipaddr", "login", "passwd", "passwd_script",
                  "secure", "identity_file", "test", "port", "separator",
                  "inet4_only", "inet6_only", "ipport",
                  "power_timeout", "shell_timeout",
                  "login_timeout", "power_wait"]

    atexit.register(atexit_handler)

    all_opt["login_timeout"]["default"] = 60

    pinput = process_input(device_opt)

    # use ssh to manipulate node
    pinput["-x"] = 1

    options = check_input(device_opt, pinput)

    if options["-o"] != "off":
        sys.exit(0)

    options["-c"] = "\[EXPECT\]#\ "

    # this string will be appended to the end of ssh command
    strict = "-t -o 'StrictHostKeyChecking=no'"
    serveralive = "-o 'ServerAliveInterval 2'"
    no_stdin = "-n"
    bash = "/bin/bash --noprofile --norc"
    options["ssh_options"] = "{0} {1} {2} '/bin/bash -c " \
                             "\"PS1={3} {4}\"'".format(
                             strict, serveralive, no_stdin, options["-c"],
                             bash)
    options["-X"] = "{0} {1} {2} '/bin/bash -c " \
                    "\"PS1={3} {4}\"'".format(
                    strict, serveralive, no_stdin, options["-c"], bash)

    docs = {}
    docs["shortdesc"] = "Fence agent that can just reboot node via ssh"
    docs["longdesc"] = "fence_ssh is an I/O Fencing agent \
which can be used to reboot nodes via ssh."
    show_docs(options, docs)

    # Operate the fencing device

    # this method will actually launch ssh command
    conn = fence_login(options)

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

    try:
        conn.close()
    except exceptions.OSError:
        pass
    except pexpect.ExceptionPexpect:
        pass

    sys.exit(result)
def main():
    device_opt = [
        "help", "version", "agent", "verbose", "debug", "action", "ipaddr",
        "login", "passwd", "passwd_script", "secure", "identity_file", "port",
        "separator", "inet4_only", "inet6_only", "ipport", "power_timeout",
        "shell_timeout", "login_timeout", "power_wait"
    ]

    atexit.register(atexit_handler)

    all_opt["login_timeout"]["default"] = 60

    pinput = process_input(device_opt)

    # use ssh to manipulate node
    pinput["--ssh"] = 1
    pinput["--command-prompt"] = ".*"

    options = check_input(device_opt, pinput)

    if options["--action"] != "off":
        sys.exit(0)

    options["-c"] = "\[EXPECT\]#\ "

    # this string will be appended to the end of ssh command
    strict = "-t -o 'StrictHostKeyChecking=no'"
    serveralive = "-o 'ServerAliveInterval 2'"
    no_stdin = "-n"
    options["ssh_options"] = "{0} {1} {2} '/bin/bash -c \"PS1={3} /bin/bash " \
                             "--noprofile --norc\"'".format(
                             strict, serveralive, no_stdin, options["-c"])
    options["-X"] = "{0} {1} {2} '/bin/bash -c \"PS1={3}  /bin/bash " \
                    "--noprofile --norc\"'".format(
                    strict, serveralive, no_stdin, options["-c"])

    docs = {}
    docs["shortdesc"] = "Fence agent that can just reboot node via ssh"
    docs["longdesc"] = "fence_ssh is an I/O Fencing agent " \
                       "which can be used to reboot nodes via ssh."
    show_docs(options, docs)

    # Operate the fencing device

    # this method will actually launch ssh command
    conn = fence_login(options)

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

    try:
        conn.close()
    except exceptions.OSError:
        pass
    except pexpect.ExceptionPexpect:
        pass

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

	all_opt["tlscert"] = {
		"getopt" : ":",
		"longopt" : "tlscert",
		"help" : "--tlscert                      "
			"Path to client certificate for TLS authentication",
		"required" : "0",
		"shortdesc" : "Path to client certificate (PEM format) \
for TLS authentication. Required if --ssl option is used.",
		"order": 2
	}

	all_opt["tlskey"] = {
		"getopt" : ":",
		"longopt" : "tlskey",
		"help" : "--tlskey                       "
			"Path to client key for TLS authentication",
		"required" : "0",
		"shortdesc" : "Path to client key (PEM format) for TLS \
authentication.  Required if --ssl option is used.",
		"order": 2
	}

	all_opt["tlscacert"] = {
		"getopt" : ":",
		"longopt" : "tlscacert",
		"help" : "--tlscacert                    "
			"Path to CA certificate for TLS authentication",
		"required" : "0",
		"shortdesc" : "Path to CA certificate (PEM format) for \
TLS authentication.  Required if --ssl option is used.",
		"order": 2
	}

	device_opt = ["ipaddr", "no_password", "no_login", "port", "method", "web", "tlscert", "tlskey", "tlscacert", "ssl"]

	options = check_input(device_opt, process_input(device_opt))

	docs = { }
	docs["shortdesc"] = "Fence agent for Docker"
	docs["longdesc"] = "fence_docker is I/O fencing agent which \
can be used with the Docker Engine containers. You can use this \
fence-agent without any authentication, or you can use TLS authentication \
(use --ssl option, more info about TLS authentication in docker: \
http://docs.docker.com/examples/https/)."
	docs["vendorurl"] = "www.docker.io"
	show_docs(options, docs)

	run_delay(options)

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

	sys.exit(result)
Beispiel #7
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()

    # 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)

    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 #8
0
def main():
	atexit.register(atexit_handler)

	all_opt["node_name"] = {
		"getopt" : "N:",
		"longopt" : "nodename",
		"help" : "-N, --nodename                 "
			"Node on which machine is located",
		"required" : "0",
		"shortdesc" : "Node on which machine is located. "
			"(Optional, will be automatically determined)",
		"order": 2
	}

	device_opt = ["ipaddr", "login", "passwd", "web", "port", "node_name"]

	all_opt["login"]["required"] = "0"
	all_opt["login"]["default"] = "root@pam"
	all_opt["ipport"]["default"] = "8006"
	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 "--nodename" not in options or not options["--nodename"]:
		options["--nodename"] = None

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

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

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

	sys.exit(result)
Beispiel #9
0
def main():
    device_opt = [
        "no_status", "no_password", "ping_count", "ping_good_count",
        "ping_interval", "ping_timeout", "ping_maxfail", "ping_targets",
        "method"
    ]
    define_new_opts()
    atexit.register(atexit_handler)

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

    options = check_input(device_opt, process_input(device_opt))

    docs = {}
    docs["shortdesc"] = "Fence agent for ping-heuristic based fencing"
    docs[
        "longdesc"] = "fence_heuristics_ping uses ping-heuristics to control execution of another fence agent on the same fencing level.\
\n.P\n\
This is not a fence agent by itself! \
Its only purpose is to enable/disable another fence agent that lives on the same fencing level but after fence_heuristics_ping."

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

    # move ping-test to the end of the time-window set via --delay
    # as to give the network time to settle after the incident that has
    # caused fencing and have the results as current as possible
    max_pingcheck = (int(options["--ping-count"]) - 1) * \
     int(options["--ping-interval"]) + int(options["--ping-timeout"])
    run_delay(options, reserve=max_pingcheck)

    result = fence_action(\
       None, \
       options, \
       None, \
       None, \
       reboot_cycle_fn = ping_test,
       sync_set_power_fn = ping_test)

    # execute the remaining delay
    run_delay(options, result=result)
    sys.exit(result)
def main():
    atexit.register(atexit_handler)

    device_opt = ["crosscableip", "timeout", "no_password", "no_login", "port"]
    define_new_opts()

    options = check_input(device_opt, process_input(device_opt))

    docs = {}
    docs["shortdesc"] = "Fence agent for cross-link two-node clusters"
    docs["longdesc"] = "This agent helps two-node clusters to tackle the " \
                       "situation where one node lost power, cannot be " \
                       "fenced by telling pacemaker that if the node is not " \
                       "reachable over the crosslink cable, we can assume " \
                       "it is dead"
    docs["vendorurl"] = ""
    show_docs(options, docs)

    run_delay(options)

    result = fence_action(None, options, set_power_status, get_power_status)
    sys.exit(result)
def main():
	device_opt = ["no_status", "no_password", "ping_count", "ping_good_count",
		"ping_interval", "ping_timeout", "ping_maxfail", "ping_targets", "method"]
	define_new_opts()
	atexit.register(atexit_handler)

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

	options = check_input(device_opt, process_input(device_opt))

	docs = {}
	docs["shortdesc"] = "Fence agent for ping-heuristic based fencing"
	docs["longdesc"] = "fence_heuristics_ping uses ping-heuristics to control execution of another fence agent on the same fencing level.\
\n.P\n\
This is not a fence agent by itself! \
Its only purpose is to enable/disable another fence agent that lives on the same fencing level but after fence_heuristics_ping."
	docs["vendorurl"] = ""
	show_docs(options, docs)

	# move ping-test to the end of the time-window set via --delay
	# as to give the network time to settle after the incident that has
	# caused fencing and have the results as current as possible
	max_pingcheck = (int(options["--ping-count"]) - 1) * \
		int(options["--ping-interval"]) + int(options["--ping-timeout"])
	run_delay(options, reserve=max_pingcheck)

	result = fence_action(\
				None, \
				options, \
				None, \
				None, \
				reboot_cycle_fn = ping_test,
				sync_set_power_fn = ping_test)

	# execute the remaining delay
	run_delay(options, result=result)
	sys.exit(result)
Beispiel #12
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 = None
		if tuple(googleapiclient.__version__) < tuple("1.6.0"):
			import oauth2client.client
			credentials = oauth2client.client.GoogleCredentials.get_application_default()
		conn = googleapiclient.discovery.build('compute', 'v1', credentials=credentials)
	except Exception as err:
		fail_usage("Failed: Create GCE compute v1 connection: {}".format(str(err)))

	# Operate the fencing device
	result = fence_action(conn, options, set_power_status, get_power_status, get_nodes_list)
	sys.exit(result)
Beispiel #13
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", "logfile", "vgs_path", "force_on"]

	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). 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 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 #14
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:
            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 #15
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 #16
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", "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["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)
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.\
\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"] = "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"] = [
        d for d in re.split("\s*,\s*|\s+", options["--devices"].strip()) if d
    ]
    # Input control END

    result = fence_action(None, options, set_status, get_status)
    sys.exit(result)
Beispiel #18
0
def main():
    conn = 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 cli
    try:
        credentials = None
        if tuple(googleapiclient.__version__) < tuple("1.6.0"):
            import oauth2client.client
            credentials = oauth2client.client.GoogleCredentials.get_application_default(
            )
        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)
Beispiel #19
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"]

	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())

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

	docs = {}
	docs["shortdesc"] = "Fence agent for SCSI persistentl 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 \
devive(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 #20
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"]

    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())

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

    docs = {}
    docs["shortdesc"] = "Fence agent for SCSI persistentl 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 \
devive(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 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 #21
0
def main():
    conn = None

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

    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')

# 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:
        serviceaccount = options.get("--serviceaccount")
        if serviceaccount:
            scope = ['https://www.googleapis.com/auth/cloud-platform']
            logging.debug("using credentials from service account")
            try:
                from google.oauth2.service_account import Credentials as ServiceAccountCredentials
                credentials = ServiceAccountCredentials.from_service_account_file(
                    filename=serviceaccount, scopes=scope)
            except ImportError:
                from oauth2client.service_account import ServiceAccountCredentials
                credentials = ServiceAccountCredentials.from_json_keyfile_name(
                    serviceaccount, scope)
        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"

    # Populates zone automatically if missing from the command
    zones = [] if not "--zone" in options else options["--zone"].split(",")
    options["--plugzonemap"] = {}
    if "--plug" in options:
        for i, instance in enumerate(options["--plug"].split(",")):
            if len(zones) == 1:
                # If only one zone is specified, use it across all plugs
                options["--plugzonemap"][instance] = zones[0]
                continue

            if len(zones) - 1 >= i:
                # If we have enough zones specified with the --zone flag use the zone at
                # the same index as the plug
                options["--plugzonemap"][instance] = zones[i]
                continue

            try:
                # In this case we do not have a zone specified so we attempt to detect it
                options["--plugzonemap"][instance] = get_zone(
                    conn, options, instance)
            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)