Commit d0e1a082 authored by Cédric Le Ninivin's avatar Cédric Le Ninivin Committed by Titouan Soulard

wip: First Draft of news Request Version

parent 6c4e5c2a
...@@ -30,6 +30,7 @@ from slapos.recipe.librecipe import wrap, JSON_SERIALISED_MAGIC_KEY ...@@ -30,6 +30,7 @@ from slapos.recipe.librecipe import wrap, JSON_SERIALISED_MAGIC_KEY
import json import json
from slapos import slap as slapmodule from slapos import slap as slapmodule
from slapos.slap import SoftwareProductCollection from slapos.slap import SoftwareProductCollection
from slapos.slap.slap import json_loads_byteified
import slapos.recipe.librecipe.generic as librecipe import slapos.recipe.librecipe.generic as librecipe
import traceback import traceback
...@@ -137,10 +138,11 @@ class Recipe(object): ...@@ -137,10 +138,11 @@ class Recipe(object):
options.get('key-file'), options.get('key-file'),
options.get('cert-file'), options.get('cert-file'),
) )
request = slap.registerComputerPartition( if not slap.jio_api_connector:
options['computer-id'], request = slap.registerComputerPartition(
options['partition-id'], options['computer-id'],
).request options['partition-id'],
).request
if software_url is not None and \ if software_url is not None and \
software_url.startswith(SOFTWARE_PRODUCT_NAMESPACE): software_url.startswith(SOFTWARE_PRODUCT_NAMESPACE):
...@@ -158,44 +160,94 @@ class Recipe(object): ...@@ -158,44 +160,94 @@ class Recipe(object):
self._raise_request_exception_formatted = None self._raise_request_exception_formatted = None
self.instance = None self.instance = None
# Try to do the request and fetch parameter dict... if slap.jio_api_connector:
try: request_dict = {
self.instance = request(software_url, software_type, "title": name,
name, partition_parameter_kw=partition_parameter_kw, "software_type": software_type,
filter_kw=filter_kw, shared=shared, state=requested_state) "software_release_uri": software_url,
return_parameter_dict = self._getReturnParameterDict(self.instance, "portal_type": "Software Instance",
return_parameters) }
# Fetch the instance-guid and the instance-state if partition_parameter_kw:
# Note: SlapOS Master does not support it for shared instances request_dict["parameters"] = json.dumps(partition_parameter_kw)
if not shared: if filter_kw:
try: request_dict["sla_parameters"] = filter_kw
options['instance-guid'] = self.instance.getInstanceGuid() \ if slave:
.encode('UTF-8') request_dict["shared"] = True
if requested_state:
request_dict["state"] = requested_state
partition_dict = slap.jio_api_connector.post(request_dict)
if "$schema" in partition_dict and "error-response-schema.json" in partition_dict["$schema"]:
self.logger.warning(
'Request for %(request_name)r with software release '
'%(software_release)r and software type %(software_type)r failed '
'with partition_parameter_kw=%(partition_parameter_kw)r, '
'filter_kw=%(filter_kw)r, shared=%(shared)r, state=%(state)r.', dict(
software_release=software_url,
software_type=software_type,
request_name=name,
partition_parameter_kw=partition_parameter_kw,
filter_kw=filter_kw,
shared=slave,
state=requested_state
)
)
self._raise_request_exception = slapmodule.NotFoundError
self._raise_request_exception_formatted = str(partition_dict["message"])
return_parameter_dict = {}
else:
return_parameter_dict = self._getFilteredParameterDict(
partition_dict,
return_parameters
)
# Fetch the instance-guid and the instance-state
# Note: SlapOS Master does not support it for slave instances
if not slave:
options['instance-guid'] = partition_dict["reference"]
# XXX: deprecated, to be removed # XXX: deprecated, to be removed
options['instance_guid'] = options['instance-guid'] options['instance_guid'] = options['instance-guid']
options['instance-state'] = self.instance.getState() options['instance-state'] = options['state']
options['instance-status'] = self.instance.getStatus() options['instance-status'] = options.get('access_status_message')
except (slapmodule.ResourceNotReady, AttributeError):
# Backward compatibility. Old SlapOS master and core don't know this. else:
self.logger.warning("Impossible to fetch instance GUID nor state.") # Try to do the request and fetch parameter dict...
except (slapmodule.NotFoundError, slapmodule.ServerError, slapmodule.ResourceNotReady) as exc: try:
self.logger.warning( self.instance = request(software_url, software_type,
'Request for %(request_name)r with software release ' name, partition_parameter_kw=partition_parameter_kw,
'%(software_release)r and software type %(software_type)r failed ' filter_kw=filter_kw, shared=slave, state=requested_state)
'with partition_parameter_kw=%(partition_parameter_kw)r, ' return_parameter_dict = self._getReturnParameterDict(self.instance,
'filter_kw=%(filter_kw)r, shared=%(shared)r, state=%(state)r.', dict( return_parameters)
software_release=software_url, # Fetch the instance-guid and the instance-state
software_type=software_type, # Note: SlapOS Master does not support it for slave instances
request_name=name, if not slave:
partition_parameter_kw=partition_parameter_kw, try:
filter_kw=filter_kw, options['instance-guid'] = self.instance.getInstanceGuid() \
shared=shared, .encode('UTF-8')
state=requested_state # XXX: deprecated, to be removed
options['instance_guid'] = options['instance-guid']
options['instance-state'] = self.instance.getState()
options['instance-status'] = self.instance.getStatus()
except (slapmodule.ResourceNotReady, AttributeError):
# Backward compatibility. Old SlapOS master and core don't know this.
self.logger.warning("Impossible to fetch instance GUID nor state.")
except (slapmodule.NotFoundError, slapmodule.ServerError, slapmodule.ResourceNotReady) as exc:
self.logger.warning(
'Request for %(request_name)r with software release '
'%(software_release)r and software type %(software_type)r failed '
'with partition_parameter_kw=%(partition_parameter_kw)r, '
'filter_kw=%(filter_kw)r, shared=%(shared)r, state=%(state)r.', dict(
software_release=software_url,
software_type=software_type,
request_name=name,
partition_parameter_kw=partition_parameter_kw,
filter_kw=filter_kw,
shared=slave,
state=requested_state
)
) )
) self._raise_request_exception = exc
self._raise_request_exception = exc self._raise_request_exception_formatted = traceback.format_exc()
self._raise_request_exception_formatted = traceback.format_exc() return_parameter_dict = {}
return_parameter_dict = {}
# Then try to get all the parameters. In case of problem, put empty string. # Then try to get all the parameters. In case of problem, put empty string.
for param in return_parameters: for param in return_parameters:
...@@ -221,6 +273,14 @@ class Recipe(object): ...@@ -221,6 +273,14 @@ class Recipe(object):
pass pass
return result return result
def _getFilteredParameterDict(self, partition_dict, return_parameter_list):
result = {}
parameters = json_loads_byteified(partition.get("parameters", "{}"))
for key in return_parameter_list:
if key in parameters:
result[key] = parameters["key"]
return result
def install(self): def install(self):
if self._raise_request_exception: if self._raise_request_exception:
raise self._raise_request_exception raise self._raise_request_exception
...@@ -286,6 +346,12 @@ class JSONCodec(object): ...@@ -286,6 +346,12 @@ class JSONCodec(object):
except slapmodule.NotFoundError: except slapmodule.NotFoundError:
return {} return {}
def _getFilteredParameterDict(self, partition_dict, return_parameter_list):
parameters = json_loads_byteified(partition.get("parameters", "{}"))
if JSON_SERIALISED_MAGIC_KEY in parameters:
return json.loads(parameters[JSON_SERIALISED_MAGIC_KEY])
return {}
class RequestJSONEncoded(JSONCodec, Recipe): class RequestJSONEncoded(JSONCodec, Recipe):
""" """
Like Recipe, but serialised with JSONCodec. Like Recipe, but serialised with JSONCodec.
......
...@@ -2,6 +2,7 @@ import mock ...@@ -2,6 +2,7 @@ import mock
import unittest import unittest
from collections import defaultdict from collections import defaultdict
from slapos.recipe import request from slapos.recipe import request
from test_slaposconfiguration import APIRequestHandler
from testfixtures import LogCapture from testfixtures import LogCapture
...@@ -25,6 +26,7 @@ class RecipeTestMixin(object): ...@@ -25,6 +26,7 @@ class RecipeTestMixin(object):
self.request_instance.return_value = requested_instance self.request_instance.return_value = requested_instance
register_instance.request = self.request_instance register_instance.request = self.request_instance
slap_instance.registerComputerPartition.return_value = register_instance slap_instance.registerComputerPartition.return_value = register_instance
slap_instance.jio_api_connector = None
slap.return_value = slap_instance slap.return_value = slap_instance
self.instance_getConnectionParameter = \ self.instance_getConnectionParameter = \
requested_instance.getConnectionParameter requested_instance.getConnectionParameter
...@@ -149,3 +151,6 @@ class RequestOptionalJSONEncodedTest(RecipeTestMixin, unittest.TestCase): ...@@ -149,3 +151,6 @@ class RequestOptionalJSONEncodedTest(RecipeTestMixin, unittest.TestCase):
return_value = '{"anything": "done"}' return_value = '{"anything": "done"}'
raises = False raises = False
called_partition_parameter_kw = {'_': '{}'} called_partition_parameter_kw = {'_': '{}'}
class RecipejIOTestMixin:
pass
\ No newline at end of file
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