Add shell run and output commands

Opengnsys needs a support to execute commands on the machine. This patch adds
the support for executing two new commands "shell/run" and "shell/output". The
first one, give us the support for executing a command in the machine and keep
save in a queue the output. The second one, give us the support for sending the
output from the command executed.
more_events
Alvaro Neira Ayuso 2019-12-27 13:46:49 +01:00 committed by Alvaro Neira Ayuso
parent dfc97ffedb
commit e20daf639d
4 changed files with 73 additions and 16 deletions

View File

@ -1,5 +1,6 @@
import email
from io import StringIO
import json
class HTTPParser:
def __init__(self):
@ -11,24 +12,32 @@ class HTTPParser:
self.contentLen = None
self.operation = None
self.URI = None
self.cmd = None
def parser(self,data):
self.requestLine, self.headersAlone = data.split('\n', 1)
self.headers = email.message_from_file(StringIO(self.headersAlone))
if 'host' in self.headers.keys():
self.host = self.headers['host']
if 'Host' in self.headers.keys():
self.host = self.headers['Host']
if 'content-type' in self.headers.keys():
self.contentType = self.headers['content-type']
if 'Content-Type' in self.headers.keys():
self.contentType = self.headers['Content-Type']
if 'content-length' in self.headers.keys():
self.contentLen = int(self.headers['content-length'])
if 'Content-Length' in self.headers.keys():
self.contentLen = int(self.headers['Content-Length'])
if (not self.requestLine == None or not self.requestLine == ''):
self.operation = self.requestLine.split('/', 1)[0]
self.URI = self.requestLine.split('/', 1)[1]
if not self.contentLen == 0:
msgs = self.headersAlone.rstrip().split('\n')
cmd = msgs[len(msgs) - 1]
jsoncmd = json.loads(cmd)
if "run" in cmd:
self.cmd = jsoncmd["run"]
def getHeaderLine(self):
return self.headersAlone
@ -52,3 +61,6 @@ class HTTPParser:
def getURI(self):
return self.URI
def getCMD(self):
return self.cmd

View File

@ -14,3 +14,8 @@ def reboot():
subprocess.call('source ' + OG_SCRIPT_PATH + 'etc/preinit/loadenviron.sh; ' + OG_SCRIPT_PATH + 'scripts/reboot', shell=True)
else:
subprocess.call(['/sbin/reboot'])
def execCMD(cmd):
cmds = cmd.split(" ")
result = subprocess.run(cmds, stdout=subprocess.PIPE)
return result.stdout.decode('utf-8')

View File

@ -18,6 +18,7 @@ class ogClient:
def __init__(self, ip, port):
self.ip = ip
self.port = port
self.ogrest = ogRest()
def get_socket(self):
return self.sock
@ -74,7 +75,6 @@ class ogClient:
self.data = self.data + data
httpparser = HTTPParser()
ogrest = ogRest()
if not self.trailer:
if self.data.find("\r\n") > 0:
@ -89,7 +89,7 @@ class ogClient:
if self.trailer and len(self.data) >= self.content_len:
httpparser.parser(self.data)
ogrest.processOperation(httpparser.getRequestOP(), httpparser.getURI(), self)
self.ogrest.processOperation(httpparser.getRequestOP(), httpparser.getURI(), httpparser.getCMD(), self)
# Cleanup state information from request
self.data = ""

View File

@ -2,6 +2,8 @@ import threading
import platform
import time
from enum import Enum
import json
import queue
if platform.system() == 'Linux':
from src.linux import ogOperations
@ -12,21 +14,44 @@ class ogResponses(Enum):
OK=2
class ogRest():
def getResponse(self, response):
if response == ogResponses.BAD_REQUEST:
return 'HTTP/1.0 400 Bad request\r\n\r\n'
if response == ogResponses.IN_PROGRESS:
return 'HTTP/1.0 202 Accepted\r\n\r\n'
if response == ogResponses.OK:
return 'HTTP/1.0 200 OK\r\n\r\n'
def __init__(self):
self.msgqueue = queue.Queue(1000)
def processOperation(self, op, URI, client):
def buildJsonResponse(self, idstr, content):
data = { idstr :content }
return json.dumps(data)
def getResponse(self, response, idstr=None, content=None):
msg = ''
if response == ogResponses.BAD_REQUEST:
msg = 'HTTP/1.0 400 Bad request'
elif response == ogResponses.IN_PROGRESS:
msg = 'HTTP/1.0 202 Accepted'
elif response == ogResponses.OK:
msg = 'HTTP/1.0 200 OK'
else:
return msg
if not content == None:
jsonmsg = self.buildJsonResponse(idstr, content)
msg = msg + '\nContent-Type:application/json'
msg = msg + '\nContent-Length:' + str(len(jsonmsg))
msg = msg + '\n' + jsonmsg
msg = msg + '\r\n\r\n'
return msg
def processOperation(self, op, URI, cmd, client):
if ("poweroff" in URI):
self.process_poweroff(client)
elif ("reboot" in URI):
self.process_reboot(client)
elif ("probe" in URI):
self.process_probe(client)
elif ("shell/run" in URI):
self.process_shellrun(client, cmd)
elif ("shell/output" in URI):
self.process_shellout(client)
else:
client.send(self.getResponse(ogResponses.BAD_REQUEST))
@ -53,3 +78,18 @@ class ogRest():
def process_probe(self, client):
client.send(self.getResponse(ogResponses.OK))
def process_shellrun(self, client, cmd):
if cmd == None:
client.send(self.getResponse(ogResponses.BAD_REQUEST))
return
self.msgqueue.put(ogOperations.execCMD(cmd))
client.send(self.getResponse(ogResponses.IN_PROGRESS))
def process_shellout(self, client):
if self.msgqueue.empty():
client.send(self.getResponse(ogResponses.IN_PROGRESS, 'out', ''))
else:
out = self.msgqueue.get()
client.send(self.getResponse(ogResponses.IN_PROGRESS, 'out', out))