#!@PYTHON@
#
# Stonith module for RILOE Stonith device
#
# Copyright (c) 2004 Alain St-Denis <alain.st-denis@ec.gc.ca>
#
# Modified by Alan Robertson <alanr@unix.sh> for STONITH external compatibility.
# Extended and merged by Tijl Van den broeck <subspawn@gmail.com>
#  with ilo-v2 script from Guy Coates
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
# 
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# Lesser General Public License for more details.
# 
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
#
import sys
import os
import socket
from httplib import *
from time import sleep


argv = sys.argv

# Environment variables
# REALHOST (host that we are responsible for)
# ILOHOST (hostname of the ilo)
# ILOUSER (username for ilo login)
# ILOPASS (password for the ilo)
# CAN_RESET (does the ILO in question support RESET commands)
# POWERDOWN_METHOD (also version dependant, atm possible options: 1 or 2)


try:
        cmd = argv[1]
except IndexError:
        print "Not enough arguments"
        sys.exit(1)

try:
        ilohost = os.environ['ILOHOST']
        ilouser = os.environ['ILOUSER']
        ilopass = os.environ['ILOPASS']
        realhost = os.environ['REALHOST']
        reset_ok = os.environ['CAN_RESET']
        power_method = os.environ['POWERDOWN_METHOD']
        #	Some old RILOE devices don't support the reset command
        #	This variable is 1 if it does.
        if reset_ok == '':
          reset_ok = None
        anypass=1
except KeyError:
        ilopass = ""
        anypass=0

login = [ '<RIBCL VERSION="2.0">',
          '<LOGIN USER_LOGIN="'
    + ilouser + 
    '" PASSWORD="'
	  + ilopass + '">' ]


logout = [ '</LOGIN>', '</RIBCL>' ]


status = [ '<SERVER_INFO MODE="read">', '<GET_HOST_POWER_STATUS/>',
           '</SERVER_INFO>' ]



reset = [ '<SERVER_INFO MODE="write">','<RESET_SERVER/>','</SERVER_INFO>' ]


if power_method == '1':
  off = [ '<SERVER_INFO MODE = "write">', '<SET_HOST_POWER HOST_POWER  = "N"/>',
          '</SERVER_INFO>' ]
elif power_method == '2':
  off = [ '<SERVER_INFO MODE="write">', '<HOLD_PWR_BTN/>', '</SERVER_INFO>' ]


on = [ '<SERVER_INFO MODE = "write">', '<SET_HOST_POWER HOST_POWER  = "Y"/>',
          '</SERVER_INFO>' ]


todo = { 'reset':reset, 'on':on, 'off':off, 'status':status }

xmlinfo = '''<parameters>
 <parameter name="REALHOST" unique=1>
  <content type="string"/>
  <shortdesc lang="en">hostname</shortdesc>
  <longdesc lang=en>
   The hostname that the ilo controls
  </longdesc>
 </parameter>
<parameter name="ILOHOST" unique=1>
  <content type="string"/>
  <shortdesc lang="en">ilohostname</shortdesc>
  <longdesc lang=en>
   The hostname of the ilo device
  </longdesc>
 </parameter>
<parameter name="ILOUSER" unique=1>
  <content type="string"/>
  <shortdesc lang="en">ilousername</shortdesc>
  <longdesc lang=en>
   The user for connecting to the ilo device
  </longdesc>
 </parameter>
<parameter name="ILOPASS" unique=1>
  <content type="string"/>
  <shortdesc lang="en">password</shortdesc>
  <longdesc lang=en>
   The password for the ilo device user
  </longdesc>
 </parameter>
</parameters>
<parameter name="CAN_RESET" unique=1>
  <content type="string"/>
  <shortdesc lang="en">can_reset</shortdesc>
  <longdesc lang=en>
   Can the ilo issue resets (hint: older ones cannot)
  </longdesc>
 </parameter>
</parameters>
<parameter name="POWERDOWN_METHOD" unique=1>
  <content type="string"/>
  <shortdesc lang="en">powerdown_method</shortdesc>
  <longdesc lang=en>
   The method to powerdown the host in question (use 1 or 2)
  </longdesc>
 </parameter>
</parameters>'''

info = {
        'getinfo-devid':	'RILOE',
        'getinfo-devname':	'riloe ' + ilohost,
        'getinfo-devdescr':	'COMPAQ RILOE STONITH device',
        'getinfo-devurl':	'http://www.hp.com/',
	      'gethosts':	 realhost,
        'getinfo-xml':		xmlinfo
}

try:
        print info[cmd]
        sys.exit(0)
except KeyError:
        None

if cmd == 'getconfignames':
        for arg in ['ILOUSER', 'ILOPASSWD', 'ILOHOST', 'REALHOST', 'CAN_RESET', 'POWERDOWN_METHOD']:
            print arg
        sys.exit(0)

#
#	All remaining commands need host and password to succeed...
#

if ilohost == '<unconfigured>':
        print "Missing 'ILOHOST' environment variable"
        sys.exit(1)
if not anypass:
        print "Missing 'ILOPASSWD' environment variable"
        sys.exit(1)

acmds=[]


try:
        if cmd == 'reset' and not reset_ok:
                acmds.append(login + todo['off'] + logout)
                acmds.append(login + todo['on'] + logout)
        else:   
                acmds.append(login + todo[cmd] + logout)
except KeyError:
        print 'Invalid command: '+ cmd
        sys.exit(1)


try:
        for cmds in acmds:

                c=HTTPSConnection(ilohost)
                c.send('<?xml version="1.0"?>\r\n')
                c.sock.recv(1024)


                for line in cmds:
                        c.send(line+'\r\n')
                        c.sock.recv(1024)

                c.close()
                sleep(1)


except socket.gaierror, msg:
        print "ERROR: " + str(msg) + ": " + ilohost
        sys.exit(1)
except socket.sslerror, msg:
        print "ERROR: " + str(msg) + "for " + ilohost
        sys.exit(1)
except socket.error, msg:
        print "ERROR: " + str(msg) + "talking to " + ilohost
        sys.exit(1)
