#!/usr/bin/python import socket, sys, termios, tty, select, urllib, urllib2, json, warnings, getpass with warnings.catch_warnings(): warnings.simplefilter("ignore") import paramiko key = "abcde" endpoint = "http://cvm.local/api.local.php" def posix_shell(chan, ctid): oldtty = termios.tcgetattr(sys.stdin) enable_input = False try: tty.setraw(sys.stdin.fileno()) tty.setcbreak(sys.stdin.fileno()) chan.settimeout(0.0) chan.send('%s\n' % ctid) while True: r, w, e = select.select([chan, sys.stdin], [], []) if chan in r: try: buff = chan.recv(1024) if len(buff) == 0: print '\r\nYou have been logged out of your container. Goodbye!\r\n', break if "entered into" in buff: # Successfully entered into the container, we can enable user input now. enable_input = True sys.stdout.write(buff) sys.stdout.flush() except socket.timeout: pass if sys.stdin in r: if enable_input == True: buff = sys.stdin.read(1) if len(buff) == 0: break chan.send(buff) finally: termios.tcsetattr(sys.stdin, termios.TCSADRAIN, oldtty) def open_shell(hostname, user, container): ssh = paramiko.SSHClient() ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) sshkey = paramiko.RSAKey.from_private_key_file('/etc/cvm/key') ssh.connect(hostname, username=user, pkey=sshkey) chan = ssh.invoke_shell() posix_shell(chan, container) chan.close() ssh.close() def api_request(parameters, method="GET"): if method == "GET": querystring = urllib.urlencode(parameters) req = urllib2.Request(endpoint + "?" + querystring) response = urllib2.urlopen(req) result = response.read() return json.loads(result) def show_list(): print "" for key, vps in vpsmap.items(): node = nodemap[vps['node_id']] print "%s. %s (%s [%s], %s)" % (key, vps['hostname'], node['name'], node['hostname'], node['physical_location']) print "" choice = raw_input("Make your choice: ") try: current_vps = vpsmap[int(choice)] current_node = nodemap[current_vps['node_id']] open_shell(current_node['hostname'], "vz", current_vps['internal_id']) except KeyError, ValueError: print "That was not a valid option. Try again. " show_list() except paramiko.AuthenticationException: print "Could not connect to the node." exit(1) print "#############################################################" print "### CVM OpenVZ shell dropper ###" print "#############################################################" print "" print "Please enter your VPS panel login details to continue." print "" username = raw_input("Username: ") password = getpass.getpass("Password: ") print "" auth_result = api_request({ 'key': key, 'action': "verify_user", 'username': username, 'password': password }) if auth_result['data']['correct'] == True: vpslist = api_request({ 'key': key, 'action': "list_vps", 'userid': auth_result["data"]["userid"] }) print "Select the container you wish to log in to." print "" i = 1 vpsmap = {} nodelist = [] nodemap = {} for vps in vpslist["data"]: vpsmap[i] = vps if vps["node_id"] not in nodelist: nodelist.append(vps["node_id"]) i += 1 for node in nodelist: nodemap[node] = api_request({ 'key': key, 'action': "node_info", 'nodeid': node })['data'] show_list() exit(0) else: print "The supplied login details are invalid." print "Your session will now be closed." exit(1)