Gitweb: http://git.fedorahosted.org/git/?p=fence-agents.git;a=commitdiff;h=c61430f65... Commit: c61430f65c843c4e4b7b3487f378d306efe1d52a Parent: cff73b867e9e39d4161d825192b0d295751ba968 Author: Marek 'marx' Grac mgrac@redhat.com AuthorDate: Wed Jul 17 17:42:13 2013 +0200 Committer: Marek 'marx' Grac mgrac@redhat.com CommitterDate: Wed Jul 17 17:42:13 2013 +0200
fence_ovh: New fence agent for OVH
Be aware that "off" command represents reboot into rescue mode --- configure.ac | 1 + fence/agents/ovh/Makefile.am | 17 +++++ fence/agents/ovh/fence_ovh.py | 136 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 154 insertions(+), 0 deletions(-)
diff --git a/configure.ac b/configure.ac index f3acb13..910cab8 100644 --- a/configure.ac +++ b/configure.ac @@ -278,6 +278,7 @@ AC_CONFIG_FILES([Makefile fence/agents/mcdata/Makefile fence/agents/nss_wrapper/Makefile fence/agents/rackswitch/Makefile + fence/agents/ovh/Makefile fence/agents/rhevm/Makefile fence/agents/rsa/Makefile fence/agents/rsb/Makefile diff --git a/fence/agents/ovh/Makefile.am b/fence/agents/ovh/Makefile.am new file mode 100644 index 0000000..c6d7d01 --- /dev/null +++ b/fence/agents/ovh/Makefile.am @@ -0,0 +1,17 @@ +MAINTAINERCLEANFILES = Makefile.in + +TARGET = fence_ovh + +SRC = $(TARGET).py + +EXTRA_DIST = $(SRC) + +sbin_SCRIPTS = $(TARGET) + +man_MANS = $(TARGET).8 + +include $(top_srcdir)/make/fencebuild.mk +include $(top_srcdir)/make/fenceman.mk + +clean-local: clean-man + rm -f $(TARGET) diff --git a/fence/agents/ovh/fence_ovh.py b/fence/agents/ovh/fence_ovh.py new file mode 100644 index 0000000..881aa90 --- /dev/null +++ b/fence/agents/ovh/fence_ovh.py @@ -0,0 +1,136 @@ +#!/usr/bin/python +# 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 +from datetime import datetime +from suds.client import Client +from suds.xsd.doctor import ImportDoctor, Import +sys.path.append("@FENCEAGENTSLIBDIR@") +from fencing import * + +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", + "default" : "", + "order" : 1 } + +def netboot_reboot(options, mode): + conn = soap_login(options) + + # 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(options): + conn = soap_login(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 + + conn.logout(options["session"]) + + 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) + + try: + soap = Client(url, doctor=d) + session = soap.service.login(options["--username"], options["--password"], 'en', 0) + except Exception, ex: + fail(EC_LOGIN_DENIED) + + options["session"] = session + return soap + +def main(): + device_opt = [ "login", "passwd", "port", "email" ] + + atexit.register(atexit_handler) + + define_new_opts() + options = check_input(device_opt, process_input(device_opt)) + + 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"] in [ "list", "status"]: + fail_usage("Action '" + options["--action"] + "' is not supported in this fence agent") + + if options["--plug"].endswith(".ovh.net") == False: + options["--plug"] += ".ovh.net" + + if options.has_key("--email") == False: + fail_usage("You have to enter e-mail address which is notified by fence agent") + + # Save datetime just before changing netboot + before_netboot_reboot = datetime.now() + + if options["--action"] == 'off': + # Reboot in Rescue-pro + netboot_reboot(options,OVH_RESCUE_PRO_NETBOOT_ID) + time.sleep(STATUS_RESCUE_PRO_SLEEP) + elif options["--action"] in ['on', 'reboot' ]: + # Reboot from HD + netboot_reboot(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(options) + + if options.has_key("--verbose"): + options["debug_fh"].write("reboot_start_end.start: "+ reboot_t.start.strftime('%Y-%m-%d %H:%M:%S')+"\n") + options["debug_fh"].write("before_netboot_reboot: " + before_netboot_reboot.strftime('%Y-%m-%d %H:%M:%S')+"\n") + options["debug_fh"].write("reboot_start_end.end: " + reboot_t.end.strftime('%Y-%m-%d %H:%M:%S')+"\n") + options["debug_fh"].write("after_netboot_reboot: " + after_netboot_reboot.strftime('%Y-%m-%d %H:%M:%S')+"\n") + + if reboot_t.start < after_netboot_reboot < reboot_t.end: + result = 0 + if options.has_key("--verbose"): + options["debug_fh"].write("Netboot reboot went OK.\n") + else: + result = 1 + if options.has_key("--verbose"): + options["debug_fh"].write("ERROR: Netboot reboot wasn't OK.\n") + + sys.exit(result) + + +if __name__ == "__main__": + main()