Commit 06006524 authored by Łukasz Nowak's avatar Łukasz Nowak
parent 9c399c40
from flask import g, Flask, request, abort
import xml_marshaller
from flask import g, Flask, request, abort, json
import xml_marshaller.xml_marshaller
from slapos.slap.slap import Computer, ComputerPartition, SoftwareRelease
from lxml import etree
from slapos.slap.slap import Computer, ComputerPartition, SoftwareRelease, SoftwareInstance
from lxml.etree import XMLSyntaxError
import sqlite3
from simplejson.decoder import JSONDecodeError
app = Flask(__name__)
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):
pass
#Deprecated
def xml2dict(xml):
result_dict = {}
if xml is not None and xml != '':
......@@ -25,6 +28,7 @@ def xml2dict(xml):
result_dict[key] = value
return result_dict
#Deprecated
def dict2xml(dictionnary):
instance = etree.Element('instance')
for parameter_id, parameter_value in dictionnary.iteritems():
......@@ -35,7 +39,8 @@ def dict2xml(dictionnary):
return etree.tostring(instance, pretty_print=True,
xml_declaration=True, encoding='utf-8')
def partitiondict2partition(partition):
#Deprecated
def partitiondict2partitionXML(partition):
slap_partition = ComputerPartition(app.config['computer_id'],
partition['reference'])
slap_partition._requested_state = 'started'
......@@ -43,7 +48,11 @@ def partitiondict2partition(partition):
slap_partition._need_modification = 1
else:
slap_partition._need_modification = 0
try:
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 = []
for address in execute_db('partition_network', 'SELECT * FROM %s WHERE partition_reference=?', [partition['reference']]):
address_list.append((address['reference'], address['address']))
......@@ -55,6 +64,86 @@ def partitiondict2partition(partition):
computer_guid=app.config['computer_id'])
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):
try:
cur = g.db.execute(query % (table + DB_VERSION,), args)
......@@ -83,34 +172,29 @@ def after_request(response):
g.db.close()
return response
@app.route('/getComputerInformation', methods=['GET'])
def getComputerInformation():
computer_id = request.args['computer_id']
@app.route('/<computer_id>', methods=['GET'])
def getComputerInformation(computer_id):
"""Returns information about computer"""
if app.config['computer_id'] == computer_id:
slap_computer = Computer(computer_id)
slap_computer._software_release_list = []
slap_computer = dict(computer_id = computer_id,
software_release_list = [],
computer_partition_list = [])
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))
slap_computer._computer_partition_list = []
for partition in execute_db('partition', 'SELECT * FROM %s'):
slap_computer._computer_partition_list.append(partitiondict2partition(
partition))
return xml_marshaller.xml_marshaller.dumps(slap_computer)
slap_computer['computer_partition_list'].append(
partitiondict2partition(partition))
return json.dumps(slap_computer)
else:
raise UnauthorizedError, "Only accept request for: %s" % \
app.config['computer_id']
@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)
@app.route('/<computer_id>/partition/<computer_partition_id>', methods=['POST'])
def setComputerPartitionConnectionJson(computer_id, computer_partition_id):
# XXX-Cedric : change connection_xml to connection_json in sql
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)
return 'done'
......@@ -165,21 +249,29 @@ def destroyedComputerPartition():
computer_partition_id = request.form['computer_partition_id']
return 'Ignored'
@app.route('/requestComputerPartition', methods=['POST'])
def requestComputerPartition():
software_release = request.form['software_release'].encode()
#@app.route('/partition/<partition_reference>', methods=['PUT'])
@app.route('/partition', methods=['POST'])
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
software_type = request.form.get('software_type', 'RootSoftwareInstance'
).encode()
partition_reference = request.form.get('partition_reference', '').encode()
partition_id = request.form.get('computer_partition_id', '').encode()
partition_parameter_kw = request.form.get('partition_parameter_xml', None)
if partition_parameter_kw:
partition_parameter_kw = xml_marshaller.xml_marshaller.loads(
partition_parameter_kw.encode())
else:
partition_parameter_kw = {}
instance_xml = dict2xml(partition_parameter_kw)
software_type = request_dict.get('software_type', 'RootSoftwareInstance')
if (software_type is None):
software_type = 'RootSoftwareInstance'
software_type = software_type.encode()
if partition_reference is '' :
partition_reference = request_dict.get('partition_reference', '').encode()
partition_id = request_dict.get('computer_partition_id', '')
if (partition_id is None):
partition_id = ''
partition_id = partition_id.encode()
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 = []
a = args.append
q = 'SELECT * FROM %s WHERE software_release=?'
......@@ -213,9 +305,10 @@ def requestComputerPartition():
if partition_id:
q += ' ,requested_by=?'
a(partition_id)
if instance_xml:
if instance_json:
# XXX-Cedric : change xml to sjon in sql
q+= ' ,xml=?'
a(instance_xml)
a(instance_json)
q += ' WHERE reference=?'
a(partition['reference'].encode())
execute_db('partition', q, args)
......@@ -225,25 +318,28 @@ def requestComputerPartition():
address_list = []
for address in execute_db('partition_network', 'SELECT * FROM %s WHERE partition_reference=?', [partition['reference']]):
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'],
connection_xml=partition['connection_xml'],
partition_reference=partition['partition_reference'],
slap_computer_id=app.config['computer_id'],
slap_computer_partition_id=partition['reference'],
slap_software_release_url=partition['software_release'],
slap_server_url='slap_server_url',
slap_software_type=partition['software_type'],
software_type=partition['software_type'],
slave_id_list=[],
ip_list=address_list
)))
))
abort(408)
computer_id = request.form.get('computer_id')
computer_partition_id = request.form.get('computer_partition_id')
software_type = request.form.get('software_type')
partition_reference = request.form.get('partition_reference')
shared_xml = request.form.get('shared_xml')
partition_parameter_xml = request.form.get('partition_parameter_xml')
filter_xml = request.form.get('filter_xml')
shared = request.form.get('shared')
parameter_dict = request.form.get('parameter_dict')
filter_json = request.form.get('filter_json')
raise NotImplementedError
@app.route('/useComputer', methods=['POST'])
......@@ -275,25 +371,45 @@ def loadComputerConfigurationFromXML():
raise UnauthorizedError, "Only accept request for: %s" % \
app.config['computer_id']
@app.route('/registerComputerPartition', methods=['GET'])
def registerComputerPartition():
computer_reference = request.args['computer_reference']
computer_partition_reference = request.args['computer_partition_reference']
#XXX-Cedric : We still use XML for formatting for now.
#@app.route('/loadComputerConfiguration', methods=['POST'])
#def loadComputerConfigurationFromJson():
# 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:
partition = execute_db('partition', 'SELECT * FROM %s WHERE reference=?',
[computer_partition_reference.encode()], one=True)
[partition_reference.encode()], one=True)
if partition is None:
raise UnauthorizedError
return xml_marshaller.xml_marshaller.dumps(
partitiondict2partition(partition))
return json.dumps(partitiondict2partition(partition))
else:
raise UnauthorizedError, "Only accept request for: %s" % \
app.config['computer_id']
@app.route('/supplySupply', methods=['POST'])
def supplySupply():
url = request.form['url']
computer_id = request.form['computer_id']
@app.route('/<computer_id>/software', methods=['POST'])
def supplySupply(computer_id):
url = request.json['url']
if app.config['computer_id'] == computer_id:
execute_db('software', 'INSERT OR REPLACE INTO %s VALUES(?)', [url])
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