mirror of
https://github.com/xcat2/confluent.git
synced 2024-11-22 09:32:21 +00:00
Flesh out the confetty interactive console slightly
This commit is contained in:
parent
51229d8185
commit
abab0e5cae
81
bin/confetty
81
bin/confetty
@ -29,12 +29,14 @@ import getpass
|
||||
import optparse
|
||||
import os
|
||||
import select
|
||||
import shlex
|
||||
import socket
|
||||
import ssl
|
||||
import sys
|
||||
import termios
|
||||
import tty
|
||||
|
||||
target = "/"
|
||||
path = os.path.dirname(os.path.realpath(__file__))
|
||||
path = os.path.realpath(os.path.join(path, '..'))
|
||||
sys.path.append(path)
|
||||
@ -47,6 +49,10 @@ conserversequence = '\x05c' # ctrl-e, c
|
||||
oldtcattr = termios.tcgetattr(sys.stdin.fileno())
|
||||
server = None
|
||||
|
||||
def prompt():
|
||||
sys.stdout.write(target + ' -> ')
|
||||
sys.stdout.flush()
|
||||
|
||||
def parseservervalue(serverstring):
|
||||
if serverstring.find(']:') != -1:
|
||||
server, port = serverstring[1:].split(']:')
|
||||
@ -61,6 +67,62 @@ def parseservervalue(serverstring):
|
||||
return (server, port)
|
||||
|
||||
|
||||
def parse_command(command):
|
||||
args = shlex.split(command, posix=True)
|
||||
return args
|
||||
|
||||
def do_command(command, server):
|
||||
global target
|
||||
if command == "": # result of ctrl-d
|
||||
command = "exit\n"
|
||||
print("exit")
|
||||
command = command[:-1]
|
||||
command = command.lower()
|
||||
argv = parse_command(command)
|
||||
if len(argv) == 0:
|
||||
prompt()
|
||||
return
|
||||
if argv[0] == "exit":
|
||||
server.close()
|
||||
sys.exit(0)
|
||||
if argv[0] == "cd":
|
||||
otarget = target
|
||||
change_target(argv[1])
|
||||
tlvdata.send_tlvdata(server, {"operation": 'retrieve', 'path': target})
|
||||
result = tlvdata.recv_tlvdata(server)
|
||||
if 'error' in result:
|
||||
print target + ':' + result['error']
|
||||
target = otarget
|
||||
|
||||
|
||||
|
||||
prompt()
|
||||
|
||||
|
||||
def change_target(path):
|
||||
global target
|
||||
pathcomponents = path.split("/")
|
||||
if pathcomponents[0] == "": # absolute path
|
||||
target = path
|
||||
else:
|
||||
targparts = target.split("/")[:-1]
|
||||
for component in pathcomponents:
|
||||
if component in ('.',''): # ignore these
|
||||
continue
|
||||
elif component == '..':
|
||||
if len(targparts) > 0:
|
||||
del targparts[-1]
|
||||
else:
|
||||
targparts.append(component)
|
||||
targparts.append('')
|
||||
target = '/'.join(targparts)
|
||||
if len(target) ==0 or target[-1] != '/':
|
||||
target += '/'
|
||||
|
||||
def startconsole():
|
||||
tty.setraw(sys.stdin.fileno())
|
||||
fcntl.fcntl(sys.stdin.fileno(), fcntl.F_SETFL, os.O_NONBLOCK)
|
||||
|
||||
def exit(code=0):
|
||||
termios.tcsetattr(sys.stdin.fileno(), termios.TCSANOW, oldtcattr)
|
||||
server.shutdown(socket.SHUT_RDWR)
|
||||
@ -151,13 +213,15 @@ while authinfo['authpassed'] != 1:
|
||||
tlvdata.send_tlvdata(server,
|
||||
{'username': username, 'passphrase': passphrase})
|
||||
authinfo = tlvdata.recv_tlvdata(server)
|
||||
tty.setraw(sys.stdin.fileno())
|
||||
fcntl.fcntl(sys.stdin.fileno(), fcntl.F_SETFL, os.O_NONBLOCK)
|
||||
# clear on start can help with readable of TUI, but it
|
||||
# can be annoying, so for now don't do it.
|
||||
# sys.stdout.write('\x1b[H\x1b[J')
|
||||
# sys.stdout.flush()
|
||||
|
||||
doexit = False
|
||||
inconsole = False
|
||||
pendingcommand = ""
|
||||
prompt()
|
||||
while not doexit:
|
||||
rdylist, _, _ = select.select((sys.stdin, server), (), (), 60)
|
||||
for fh in rdylist:
|
||||
@ -175,8 +239,13 @@ while not doexit:
|
||||
sys.stdout.write("\r\n[remote disconnected]\r\n")
|
||||
break
|
||||
else:
|
||||
input = fh.read()
|
||||
input = check_escape_seq(input, fh)
|
||||
if input:
|
||||
tlvdata.send_tlvdata(server, input)
|
||||
if inconsole:
|
||||
input = fh.read()
|
||||
input = check_escape_seq(input, fh)
|
||||
if input:
|
||||
tlvdata.send_tlvdata(server, input)
|
||||
else:
|
||||
command = fh.readline()
|
||||
inconsole = do_command(command, server)
|
||||
|
||||
exit()
|
||||
|
@ -91,7 +91,7 @@ class ConfluentChoiceMessage(ConfluentMessage):
|
||||
|
||||
|
||||
class LinkRelation(ConfluentMessage):
|
||||
def json_hal(self):
|
||||
def json(self):
|
||||
"""Provide json_hal style representation of the relation.
|
||||
|
||||
This currently only makes sense for the socket api.
|
||||
|
@ -9,9 +9,13 @@ import confluent.auth as auth
|
||||
import confluent.common.tlvdata as tlvdata
|
||||
import confluent.consoleserver as consoleserver
|
||||
import confluent.config.configmanager as configmanager
|
||||
import confluent.exceptions as exc
|
||||
import confluent.messages
|
||||
import confluent.pluginapi as pluginapi
|
||||
import eventlet.green.socket as socket
|
||||
import eventlet.green.ssl as ssl
|
||||
import eventlet
|
||||
import json
|
||||
import os
|
||||
import struct
|
||||
|
||||
@ -19,7 +23,7 @@ SO_PEERCRED = 17
|
||||
|
||||
class ClientConsole(object):
|
||||
def __init__(self, client):
|
||||
self.client = client
|
||||
self.client = clientn
|
||||
|
||||
def sendall(self, data):
|
||||
tlvdata.send_tlvdata(self.client, data)
|
||||
@ -41,7 +45,7 @@ def sessionhdl(connection, authname):
|
||||
response = tlvdata.recv_tlvdata(connection)
|
||||
username = response['username']
|
||||
passphrase = response['passphrase']
|
||||
# NOTE(jbjohnso): Here, we need to authenticate, but not
|
||||
# note(jbjohnso): here, we need to authenticate, but not
|
||||
# authorize a user. When authorization starts understanding
|
||||
# element path, that authorization will need to be called
|
||||
# per request the user makes
|
||||
@ -50,6 +54,34 @@ def sessionhdl(connection, authname):
|
||||
authenticated = True
|
||||
cfm = authdata[1]
|
||||
tlvdata.send_tlvdata(connection, {'authpassed': 1})
|
||||
request = tlvdata.recv_tlvdata(connection)
|
||||
while request is not None:
|
||||
process_request(connection, request, cfm, authdata)
|
||||
request = tlvdata.recv_tlvdata(connection)
|
||||
|
||||
|
||||
def send_response(responses, connection):
|
||||
for rsp in responses:
|
||||
tlvdata.send_tlvdata(connection, json.dumps(rsp.json()))
|
||||
|
||||
def process_request(connection, request, cfm, authdata):
|
||||
#TODO(jbjohnso): authorize each request
|
||||
if type(request) == dict:
|
||||
operation = request['operation']
|
||||
path = request['path']
|
||||
params = request.get('parameters', None)
|
||||
try:
|
||||
hdlr = pluginapi.handle_path(path, operation, cfm, params)
|
||||
except exc.NotFoundException:
|
||||
tlvdata.send_tlvdata(connection, {"errorcode": 404,
|
||||
"error": "Target not found"})
|
||||
return
|
||||
except exc.InvalidArgumentException:
|
||||
tlvdata.send_tlvdata(connection, {"errorcode": 400,
|
||||
"error": "Bad Request"})
|
||||
return
|
||||
send_response(hdlr, connection)
|
||||
return
|
||||
ccons = ClientConsole(connection)
|
||||
consession = consoleserver.ConsoleSession(node='n4', configmanager=cfm,
|
||||
datacallback=ccons.sendall)
|
||||
|
Loading…
Reference in New Issue
Block a user