Commit 06006524 authored by Łukasz Nowak's avatar Łukasz Nowak
parent 9c399c40
from flask import g, Flask, request, abort from flask import g, Flask, request, abort, json
import xml_marshaller import xml_marshaller.xml_marshaller
from slapos.slap.slap import Computer, ComputerPartition, SoftwareRelease
from lxml import etree from lxml import etree
from slapos.slap.slap import Computer, ComputerPartition, SoftwareRelease, SoftwareInstance from lxml.etree import XMLSyntaxError
import sqlite3 import sqlite3
from simplejson.decoder import JSONDecodeError
app = Flask(__name__) app = Flask(__name__)
DB_VERSION = app.open_resource('schema.sql').readline().strip().split(':')[1] DB_VERSION = app.open_resource('schema.sql').readline().strip().split(':')[1]
...@@ -10,6 +12,7 @@ DB_VERSION = app.open_resource('schema.sql').readline().strip().split(':')[1] ...@@ -10,6 +12,7 @@ DB_VERSION = app.open_resource('schema.sql').readline().strip().split(':')[1]
class UnauthorizedError(Exception): class UnauthorizedError(Exception):
pass pass
#Deprecated
def xml2dict(xml): def xml2dict(xml):
result_dict = {} result_dict = {}
if xml is not None and xml != '': if xml is not None and xml != '':
...@@ -25,6 +28,7 @@ def xml2dict(xml): ...@@ -25,6 +28,7 @@ def xml2dict(xml):
result_dict[key] = value result_dict[key] = value
return result_dict return result_dict
#Deprecated
def dict2xml(dictionnary): def dict2xml(dictionnary):
instance = etree.Element('instance') instance = etree.Element('instance')
for parameter_id, parameter_value in dictionnary.iteritems(): for parameter_id, parameter_value in dictionnary.iteritems():
...@@ -35,7 +39,8 @@ def dict2xml(dictionnary): ...@@ -35,7 +39,8 @@ def dict2xml(dictionnary):
return etree.tostring(instance, pretty_print=True, return etree.tostring(instance, pretty_print=True,
xml_declaration=True, encoding='utf-8') xml_declaration=True, encoding='utf-8')
def partitiondict2partition(partition): #Deprecated
def partitiondict2partitionXML(partition):
slap_partition = ComputerPartition(app.config['computer_id'], slap_partition = ComputerPartition(app.config['computer_id'],
partition['reference']) partition['reference'])
slap_partition._requested_state = 'started' slap_partition._requested_state = 'started'
...@@ -43,7 +48,11 @@ def partitiondict2partition(partition): ...@@ -43,7 +48,11 @@ def partitiondict2partition(partition):
slap_partition._need_modification = 1 slap_partition._need_modification = 1
else: else:
slap_partition._need_modification = 0 slap_partition._need_modification = 0
try:
slap_partition._parameter_dict = xml2dict(partition['xml']) slap_partition._parameter_dict = xml2dict(partition['xml'])
except XMLSyntaxError:
# Maybe it was encoded in json
slap_partition._parameter_dict = json.loads(partition['xml'])
address_list = [] address_list = []
for address in execute_db('partition_network', 'SELECT * FROM %s WHERE partition_reference=?', [partition['reference']]): for address in execute_db('partition_network', 'SELECT * FROM %s WHERE partition_reference=?', [partition['reference']]):
address_list.append((address['reference'], address['address'])) address_list.append((address['reference'], address['address']))
...@@ -55,6 +64,86 @@ def partitiondict2partition(partition): ...@@ -55,6 +64,86 @@ def partitiondict2partition(partition):
computer_guid=app.config['computer_id']) computer_guid=app.config['computer_id'])
return slap_partition return slap_partition
#Deprecated. Only used for current version of slapgrid
@app.route('/registerComputerPartition', methods=['GET'])
def registerComputerPartitionXml():
computer_reference = request.args['computer_reference']
computer_partition_reference = request.args['computer_partition_reference']
if app.config['computer_id'] == computer_reference:
partition = execute_db('partition', 'SELECT * FROM %s WHERE reference=?',
[computer_partition_reference.encode()], one=True)
if partition is None:
raise UnauthorizedError
return xml_marshaller.xml_marshaller.dumps(
partitiondict2partitionXML(partition))
else:
raise UnauthorizedError, "Only accept request for: %s" % \
app.config['computer_id']
#Deprecated. Only used for current version of slapgrid
@app.route('/getComputerInformation', methods=['GET'])
def getComputerInformationXml():
computer_id = request.args['computer_id']
if app.config['computer_id'] == computer_id:
slap_computer = Computer(computer_id)
slap_computer._software_release_list = []
for sr in execute_db('software', 'select * from %s'):
slap_computer._software_release_list.append(SoftwareRelease(
software_release=sr['url'], computer_guid=computer_id))
slap_computer._computer_partition_list = []
for partition in execute_db('partition', 'SELECT * FROM %s'):
slap_computer._computer_partition_list.append(partitiondict2partitionXML(
partition))
return xml_marshaller.xml_marshaller.dumps(slap_computer)
else:
raise UnauthorizedError, "Only accept request for: %s" % \
app.config['computer_id']
#Deprecated. Only used for current version of slapgrid
@app.route('/setComputerPartitionConnectionXml', methods=['POST'])
def setComputerPartitionConnectionXml():
computer_id = request.form['computer_id']
computer_partition_id = request.form['computer_partition_id']
connection_xml = request.form['connection_xml']
connection_dict = xml_marshaller.xml_marshaller.loads(
connection_xml.encode())
connection_xml = dict2xml(connection_dict)
query = 'UPDATE %s SET connection_xml=? WHERE reference=?'
argument_list = [connection_xml, computer_partition_id.encode()]
execute_db('partition', query, argument_list)
return 'done'
def partitiondict2partition(partition):
# XXX-Cedric : change function name, as it does no longer create a
# Partition instance, but rather create a dict ready to be sent in json
slap_partition = dict(computer_id = app.config['computer_id'],
computer_partition_id = partition['reference'],
requested_state = 'started',
partition_reference = partition['partition_reference'])
if partition['software_release']:
slap_partition['need_modification'] = 1
else:
slap_partition['need_modification'] = 0
# XXX-Cedric : do we have to load a json into dict? It will be changed back to json anyway.
# XXX-Cedric : change from partition['xml'] to partition['json']
parameter_dict = dict()
if partition['xml']:
parameter_dict = json.loads(partition['xml'])
slap_partition['parameter_dict'] = parameter_dict
address_list = []
#XXX-Cedric : I do not understand the query. It is unclear what is partition['reference'], is it computer_partition_id or partition_reference?
for address in execute_db('partition_network', 'SELECT * FROM %s WHERE partition_reference=?', [partition['reference']]):
address_list.append((address['reference'], address['address']))
slap_partition['parameter_dict']['ip_list'] = address_list
slap_partition['parameter_dict']['software_type'] = partition['software_type']
# XXX-Cedric: same here
connection_dict = None
if partition['connection_xml']:
connection_dict = xml2dict(partition['connection_xml'])
slap_partition['connection_dict'] = connection_dict
slap_partition['software_release'] = partition['software_release']
return slap_partition
def execute_db(table, query, args=(), one=False): def execute_db(table, query, args=(), one=False):
try: try:
cur = g.db.execute(query % (table + DB_VERSION,), args) cur = g.db.execute(query % (table + DB_VERSION,), args)
...@@ -83,34 +172,29 @@ def after_request(response): ...@@ -83,34 +172,29 @@ def after_request(response):
g.db.close() g.db.close()
return response return response
@app.route('/getComputerInformation', methods=['GET']) @app.route('/<computer_id>', methods=['GET'])
def getComputerInformation(): def getComputerInformation(computer_id):
computer_id = request.args['computer_id'] """Returns information about computer"""
if app.config['computer_id'] == computer_id: if app.config['computer_id'] == computer_id:
slap_computer = Computer(computer_id) slap_computer = dict(computer_id = computer_id,
slap_computer._software_release_list = [] software_release_list = [],
computer_partition_list = [])
for sr in execute_db('software', 'select * from %s'): for sr in execute_db('software', 'select * from %s'):
slap_computer._software_release_list.append(SoftwareRelease( slap_computer['software_release_list'].append(dict(
software_release=sr['url'], computer_guid=computer_id)) software_release=sr['url'], computer_guid=computer_id))
slap_computer._computer_partition_list = []
for partition in execute_db('partition', 'SELECT * FROM %s'): for partition in execute_db('partition', 'SELECT * FROM %s'):
slap_computer._computer_partition_list.append(partitiondict2partition( slap_computer['computer_partition_list'].append(
partition)) partitiondict2partition(partition))
return xml_marshaller.xml_marshaller.dumps(slap_computer) return json.dumps(slap_computer)
else: else:
raise UnauthorizedError, "Only accept request for: %s" % \ raise UnauthorizedError, "Only accept request for: %s" % \
app.config['computer_id'] app.config['computer_id']
@app.route('/setComputerPartitionConnectionXml', methods=['POST']) @app.route('/<computer_id>/partition/<computer_partition_id>', methods=['POST'])
def setComputerPartitionConnectionXml(): def setComputerPartitionConnectionJson(computer_id, computer_partition_id):
computer_id = request.form['computer_id'] # XXX-Cedric : change connection_xml to connection_json in sql
computer_partition_id = request.form['computer_partition_id']
connection_xml = request.form['connection_xml']
connection_dict = xml_marshaller.xml_marshaller.loads(
connection_xml.encode())
connection_xml = dict2xml(connection_dict)
query = 'UPDATE %s SET connection_xml=? WHERE reference=?' query = 'UPDATE %s SET connection_xml=? WHERE reference=?'
argument_list = [connection_xml, computer_partition_id.encode()] argument_list = [request.json, computer_partition_id.encode()]
execute_db('partition', query, argument_list) execute_db('partition', query, argument_list)
return 'done' return 'done'
...@@ -165,21 +249,29 @@ def destroyedComputerPartition(): ...@@ -165,21 +249,29 @@ def destroyedComputerPartition():
computer_partition_id = request.form['computer_partition_id'] computer_partition_id = request.form['computer_partition_id']
return 'Ignored' return 'Ignored'
@app.route('/requestComputerPartition', methods=['POST']) #@app.route('/partition/<partition_reference>', methods=['PUT'])
def requestComputerPartition(): @app.route('/partition', methods=['POST'])
software_release = request.form['software_release'].encode() def requestComputerPartition(partition_reference = ''):
"""Request the creation of a computer partition"""
request_dict = request.json
software_release = request_dict['software_release'].encode()
# some supported parameters # some supported parameters
software_type = request.form.get('software_type', 'RootSoftwareInstance' software_type = request_dict.get('software_type', 'RootSoftwareInstance')
).encode() if (software_type is None):
partition_reference = request.form.get('partition_reference', '').encode() software_type = 'RootSoftwareInstance'
partition_id = request.form.get('computer_partition_id', '').encode() software_type = software_type.encode()
partition_parameter_kw = request.form.get('partition_parameter_xml', None) if partition_reference is '' :
if partition_parameter_kw: partition_reference = request_dict.get('partition_reference', '').encode()
partition_parameter_kw = xml_marshaller.xml_marshaller.loads( partition_id = request_dict.get('computer_partition_id', '')
partition_parameter_kw.encode()) if (partition_id is None):
else: partition_id = ''
partition_parameter_kw = {} partition_id = partition_id.encode()
instance_xml = dict2xml(partition_parameter_kw) parameter_dict_kw = request_dict.get('parameter_dict', None)
if parameter_dict_kw:
# In the future, parameter_dict will come either in xml or in json.
# We will check it with schema.
parameter_dict_kw = json.dumps(parameter_dict_kw).encode()
instance_json = parameter_dict_kw
args = [] args = []
a = args.append a = args.append
q = 'SELECT * FROM %s WHERE software_release=?' q = 'SELECT * FROM %s WHERE software_release=?'
...@@ -213,9 +305,10 @@ def requestComputerPartition(): ...@@ -213,9 +305,10 @@ def requestComputerPartition():
if partition_id: if partition_id:
q += ' ,requested_by=?' q += ' ,requested_by=?'
a(partition_id) a(partition_id)
if instance_xml: if instance_json:
# XXX-Cedric : change xml to sjon in sql
q+= ' ,xml=?' q+= ' ,xml=?'
a(instance_xml) a(instance_json)
q += ' WHERE reference=?' q += ' WHERE reference=?'
a(partition['reference'].encode()) a(partition['reference'].encode())
execute_db('partition', q, args) execute_db('partition', q, args)
...@@ -225,25 +318,28 @@ def requestComputerPartition(): ...@@ -225,25 +318,28 @@ def requestComputerPartition():
address_list = [] address_list = []
for address in execute_db('partition_network', 'SELECT * FROM %s WHERE partition_reference=?', [partition['reference']]): for address in execute_db('partition_network', 'SELECT * FROM %s WHERE partition_reference=?', [partition['reference']]):
address_list.append((address['reference'], address['address'])) address_list.append((address['reference'], address['address']))
return xml_marshaller.xml_marshaller.dumps(SoftwareInstance(**dict( return json.dumps(dict(
# XXX-Cedric : change xml to json in sql
# XXX-Cedric : change this to return something that looks like a computer partition
xml=partition['xml'], xml=partition['xml'],
connection_xml=partition['connection_xml'], connection_xml=partition['connection_xml'],
partition_reference=partition['partition_reference'],
slap_computer_id=app.config['computer_id'], slap_computer_id=app.config['computer_id'],
slap_computer_partition_id=partition['reference'], slap_computer_partition_id=partition['reference'],
slap_software_release_url=partition['software_release'], slap_software_release_url=partition['software_release'],
slap_server_url='slap_server_url', slap_server_url='slap_server_url',
slap_software_type=partition['software_type'], software_type=partition['software_type'],
slave_id_list=[], slave_id_list=[],
ip_list=address_list ip_list=address_list
))) ))
abort(408) abort(408)
computer_id = request.form.get('computer_id') computer_id = request.form.get('computer_id')
computer_partition_id = request.form.get('computer_partition_id') computer_partition_id = request.form.get('computer_partition_id')
software_type = request.form.get('software_type') software_type = request.form.get('software_type')
partition_reference = request.form.get('partition_reference') partition_reference = request.form.get('partition_reference')
shared_xml = request.form.get('shared_xml') shared = request.form.get('shared')
partition_parameter_xml = request.form.get('partition_parameter_xml') parameter_dict = request.form.get('parameter_dict')
filter_xml = request.form.get('filter_xml') filter_json = request.form.get('filter_json')
raise NotImplementedError raise NotImplementedError
@app.route('/useComputer', methods=['POST']) @app.route('/useComputer', methods=['POST'])
...@@ -275,25 +371,45 @@ def loadComputerConfigurationFromXML(): ...@@ -275,25 +371,45 @@ def loadComputerConfigurationFromXML():
raise UnauthorizedError, "Only accept request for: %s" % \ raise UnauthorizedError, "Only accept request for: %s" % \
app.config['computer_id'] app.config['computer_id']
@app.route('/registerComputerPartition', methods=['GET']) #XXX-Cedric : We still use XML for formatting for now.
def registerComputerPartition(): #@app.route('/loadComputerConfiguration', methods=['POST'])
computer_reference = request.args['computer_reference'] #def loadComputerConfigurationFromJson():
computer_partition_reference = request.args['computer_partition_reference'] # json_document = request.form['json']
# computer_dict = json.loads(str(json_document))
# if app.config['computer_id'] == computer_dict['reference']:
# args = []
# a = args.append
# execute_db('computer', 'INSERT OR REPLACE INTO %s values(:address, :netmask)',
# computer_dict)
# for partition in computer_dict['partition_list']:
#
# execute_db('partition', 'INSERT OR IGNORE INTO %s (reference) values(:reference)', partition)
# execute_db('partition_network', 'DELETE FROM %s WHERE partition_reference = ?', [partition['reference']])
# for address in partition['address_list']:
# address['reference'] = partition['tap']['name']
# address['partition_reference'] = partition['reference']
# execute_db('partition_network', 'INSERT OR REPLACE INTO %s (reference, partition_reference, address, netmask) values(:reference, :partition_reference, :addr, :netmask)', address)
#
# return 'done'
# else:
# raise UnauthorizedError, "Only accept request for: %s" % \
# app.config['computer_id']
@app.route('/<computer_reference>/partition/<partition_reference>', methods=['GET'])
def registerComputerPartition(computer_reference, partition_reference):
if app.config['computer_id'] == computer_reference: if app.config['computer_id'] == computer_reference:
partition = execute_db('partition', 'SELECT * FROM %s WHERE reference=?', partition = execute_db('partition', 'SELECT * FROM %s WHERE reference=?',
[computer_partition_reference.encode()], one=True) [partition_reference.encode()], one=True)
if partition is None: if partition is None:
raise UnauthorizedError raise UnauthorizedError
return xml_marshaller.xml_marshaller.dumps( return json.dumps(partitiondict2partition(partition))
partitiondict2partition(partition))
else: else:
raise UnauthorizedError, "Only accept request for: %s" % \ raise UnauthorizedError, "Only accept request for: %s" % \
app.config['computer_id'] app.config['computer_id']
@app.route('/supplySupply', methods=['POST']) @app.route('/<computer_id>/software', methods=['POST'])
def supplySupply(): def supplySupply(computer_id):
url = request.form['url'] url = request.json['url']
computer_id = request.form['computer_id']
if app.config['computer_id'] == computer_id: if app.config['computer_id'] == computer_id:
execute_db('software', 'INSERT OR REPLACE INTO %s VALUES(?)', [url]) execute_db('software', 'INSERT OR REPLACE INTO %s VALUES(?)', [url])
else: else:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment