Advertisement
Guest User

Untitled

a guest
Aug 25th, 2016
108
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.05 KB | None | 0 0
  1. import sys, time, os, uuid, re
  2. import pycurl, pexpect
  3. import atexit
  4. import subprocess
  5. import threading
  6. import shlex
  7. from pipes import quote#@TODELETE
  8.  
  9. actions = ["status", "on", "off", "reboot"]
  10.  
  11. def get_power_status(_, options):
  12. output = run_command(options, create_command(options, "status"))
  13. match = re.search('[Cc]hassis [Pp]ower is [\\s]*([a-zA-Z]{2,3})', str(output))
  14. status = match.group(1) if match else None
  15. return status
  16.  
  17. def set_power_status(_, options):
  18. run_command(options, create_command(options, options["--action"]))
  19. return
  20.  
  21. def reboot_cycle(_, options):
  22. output = run_command(options, create_command(options, "cycle"))
  23. return bool(re.search('chassis power control: cycle', str(output).lower()))
  24.  
  25. def create_command(options, action):
  26. cmd = options["--ipmitool-path"]
  27.  
  28. # --lanplus / -L
  29. if "--lanplus" in options and options["--lanplus"] in ["", "1"]:
  30. cmd += " -I lanplus"
  31. else:
  32. cmd += " -I lan"
  33.  
  34. # --ip / -a
  35. cmd += " -H " + options["--ip"]
  36.  
  37. # --username / -l
  38. if "--username" in options and len(options["--username"]) != 0:
  39. cmd += " -U " + quote(options["--username"])
  40.  
  41. # --auth / -A
  42. if "--auth" in options:
  43. cmd += " -A " + options["--auth"]
  44.  
  45. # --password / -p
  46. if "--password" in options:
  47. cmd += " -P " + quote(options["--password"])
  48. else:
  49. cmd += " -P ''"
  50.  
  51. # --cipher / -C
  52. if "--cipher" in options:
  53. cmd += " -C " + options["--cipher"]
  54.  
  55. # --port / -n
  56. if "--ipport" in options:
  57. cmd += " -p " + options["--ipport"]
  58.  
  59. if "--privlvl" in options:
  60. cmd += " -L " + options["--privlvl"]
  61.  
  62. # --action / -o
  63. cmd += " chassis power " + action
  64.  
  65. # --use-sudo / -d
  66. if "--use-sudo" in options:
  67. cmd = options["--sudo-path"] + " " + cmd
  68.  
  69. return cmd
  70.  
  71. def run_command(options, command, timeout=None, env=None):
  72. if timeout is None and "--power-timeout" in options:
  73. timeout = options["--power-timeout"]
  74. if timeout is not None:
  75. timeout = float(timeout)
  76. try:
  77. process = subprocess.Popen(shlex.split(command), stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=env)
  78. except OSError:
  79. print("Unable to run %s\n" % command)
  80. sys.exit(1)
  81.  
  82. thread = threading.Thread(target=process.wait)
  83. thread.start()
  84. thread.join(timeout)
  85. if thread.is_alive():
  86. process.kill()
  87. print "Connection timed out"
  88. sys.exit(1)
  89.  
  90. status = process.wait()
  91.  
  92. (pipe_stdout, pipe_stderr) = process.communicate()
  93. process.stdout.close()
  94. process.stderr.close()
  95.  
  96. return (status, pipe_stdout, pipe_stderr)
  97.  
  98. def get_multi_power_fn(connection, options, get_power_fn):
  99. status = "off"
  100. plugs = options["--plugs"] if "--plugs" in options else [""]
  101.  
  102. for plug in plugs:
  103. try:
  104. options["--uuid"] = str(uuid.UUID(plug))
  105. except ValueError:
  106. pass
  107. except KeyError:
  108. pass
  109.  
  110. options["--plug"] = plug
  111. plug_status = get_power_fn(connection, options)
  112. if plug_status != "off":
  113. status = plug_status
  114.  
  115. return status
  116.  
  117. def set_multi_power_fn(connection, options, set_power_fn, get_power_fn, retry_attempts=1):
  118. plugs = options["--plugs"] if "--plugs" in options else [""]
  119.  
  120. for _ in range(retry_attempts):
  121. for plug in plugs:
  122. try:
  123. options["--uuid"] = str(uuid.UUID(plug))
  124. except ValueError:
  125. pass
  126. except KeyError:
  127. pass
  128.  
  129. options["--plug"] = plug
  130. set_power_fn(connection, options)
  131. time.sleep(int(options["--power-wait"]))
  132.  
  133. for _ in range(int(options["--power-timeout"])):
  134. if get_multi_power_fn(connection, options, get_power_fn) != options["--action"]:
  135. time.sleep(1)
  136. else:
  137. return True
  138. return False
  139.  
  140. def fence_action(connection, options, set_power_fn, get_power_fn, get_outlet_list=None, reboot_cycle_fn=None):
  141. result = 0
  142.  
  143. try:
  144. status = None
  145. if not "no_status" in options["device_opt"]:
  146. status = get_multi_power_fn(connection, options, get_power_fn)
  147. if status != "on" and status != "off":
  148. sys.exit(1)#@TODELETE fail(EC_STATUS)
  149.  
  150. if options["--action"] == status:
  151. if not (status == "on" and "force_on" in options["device_opt"]):
  152. print("Success: Already %s" % (status.upper()))
  153. return 0
  154.  
  155. if options["--action"] == "on":
  156. if set_multi_power_fn(connection, options, set_power_fn, get_power_fn, 1 + int(options["--retry-on"])):
  157. print("Success: Powered ON")
  158. else:
  159. sys.exit(1)#@TODELETE fail(EC_WAITING_ON)
  160. elif options["--action"] == "off":
  161. if set_multi_power_fn(connection, options, set_power_fn, get_power_fn):
  162. print("Success: Powered OFF")
  163. else:
  164. sys.exit(1)#@TODELETE fail(EC_WAITING_OFF)
  165. elif options["--action"] == "reboot":
  166. power_on = False
  167. if options.get("--method", "").lower() == "cycle" and reboot_cycle_fn is not None:
  168. for _ in range(1, 1 + int(options["--retry-on"])):
  169. if reboot_cycle_fn(connection, options):
  170. power_on = True
  171. break
  172.  
  173. if not power_on:
  174. sys.exit(1)#@TODELETE fail(EC_TIMED_OUT)
  175.  
  176. else:
  177. if status != "off":
  178. options["--action"] = "off"
  179. if not set_multi_power_fn(connection, options, set_power_fn, get_power_fn):
  180. sys.exit(1)#@TODELETE fail(EC_WAITING_OFF)
  181.  
  182. options["--action"] = "on"
  183.  
  184. try:
  185. power_on = set_multi_power_fn(connection, options, set_power_fn, get_power_fn, int(options["--retry-on"]))
  186. except Exception as ex:
  187. print("%s", str(ex))
  188.  
  189. if power_on == False:
  190. print('Timed out waiting to power ON\n')
  191.  
  192. print("Success: Rebooted")
  193. elif options["--action"] == "status":
  194. print("Status: " + status.upper())
  195. if status.upper() == "OFF":
  196. result = 2
  197. elif options["--action"] == "monitor":
  198. pass
  199. except pexpect.EOF:
  200. sys.exit(1)#@TODELETE fail(EC_CONNECTION_LOST)
  201. except pexpect.TIMEOUT:
  202. sys.exit(1)#@TODELETE fail(EC_TIMED_OUT)
  203. except pycurl.error as ex:
  204. print("%s\n", str(ex))
  205. sys.exit(1)#@TODELETE fail(EC_TIMED_OUT)
  206. except socket.timeout as ex:
  207. print("%s\n", str(ex))
  208. sys.exit(1)#@TODELETE fail(EC_TIMED_OUT)
  209.  
  210. return result
  211.  
  212.  
  213. def atexit_handler():
  214. try:
  215. sys.stdout.close()
  216. os.close(1)
  217. except IOError:
  218. print ("%s failed to close standard output\n", sys.argv[0])
  219. sys.exit(1)
  220.  
  221. def fence_ipmilan_main(ip, username, password, action):
  222. atexit.register(atexit_handler)
  223.  
  224. options = {'--ipmitool-path': '/usr/bin/ipmitool', '--ipport': '623', '--power-timeout': '20','--privlvl': 'ADMINISTRATOR', '--method': 'ONOFF', '--delay': '0',
  225. 'device_opt': ['ipaddr', 'login', 'no_login', 'no_password', 'passwd', 'diag', 'lanplus', 'auth', 'cipher', 'privlvl', 'sudo', 'ipmitool_path', 'method', 'ipport', 'inet4_only', 'inet6_only',
  226. 'passwd_script', 'sudo_path', 'help', 'debug', 'verbose', 'version', 'action', 'agent', 'power_timeout', 'shell_timeout', 'login_timeout', 'power_wait', 'retry_on', 'delay', 'port_as_ip', 'port', 'separator'],
  227. '--separator': ',', '--shell-timeout': '3', '--power-wait': 2, '--retry-on': '1', '--sudo-path': '@SUDO_PATH@', '--lanplus': '', '--login-timeout': '5'}
  228.  
  229. if action not in actions:
  230. print "Action not supported!"
  231. sys.exit(1)
  232. options['--action'] = action
  233. options['--ip'] = ip
  234. options['--username'] = username
  235. options['--password'] = password
  236.  
  237. result = fence_action(None, options, set_power_status, get_power_status, None, reboot_cycle)
  238. sys.exit(result)
  239.  
  240.  
  241. if __name__ == "__main__":
  242. fence_ipmilan_main(ip='10.108.*.*', username='username', password="password", action="status")
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement