Commit 5dc02df9 authored by Romain Courteaud's avatar Romain Courteaud

Draft version of hypermedia access to slapos.

Use http://tools.ietf.org/html/draft-kelly-json-hal-05 has base format.
Provide possibility to request instance, browse them and check their message
and connection parameters.
parent a1dcdb01
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Folder" module="OFS.Folder"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_local_properties</string> </key>
<value>
<tuple>
<dictionary>
<item>
<key> <string>id</string> </key>
<value> <string>business_template_skin_layer_priority</string> </value>
</item>
<item>
<key> <string>type</string> </key>
<value> <string>float</string> </value>
</item>
</dictionary>
</tuple>
</value>
</item>
<item>
<key> <string>_objects</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>business_template_skin_layer_priority</string> </key>
<value> <float>60.0</float> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>slapos_hypermedia</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>Script_magic</string> </key>
<value> <int>3</int> </value>
</item>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>_asgns</string> </key>
<value>
<dictionary>
<item>
<key> <string>name_container</string> </key>
<value> <string>container</string> </value>
</item>
<item>
<key> <string>name_context</string> </key>
<value> <string>context</string> </value>
</item>
<item>
<key> <string>name_m_self</string> </key>
<value> <string>script</string> </value>
</item>
<item>
<key> <string>name_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>_body</string> </key>
<value> <string>from zExceptions import Unauthorized\n
from AccessControl import getSecurityManager\n
if REQUEST is None:\n
raise Unauthorized\n
\n
response = REQUEST.RESPONSE\n
type = \'application/vnd.slapos.org.hal+json; class=slapos.org.master\'\n
\n
if REQUEST.other[\'method\'] != "GET":\n
response.setStatus(405)\n
return ""\n
elif type != context.Base_handleAcceptHeader([type]):\n
response.setStatus(406)\n
return ""\n
else:\n
import json\n
result_dict = {\n
\'_class\': \'slapos.org.master\',\n
# \'title\': \'Vifib SlapOS Master\',\n
# \'description\': \'Reference implementation of the SlapOS Master specifications.\',\n
\'_links\': {\n
"self": { "href": context.Base_getRequestUrl(),\n
"type": type },\n
# "http://slapos.org/reg/edit": {\n
# "href": "/edit",\n
# "method": "PUT",\n
# "type": "application/json; class=slapos.org.master",\n
# },\n
# "http://slapos.org/reg/create": {\n
# "href": "/new",\n
# "method": "POST",\n
# "type": "application/json; class=slapos.org.person",\n
# },\n
},\n
}\n
\n
portal = context.getPortalObject()\n
\n
# XXX Handle also other kind of users: instance, computer, master\n
person = portal.ERP5Site_getAuthenticatedMemberPersonValue()\n
if person is not None:\n
result_dict[\'_links\'][\'http://slapos.org/reg/me\'] = {\n
\'href\': \'%s/Person_getHateoas\' % person.absolute_url(),\n
"type": "application/vnd.slapos.org.hal+json; class=slapos.org.person"\n
}\n
\n
response.setHeader(\'Content-Type\', type)\n
return json.dumps(result_dict)\n
</string> </value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>REQUEST=None</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>Base_getHateoasMaster</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>Script_magic</string> </key>
<value> <int>3</int> </value>
</item>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>_asgns</string> </key>
<value>
<dictionary>
<item>
<key> <string>name_container</string> </key>
<value> <string>container</string> </value>
</item>
<item>
<key> <string>name_context</string> </key>
<value> <string>context</string> </value>
</item>
<item>
<key> <string>name_m_self</string> </key>
<value> <string>script</string> </value>
</item>
<item>
<key> <string>name_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>_body</string> </key>
<value> <string>from zExceptions import Unauthorized\n
if REQUEST is not None:\n
raise Unauthorized\n
\n
# XXX requested to simulate in unit test for now\n
return context.REQUEST.get(\'BODY\')\n
</string> </value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>REQUEST=None</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>Base_getRequestBody</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>Script_magic</string> </key>
<value> <int>3</int> </value>
</item>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>_asgns</string> </key>
<value>
<dictionary>
<item>
<key> <string>name_container</string> </key>
<value> <string>container</string> </value>
</item>
<item>
<key> <string>name_context</string> </key>
<value> <string>context</string> </value>
</item>
<item>
<key> <string>name_m_self</string> </key>
<value> <string>script</string> </value>
</item>
<item>
<key> <string>name_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>_body</string> </key>
<value> <string>from zExceptions import Unauthorized\n
if REQUEST is not None:\n
raise Unauthorized\n
\n
# XXX requested to simulate in unit test for now\n
return context.REQUEST.getHeader(name, default)\n
</string> </value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>name, default=None, REQUEST=None</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>Base_getRequestHeader</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>Script_magic</string> </key>
<value> <int>3</int> </value>
</item>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>_asgns</string> </key>
<value>
<dictionary>
<item>
<key> <string>name_container</string> </key>
<value> <string>container</string> </value>
</item>
<item>
<key> <string>name_context</string> </key>
<value> <string>context</string> </value>
</item>
<item>
<key> <string>name_m_self</string> </key>
<value> <string>script</string> </value>
</item>
<item>
<key> <string>name_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>_body</string> </key>
<value> <string>from zExceptions import Unauthorized\n
if REQUEST is not None:\n
raise Unauthorized\n
\n
# XXX requested to simulate in unit test for now\n
return context.REQUEST.getURL()\n
</string> </value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>REQUEST=None</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>Base_getRequestUrl</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>Script_magic</string> </key>
<value> <int>3</int> </value>
</item>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>_asgns</string> </key>
<value>
<dictionary>
<item>
<key> <string>name_container</string> </key>
<value> <string>container</string> </value>
</item>
<item>
<key> <string>name_context</string> </key>
<value> <string>context</string> </value>
</item>
<item>
<key> <string>name_m_self</string> </key>
<value> <string>script</string> </value>
</item>
<item>
<key> <string>name_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>_body</string> </key>
<value> <string>from zExceptions import Unauthorized\n
if REQUEST is not None:\n
raise Unauthorized\n
\n
result = None\n
accept = context.Base_getRequestHeader(\'Accept\', default=\'\')\n
for accepted_type in accepted_type_list:\n
if accepted_type in accept:\n
# XXX Really simple and stupid matching.\n
# Better test to ensure best matching type\n
result = accepted_type\n
break\n
\n
if (result is None) and (\'*/*\' in accept):\n
result = accepted_type_list[0]\n
\n
return result\n
</string> </value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>accepted_type_list, REQUEST=None</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>Base_handleAcceptHeader</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>Script_magic</string> </key>
<value> <int>3</int> </value>
</item>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>_asgns</string> </key>
<value>
<dictionary>
<item>
<key> <string>name_container</string> </key>
<value> <string>container</string> </value>
</item>
<item>
<key> <string>name_context</string> </key>
<value> <string>context</string> </value>
</item>
<item>
<key> <string>name_m_self</string> </key>
<value> <string>script</string> </value>
</item>
<item>
<key> <string>name_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>_body</string> </key>
<value> <string>from zExceptions import Unauthorized\n
from AccessControl import getSecurityManager\n
if REQUEST is None:\n
raise Unauthorized\n
\n
response = REQUEST.RESPONSE\n
type = \'application/vnd.slapos.org.hal+json; class=slapos.org.hosting_subscription\'\n
\n
if REQUEST.other[\'method\'] != "GET":\n
response.setStatus(405)\n
return ""\n
elif type != context.Base_handleAcceptHeader([type]):\n
response.setStatus(406)\n
return ""\n
elif context.getPortalType() != "Hosting Subscription":\n
response.setStatus(403)\n
return ""\n
else:\n
\n
# XXX Set more properties on the document\n
\n
import json\n
result_dict = {\n
\'_class\': \'slapos.org.hosting_subscription\',\n
\'title\': context.getTitle(),\n
\'_links\': {\n
"self": { "href": context.Base_getRequestUrl(),\n
"type": "application/vnd.slapos.org.hal+json; class=slapos.org.hosting_subscription" },\n
\n
"http://slapos.org/reg/instance": {\n
"href": "%s/HostingSubscription_getHateoasInstanceList" % context.absolute_url(),\n
"type": "application/vnd.slapos.org.hal+json; class=slapos.org.collection",\n
},\n
\n
},\n
}\n
\n
response.setHeader(\'Content-Type\', type)\n
return json.dumps(result_dict)\n
</string> </value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>REQUEST=None</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>HostingSubscription_getHateoas</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>Script_magic</string> </key>
<value> <int>3</int> </value>
</item>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>_asgns</string> </key>
<value>
<dictionary>
<item>
<key> <string>name_container</string> </key>
<value> <string>container</string> </value>
</item>
<item>
<key> <string>name_context</string> </key>
<value> <string>context</string> </value>
</item>
<item>
<key> <string>name_m_self</string> </key>
<value> <string>script</string> </value>
</item>
<item>
<key> <string>name_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>_body</string> </key>
<value> <string>from zExceptions import Unauthorized\n
from AccessControl import getSecurityManager\n
if REQUEST is None:\n
raise Unauthorized\n
\n
response = REQUEST.RESPONSE\n
type = \'application/vnd.slapos.org.hal+json; class=slapos.org.collection\'\n
\n
if REQUEST.other[\'method\'] != "GET":\n
response.setStatus(405)\n
return ""\n
elif type != context.Base_handleAcceptHeader([type]):\n
response.setStatus(406)\n
return ""\n
elif context.getPortalType() != "Hosting Subscription":\n
response.setStatus(403)\n
return ""\n
else:\n
import json\n
result_dict = {\n
\'_class\': \'slapos.org.collection\',\n
\'_links\': {\n
"self": { "href": context.Base_getRequestUrl(),\n
"type": type },\n
"item": [],\n
},\n
}\n
\n
for sql_obj in context.getPortalObject().portal_catalog(\n
portal_type=[\'Software Instance\', \'Slave Instance\'],\n
default_specialise_uid=context.getUid(),\n
):\n
obj = sql_obj.getObject()\n
result_dict[\'_links\'][\'item\'].append({\n
\'href\': \'%s/Instance_getHateoas\' % obj.absolute_url(),\n
\'type\': \'application/vnd.slapos.org.hal+json; class=slapos.org.instance\',\n
})\n
\n
response.setHeader(\'Content-Type\', type)\n
return json.dumps(result_dict)\n
</string> </value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>REQUEST=None</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>HostingSubscription_getHateoasInstanceList</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>Script_magic</string> </key>
<value> <int>3</int> </value>
</item>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>_asgns</string> </key>
<value>
<dictionary>
<item>
<key> <string>name_container</string> </key>
<value> <string>container</string> </value>
</item>
<item>
<key> <string>name_context</string> </key>
<value> <string>context</string> </value>
</item>
<item>
<key> <string>name_m_self</string> </key>
<value> <string>script</string> </value>
</item>
<item>
<key> <string>name_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>_body</string> </key>
<value> <string>from zExceptions import Unauthorized\n
from AccessControl import getSecurityManager\n
if REQUEST is None:\n
raise Unauthorized\n
\n
response = REQUEST.RESPONSE\n
type = \'application/vnd.slapos.org.hal+json; class=slapos.org.instance\'\n
\n
if REQUEST.other[\'method\'] != "GET":\n
response.setStatus(405)\n
return ""\n
elif type != context.Base_handleAcceptHeader([type]):\n
response.setStatus(406)\n
return ""\n
elif context.getPortalType() not in ["Software Instance", "Slave Instance"]:\n
response.setStatus(403)\n
return ""\n
else:\n
\n
if context.getSlapState() == "stop_requested":\n
state = \'stopped\'\n
elif context.getSlapState() == "start_requested":\n
state = \'started\'\n
else:\n
state = \'destroyed\'\n
\n
import json\n
result_dict = {\n
\'_class\': \'slapos.org.instance\',\n
\'title\': context.getTitle(),\n
\'slave\': context.getPortalType() == \'Slave Instance\',\n
\'software_type\': context.getSourceReference(),\n
\'parameter\': context.getInstanceXmlAsDict(),\n
\'sla\': context.getSlaXmlAsDict(),\n
\'connection\': context.getConnectionXmlAsDict(),\n
\'status\': state,\n
\'_links\': {\n
"self": { "href": context.Base_getRequestUrl(),\n
"type": "application/vnd.slapos.org.hal+json; class=slapos.org.instance" },\n
"http://slapos.org/reg/news": { "href": "%s/Instance_getHateoasNews" % context.absolute_url(),\n
"type": "application/vnd.slapos.org.hal+json; class=slapos.org.news" },\n
"http://slapos.org/reg/release": { "href": context.getUrlString()},\n
},\n
}\n
\n
response.setHeader(\'Content-Type\', type)\n
return json.dumps(result_dict)\n
</string> </value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>REQUEST=None</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>Instance_getHateoas</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>Script_magic</string> </key>
<value> <int>3</int> </value>
</item>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>_asgns</string> </key>
<value>
<dictionary>
<item>
<key> <string>name_container</string> </key>
<value> <string>container</string> </value>
</item>
<item>
<key> <string>name_context</string> </key>
<value> <string>context</string> </value>
</item>
<item>
<key> <string>name_m_self</string> </key>
<value> <string>script</string> </value>
</item>
<item>
<key> <string>name_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>_body</string> </key>
<value> <string>from zExceptions import Unauthorized\n
from AccessControl import getSecurityManager\n
if REQUEST is None:\n
raise Unauthorized\n
\n
response = REQUEST.RESPONSE\n
type = \'application/vnd.slapos.org.hal+json; class=slapos.org.news\'\n
\n
if REQUEST.other[\'method\'] != "GET":\n
response.setStatus(405)\n
return ""\n
elif type != context.Base_handleAcceptHeader([type]):\n
response.setStatus(406)\n
return ""\n
elif context.getPortalType() not in ["Software Instance", "Slave Instance"]:\n
response.setStatus(403)\n
return ""\n
else:\n
\n
import json\n
\n
memcached_dict = context.getPortalObject().portal_memcached.getMemcachedDict(\n
key_prefix=\'slap_tool\',\n
plugin_path=\'portal_memcached/default_memcached_plugin\')\n
try:\n
d = memcached_dict[context.getReference()]\n
except KeyError:\n
d = {\n
"user": "SlapOS Master",\n
"text": "#error no data found for %s" % context.getReference()\n
}\n
else:\n
d = json.loads(d)\n
\n
result_dict = {\n
\'_class\': \'slapos.org.news\',\n
\'news\': [d],\n
\'_links\': {\n
"self": { "href": context.Base_getRequestUrl(),\n
"type": "application/vnd.slapos.org.hal+json; class=slapos.org.news" },\n
"http://slapos.org/reg/instance": { "href": "%s/Instance_getHateoas" % context.absolute_url(),\n
"type": "application/vnd.slapos.org.hal+json; class=slapos.org.instance" },\n
},\n
}\n
\n
response.setHeader(\'Content-Type\', type)\n
return json.dumps(result_dict)\n
</string> </value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>REQUEST=None</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>Instance_getHateoasNews</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>Script_magic</string> </key>
<value> <int>3</int> </value>
</item>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>_asgns</string> </key>
<value>
<dictionary>
<item>
<key> <string>name_container</string> </key>
<value> <string>container</string> </value>
</item>
<item>
<key> <string>name_context</string> </key>
<value> <string>context</string> </value>
</item>
<item>
<key> <string>name_m_self</string> </key>
<value> <string>script</string> </value>
</item>
<item>
<key> <string>name_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>_body</string> </key>
<value> <string>from zExceptions import Unauthorized\n
from AccessControl import getSecurityManager\n
if REQUEST is None:\n
raise Unauthorized\n
\n
response = REQUEST.RESPONSE\n
type = \'application/vnd.slapos.org.hal+json; class=slapos.org.person\'\n
\n
if REQUEST.other[\'method\'] != "GET":\n
response.setStatus(405)\n
return ""\n
elif type != context.Base_handleAcceptHeader([type]):\n
response.setStatus(406)\n
return ""\n
elif context.getPortalType() != "Person":\n
response.setStatus(403)\n
return ""\n
else:\n
import json\n
result_dict = {\n
\'_class\': \'slapos.org.person\',\n
\'title\': context.getTitle(),\n
\'_links\': {\n
"self": { "href": context.Base_getRequestUrl(),\n
"type": "application/vnd.slapos.org.hal+json; class=slapos.org.person" },\n
\n
"http://slapos.org/reg/request": {\n
"href": "%s/Person_requestHateoasHostingSubscription" % context.absolute_url(),\n
"method": "POST",\n
"type": "application/json; class=slapos.org.hosting_subscription",\n
},\n
\n
"http://slapos.org/reg/hosting_subscription": {\n
"href": "%s/Person_getHateoasHostingSubscriptionList" % context.absolute_url(),\n
"type": "application/vnd.slapos.org.hal+json; class=slapos.org.collection",\n
},\n
\n
},\n
}\n
\n
response.setHeader(\'Content-Type\', type)\n
return json.dumps(result_dict)\n
</string> </value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>REQUEST=None</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>Person_getHateoas</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>Script_magic</string> </key>
<value> <int>3</int> </value>
</item>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>_asgns</string> </key>
<value>
<dictionary>
<item>
<key> <string>name_container</string> </key>
<value> <string>container</string> </value>
</item>
<item>
<key> <string>name_context</string> </key>
<value> <string>context</string> </value>
</item>
<item>
<key> <string>name_m_self</string> </key>
<value> <string>script</string> </value>
</item>
<item>
<key> <string>name_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>_body</string> </key>
<value> <string>from zExceptions import Unauthorized\n
from AccessControl import getSecurityManager\n
if REQUEST is None:\n
raise Unauthorized\n
\n
response = REQUEST.RESPONSE\n
type = \'application/vnd.slapos.org.hal+json; class=slapos.org.collection\'\n
\n
if REQUEST.other[\'method\'] != "GET":\n
response.setStatus(405)\n
return ""\n
elif type != context.Base_handleAcceptHeader([type]):\n
response.setStatus(406)\n
return ""\n
elif context.getPortalType() != "Person":\n
response.setStatus(403)\n
return ""\n
else:\n
import json\n
result_dict = {\n
\'_class\': \'slapos.org.collection\',\n
\'_links\': {\n
"self": { "href": context.Base_getRequestUrl(),\n
"type": type },\n
"item": [],\n
},\n
}\n
\n
for sql_obj in context.getPortalObject().portal_catalog(\n
portal_type="Hosting Subscription",\n
default_destination_section_uid=context.getUid(),\n
):\n
obj = sql_obj.getObject()\n
result_dict[\'_links\'][\'item\'].append({\n
\'href\': \'%s/HostingSubscription_getHateoas\' % obj.absolute_url(),\n
\'type\': \'application/vnd.slapos.org.hal+json; class=slapos.org.hosting_subscription\',\n
})\n
\n
response.setHeader(\'Content-Type\', type)\n
return json.dumps(result_dict)\n
</string> </value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>REQUEST=None</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>Person_getHateoasHostingSubscriptionList</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>Script_magic</string> </key>
<value> <int>3</int> </value>
</item>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>_asgns</string> </key>
<value>
<dictionary>
<item>
<key> <string>name_container</string> </key>
<value> <string>container</string> </value>
</item>
<item>
<key> <string>name_context</string> </key>
<value> <string>context</string> </value>
</item>
<item>
<key> <string>name_m_self</string> </key>
<value> <string>script</string> </value>
</item>
<item>
<key> <string>name_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>_body</string> </key>
<value> <string encoding="cdata"><![CDATA[
from zExceptions import Unauthorized\n
from AccessControl import getSecurityManager\n
if REQUEST is None:\n
raise Unauthorized\n
\n
response = REQUEST.RESPONSE\n
type = \'application/json; class=slapos.org.hosting_subscription\'\n
\n
if REQUEST.other[\'method\'] != "POST":\n
response.setStatus(405)\n
return ""\n
elif type != context.Base_getRequestHeader(\'Content-Type\'):\n
response.setStatus(406)\n
return ""\n
elif context.getPortalType() != "Person":\n
response.setStatus(403)\n
return ""\n
else:\n
import json\n
try:\n
data_dict = json.loads(context.Base_getRequestBody())\n
except (TypeError, ValueError):\n
response.setStatus(400)\n
return ""\n
else:\n
\n
def dictToXml(dict_data):\n
assert same_type(dict_data, {})\n
result = "<?xml version=\'1.0\' encoding=\'utf-8\'?><instance>\\n"\n
for key, value in dict_data.items():\n
result += """ <parameter id="%s">%s</parameter>\\n""" % (key, value)\n
result += "</instance>"\n
return result\n
\n
try:\n
parameter_kw = {\n
\'software_release\': data_dict[\'software_release\'],\n
\'software_title\': data_dict[\'title\'],\n
\'software_type\': data_dict[\'software_type\'],\n
\'instance_xml\': dictToXml(data_dict[\'parameter\']),\n
\'sla_xml\': dictToXml(data_dict[\'sla\']),\n
\'shared\': data_dict[\'slave\'],\n
\'state\': data_dict[\'status\'],\n
}\n
except KeyError:\n
response.setStatus(400)\n
return ""\n
else:\n
\n
context.requestSoftwareInstance(**parameter_kw)\n
# XXX Return hosting subscription link\n
response.setStatus(201)\n
return ""\n
]]></string> </value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>REQUEST=None</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>Person_requestHateoasHostingSubscription</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
# Copyright (c) 2002-2013 Nexedi SA and Contributors. All Rights Reserved.
import transaction
from Products.SlapOS.tests.testSlapOSMixin import \
testSlapOSMixin
import json
import httplib
import urlparse
import base64
class TestSlapOSHypermediaPersonScenario(testSlapOSMixin):
def _makeUser(self):
new_id = self.generateNewId()
person_user = self.portal.person_module.template_member.\
Base_createCloneDocument(batch_mode=1)
person_user.edit(
title="live_test_%s" % new_id,
reference="live_test_%s" % new_id,
password="live_test_%s" % new_id,
default_email_text="live_test_%s@example.org" % new_id,
)
person_user.validate()
for assignment in person_user.contentValues(portal_type="Assignment"):
assignment.open()
self.tic()
return person_user
def test(self):
erp5_person = self._makeUser()
authorization = 'Basic %s' % base64.b64encode(
"%s:%s" % (erp5_person.getReference(), erp5_person.getReference()))
# XXX Default home url. 'Hardcoded' in client.
api_scheme, api_netloc, api_path, api_query, \
api_fragment = urlparse.urlsplit('%s/Base_getHateoasMaster' % \
self.portal.absolute_url())
#####################################################
# Access the master home page hal
#####################################################
content_type = "application/vnd.slapos.org.hal+json; class=slapos.org.master"
connection = httplib.HTTPConnection(api_netloc)
connection.request(
method='GET',
url='%s/Base_getHateoasMaster' % \
self.portal.absolute_url(),
headers={
'Authorization': authorization,
'Accept': content_type,
},
body="",
)
response = connection.getresponse()
self.assertEquals(response.status, 200)
self.assertEquals(response.getheader('Content-Type'), content_type)
home_page_hal = json.loads(response.read())
#####################################################
# Fetch the user hal
#####################################################
content_type = "application/vnd.slapos.org.hal+json; class=slapos.org.person"
user_link_dict = home_page_hal['_links']['http://slapos.org/reg/me']
connection = httplib.HTTPConnection(api_netloc)
connection.request(
method=user_link_dict.get('method', 'GET'),
url=user_link_dict['href'],
headers={
'Authorization': authorization,
'Accept': user_link_dict['type'],
},
body="",
)
response = connection.getresponse()
self.assertEquals(response.status, 200)
self.assertEquals(response.getheader('Content-Type'), content_type)
user_hal = json.loads(response.read())
#####################################################
# Run method to request an hosting subscription
#####################################################
content_type = "application/json; " \
"class=slapos.org.hosting_subscription"
request_link_dict = user_hal['_links']['http://slapos.org/reg/request']
connection = httplib.HTTPConnection(api_netloc)
connection.request(
method=request_link_dict.get('method', 'GET'),
url=request_link_dict['href'],
headers={
'Authorization': authorization,
'Content-Type': request_link_dict['type'],
},
body=json.dumps({
'software_release': 'http://example.org',
'title': 'a great title',
'software_type': 'foo',
'parameter': {'param1': 'value1', 'param2': 'value2'},
'sla': {'param3': 'value3', 'param4': 'value4'},
'slave': False,
'status': 'started',
}),
)
response = connection.getresponse()
self.assertEquals(response.status, 201)
self.tic()
#####################################################
# Get user's hosting subscription list
#####################################################
content_type = "application/vnd.slapos.org.hal+json; " \
"class=slapos.org.collection"
user_link_dict = user_hal['_links']\
['http://slapos.org/reg/hosting_subscription']
connection = httplib.HTTPConnection(api_netloc)
connection.request(
method=user_link_dict.get('method', 'GET'),
url=user_link_dict['href'],
headers={
'Authorization': authorization,
'Accept': user_link_dict['type'],
},
body="",
)
response = connection.getresponse()
self.assertEquals(response.status, 200)
self.assertEquals(response.getheader('Content-Type'), content_type)
subscription_collection_hal = json.loads(response.read())
#####################################################
# Get user's hosting subscription
#####################################################
content_type = "application/vnd.slapos.org.hal+json; " \
"class=slapos.org.hosting_subscription"
subscription_link_dict = subscription_collection_hal['_links']\
['item'][0]
connection = httplib.HTTPConnection(api_netloc)
connection.request(
method=subscription_link_dict.get('method', 'GET'),
url=subscription_link_dict['href'],
headers={
'Authorization': authorization,
'Accept': subscription_link_dict['type'],
},
body="",
)
response = connection.getresponse()
self.assertEquals(response.status, 200)
self.assertEquals(response.getheader('Content-Type'), content_type)
subscription_hal = json.loads(response.read())
#####################################################
# Get hosting subscription's instance list
#####################################################
content_type = "application/vnd.slapos.org.hal+json; " \
"class=slapos.org.collection"
user_link_dict = subscription_hal['_links']\
['http://slapos.org/reg/instance']
connection = httplib.HTTPConnection(api_netloc)
connection.request(
method=user_link_dict.get('method', 'GET'),
url=user_link_dict['href'],
headers={
'Authorization': authorization,
'Accept': user_link_dict['type'],
},
body="",
)
response = connection.getresponse()
self.assertEquals(response.status, 200)
self.assertEquals(response.getheader('Content-Type'), content_type)
instance_collection_hal = json.loads(response.read())
#####################################################
# Get instance
#####################################################
content_type = "application/vnd.slapos.org.hal+json; " \
"class=slapos.org.instance"
subscription_link_dict = instance_collection_hal['_links']\
['item'][0]
connection = httplib.HTTPConnection(api_netloc)
connection.request(
method=subscription_link_dict.get('method', 'GET'),
url=subscription_link_dict['href'],
headers={
'Authorization': authorization,
'Accept': subscription_link_dict['type'],
},
body="",
)
response = connection.getresponse()
self.assertEquals(response.status, 200)
self.assertEquals(response.getheader('Content-Type'), content_type)
instance_hal = json.loads(response.read())
#####################################################
# Get instance news
#####################################################
content_type = "application/vnd.slapos.org.hal+json; " \
"class=slapos.org.news"
news_link_dict = instance_hal['_links']\
['http://slapos.org/reg/news']
connection = httplib.HTTPConnection(api_netloc)
connection.request(
method=news_link_dict.get('method', 'GET'),
url=news_link_dict['href'],
headers={
'Authorization': authorization,
'Accept': news_link_dict['type'],
},
body="",
)
response = connection.getresponse()
self.assertEquals(response.status, 200)
self.assertEquals(response.getheader('Content-Type'), content_type)
news_hal = json.loads(response.read())
2013 Nexedi S.A.
\ No newline at end of file
slapos_cloud
slapos_slap_tool
\ No newline at end of file
Provide hypermedia access to slapos
\ No newline at end of file
GPL
\ No newline at end of file
1
\ No newline at end of file
slapos_hypermedia
\ No newline at end of file
testSlapOSHypermediaScenario
testSlapOSHypermediaSkins
\ No newline at end of file
slapos_hypermedia
\ No newline at end of file
0.1
\ No newline at end of file
......@@ -238,6 +238,7 @@ class testSlapOSMixin(ERP5TypeTestCase):
'slapos_category',
'slapos_rest_api_tool_portal_type',
'slapos_rest_api',
'slapos_hypermedia',
'slapos_pdm',
'slapos_crm',
'slapos_accounting',
......
......@@ -10,6 +10,7 @@ slapos_bt_list = [
'slapos_pdm',
'slapos_rest_api',
'slapos_slap_tool',
'slapos_hypermedia',
'slapos_web',
'slapos_payzen',
]
......
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