summaryrefslogtreecommitdiffstats
path: root/agents/ovh/fence_ovh.py
diff options
context:
space:
mode:
Diffstat (limited to 'agents/ovh/fence_ovh.py')
-rw-r--r--agents/ovh/fence_ovh.py164
1 files changed, 164 insertions, 0 deletions
diff --git a/agents/ovh/fence_ovh.py b/agents/ovh/fence_ovh.py
new file mode 100644
index 0000000..2b7eb86
--- /dev/null
+++ b/agents/ovh/fence_ovh.py
@@ -0,0 +1,164 @@
+#!@PYTHON@ -tt
+# Copyright 2013 Adrian Gibanel Lopez (bTactic)
+# Adrian Gibanel improved this script at 2013 to add verification of success and to output metadata
+
+# Based on:
+# This is a fence agent for use at OVH
+# As there are no other fence devices available, we must use OVH's SOAP API #Quick-and-dirty
+# assemled by Dennis Busch, secofor GmbH, Germany
+# This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.
+
+import sys, time
+import shutil, tempfile
+import logging
+import atexit
+from datetime import datetime
+from suds.client import Client
+from suds.xsd.doctor import ImportDoctor, Import
+sys.path.append("@FENCEAGENTSLIBDIR@")
+from fencing import *
+from fencing import fail, fail_usage, EC_LOGIN_DENIED, run_delay
+
+OVH_RESCUE_PRO_NETBOOT_ID = '28'
+OVH_HARD_DISK_NETBOOT_ID = '1'
+
+STATUS_HARD_DISK_SLEEP = 240 # Wait 4 minutes to SO to boot
+STATUS_RESCUE_PRO_SLEEP = 150 # Wait 2 minutes 30 seconds to Rescue-Pro to run
+
+def define_new_opts():
+ all_opt["email"] = {
+ "getopt" : "Z:",
+ "longopt" : "email",
+ "help" : "-Z, --email=[email] email for reboot message: admin@domain.com",
+ "required" : "1",
+ "shortdesc" : "Reboot email",
+ "order" : 1}
+
+def netboot_reboot(conn, options, mode):
+ # dedicatedNetbootModifyById changes the mode of the next reboot
+ conn.service.dedicatedNetbootModifyById(options["session"], options["--plug"], mode, '', options["--email"])
+
+ # dedicatedHardRebootDo initiates a hard reboot on the given node
+ conn.service.dedicatedHardRebootDo(options["session"],
+ options["--plug"], 'Fencing initiated by cluster', '', 'en')
+
+ conn.logout(options["session"])
+
+def reboot_time(conn, options):
+ result = conn.service.dedicatedHardRebootStatus(options["session"], options["--plug"])
+ tmpstart = datetime.strptime(result.start, '%Y-%m-%d %H:%M:%S')
+ tmpend = datetime.strptime(result.end, '%Y-%m-%d %H:%M:%S')
+ result.start = tmpstart
+ result.end = tmpend
+
+ return result
+
+def soap_login(options):
+ imp = Import('http://schemas.xmlsoap.org/soap/encoding/')
+ url = 'https://www.ovh.com/soapi/soapi-re-1.59.wsdl'
+ imp.filter.add('http://soapi.ovh.com/manager')
+ d = ImportDoctor(imp)
+
+ tmp_dir = tempfile.mkdtemp()
+ tempfile.tempdir = tmp_dir
+ atexit.register(remove_tmp_dir, tmp_dir)
+
+ try:
+ soap = Client(url, doctor=d)
+ session = soap.service.login(options["--username"], options["--password"], 'en', 0)
+ except Exception as e:
+ logging.error("Failed: {}".format(str(e)))
+ fail(EC_LOGIN_DENIED)
+
+ options["session"] = session
+ return soap
+
+def remove_tmp_dir(tmp_dir):
+ shutil.rmtree(tmp_dir)
+
+def main():
+ device_opt = ["login", "passwd", "port", "email", "no_status", "web"]
+
+ atexit.register(atexit_handler)
+
+ define_new_opts()
+ options = check_input(device_opt, process_input(device_opt), other_conditions=True)
+
+ docs = {}
+ docs["shortdesc"] = "Fence agent for OVH"
+ docs["longdesc"] = "fence_ovh is an Power Fencing agent \
+which can be used within OVH datecentre. \
+Poweroff is simulated with a reboot into rescue-pro mode."
+
+ docs["vendorurl"] = "http://www.ovh.net"
+ show_docs(options, docs)
+
+ if options["--action"] == "list":
+ fail_usage("Action 'list' is not supported in this fence agent")
+
+ if options["--action"] == "list-status":
+ fail_usage("Action 'list-status' is not supported in this fence agent")
+
+ if "--email" not in options:
+ fail_usage("You have to enter e-mail address which is notified by fence agent")
+
+ if options["--action"] == "validate-all":
+ sys.exit(0)
+
+ if options["--action"] != "monitor" and not options["--plug"].endswith(".ovh.net"):
+ options["--plug"] += ".ovh.net"
+
+ run_delay(options)
+
+ conn = soap_login(options)
+
+ if options["--action"] == 'monitor':
+ try:
+ conn.service.logout(options["session"])
+ except Exception:
+ pass
+ sys.exit(0)
+
+ # Save datetime just before changing netboot
+ before_netboot_reboot = datetime.now()
+
+ if options["--action"] == 'off':
+ # Reboot in Rescue-pro
+ netboot_reboot(conn, options, OVH_RESCUE_PRO_NETBOOT_ID)
+ time.sleep(STATUS_RESCUE_PRO_SLEEP)
+ elif options["--action"] in ['on', 'reboot']:
+ # Reboot from HD
+ netboot_reboot(conn, options, OVH_HARD_DISK_NETBOOT_ID)
+ time.sleep(STATUS_HARD_DISK_SLEEP)
+
+ # Save datetime just after reboot
+ after_netboot_reboot = datetime.now()
+
+ # Verify that action was completed sucesfully
+ reboot_t = reboot_time(conn, options)
+
+ logging.debug("reboot_start_end.start: %s\n",
+ reboot_t.start.strftime('%Y-%m-%d %H:%M:%S'))
+ logging.debug("before_netboot_reboot: %s\n",
+ before_netboot_reboot.strftime('%Y-%m-%d %H:%M:%S'))
+ logging.debug("reboot_start_end.end: %s\n",
+ reboot_t.end.strftime('%Y-%m-%d %H:%M:%S'))
+ logging.debug("after_netboot_reboot: %s\n",
+ after_netboot_reboot.strftime('%Y-%m-%d %H:%M:%S'))
+
+ if reboot_t.start < after_netboot_reboot < reboot_t.end:
+ result = 0
+ logging.debug("Netboot reboot went OK.\n")
+ else:
+ result = 1
+ logging.debug("ERROR: Netboot reboot wasn't OK.\n")
+
+ try:
+ conn.service.logout(options["session"])
+ except Exception:
+ pass
+
+ sys.exit(result)
+
+if __name__ == "__main__":
+ main()