diff options
Diffstat (limited to 'agents/autodetect/autodetect.py')
-rwxr-xr-x | agents/autodetect/autodetect.py | 255 |
1 files changed, 255 insertions, 0 deletions
diff --git a/agents/autodetect/autodetect.py b/agents/autodetect/autodetect.py new file mode 100755 index 0000000..24d9a73 --- /dev/null +++ b/agents/autodetect/autodetect.py @@ -0,0 +1,255 @@ +#!/usr/bin/python + +import pexpect +import re +import logging +import time +import sys +import fencing + +import fence_apc +import fence_bladecenter +import fence_brocade +import fence_rsa + +def check_agent(conn, options, found_prompt, prompts, test_fn, eol=None): + options["--action"] = "list" + options["--command-prompt"] = found_prompt + if any(x in options["--command-prompt"][0] for x in prompts): + options["--command-prompt"] = prompts + + return test_fn(conn, options) + return False + +def get_list(conn, options, found_prompt, prompts, list_fn, eol=None): + def test_fn(conn, options): + if len(list_fn(conn, options)) > 0: + return True + else: + return False + + return check_agent(conn, options, found_prompt, prompts, test_fn, eol) + +""" *************************** MAIN ******************************** """ + + +def detect_login_telnet(options): + options["--ipport"] = 23 + re_login_string = r"([\r\n])((?!Last )login\s*:)|((?!Last )Login Name: )|(username: )|(User Name :)" + re_login = re.compile(re_login_string, re.IGNORECASE) + re_pass = re.compile("(password)|(pass phrase)", re.IGNORECASE) + + options["eol"] = "\r\n" + conn = fencing.fspawn(options, options["--telnet-path"]) + conn.send("set binary\n") + conn.send("open %s -%s\n"%(options["--ip"], options["--ipport"])) + + conn.log_expect(re_login, int(options["--login-timeout"])) + conn.send_eol(options["--username"]) + + ## automatically change end of line separator + screen = conn.read_nonblocking(size=100, timeout=int(options["--shell-timeout"])) + if re_login.search(screen) != None: + options["eol"] = "\n" + conn.send_eol(options["--username"]) + conn.log_expect(re_pass, int(options["--login-timeout"])) + elif re_pass.search(screen) == None: + conn.log_expect(re_pass, int(options["--shell-timeout"])) + + try: + conn.send_eol(options["--password"]) + valid_password = conn.log_expect([re_login] + \ + [pexpect.TIMEOUT], int(options["--shell-timeout"])) + if valid_password == 0: + ## password is invalid or we have to change EOL separator + options["eol"] = "\r" + conn.send_eol("") + screen = conn.read_nonblocking(size=100, timeout=int(options["--shell-timeout"])) + ## after sending EOL the fence device can either show 'Login' or 'Password' + if re_login.search(conn.after + screen) != None: + conn.send_eol("") + conn.send_eol(options["--username"]) + conn.log_expect(re_pass, int(options["--login-timeout"])) + conn.send_eol(options["--password"]) + conn.log_expect(pexpect.TIMEOUT, int(options["--login-timeout"])) + except KeyError: + fencing.fail(fencing.EC_PASSWORD_MISSING) + + found_cmd_prompt = guess_prompt(conn, options, conn.before) + return (found_cmd_prompt, conn) + +def guess_prompt(conn, options, before=""): + time.sleep(2) + conn.send_eol("") + conn.send_eol("") + + conn.log_expect(pexpect.TIMEOUT, int(options["--login-timeout"])) + lines = re.split(r'\r|\n', before + conn.before) + logging.info("Cmd-prompt candidate: %s" % (lines[-1])) + if lines.count(lines[-1]) >= 3: + found_cmd_prompt = ["\n" + lines[-1]] + else: + if lines.count(lines[-1]) == 2: + conn.log_expect(lines[-1], int(options["--shell-timeout"])) + conn.log_expect(lines[-1], int(options["--shell-timeout"])) + options["eol"] = "\r" + conn.send_eol("") + time.sleep(0.1) + conn.send_eol("") + time.sleep(0.1) + conn.send_eol("") + time.sleep(0.1) + conn.log_expect(pexpect.TIMEOUT, int(options["--login-timeout"])) + lines = re.split(r'\r|\n', conn.before) + logging.info("Cmd-prompt candidate: %s" % (lines[1])) + if lines.count(lines[-1]) >= 3: + found_cmd_prompt = ["\n" + lines[-1]] + else: + print "Unable to obtain command prompt automatically" + sys.exit(1) + else: + print "Unable to obtain command prompt automatically" + print lines[-1] + print conn.before + sys.exit(1) + + conn.log_expect(found_cmd_prompt, int(options["--shell-timeout"])) + conn.log_expect(found_cmd_prompt, int(options["--shell-timeout"])) + conn.log_expect(found_cmd_prompt, int(options["--shell-timeout"])) + + # Handle situation when CR/LF is interpreted as ENTER, ENTER + # In such case we will have get two additional command prompts to get on right position + res = conn.log_expect([pexpect.TIMEOUT] + found_cmd_prompt, int(options["--shell-timeout"])) + if res > 0: + # @note: store that information? + print "CMD twice" + conn.log_expect(found_cmd_prompt, int(options["--shell-timeout"])) + return found_cmd_prompt + +def detect_login_ssh(options, version=2): + options["--ipport"] = 22 + if version == "1": + command = '%s %s@%s -p %s -1 -c blowfish -o PubkeyAuthentication=no' % (options["--ssh-path"], options["--username"], options["--ip"], options["--ipport"]) + else: + command = '%s %s@%s -p %s -o PubkeyAuthentication=no' % (options["--ssh-path"], options["--username"], options["--ip"], options["--ipport"]) + + conn = fencing.fspawn(options, command) + result = conn.log_expect(["ssword:", "Are you sure you want to continue connecting (yes/no)?"], int(options["--login-timeout"])) + if result == 1: + conn.send("yes\n") + conn.log_expect("ssword:", int(options["--login-timeout"])) + + conn.send(options["--password"] + "\n") + + found_cmd_prompt = guess_prompt(conn, options, conn.before) + return (found_cmd_prompt, conn) + +def detect_device(conn, options, found_cmd_prompt): + if get_list(conn, options, found_cmd_prompt, prompts=["\n>", "\napc>"], list_fn=fence_apc.get_power_status): + fencing.fence_logout(conn, "4") + return "fence_apc # older serie" + + if get_list(conn, options, found_cmd_prompt, prompts=["\n>", "\napc>"], list_fn=fence_apc.get_power_status5): + fencing.fence_logout(conn, "exit") + return "fence_apc # v5+" + + ## Test fence_lpar with list action (HMC version 3 and 4) + def test_lpar(conn, options): + conn.send_eol("lssyscfg; echo $?") + conn.log_expect(options["--command-prompt"], int(options["--shell-timeout"])) + if "\n0\r\n" in conn.before: + return True + else: + return False + + if check_agent(conn, options, found_cmd_prompt, [r":~>", r"]\$", r"\$ "], test_lpar): + fencing.fence_logout(conn, "quit") + return "fence_lpar # 2" + + if get_list(conn, options, found_cmd_prompt, prompts=["system>"], list_fn=fence_bladecenter.get_blades_list): + fencing.fence_logout(conn, "exit") + return "fence_bladecenter #2" + + if get_list(conn, options, found_cmd_prompt, prompts=["> "], list_fn=fence_brocade.get_power_status, eol="\n"): + fencing.fence_logout(conn, "exit") + return "fence_brocade #2" + + if get_list(conn, options, found_cmd_prompt, prompts=["> "], list_fn=fence_rsa.get_power_status): + fencing.fence_logout(conn, "exit") + return "fence_rsa" + + return None + +# Test fence ilo moonshot +#cmd_possible = ["MP>", "hpiLO->"] +#options["--action"] = "list" +#options["--command-prompt"] = found_cmd_prompt +#options["eol"] = "\n" +#if any(x in options["--command-prompt"][0] for x in cmd_possible): +# options["--command-prompt"] = cmd_possible +# +# plugs = fence_ilo_moonshot.get_power_status(conn, options) +# if len(plugs) > 0: +# print "fence_ilo_moonshot # " +# fencing.fence_logout(conn, "exit") +# sys.exit(0) + +def xxx(): + ## login mechanism as in fencing.py.py - differences is that we do not know command prompt + #logging.getLogger().setLevel(logging.DEBUG) + options = {} + options["--ssh-path"] = "/usr/bin/ssh" + options["--telnet-path"] = "/usr/bin/telnet" + + # virtual machine + #options["--username"] = "marx" + #options["--ip"] = "localhost" + #options["--password"] = "batalion" + + # APC + #options["--username"] = "labuser" + #options["--ip"] = "pdu-bar.englab.brq.redhat.com" + #options["--password"] = "labuser" + + # LPAR + options["--username"] = "rhts" + options["--ip"] = "ppc-hmc-01.mgmt.lab.eng.bos.redhat.com" + #options["--ip"] = "ibm-js22-vios-02.rhts.eng.bos.redhat.com" + options["--password"] = "100yard-" + + # Bladecenter + options["--ip"] = "blade-mm.englab.brq.redhat.com" + + # Brocade + #options["--ip"] = "hp-fcswitch-01.lab.bos.redhat.com" + #options["--password"] = "password" + #options["--username"] = "admin" + + # iLO Moonshot - chova sa to divne + #options["--password"] = "Access@gis" + #options["--username"] = "rcuser" + #options["--ip"] = "hp-m1500-mgmt.gsslab.pnq.redhat.com" + + #options["--ip"] = "ibm-x3755-01-rsa.ovirt.rhts.eng.bos.redhat.com" + #options["--username"] = "USERID" + #options["--password"] = "PASSW0RD" + + options["--login-timeout"] = "10" + options["--shell-timeout"] = "5" + options["--power-timeout"] = "10" + + options["eol"] = "\r\n" + + (found_cmd_prompt, conn) = detect_login_telnet(options) + #(found_cmd_prompt, conn) = detect_login_ssh(options) + + res = detect_device(conn, options, found_cmd_prompt) + if not res is None: + print res + sys.exit(0) + else: + ## Nothing found + sys.exit(2) + +if __name__ == "__main__": + xxx() |