#!/usr/bin/python
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.




import sys, os, subprocess, errno, re
from os.path import exists

TOOl_PATH = "/usr/bin/ipmitool"

try:
    from subprocess import check_call
    from subprocess import CalledProcessError
except ImportError:
    def check_call(*popenargs, **kwargs):
        import subprocess
        retcode = subprocess.call(*popenargs, **kwargs)
        cmd = kwargs.get("args")
        if cmd is None: cmd = popenargs[0]
        if retcode: raise CalledProcessError(retcode, cmd)
        return retcode

    class CalledProcessError(Exception):
        def __init__(self, returncode, cmd):
            self.returncode = returncode ; self.cmd = cmd
        def __str__(self): return "Command '%s' returned non-zero exit status %d" % (self.cmd, self.returncode)

class Command:
    def __init__(self,name,parent=None):
        self.__name = name
        self.__parent = parent
    def __getattr__(self,name):
        if name == "_print": name = "print"
        return Command(name,self)
    def __call__(self,*args):
        class CommandOutput:
            def __init__(self,ret,stdout,stderr):
                self.stdout = stdout
                self.stderr = stderr
                self.ret = ret

        cmd = self.__get_recursive_name() + list(args)
        #print "    ",cmd
        popen = subprocess.Popen(cmd,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
        m = popen.communicate()
        ret = popen.wait()
        return CommandOutput(ret,*m)
    def __get_recursive_name(self,sep=None):
        m = self
        l = []
        while m is not None:
            l.append(m.__name)
            m = m.__parent
        l.reverse()
        if sep: return sep.join(l)
        else: return l
    def __str__(self):
        return '<Command %r>'%self.__get_recursive_name(sep=" ")

    def __repr__(self): return self.__str__()


ipmitool = Command("ipmitool")

def check_tool():
    if exists(TOOl_PATH) == False:
        print "Can not find ipmitool"
        return False

def ping(args):
    hostname = args.get("hostname")
    usrname = args.get("usrname")
    password = args.get("password")

    if hostname == None:
        print "No hostname"
        return 1

    o = ipmitool("-H", hostname, "-U", usrname, "-P", password, "chassis", "power", "status")
    if o.ret:
        print o.stderr
        return 1
    else:
        print o.stdout
        return 0

def boot_dev(args):
    hostname = args.get("hostname")
    usrname = args.get("usrname")
    password = args.get("password")
    dev = args.get("dev")

    if hostname == None:
        print "No hostname"
        return 1

    if dev == None:
        print "No boot device specified"
        return 1

    o = ipmitool("-H", hostname, "-U", usrname, "-P", password, "chassis", "bootdev", dev)
    if o.ret:
        print o.stderr
        return 1
    else:
        return 0

def reboot(args):
    hostname = args.get("hostname")
    usrname = args.get("usrname")
    password = args.get("password")

    if hostname == None:
        print "No hostname"
        return 1

    o = ipmitool("-H", hostname, "-U", usrname, "-P", password, "chassis", "power", "status")
    if o.ret:
        print o.stderr
        return 1


    if "is on" in o.stdout:
        o = ipmitool("-H", hostname, "-U", usrname, "-P", password, "chassis", "power", "cycle")
    else:
        o = ipmitool("-H", hostname, "-U", usrname, "-P", password, "chassis", "power", "reset")

    if o.ret:
        print o.stderr
        return 1
    else:
        return 0

def power(args):
    hostname = args.get("hostname")
    usrname = args.get("usrname")
    password = args.get("password")
    action = args.get("action")

    if hostname == None:
        print "No hostname"
        return 1

    o = ipmitool("-H", hostname, "-U", usrname, "-P", password, "chassis", "power", action)
    if o.ret:
        print o.stderr
        return 1
    else:
        return 0

def boot_or_reboot(args):
    hostname = args.get("hostname")
    usrname = args.get("usrname")
    password = args.get("password")
    o = ipmitool("-H", hostname, "-U", usrname, "-P", password, "chassis", "power", "status")
    if o.ret:
        print o.stderr
        return 1

    if "is on" in o.stdout:
        return reboot(args)
    elif "is off" in o.stdout:
        args["action"] = "on"
        return power(args)
    else:
        print "unknown power status:" + o.stdout
        return 1


call_table = {"ping":ping, "boot_dev":boot_dev, "reboot":reboot, "power":power, "boot_or_reboot":boot_or_reboot}
def dispatch(args):
    cmd = args[1]
    params = args[2:]
    func_params = {}

    if call_table.has_key(cmd) == False:
        print "No function %s" % cmd
        return 1

    for p in params:
        pairs = p.split("=")
        if len(pairs) != 2:
            print "Invalid parameter %s" % p
            return 1
        func_params[pairs[0]] = pairs[1]

    func = call_table[cmd]
    return func(func_params)

if __name__ == "__main__":
    if check_tool() == False:
        sys.exit(1)
    if len(sys.argv) < 2:
        print "Not enough arguments, at least one"
        sys.exit(1)
    sys.exit(dispatch(sys.argv))
