Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
S
slapos.core
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Guillaume Hervier
slapos.core
Commits
794fca99
Commit
794fca99
authored
Aug 23, 2017
by
Rafael Monnerat
👻
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
cleanup master: Remove old rest API
Remove old rest API as it will be replaced by hal implementation
parent
78407bb9
Changes
39
Show whitespace changes
Inline
Side-by-side
Showing
39 changed files
with
0 additions
and
3684 deletions
+0
-3684
master/bt5/slapos_configurator/TestTemplateItem/portal_components/test.erp5.testSlapOSConfigurator.py
...tem/portal_components/test.erp5.testSlapOSConfigurator.py
+0
-2
master/bt5/slapos_erp5/TestTemplateItem/portal_components/test.erp5.testSlapOSERP5SkinSelection.py
...ortal_components/test.erp5.testSlapOSERP5SkinSelection.py
+0
-11
master/bt5/slapos_erp5/bt/dependency_list
master/bt5/slapos_erp5/bt/dependency_list
+0
-1
master/bt5/slapos_rest_api/ActionTemplateItem/portal_types/System%20Preference/slapos_rest_api_preference.xml
..._types/System%20Preference/slapos_rest_api_preference.xml
+0
-85
master/bt5/slapos_rest_api/DocumentTemplateItem/portal_components/SlapOSRestAPIV1.py
...DocumentTemplateItem/portal_components/SlapOSRestAPIV1.py
+0
-710
master/bt5/slapos_rest_api/DocumentTemplateItem/portal_components/SlapOSRestAPIV1.xml
...ocumentTemplateItem/portal_components/SlapOSRestAPIV1.xml
+0
-111
master/bt5/slapos_rest_api/PropertySheetTemplateItem/portal_property_sheets/SlapOSRestAPISystemPreference.xml
.../portal_property_sheets/SlapOSRestAPISystemPreference.xml
+0
-66
master/bt5/slapos_rest_api/PropertySheetTemplateItem/portal_property_sheets/SlapOSRestAPISystemPreference/preferred_rest_api_token_server_url_property.xml
...eference/preferred_rest_api_token_server_url_property.xml
+0
-71
master/bt5/slapos_rest_api/SkinTemplateItem/portal_skins/slapos_rest_api.xml
...est_api/SkinTemplateItem/portal_skins/slapos_rest_api.xml
+0
-47
master/bt5/slapos_rest_api/SkinTemplateItem/portal_skins/slapos_rest_api/SystemPreference_viewSlapOSRestAPI.xml
...ns/slapos_rest_api/SystemPreference_viewSlapOSRestAPI.xml
+0
-152
master/bt5/slapos_rest_api/SkinTemplateItem/portal_skins/slapos_rest_api/SystemPreference_viewSlapOSRestAPI/my_preferred_rest_api_token_server_url.xml
...wSlapOSRestAPI/my_preferred_rest_api_token_server_url.xml
+0
-126
master/bt5/slapos_rest_api/TestTemplateItem/portal_components/test.erp5.testSlapOSRestAPIV1.py
...teItem/portal_components/test.erp5.testSlapOSRestAPIV1.py
+0
-1993
master/bt5/slapos_rest_api/TestTemplateItem/portal_components/test.erp5.testSlapOSRestAPIV1.xml
...eItem/portal_components/test.erp5.testSlapOSRestAPIV1.xml
+0
-109
master/bt5/slapos_rest_api/ToolTemplateItem/portal_slapos_rest_api.xml
...apos_rest_api/ToolTemplateItem/portal_slapos_rest_api.xml
+0
-41
master/bt5/slapos_rest_api/bt/copyright_list
master/bt5/slapos_rest_api/bt/copyright_list
+0
-1
master/bt5/slapos_rest_api/bt/dependency_list
master/bt5/slapos_rest_api/bt/dependency_list
+0
-2
master/bt5/slapos_rest_api/bt/description
master/bt5/slapos_rest_api/bt/description
+0
-1
master/bt5/slapos_rest_api/bt/license
master/bt5/slapos_rest_api/bt/license
+0
-1
master/bt5/slapos_rest_api/bt/template_action_path_list
master/bt5/slapos_rest_api/bt/template_action_path_list
+0
-1
master/bt5/slapos_rest_api/bt/template_document_id_list
master/bt5/slapos_rest_api/bt/template_document_id_list
+0
-1
master/bt5/slapos_rest_api/bt/template_format_version
master/bt5/slapos_rest_api/bt/template_format_version
+0
-1
master/bt5/slapos_rest_api/bt/template_property_sheet_id_list
...er/bt5/slapos_rest_api/bt/template_property_sheet_id_list
+0
-1
master/bt5/slapos_rest_api/bt/template_skin_id_list
master/bt5/slapos_rest_api/bt/template_skin_id_list
+0
-1
master/bt5/slapos_rest_api/bt/template_test_id_list
master/bt5/slapos_rest_api/bt/template_test_id_list
+0
-1
master/bt5/slapos_rest_api/bt/template_tool_id_list
master/bt5/slapos_rest_api/bt/template_tool_id_list
+0
-1
master/bt5/slapos_rest_api/bt/template_update_tool
master/bt5/slapos_rest_api/bt/template_update_tool
+0
-1
master/bt5/slapos_rest_api/bt/title
master/bt5/slapos_rest_api/bt/title
+0
-1
master/bt5/slapos_rest_api/bt/version
master/bt5/slapos_rest_api/bt/version
+0
-1
master/bt5/slapos_rest_api_tool_portal_type/PortalTypeTemplateItem/portal_types/SlapOS%20Rest%20API%20Tool.xml
...eTemplateItem/portal_types/SlapOS%20Rest%20API%20Tool.xml
+0
-60
master/bt5/slapos_rest_api_tool_portal_type/bt/copyright_list
...er/bt5/slapos_rest_api_tool_portal_type/bt/copyright_list
+0
-1
master/bt5/slapos_rest_api_tool_portal_type/bt/description
master/bt5/slapos_rest_api_tool_portal_type/bt/description
+0
-1
master/bt5/slapos_rest_api_tool_portal_type/bt/license
master/bt5/slapos_rest_api_tool_portal_type/bt/license
+0
-1
master/bt5/slapos_rest_api_tool_portal_type/bt/template_format_version
...apos_rest_api_tool_portal_type/bt/template_format_version
+0
-1
master/bt5/slapos_rest_api_tool_portal_type/bt/template_portal_type_id_list
...rest_api_tool_portal_type/bt/template_portal_type_id_list
+0
-1
master/bt5/slapos_rest_api_tool_portal_type/bt/template_update_tool
.../slapos_rest_api_tool_portal_type/bt/template_update_tool
+0
-1
master/bt5/slapos_rest_api_tool_portal_type/bt/title
master/bt5/slapos_rest_api_tool_portal_type/bt/title
+0
-1
master/bt5/slapos_rest_api_tool_portal_type/bt/version
master/bt5/slapos_rest_api_tool_portal_type/bt/version
+0
-1
master/product/SlapOS/Tool/SlapOSRestAPITool.py
master/product/SlapOS/Tool/SlapOSRestAPITool.py
+0
-75
master/tests/__init__.py
master/tests/__init__.py
+0
-1
No files found.
master/bt5/slapos_configurator/TestTemplateItem/portal_components/test.erp5.testSlapOSConfigurator.py
View file @
794fca99
...
...
@@ -196,8 +196,6 @@ class TestSlapOSConfigurator(testSlapOSMixin):
'slapos_cloud'
,
'slapos_slap_tool'
,
'slapos_category'
,
'slapos_rest_api_tool_portal_type'
,
'slapos_rest_api'
,
'slapos_pdm'
,
'slapos_crm'
,
'slapos_accounting'
,
...
...
master/bt5/slapos_erp5/TestTemplateItem/portal_components/test.erp5.testSlapOSERP5SkinSelection.py
View file @
794fca99
...
...
@@ -132,7 +132,6 @@ slapos_core
slapos_crm
slapos_payzen
slapos_pdm
slapos_rest_api
slapos_simulation
slapos_slap_tool
slapos_web
...
...
@@ -244,7 +243,6 @@ slapos_core
slapos_crm
slapos_payzen
slapos_pdm
slapos_rest_api
slapos_simulation
slapos_slap_tool
slapos_web
...
...
@@ -351,7 +349,6 @@ slapos_core
slapos_crm
slapos_payzen
slapos_pdm
slapos_rest_api
slapos_simulation
slapos_slap_tool
slapos_web
...
...
@@ -459,7 +456,6 @@ slapos_core
slapos_crm
slapos_payzen
slapos_pdm
slapos_rest_api
slapos_simulation
slapos_slap_tool
slapos_web
...
...
@@ -564,7 +560,6 @@ slapos_core
slapos_crm
slapos_payzen
slapos_pdm
slapos_rest_api
slapos_simulation
slapos_slap_tool
slapos_web
...
...
@@ -670,7 +665,6 @@ slapos_core
slapos_crm
slapos_payzen
slapos_pdm
slapos_rest_api
slapos_simulation
slapos_slap_tool
slapos_web
...
...
@@ -775,7 +769,6 @@ slapos_core
slapos_crm
slapos_payzen
slapos_pdm
slapos_rest_api
slapos_simulation
slapos_slap_tool
slapos_web
...
...
@@ -881,7 +874,6 @@ slapos_core
slapos_crm
slapos_payzen
slapos_pdm
slapos_rest_api
slapos_simulation
slapos_slap_tool
slapos_web
...
...
@@ -986,7 +978,6 @@ slapos_core
slapos_crm
slapos_payzen
slapos_pdm
slapos_rest_api
slapos_simulation
slapos_slap_tool
slapos_web
...
...
@@ -1093,7 +1084,6 @@ slapos_core
slapos_crm
slapos_payzen
slapos_pdm
slapos_rest_api
slapos_simulation
slapos_slap_tool
slapos_web
...
...
@@ -1201,7 +1191,6 @@ slapos_core
slapos_crm
slapos_payzen
slapos_pdm
slapos_rest_api
slapos_simulation
slapos_slap_tool
slapos_web
...
...
master/bt5/slapos_erp5/bt/dependency_list
View file @
794fca99
...
...
@@ -13,7 +13,6 @@ slapos_cache
slapos_category
slapos_cloud
slapos_ecoallocation
slapos_rest_api
slapos_slap_tool
slapos_crm
slapos_pdm
...
...
master/bt5/slapos_rest_api/ActionTemplateItem/portal_types/System%20Preference/slapos_rest_api_preference.xml
deleted
100644 → 0
View file @
78407bb9
<?xml version="1.0"?>
<ZopeData>
<record
id=
"1"
aka=
"AAAAAAAAAAE="
>
<pickle>
<global
name=
"ActionInformation"
module=
"Products.CMFCore.ActionInformation"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
action
</string>
</key>
<value>
<persistent>
<string
encoding=
"base64"
>
AAAAAAAAAAI=
</string>
</persistent>
</value>
</item>
<item>
<key>
<string>
categories
</string>
</key>
<value>
<tuple>
<string>
action_type/object_view
</string>
</tuple>
</value>
</item>
<item>
<key>
<string>
category
</string>
</key>
<value>
<string>
object_view
</string>
</value>
</item>
<item>
<key>
<string>
condition
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
description
</string>
</key>
<value>
<none/>
</value>
</item>
<item>
<key>
<string>
icon
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
id
</string>
</key>
<value>
<string>
slapos_rest_api_preference
</string>
</value>
</item>
<item>
<key>
<string>
permissions
</string>
</key>
<value>
<tuple>
<string>
View
</string>
</tuple>
</value>
</item>
<item>
<key>
<string>
portal_type
</string>
</key>
<value>
<string>
Action Information
</string>
</value>
</item>
<item>
<key>
<string>
priority
</string>
</key>
<value>
<float>
11.0
</float>
</value>
</item>
<item>
<key>
<string>
title
</string>
</key>
<value>
<string>
SlapOS Rest API
</string>
</value>
</item>
<item>
<key>
<string>
visible
</string>
</key>
<value>
<int>
1
</int>
</value>
</item>
</dictionary>
</pickle>
</record>
<record
id=
"2"
aka=
"AAAAAAAAAAI="
>
<pickle>
<global
name=
"Expression"
module=
"Products.CMFCore.Expression"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
text
</string>
</key>
<value>
<string>
string:${object_url}/SystemPreference_viewSlapOSRestAPI
</string>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
master/bt5/slapos_rest_api/DocumentTemplateItem/portal_components/SlapOSRestAPIV1.py
deleted
100644 → 0
View file @
78407bb9
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright (c) 2012 Nexedi SA and Contributors. All Rights Reserved.
# Łukasz Nowak <luke@nexedi.com>
# Romain Courteaud <romain@nexedi.com>
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsibility of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# guarantees and support are strongly advised to contract a Free Software
# Service Company
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
##############################################################################
from
Acquisition
import
Implicit
from
AccessControl
import
ClassSecurityInfo
,
getSecurityManager
,
Unauthorized
from
Products.SlapOS.SlapOSMachineAuthenticationPlugin
import
getUserByLogin
from
Products.ERP5Type
import
Permissions
from
ComputedAttribute
import
ComputedAttribute
from
zLOG
import
LOG
,
ERROR
from
lxml
import
etree
import
json
import
transaction
from
App.Common
import
rfc1123_date
from
DateTime
import
DateTime
import
re
class
WrongRequest
(
Exception
):
pass
def
etreeXml
(
d
):
r
=
etree
.
Element
(
'instance'
)
for
k
,
v
in
d
.
iteritems
():
v
=
str
(
v
)
etree
.
SubElement
(
r
,
"parameter"
,
attrib
=
{
'id'
:
k
}).
text
=
v
return
etree
.
tostring
(
r
,
pretty_print
=
True
,
xml_declaration
=
True
,
encoding
=
'utf-8'
)
def
jsonify
(
d
):
return
json
.
dumps
(
d
,
indent
=
2
)
def
requireHeader
(
header_dict
):
def
outer
(
fn
):
def
wrapperRequireHeader
(
self
,
*
args
,
**
kwargs
):
problem_dict
=
{}
for
header
,
value
in
header_dict
.
iteritems
():
send_header
=
self
.
REQUEST
.
getHeader
(
header
)
if
send_header
is
None
or
not
re
.
match
(
value
,
send_header
):
problem_dict
[
header
]
=
'Header with value %r is required.'
%
value
if
not
problem_dict
:
return
fn
(
self
,
*
args
,
**
kwargs
)
else
:
self
.
REQUEST
.
response
.
setStatus
(
400
)
self
.
REQUEST
.
response
.
setBody
(
jsonify
(
problem_dict
))
return
self
.
REQUEST
.
response
wrapperRequireHeader
.
__doc__
=
fn
.
__doc__
return
wrapperRequireHeader
return
outer
def
supportModifiedSince
(
document_url_id
):
def
outer
(
fn
):
def
wrapperSupportModifiedSince
(
self
,
*
args
,
**
kwargs
):
modified_since
=
self
.
REQUEST
.
getHeader
(
'If-Modified-Since'
)
if
modified_since
is
not
None
:
# RFC 2616 If-Modified-Since support
try
:
modified_since
=
DateTime
(
self
.
REQUEST
.
getHeader
(
'If-Modified-Since'
))
except
Exception
:
# client sent wrong header, shall be ignored
pass
else
:
if
modified_since
<=
DateTime
():
# client send date before current time, shall continue and
# compare with second precision, as client by default shall set
# If-Modified-Since to last known Last-Modified value
document
=
self
.
restrictedTraverse
(
getattr
(
self
,
document_url_id
))
document_date
=
document
.
getModificationDate
()
or
\
document
.
bobobase_modification_time
()
if
int
(
document_date
.
timeTime
())
<=
int
(
modified_since
.
timeTime
()):
# document was not modified since
self
.
REQUEST
.
response
.
setStatus
(
304
)
return
self
.
REQUEST
.
response
return
fn
(
self
,
*
args
,
**
kwargs
)
wrapperSupportModifiedSince
.
__doc__
=
fn
.
__doc__
return
wrapperSupportModifiedSince
return
outer
def
encode_utf8
(
s
):
return
s
.
encode
(
'utf-8'
)
def
requireParameter
(
json_dict
,
optional_key_list
=
None
):
if
optional_key_list
is
None
:
optional_key_list
=
[]
def
outer
(
fn
):
def
wrapperRequireJson
(
self
,
*
args
,
**
kwargs
):
self
.
jbody
=
{}
error_dict
=
{}
for
key
,
type_
in
json_dict
.
iteritems
():
if
key
not
in
self
.
REQUEST
:
if
key
not
in
optional_key_list
:
error_dict
[
key
]
=
'Missing.'
else
:
value
=
self
.
REQUEST
[
key
]
method
=
None
if
type
(
type_
)
in
(
tuple
,
list
):
type_
,
method
=
type_
if
type_
==
unicode
:
value
=
'"%s"'
%
value
try
:
value
=
json
.
loads
(
value
)
except
Exception
:
error_dict
[
key
]
=
'Malformed value.'
else
:
if
not
isinstance
(
value
,
type_
):
error_dict
[
key
]
=
'%s is not %s.'
%
(
type
(
value
).
__name__
,
type_
.
__name__
)
if
method
is
None
:
self
.
jbody
[
key
]
=
value
else
:
try
:
self
.
jbody
[
key
]
=
method
(
value
)
except
Exception
:
error_dict
[
key
]
=
'Malformed value.'
if
error_dict
:
self
.
REQUEST
.
response
.
setStatus
(
400
)
self
.
REQUEST
.
response
.
setBody
(
jsonify
(
error_dict
))
return
self
.
REQUEST
.
response
return
fn
(
self
,
*
args
,
**
kwargs
)
wrapperRequireJson
.
__doc__
=
fn
.
__doc__
return
wrapperRequireJson
return
outer
def
requireJson
(
json_dict
,
optional_key_list
=
None
):
if
optional_key_list
is
None
:
optional_key_list
=
[]
def
outer
(
fn
):
def
wrapperRequireJson
(
self
,
*
args
,
**
kwargs
):
self
.
REQUEST
.
stdin
.
seek
(
0
)
try
:
self
.
jbody
=
json
.
load
(
self
.
REQUEST
.
stdin
)
except
Exception
:
self
.
REQUEST
.
response
.
setStatus
(
400
)
self
.
REQUEST
.
response
.
setBody
(
jsonify
(
{
'error'
:
'Data is not json object.'
}))
return
self
.
REQUEST
.
response
else
:
error_dict
=
{}
for
key
,
type_
in
json_dict
.
iteritems
():
if
key
not
in
self
.
jbody
:
if
key
not
in
optional_key_list
:
error_dict
[
key
]
=
'Missing.'
elif
key
in
self
.
jbody
:
method
=
None
if
type
(
type_
)
in
(
tuple
,
list
):
type_
,
method
=
type_
if
not
isinstance
(
self
.
jbody
[
key
],
type_
):
error_dict
[
key
]
=
'%s is not %s.'
%
(
type
(
self
.
jbody
[
key
]
).
__name__
,
type_
.
__name__
)
if
method
is
not
None
:
try
:
self
.
jbody
[
key
]
=
method
(
self
.
jbody
[
key
])
except
Exception
:
error_dict
[
key
]
=
'Malformed value.'
if
error_dict
:
self
.
REQUEST
.
response
.
setStatus
(
400
)
self
.
REQUEST
.
response
.
setBody
(
jsonify
(
error_dict
))
return
self
.
REQUEST
.
response
return
fn
(
self
,
*
args
,
**
kwargs
)
wrapperRequireJson
.
__doc__
=
fn
.
__doc__
return
wrapperRequireJson
return
outer
def
responseSupport
(
anonymous
=
False
):
def
outer
(
fn
):
def
wrapperResponseSupport
(
self
,
*
args
,
**
kwargs
):
self
.
REQUEST
.
response
.
setHeader
(
'Content-Type'
,
'application/json'
)
request_headers
=
self
.
REQUEST
.
getHeader
(
'Access-Control-Request-Headers'
)
if
request_headers
:
self
.
REQUEST
.
response
.
setHeader
(
'Access-Control-Allow-Headers'
,
request_headers
)
self
.
REQUEST
.
response
.
setHeader
(
'Access-Control-Allow-Origin'
,
'*'
)
self
.
REQUEST
.
response
.
setHeader
(
'Access-Control-Allow-Methods'
,
'DELETE, PUT, POST, '
'GET, OPTIONS'
)
if
not
anonymous
:
if
getSecurityManager
().
getUser
().
getId
()
is
None
:
if
self
.
REQUEST
.
get
(
'USER_CREATION_IN_PROGRESS'
)
is
not
None
:
# inform that user is not ready yet
self
.
REQUEST
.
response
.
setStatus
(
202
)
self
.
REQUEST
.
response
.
setBody
(
jsonify
(
{
'status'
:
'User under creation.'
}))
else
:
# force login
self
.
REQUEST
.
response
.
setStatus
(
401
)
self
.
REQUEST
.
response
.
setHeader
(
'WWW-Authenticate'
,
'Bearer realm="%s"'
%
self
.
getAPIRoot
())
self
.
REQUEST
.
response
.
setHeader
(
'Location'
,
self
.
getPortalObject
()
\
.
portal_preferences
.
getPreferredRestApiTokenServerUrl
())
return
self
.
REQUEST
.
response
else
:
user_name
=
self
.
getPortalObject
().
portal_membership
\
.
getAuthenticatedMember
()
user_document
=
getUserByLogin
(
self
.
getPortalObject
(),
str
(
user_name
))
if
len
(
user_document
)
!=
1
:
transaction
.
abort
()
LOG
(
'SlapOSRestApiV1'
,
ERROR
,
'Currenty logged in user %r wrong document list %r.'
%
(
user_name
,
user_document
))
self
.
REQUEST
.
response
.
setStatus
(
500
)
self
.
REQUEST
.
response
.
setBody
(
jsonify
({
'error'
:
'There is system issue, please try again later.'
}))
return
self
.
REQUEST
.
response
self
.
user_url
=
user_document
[
0
].
getRelativeUrl
()
return
fn
(
self
,
*
args
,
**
kwargs
)
wrapperResponseSupport
.
__doc__
=
fn
.
__doc__
return
wrapperResponseSupport
return
outer
def
extractDocument
(
portal_type
):
if
not
isinstance
(
portal_type
,
(
list
,
tuple
)):
portal_type
=
[
portal_type
]
def
outer
(
fn
):
def
wrapperExtractDocument
(
self
,
*
args
,
**
kwargs
):
if
not
self
.
REQUEST
[
'traverse_subpath'
]:
self
.
REQUEST
.
response
.
setStatus
(
404
)
return
self
.
REQUEST
.
response
path
=
self
.
REQUEST
[
'traverse_subpath'
][:
2
]
try
:
document
=
self
.
getPortalObject
().
restrictedTraverse
(
path
)
if
getattr
(
document
,
'getPortalType'
,
None
)
is
None
or
\
document
.
getPortalType
()
not
in
portal_type
:
raise
WrongRequest
(
'%r is neiter of %s'
%
(
path
,
', '
.
join
(
portal_type
)))
self
.
document_url
=
document
.
getRelativeUrl
()
except
WrongRequest
:
LOG
(
'SlapOSRestApiV1'
,
ERROR
,
'Problem while trying to find document:'
,
error
=
True
)
self
.
REQUEST
.
response
.
setStatus
(
404
)
except
(
Unauthorized
,
KeyError
):
self
.
REQUEST
.
response
.
setStatus
(
404
)
except
Exception
:
LOG
(
'SlapOSRestApiV1'
,
ERROR
,
'Problem while trying to find instance:'
,
error
=
True
)
self
.
REQUEST
.
response
.
setStatus
(
500
)
self
.
REQUEST
.
response
.
setBody
(
jsonify
({
'error'
:
'There is system issue, please try again later.'
}))
else
:
self
.
REQUEST
[
'traverse_subpath'
]
=
self
.
REQUEST
[
'traverse_subpath'
][
2
:]
return
fn
(
self
,
*
args
,
**
kwargs
)
return
self
.
REQUEST
.
response
wrapperExtractDocument
.
__doc__
=
fn
.
__doc__
return
wrapperExtractDocument
return
outer
class
GenericPublisher
(
Implicit
):
@
responseSupport
(
True
)
def
OPTIONS
(
self
,
*
args
,
**
kwargs
):
"""HTTP OPTIONS implementation"""
self
.
REQUEST
.
response
.
setStatus
(
204
)
return
self
.
REQUEST
.
response
def
__before_publishing_traverse__
(
self
,
self2
,
request
):
path
=
request
[
'TraversalRequestNameStack'
]
subpath
=
path
[:]
path
[:]
=
[]
subpath
.
reverse
()
request
.
set
(
'traverse_subpath'
,
subpath
)
class
InstancePublisher
(
GenericPublisher
):
"""Instance publisher"""
@
responseSupport
()
@
requireHeader
({
'Content-Type'
:
'^application/json.*'
})
@
requireJson
(
dict
(
title
=
(
unicode
,
encode_utf8
),
connection
=
dict
),
[
'title'
,
'connection'
])
@
extractDocument
([
'Software Instance'
,
'Slave Instance'
])
def
PUT
(
self
):
"""Instance PUT support"""
d
=
{}
try
:
self
.
REQUEST
.
response
.
setStatus
(
204
)
software_instance
=
self
.
restrictedTraverse
(
self
.
document_url
)
if
'title'
in
self
.
jbody
and
\
software_instance
.
getTitle
()
!=
self
.
jbody
[
'title'
]:
software_instance
.
setTitle
(
self
.
jbody
[
'title'
])
d
[
'title'
]
=
'Modified.'
self
.
REQUEST
.
response
.
setStatus
(
200
)
if
'connection'
in
self
.
jbody
:
xml
=
etreeXml
(
self
.
jbody
[
'connection'
])
if
xml
!=
software_instance
.
getConnectionXml
():
software_instance
.
setConnectionXml
(
xml
)
d
[
'connection'
]
=
'Modified.'
self
.
REQUEST
.
response
.
setStatus
(
200
)
except
Exception
:
transaction
.
abort
()
LOG
(
'SlapOSRestApiV1'
,
ERROR
,
'Problem while modifying:'
,
error
=
True
)
self
.
REQUEST
.
response
.
setStatus
(
500
)
self
.
REQUEST
.
response
.
setBody
(
jsonify
({
'error'
:
'There is system issue, please try again later.'
}))
else
:
if
d
:
self
.
REQUEST
.
response
.
setBody
(
jsonify
(
d
))
return
self
.
REQUEST
.
response
@
requireHeader
({
'Content-Type'
:
'^application/json.*'
})
@
requireJson
(
dict
(
log
=
unicode
))
@
extractDocument
([
'Software Instance'
,
'Slave Instance'
])
def
__bang
(
self
):
try
:
self
.
restrictedTraverse
(
self
.
document_url
).
bang
(
bang_tree
=
True
,
comment
=
self
.
jbody
[
'log'
])
except
Exception
:
LOG
(
'SlapOSRestApiV1'
,
ERROR
,
'Problem while trying to generate instance dict:'
,
error
=
True
)
self
.
REQUEST
.
response
.
setStatus
(
500
)
self
.
REQUEST
.
response
.
setBody
(
jsonify
({
'error'
:
'There is system issue, please try again later.'
}))
else
:
self
.
REQUEST
.
response
.
setStatus
(
204
)
return
self
.
REQUEST
.
response
@
requireHeader
({
'Content-Type'
:
'^application/json.*'
})
@
requireJson
(
dict
(
slave
=
bool
,
software_release
=
(
unicode
,
encode_utf8
),
title
=
(
unicode
,
encode_utf8
),
software_type
=
(
unicode
,
encode_utf8
),
parameter
=
(
dict
,
etreeXml
),
sla
=
(
dict
,
etreeXml
),
status
=
(
unicode
,
encode_utf8
),
))
def
__request
(
self
):
request_dict
=
{}
for
k_j
,
k_i
in
(
(
'software_release'
,
'software_release'
),
(
'title'
,
'software_title'
),
(
'software_type'
,
'software_type'
),
(
'parameter'
,
'instance_xml'
),
(
'sla'
,
'sla_xml'
),
(
'slave'
,
'shared'
),
(
'status'
,
'state'
)
):
request_dict
[
k_i
]
=
self
.
jbody
[
k_j
]
if
request_dict
[
'state'
]
not
in
[
'started'
,
'stopped'
,
'destroyed'
]:
self
.
REQUEST
.
response
.
setStatus
(
400
)
self
.
REQUEST
.
response
.
setBody
(
jsonify
(
{
'status'
:
'Status shall be one of: started, stopped, destroyed.'
}))
return
self
.
REQUEST
.
response
try
:
self
.
restrictedTraverse
(
self
.
user_url
).
requestSoftwareInstance
(
**
request_dict
)
except
Exception
:
transaction
.
abort
()
LOG
(
'SlapOSRestApiV1'
,
ERROR
,
'Problem with person.requestSoftwareInstance:'
,
error
=
True
)
self
.
REQUEST
.
response
.
setStatus
(
500
)
self
.
REQUEST
.
response
.
setBody
(
jsonify
({
'error'
:
'There is system issue, please try again later.'
}))
return
self
.
REQUEST
.
response
self
.
REQUEST
.
response
.
setStatus
(
202
)
self
.
REQUEST
.
response
.
setBody
(
jsonify
({
'status'
:
'processing'
}))
return
self
.
REQUEST
.
response
@
requireParameter
(
dict
(
slave
=
bool
,
software_release
=
(
unicode
,
encode_utf8
),
software_type
=
(
unicode
,
encode_utf8
),
sla
=
dict
,
))
def
__allocable
(
self
):
try
:
user
=
self
.
restrictedTraverse
(
self
.
user_url
)
user_portal_type
=
user
.
getPortalType
()
if
user_portal_type
==
'Person'
:
pass
elif
user_portal_type
==
'Software Instance'
:
hosting_subscription
=
user
.
getSpecialiseValue
(
portal_type
=
"Hosting Subscription"
)
user
=
hosting_subscription
.
getDestinationSectionValue
(
portal_type
=
"Person"
)
else
:
raise
NotImplementedError
,
"Can not get Person document"
result
=
user
.
Person_restrictMethodAsShadowUser
(
shadow_document
=
user
,
callable_object
=
user
.
Person_findPartition
,
argument_list
=
[
self
.
jbody
[
'software_release'
],
self
.
jbody
[
'software_type'
],
(
'Software Instance'
,
'Slave Instance'
)[
int
(
self
.
jbody
[
'slave'
])],
self
.
jbody
[
'sla'
]],
argument_dict
=
{
'test_mode'
:
True
})
except
Exception
:
transaction
.
abort
()
LOG
(
'SlapOSRestApiV1'
,
ERROR
,
'Problem with person.allocable:'
,
error
=
True
)
self
.
REQUEST
.
response
.
setStatus
(
500
)
self
.
REQUEST
.
response
.
setBody
(
jsonify
({
'error'
:
'There is system issue, please try again later.'
}))
return
self
.
REQUEST
.
response
self
.
REQUEST
.
response
.
setStatus
(
200
)
self
.
REQUEST
.
response
.
setHeader
(
'Cache-Control'
,
'no-cache, no-store'
)
self
.
REQUEST
.
response
.
setBody
(
jsonify
({
'result'
:
result
}))
return
self
.
REQUEST
.
response
@
extractDocument
([
'Software Instance'
,
'Slave Instance'
])
@
supportModifiedSince
(
'document_url'
)
def
__instance_info
(
self
):
certificate
=
False
software_instance
=
self
.
restrictedTraverse
(
self
.
document_url
)
if
self
.
REQUEST
[
'traverse_subpath'
]
and
self
.
REQUEST
[
'traverse_subpath'
][
-
1
]
==
'certificate'
:
certificate
=
True
try
:
if
certificate
:
d
=
{
"ssl_key"
:
software_instance
.
getSslKey
(),
"ssl_certificate"
:
software_instance
.
getSslCertificate
()
}
else
:
d
=
{
"title"
:
software_instance
.
getTitle
(),
"status"
:
software_instance
.
getSlapState
(),
"software_release"
:
software_instance
.
getUrlString
(),
"software_type"
:
software_instance
.
getSourceReference
(),
"slave"
:
software_instance
.
getPortalType
()
==
'Slave Instance'
,
"connection"
:
software_instance
.
getConnectionXmlAsDict
(),
"parameter"
:
software_instance
.
getInstanceXmlAsDict
(),
"sla"
:
software_instance
.
getSlaXmlAsDict
(),
"children_list"
:
[
self
.
getAPIRoot
()
+
'/'
+
q
.
getRelativeUrl
()
\
for
q
in
software_instance
.
getPredecessorValueList
()],
"partition"
:
{
# not ready yet
"public_ip"
:
[],
"private_ip"
:
[],
"tap_interface"
:
""
,
}
}
except
Exception
:
LOG
(
'SlapOSRestApiV1'
,
ERROR
,
'Problem while trying to generate instance dict:'
,
error
=
True
)
self
.
REQUEST
.
response
.
setStatus
(
500
)
self
.
REQUEST
.
response
.
setBody
(
jsonify
({
'error'
:
'There is system issue, please try again later.'
}))
else
:
self
.
REQUEST
.
response
.
setStatus
(
200
)
# Note: Last-Modified will result in resending certificate many times,
# because each modification of instance will result in new Last-Modified
# TODO: Separate certificate from instance and use correct
# Last-Modified header of subobject containing certificate
self
.
REQUEST
.
response
.
setHeader
(
'Last-Modified'
,
rfc1123_date
(
software_instance
.
getModificationDate
()))
# Say that content is publicly cacheable. It is only required in order to
# *force* storing content on clients' disk in case of using HTTPS
self
.
REQUEST
.
response
.
setHeader
(
'Cache-Control'
,
'must-revalidate'
)
self
.
REQUEST
.
response
.
setBody
(
jsonify
(
d
))
return
self
.
REQUEST
.
response
def
__instance_list
(
self
):
kw
=
dict
(
portal_type
=
(
'Software Instance'
,
'Slave Instance'
),
)
d
=
{
"list"
:
[]}
a
=
d
[
'list'
].
append
for
si
in
self
.
getPortalObject
().
portal_catalog
(
**
kw
):
a
(
'/'
.
join
([
self
.
getAPIRoot
(),
'instance'
,
si
.
getRelativeUrl
()]))
try
:
d
[
'list'
][
0
]
except
IndexError
:
# no results, so nothing to return
self
.
REQUEST
.
response
.
setStatus
(
204
)
else
:
self
.
REQUEST
.
response
.
setStatus
(
200
)
self
.
REQUEST
.
response
.
setBody
(
jsonify
(
d
))
return
self
.
REQUEST
.
response
@
responseSupport
()
def
__call__
(
self
):
"""Instance GET/POST support"""
if
self
.
REQUEST
[
'REQUEST_METHOD'
]
==
'POST'
:
if
self
.
REQUEST
[
'traverse_subpath'
]
and
\
self
.
REQUEST
[
'traverse_subpath'
][
-
1
]
==
'bang'
:
self
.
__bang
()
else
:
self
.
__request
()
elif
self
.
REQUEST
[
'REQUEST_METHOD'
]
==
'GET'
:
if
self
.
REQUEST
[
'traverse_subpath'
]:
if
self
.
REQUEST
[
'traverse_subpath'
][
-
1
]
==
'request'
:
self
.
__allocable
()
else
:
self
.
__instance_info
()
else
:
self
.
__instance_list
()
class
ComputerPublisher
(
GenericPublisher
):
@
responseSupport
()
@
requireHeader
({
'Content-Type'
:
'^application/json.*'
})
@
extractDocument
(
'Computer'
)
@
requireJson
(
dict
(
partition
=
list
,
software
=
list
),
[
'partition'
,
'software'
])
def
PUT
(
self
):
"""Computer PUT support"""
computer
=
self
.
restrictedTraverse
(
self
.
document_url
)
error_dict
=
{}
def
getErrorDict
(
list_
,
key_list
,
prefix
):
no
=
0
for
dict_
in
list_
:
error_list
=
[]
if
not
isinstance
(
dict_
,
dict
):
error_list
.
append
(
'Not a dict.'
)
else
:
for
k
in
key_list
:
if
k
not
in
dict_
:
error_list
.
append
(
'Missing key "%s".'
%
k
)
elif
not
isinstance
(
dict_
[
k
],
unicode
):
error_list
.
append
(
'Key "%s" is not unicode.'
%
k
)
elif
k
==
'status'
and
dict_
[
k
]
not
in
[
'installed'
,
'uninstalled'
,
'error'
]:
error_list
.
append
(
'Status "%s" is incorrect.'
%
dict_
[
k
])
if
len
(
error_list
)
>
0
:
error_dict
[
'%s_%s'
%
(
prefix
,
no
)]
=
error_list
no
+=
1
return
error_dict
error_dict
=
{}
transmitted
=
False
if
'partition'
in
self
.
jbody
:
error_dict
.
update
(
getErrorDict
(
self
.
jbody
[
'partition'
],
(
'title'
,
'public_ip'
,
'private_ip'
,
'tap_interface'
),
'partition'
))
transmitted
=
True
if
'software'
in
self
.
jbody
:
error_dict
.
update
(
getErrorDict
(
self
.
jbody
[
'software'
],
(
'software_release'
,
'status'
,
'log'
),
'software'
))
transmitted
=
True
# XXX: Support status as enum.
if
error_dict
:
self
.
REQUEST
.
response
.
setStatus
(
400
)
self
.
REQUEST
.
response
.
setBody
(
jsonify
(
error_dict
))
return
self
.
REQUEST
.
response
if
transmitted
:
try
:
computer
.
Computer_updateFromJson
(
self
.
jbody
)
except
Exception
:
transaction
.
abort
()
LOG
(
'SlapOSRestApiV1'
,
ERROR
,
'Problem while trying to update computer:'
,
error
=
True
)
self
.
REQUEST
.
response
.
setStatus
(
500
)
self
.
REQUEST
.
response
.
setBody
(
jsonify
({
'error'
:
'There is system issue, please try again later.'
}))
return
self
.
REQUEST
.
response
self
.
REQUEST
.
response
.
setStatus
(
204
)
return
self
.
REQUEST
.
response
class
StatusPublisher
(
GenericPublisher
):
@
responseSupport
()
def
__call__
(
self
):
"""Log GET support"""
if
self
.
REQUEST
[
'REQUEST_METHOD'
]
==
'POST'
:
self
.
REQUEST
.
response
.
setStatus
(
404
)
return
self
.
REQUEST
.
response
elif
self
.
REQUEST
[
'REQUEST_METHOD'
]
==
'GET'
:
if
self
.
REQUEST
[
'traverse_subpath'
]:
self
.
__status_info
()
else
:
self
.
__status_list
()
def
__status_list
(
self
):
portal
=
self
.
getPortalObject
()
open_friend
=
portal
.
restrictedTraverse
(
"portal_categories/allocation_scope/open/friend"
,
None
).
getUid
()
open_personal
=
portal
.
restrictedTraverse
(
"portal_categories/allocation_scope/open/personal"
,
None
).
getUid
()
open_public
=
portal
.
restrictedTraverse
(
"portal_categories/allocation_scope/open/public"
,
None
).
getUid
()
kw
=
dict
(
validation_state
=
"validated"
,
portal_type
=
[
'Computer'
,
'Software Installation'
,
'Software Instance'
]
)
d
=
{
"list"
:
[]}
a
=
d
[
'list'
].
append
for
si
in
self
.
getPortalObject
().
portal_catalog
(
**
kw
):
if
(
si
.
getPortalType
()
==
"Software Instance"
or
\
si
.
getPortalType
()
==
"Software Installation"
)
and
\
si
.
getSlapState
()
not
in
[
'start_requested'
,
'stop_requested'
]:
continue
if
si
.
getPortalType
()
==
"Computer"
and
\
si
.
getAllocationScopeUid
()
not
in
[
open_friend
,
open_personal
,
open_public
]:
continue
a
(
'/'
.
join
([
self
.
getAPIRoot
(),
'status'
,
si
.
getRelativeUrl
()]))
try
:
d
[
'list'
][
0
]
except
IndexError
:
# no results, so nothing to return
self
.
REQUEST
.
response
.
setStatus
(
204
)
else
:
self
.
REQUEST
.
response
.
setStatus
(
200
)
self
.
REQUEST
.
response
.
setHeader
(
'Cache-Control'
,
'max-age=300, private'
)
self
.
REQUEST
.
response
.
setBody
(
jsonify
(
d
))
return
self
.
REQUEST
.
response
# XXX Use a decated document to keep the history
@
extractDocument
([
'Computer'
,
'Software Installation'
,
'Software Instance'
])
# @supportModifiedSince('document_url')
def
__status_info
(
self
):
certificate
=
False
document
=
self
.
restrictedTraverse
(
self
.
document_url
)
try
:
memcached_dict
=
self
.
getPortalObject
().
portal_memcached
.
getMemcachedDict
(
key_prefix
=
'slap_tool'
,
plugin_path
=
'portal_memcached/default_memcached_plugin'
)
try
:
d
=
memcached_dict
[
document
.
getReference
()]
except
KeyError
:
d
=
{
"user"
:
"SlapOS Master"
,
'created_at'
:
'%s'
%
rfc1123_date
(
DateTime
()),
"text"
:
"#error no data found for %s"
%
document
.
getReference
()
}
else
:
d
=
json
.
loads
(
d
)
except
Exception
:
LOG
(
'SlapOSRestApiV1'
,
ERROR
,
'Problem while trying to generate status information:'
,
error
=
True
)
self
.
REQUEST
.
response
.
setStatus
(
500
)
self
.
REQUEST
.
response
.
setBody
(
jsonify
({
'error'
:
'There is system issue, please try again later.'
}))
else
:
d
[
'@document'
]
=
self
.
document_url
self
.
REQUEST
.
response
.
setStatus
(
200
)
self
.
REQUEST
.
response
.
setHeader
(
'Cache-Control'
,
'max-age=300, private'
)
self
.
REQUEST
.
response
.
setBody
(
jsonify
(
d
))
return
self
.
REQUEST
.
response
class
SlapOSRestAPIV1
(
Implicit
):
security
=
ClassSecurityInfo
()
security
.
declareObjectProtected
(
Permissions
.
AccessContentsInformation
)
security
.
declarePublic
(
'instance'
)
security
.
declarePublic
(
'getAPIRoot'
)
def
getAPIRoot
(
self
):
"""Returns the root of API"""
return
self
.
absolute_url
()
+
'/v1'
@
ComputedAttribute
def
instance
(
self
):
"""Instance publisher"""
return
InstancePublisher
().
__of__
(
self
)
security
.
declarePublic
(
'computer'
)
@
ComputedAttribute
def
computer
(
self
):
"""Computer publisher"""
return
ComputerPublisher
().
__of__
(
self
)
security
.
declarePublic
(
'log'
)
@
ComputedAttribute
def
status
(
self
):
"""Status publisher"""
return
StatusPublisher
().
__of__
(
self
)
@
responseSupport
(
True
)
def
OPTIONS
(
self
,
*
args
,
**
kwargs
):
"""HTTP OPTIONS implementation"""
self
.
REQUEST
.
response
.
setStatus
(
204
)
return
self
.
REQUEST
.
response
security
.
declarePublic
(
'__call__'
)
@
responseSupport
(
True
)
def
__call__
(
self
):
"""Possible API discovery"""
self
.
REQUEST
.
response
.
setStatus
(
400
)
return
self
.
REQUEST
.
response
master/bt5/slapos_rest_api/DocumentTemplateItem/portal_components/SlapOSRestAPIV1.xml
deleted
100644 → 0
View file @
78407bb9
<?xml version="1.0"?>
<ZopeData>
<record
id=
"1"
aka=
"AAAAAAAAAAE="
>
<pickle>
<global
name=
"Document Component"
module=
"erp5.portal_type"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
_recorded_property_dict
</string>
</key>
<value>
<persistent>
<string
encoding=
"base64"
>
AAAAAAAAAAI=
</string>
</persistent>
</value>
</item>
<item>
<key>
<string>
default_reference
</string>
</key>
<value>
<string>
SlapOSRestAPIV1
</string>
</value>
</item>
<item>
<key>
<string>
description
</string>
</key>
<value>
<none/>
</value>
</item>
<item>
<key>
<string>
id
</string>
</key>
<value>
<string>
SlapOSRestAPIV1
</string>
</value>
</item>
<item>
<key>
<string>
portal_type
</string>
</key>
<value>
<string>
Document Component
</string>
</value>
</item>
<item>
<key>
<string>
sid
</string>
</key>
<value>
<none/>
</value>
</item>
<item>
<key>
<string>
version
</string>
</key>
<value>
<string>
erp5
</string>
</value>
</item>
<item>
<key>
<string>
workflow_history
</string>
</key>
<value>
<persistent>
<string
encoding=
"base64"
>
AAAAAAAAAAM=
</string>
</persistent>
</value>
</item>
</dictionary>
</pickle>
</record>
<record
id=
"2"
aka=
"AAAAAAAAAAI="
>
<pickle>
<global
name=
"PersistentMapping"
module=
"Persistence.mapping"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
data
</string>
</key>
<value>
<dictionary/>
</value>
</item>
</dictionary>
</pickle>
</record>
<record
id=
"3"
aka=
"AAAAAAAAAAM="
>
<pickle>
<global
name=
"PersistentMapping"
module=
"Persistence.mapping"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
data
</string>
</key>
<value>
<dictionary>
<item>
<key>
<string>
component_validation_workflow
</string>
</key>
<value>
<persistent>
<string
encoding=
"base64"
>
AAAAAAAAAAQ=
</string>
</persistent>
</value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
<record
id=
"4"
aka=
"AAAAAAAAAAQ="
>
<pickle>
<global
name=
"WorkflowHistoryList"
module=
"Products.ERP5Type.patches.WorkflowTool"
/>
</pickle>
<pickle>
<tuple>
<none/>
<list>
<dictionary>
<item>
<key>
<string>
action
</string>
</key>
<value>
<string>
validate
</string>
</value>
</item>
<item>
<key>
<string>
validation_state
</string>
</key>
<value>
<string>
validated
</string>
</value>
</item>
</dictionary>
</list>
</tuple>
</pickle>
</record>
</ZopeData>
master/bt5/slapos_rest_api/PropertySheetTemplateItem/portal_property_sheets/SlapOSRestAPISystemPreference.xml
deleted
100644 → 0
View file @
78407bb9
<?xml version="1.0"?>
<ZopeData>
<record
id=
"1"
aka=
"AAAAAAAAAAE="
>
<pickle>
<global
name=
"Property Sheet"
module=
"erp5.portal_type"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
_count
</string>
</key>
<value>
<persistent>
<string
encoding=
"base64"
>
AAAAAAAAAAI=
</string>
</persistent>
</value>
</item>
<item>
<key>
<string>
_mt_index
</string>
</key>
<value>
<persistent>
<string
encoding=
"base64"
>
AAAAAAAAAAM=
</string>
</persistent>
</value>
</item>
<item>
<key>
<string>
_tree
</string>
</key>
<value>
<persistent>
<string
encoding=
"base64"
>
AAAAAAAAAAQ=
</string>
</persistent>
</value>
</item>
<item>
<key>
<string>
description
</string>
</key>
<value>
<none/>
</value>
</item>
<item>
<key>
<string>
id
</string>
</key>
<value>
<string>
SlapOSRestAPISystemPreference
</string>
</value>
</item>
<item>
<key>
<string>
portal_type
</string>
</key>
<value>
<string>
Property Sheet
</string>
</value>
</item>
</dictionary>
</pickle>
</record>
<record
id=
"2"
aka=
"AAAAAAAAAAI="
>
<pickle>
<global
name=
"Length"
module=
"BTrees.Length"
/>
</pickle>
<pickle>
<int>
0
</int>
</pickle>
</record>
<record
id=
"3"
aka=
"AAAAAAAAAAM="
>
<pickle>
<global
name=
"OOBTree"
module=
"BTrees.OOBTree"
/>
</pickle>
<pickle>
<none/>
</pickle>
</record>
<record
id=
"4"
aka=
"AAAAAAAAAAQ="
>
<pickle>
<global
name=
"OOBTree"
module=
"BTrees.OOBTree"
/>
</pickle>
<pickle>
<none/>
</pickle>
</record>
</ZopeData>
master/bt5/slapos_rest_api/PropertySheetTemplateItem/portal_property_sheets/SlapOSRestAPISystemPreference/preferred_rest_api_token_server_url_property.xml
deleted
100644 → 0
View file @
78407bb9
<?xml version="1.0"?>
<ZopeData>
<record
id=
"1"
aka=
"AAAAAAAAAAE="
>
<pickle>
<global
name=
"Standard Property"
module=
"erp5.portal_type"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
_local_properties
</string>
</key>
<value>
<tuple>
<dictionary>
<item>
<key>
<string>
id
</string>
</key>
<value>
<string>
mode
</string>
</value>
</item>
<item>
<key>
<string>
type
</string>
</key>
<value>
<string>
string
</string>
</value>
</item>
</dictionary>
</tuple>
</value>
</item>
<item>
<key>
<string>
categories
</string>
</key>
<value>
<tuple>
<string>
elementary_type/string
</string>
</tuple>
</value>
</item>
<item>
<key>
<string>
description
</string>
</key>
<value>
<string>
Stores token server URL
</string>
</value>
</item>
<item>
<key>
<string>
id
</string>
</key>
<value>
<string>
preferred_rest_api_token_server_url_property
</string>
</value>
</item>
<item>
<key>
<string>
mode
</string>
</key>
<value>
<string>
w
</string>
</value>
</item>
<item>
<key>
<string>
portal_type
</string>
</key>
<value>
<string>
Standard Property
</string>
</value>
</item>
<item>
<key>
<string>
preference
</string>
</key>
<value>
<int>
1
</int>
</value>
</item>
<item>
<key>
<string>
property_default
</string>
</key>
<value>
<string>
python: \'\'
</string>
</value>
</item>
<item>
<key>
<string>
read_permission
</string>
</key>
<value>
<none/>
</value>
</item>
<item>
<key>
<string>
write_permission
</string>
</key>
<value>
<string>
Manage properties
</string>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
master/bt5/slapos_rest_api/SkinTemplateItem/portal_skins/slapos_rest_api.xml
deleted
100644 → 0
View file @
78407bb9
<?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_rest_api
</string>
</value>
</item>
<item>
<key>
<string>
title
</string>
</key>
<value>
<string></string>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
master/bt5/slapos_rest_api/SkinTemplateItem/portal_skins/slapos_rest_api/SystemPreference_viewSlapOSRestAPI.xml
deleted
100644 → 0
View file @
78407bb9
<?xml version="1.0"?>
<ZopeData>
<record
id=
"1"
aka=
"AAAAAAAAAAE="
>
<pickle>
<global
name=
"ERP5Form"
module=
"Products.ERP5Form.Form"
/>
</pickle>
<pickle>
<dictionary>
<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/>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key>
<string>
_objects
</string>
</key>
<value>
<tuple/>
</value>
</item>
<item>
<key>
<string>
action
</string>
</key>
<value>
<string>
Base_edit
</string>
</value>
</item>
<item>
<key>
<string>
description
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
edit_order
</string>
</key>
<value>
<list/>
</value>
</item>
<item>
<key>
<string>
encoding
</string>
</key>
<value>
<string>
UTF-8
</string>
</value>
</item>
<item>
<key>
<string>
enctype
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
group_list
</string>
</key>
<value>
<list>
<string>
left
</string>
<string>
right
</string>
<string>
center
</string>
<string>
bottom
</string>
<string>
hidden
</string>
</list>
</value>
</item>
<item>
<key>
<string>
groups
</string>
</key>
<value>
<dictionary>
<item>
<key>
<string>
bottom
</string>
</key>
<value>
<list/>
</value>
</item>
<item>
<key>
<string>
center
</string>
</key>
<value>
<list/>
</value>
</item>
<item>
<key>
<string>
hidden
</string>
</key>
<value>
<list/>
</value>
</item>
<item>
<key>
<string>
left
</string>
</key>
<value>
<list>
<string>
my_preferred_rest_api_token_server_url
</string>
</list>
</value>
</item>
<item>
<key>
<string>
right
</string>
</key>
<value>
<list/>
</value>
</item>
</dictionary>
</value>
</item>
<item>
<key>
<string>
id
</string>
</key>
<value>
<string>
SystemPreference_viewSlapOSRestAPI
</string>
</value>
</item>
<item>
<key>
<string>
method
</string>
</key>
<value>
<string>
POST
</string>
</value>
</item>
<item>
<key>
<string>
name
</string>
</key>
<value>
<string>
SystemPreference_viewSlapOSRestAPI
</string>
</value>
</item>
<item>
<key>
<string>
pt
</string>
</key>
<value>
<string>
form_view
</string>
</value>
</item>
<item>
<key>
<string>
row_length
</string>
</key>
<value>
<int>
4
</int>
</value>
</item>
<item>
<key>
<string>
stored_encoding
</string>
</key>
<value>
<string>
UTF-8
</string>
</value>
</item>
<item>
<key>
<string>
title
</string>
</key>
<value>
<string>
SlapOS Rest API
</string>
</value>
</item>
<item>
<key>
<string>
unicode_mode
</string>
</key>
<value>
<int>
0
</int>
</value>
</item>
<item>
<key>
<string>
update_action
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
update_action_title
</string>
</key>
<value>
<string></string>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
master/bt5/slapos_rest_api/SkinTemplateItem/portal_skins/slapos_rest_api/SystemPreference_viewSlapOSRestAPI/my_preferred_rest_api_token_server_url.xml
deleted
100644 → 0
View file @
78407bb9
<?xml version="1.0"?>
<ZopeData>
<record
id=
"1"
aka=
"AAAAAAAAAAE="
>
<pickle>
<global
name=
"ProxyField"
module=
"Products.ERP5Form.ProxyField"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
delegated_list
</string>
</key>
<value>
<list>
<string>
items
</string>
<string>
title
</string>
</list>
</value>
</item>
<item>
<key>
<string>
id
</string>
</key>
<value>
<string>
my_preferred_rest_api_token_server_url
</string>
</value>
</item>
<item>
<key>
<string>
message_values
</string>
</key>
<value>
<dictionary>
<item>
<key>
<string>
external_validator_failed
</string>
</key>
<value>
<string>
The input failed the external validator.
</string>
</value>
</item>
</dictionary>
</value>
</item>
<item>
<key>
<string>
overrides
</string>
</key>
<value>
<dictionary>
<item>
<key>
<string>
field_id
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
form_id
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
target
</string>
</key>
<value>
<string></string>
</value>
</item>
</dictionary>
</value>
</item>
<item>
<key>
<string>
tales
</string>
</key>
<value>
<dictionary>
<item>
<key>
<string>
field_id
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
form_id
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
items
</string>
</key>
<value>
<persistent>
<string
encoding=
"base64"
>
AAAAAAAAAAI=
</string>
</persistent>
</value>
</item>
<item>
<key>
<string>
target
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
title
</string>
</key>
<value>
<string></string>
</value>
</item>
</dictionary>
</value>
</item>
<item>
<key>
<string>
values
</string>
</key>
<value>
<dictionary>
<item>
<key>
<string>
field_id
</string>
</key>
<value>
<string>
my_reference
</string>
</value>
</item>
<item>
<key>
<string>
form_id
</string>
</key>
<value>
<string>
Base_viewFieldLibrary
</string>
</value>
</item>
<item>
<key>
<string>
items
</string>
</key>
<value>
<list/>
</value>
</item>
<item>
<key>
<string>
target
</string>
</key>
<value>
<string>
Click to edit the target
</string>
</value>
</item>
<item>
<key>
<string>
title
</string>
</key>
<value>
<string>
Preferred Token Server URL
</string>
</value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
<record
id=
"2"
aka=
"AAAAAAAAAAI="
>
<pickle>
<global
name=
"TALESMethod"
module=
"Products.Formulator.TALESField"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
_text
</string>
</key>
<value>
<string>
python: [(\'\', \'\')] + [(x.getTitle(), x.getRelativeUrl()) for x in here.portal_catalog(portal_type=\'Service\', sort_on=((\'title\', \'ASC\'),),checked_permission=\'View\')]
</string>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
master/bt5/slapos_rest_api/TestTemplateItem/portal_components/test.erp5.testSlapOSRestAPIV1.py
deleted
100644 → 0
View file @
78407bb9
# Copyright (c) 2002-2012 Nexedi SA and Contributors. All Rights Reserved.
from
Products.SlapOS.tests.testSlapOSMixin
import
\
testSlapOSMixin
from
Products.ERP5Type.Base
import
WorkflowMethod
import
transaction
import
httplib
import
urllib
import
urlparse
import
json
import
tempfile
import
os
from
App.Common
import
rfc1123_date
from
DateTime
import
DateTime
import
time
from
unittest
import
skip
def
_getMemcachedDict
(
self
):
return
self
.
getPortal
().
portal_memcached
.
getMemcachedDict
(
key_prefix
=
'slap_tool'
,
plugin_path
=
'portal_memcached/default_memcached_plugin'
)
def
_logAccess
(
self
,
user_reference
,
context_reference
,
text
):
memcached_dict
=
self
.
_getMemcachedDict
()
value
=
json
.
dumps
({
'user'
:
'%s'
%
user_reference
,
'created_at'
:
'%s'
%
rfc1123_date
(
DateTime
()),
'text'
:
'%s'
%
text
,
})
memcached_dict
[
context_reference
]
=
value
class
Simulator
:
def
__init__
(
self
,
outfile
,
method
):
self
.
outfile
=
outfile
self
.
method
=
method
def
__call__
(
self
,
*
args
,
**
kwargs
):
"""Simulation Method"""
old
=
open
(
self
.
outfile
,
'r'
).
read
()
if
old
:
l
=
eval
(
old
)
else
:
l
=
[]
l
.
append
({
'recmethod'
:
self
.
method
,
'recargs'
:
args
,
'reckwargs'
:
kwargs
})
open
(
self
.
outfile
,
'w'
).
write
(
repr
(
l
))
class
RaisingSimulator
:
def
__init__
(
self
,
exception
):
self
.
exception
=
exception
def
__call__
(
self
,
*
args
,
**
kwargs
):
"""Simulation Method"""
raise
self
.
exception
class
CustomHeaderHTTPConnection
(
httplib
.
HTTPConnection
):
def
__init__
(
self
,
custom_header
,
*
args
,
**
kwargs
):
self
.
_custom_header
=
custom_header
httplib
.
HTTPConnection
.
__init__
(
self
,
*
args
,
**
kwargs
)
def
request
(
self
,
*
args
,
**
kwargs
):
headers
=
kwargs
.
get
(
'headers'
,
{})
headers
.
update
(
self
.
_custom_header
)
kwargs
[
'headers'
]
=
headers
return
httplib
.
HTTPConnection
.
request
(
self
,
*
args
,
**
kwargs
)
def
SlapOSRestAPIV1MixinBase_afterSetUp
(
self
):
self
.
test_random_id
=
self
.
generateNewId
()
self
.
access_control_allow_headers
=
'some, funny, headers, '
\
'always, expected, %s'
%
self
.
test_random_id
self
.
document_list
=
[]
self
.
portal
=
self
.
getPortalObject
()
self
.
api_url
=
self
.
portal
.
portal_slapos_rest_api
.
v1
.
getAPIRoot
()
self
.
api_scheme
,
self
.
api_netloc
,
self
.
api_path
,
self
.
api_query
,
\
self
.
api_fragment
=
urlparse
.
urlsplit
(
self
.
api_url
)
self
.
connection
=
CustomHeaderHTTPConnection
(
host
=
self
.
api_netloc
,
custom_header
=
{
'Access-Control-Request-Headers'
:
self
.
access_control_allow_headers
,
'Content-Type'
:
'application/json'
,
})
class
SlapOSRestAPIV1MixinBase
(
testSlapOSMixin
):
def
generateNewId
(
self
):
return
str
(
self
.
getPortalObject
().
portal_ids
.
generateNewId
(
id_group
=
(
'slapos_rest_api_v1_test'
)))
def
cloneByPath
(
self
,
path
):
return
self
.
portal
.
restrictedTraverse
(
path
).
Base_createCloneDocument
(
batch_mode
=
1
)
def
assertCacheControlHeader
(
self
):
self
.
assertEqual
(
'must-revalidate'
,
self
.
response
.
getheader
(
'Cache-Control'
))
def
_afterSetUp
(
self
):
super
(
SlapOSRestAPIV1MixinBase
,
self
).
afterSetUp
()
def
afterSetUp
(
self
):
self
.
_afterSetUp
()
SlapOSRestAPIV1MixinBase_afterSetUp
(
self
)
def
beforeTearDown
(
self
):
pass
def
prepareResponse
(
self
):
self
.
response
=
self
.
connection
.
getresponse
()
self
.
response_data
=
self
.
response
.
read
()
def
assertBasicResponse
(
self
):
self
.
assertEqual
(
self
.
response
.
getheader
(
'access-control-allow-origin'
),
'*'
)
self
.
assertEqual
(
self
.
response
.
getheader
(
'access-control-allow-methods'
),
'DELETE, PUT, POST, GET, OPTIONS'
)
self
.
assertEqual
(
self
.
response
.
getheader
(
'access-control-allow-headers'
),
self
.
access_control_allow_headers
)
def
assertResponseCode
(
self
,
code
):
self
.
assertEqual
(
self
.
response
.
status
,
code
,
'%s was expected, but got %s with response:
\
n
%s'
%
(
code
,
self
.
response
.
status
,
self
.
response_data
))
def
assertResponseJson
(
self
):
self
.
assertEqual
(
self
.
response
.
getheader
(
'Content-Type'
),
'application/json'
)
self
.
json_response
=
json
.
loads
(
self
.
response_data
)
def
assertResponseNoContentType
(
self
):
self
.
assertEqual
(
self
.
response
.
getheader
(
'Content-Type'
),
None
)
def
SlapOSRestAPIV1Mixin_afterSetUp
(
self
):
SlapOSRestAPIV1MixinBase_afterSetUp
(
self
)
self
.
person_request_simulator
=
tempfile
.
mkstemp
()[
1
]
self
.
customer
,
self
.
customer_reference
=
self
.
createPerson
()
self
.
customer
.
requestSoftwareInstance
=
Simulator
(
self
.
person_request_simulator
,
'requestSoftwareInstance'
)
transaction
.
commit
()
def
SlapOSRestAPIV1Mixin_beforeTearDown
(
self
):
if
os
.
path
.
exists
(
self
.
person_request_simulator
):
os
.
unlink
(
self
.
person_request_simulator
)
class
SlapOSRestAPIV1Mixin
(
SlapOSRestAPIV1MixinBase
):
def
createPerson
(
self
):
customer
=
self
.
cloneByPath
(
'person_module/template_member'
)
customer_reference
=
'P'
+
self
.
generateNewId
()
customer
.
edit
(
reference
=
customer_reference
,
default_email_url_string
=
customer_reference
+
'@example.com'
)
customer
.
validate
()
for
assignment
in
customer
.
contentValues
(
portal_type
=
'Assignment'
):
assignment
.
open
()
customer
.
manage_setLocalRoles
(
customer
.
getReference
(),
[
'Associate'
])
transaction
.
commit
()
customer
.
recursiveImmediateReindexObject
()
transaction
.
commit
()
return
customer
,
customer_reference
def
afterSetUp
(
self
):
self
.
_afterSetUp
()
SlapOSRestAPIV1Mixin_afterSetUp
(
self
)
def
beforeTearDown
(
self
):
SlapOSRestAPIV1Mixin_beforeTearDown
(
self
)
def
assertPersonRequestSimulatorEmpty
(
self
):
self
.
assertEqual
(
open
(
self
.
person_request_simulator
).
read
(),
''
)
def
assertPersonRequestSimulator
(
self
,
args
,
kwargs
):
stored
=
eval
(
open
(
self
.
person_request_simulator
).
read
())
# do the same translation magic as in tool
kwargs
=
kwargs
.
copy
()
for
k_j
,
k_i
in
(
(
'software_release'
,
'software_release'
),
(
'title'
,
'software_title'
),
(
'software_type'
,
'software_type'
),
(
'parameter'
,
'instance_xml'
),
(
'sla'
,
'sla_xml'
),
(
'slave'
,
'shared'
),
(
'status'
,
'state'
)
):
kwargs
[
k_i
]
=
kwargs
.
pop
(
k_j
)
self
.
assertEqual
(
stored
,
[{
'recargs'
:
args
,
'reckwargs'
:
kwargs
,
'recmethod'
:
'requestSoftwareInstance'
}])
reckwargs
=
stored
[
0
][
'reckwargs'
]
self
.
assertEqual
(
set
([
type
(
reckwargs
[
'software_title'
]),
type
(
reckwargs
[
'software_release'
]),
type
(
reckwargs
[
'software_type'
]),
type
(
reckwargs
[
'state'
]),
type
(
reckwargs
[
'instance_xml'
]),
type
(
reckwargs
[
'sla_xml'
])
]),
set
([
str
])
)
@
skip
(
'Undecided.'
)
class
TestInstanceRequest
(
SlapOSRestAPIV1Mixin
):
def
test_not_logged_in
(
self
):
self
.
connection
.
request
(
method
=
'POST'
,
url
=
'/'
.
join
([
self
.
api_path
,
'instance'
]))
self
.
prepareResponse
()
self
.
assertBasicResponse
()
self
.
assertResponseCode
(
401
)
self
.
assertTrue
(
self
.
response
.
getheader
(
'Location'
)
is
not
None
)
auth
=
self
.
response
.
getheader
(
'WWW-Authenticate'
)
self
.
assertTrue
(
auth
is
not
None
)
self
.
assertTrue
(
'Bearer realm="'
in
auth
)
self
.
assertPersonRequestSimulatorEmpty
()
def
test_no_json
(
self
):
self
.
connection
.
request
(
method
=
'POST'
,
url
=
'/'
.
join
([
self
.
api_path
,
'instance'
]),
headers
=
{
'REMOTE_USER'
:
self
.
customer_reference
})
self
.
prepareResponse
()
self
.
assertBasicResponse
()
self
.
assertResponseCode
(
400
)
self
.
assertResponseJson
()
self
.
assertEqual
({
'error'
:
"Data is not json object."
},
self
.
json_response
)
self
.
assertPersonRequestSimulatorEmpty
()
def
test_bad_json
(
self
):
self
.
connection
.
request
(
method
=
'POST'
,
url
=
'/'
.
join
([
self
.
api_path
,
'instance'
]),
body
=
'This is not JSON'
,
headers
=
{
'REMOTE_USER'
:
self
.
customer_reference
})
self
.
prepareResponse
()
self
.
assertBasicResponse
()
self
.
assertResponseCode
(
400
)
self
.
assertResponseJson
()
self
.
assertEqual
({
'error'
:
"Data is not json object."
},
self
.
json_response
)
self
.
assertPersonRequestSimulatorEmpty
()
def
test_empty_json
(
self
):
self
.
connection
.
request
(
method
=
'POST'
,
url
=
'/'
.
join
([
self
.
api_path
,
'instance'
]),
body
=
'{}'
,
headers
=
{
'REMOTE_USER'
:
self
.
customer_reference
})
self
.
prepareResponse
()
self
.
assertBasicResponse
()
self
.
assertResponseCode
(
400
)
self
.
assertResponseJson
()
self
.
assertEqual
({
"status"
:
"Missing."
,
"slave"
:
"Missing."
,
"title"
:
"Missing."
,
"software_release"
:
"Missing."
,
"software_type"
:
"Missing."
,
"parameter"
:
"Missing."
,
"sla"
:
"Missing."
},
self
.
json_response
)
self
.
assertPersonRequestSimulatorEmpty
()
def
test_status_slave_missing_json
(
self
):
self
.
connection
.
request
(
method
=
'POST'
,
url
=
'/'
.
join
([
self
.
api_path
,
'instance'
]),
body
=
"""
{
"title": "My unique instance",
"software_release": "http://example.com/example.cfg",
"software_type": "type_provided_by_the_software",
"parameter": {
"Custom1": "one string",
"Custom2": "one float",
"Custom3": [
"abc",
"def"
]
},
"sla": {
"computer_id": "COMP-0"
}
}"""
,
headers
=
{
'REMOTE_USER'
:
self
.
customer_reference
})
self
.
prepareResponse
()
self
.
assertBasicResponse
()
self
.
assertResponseCode
(
400
)
self
.
assertResponseJson
()
self
.
assertEqual
({
"status"
:
"Missing."
,
"slave"
:
"Missing."
},
self
.
json_response
)
self
.
assertPersonRequestSimulatorEmpty
()
def
test_slave_not_bool
(
self
):
kwargs
=
{
'parameter'
:
{
'Custom1'
:
'one string'
,
'Custom2'
:
'one float'
,
'Custom3'
:
[
'abc'
,
'def'
]},
'title'
:
'My unique instance'
,
'software_release'
:
'http://example.com/example.cfg'
,
'status'
:
'started'
,
'sla'
:
{
'computer_id'
:
'COMP-0'
},
'software_type'
:
'type_provided_by_the_software'
,
'slave'
:
"True"
}
self
.
connection
.
request
(
method
=
'POST'
,
url
=
'/'
.
join
([
self
.
api_path
,
'instance'
]),
body
=
json
.
dumps
(
kwargs
),
headers
=
{
'REMOTE_USER'
:
self
.
customer_reference
})
self
.
prepareResponse
()
self
.
assertBasicResponse
()
self
.
assertResponseCode
(
400
)
self
.
assertResponseJson
()
self
.
assertEqual
({
"slave"
:
"unicode is not bool."
,
},
self
.
json_response
)
self
.
assertPersonRequestSimulatorEmpty
()
def
test_incorrect_status
(
self
):
kwargs
=
{
'parameter'
:
{
'Custom1'
:
'one string'
,
'Custom2'
:
'one float'
,
'Custom3'
:
[
'abc'
,
'def'
]},
'title'
:
'My unique instance'
,
'software_release'
:
'http://example.com/example.cfg'
,
'status'
:
'badstatus'
,
'sla'
:
{
'computer_id'
:
'COMP-0'
},
'software_type'
:
'type_provided_by_the_software'
,
'slave'
:
True
}
self
.
connection
.
request
(
method
=
'POST'
,
url
=
'/'
.
join
([
self
.
api_path
,
'instance'
]),
body
=
json
.
dumps
(
kwargs
),
headers
=
{
'REMOTE_USER'
:
self
.
customer_reference
})
self
.
prepareResponse
()
self
.
assertBasicResponse
()
self
.
assertResponseCode
(
400
)
self
.
assertResponseJson
()
self
.
assertEqual
({
"status"
:
"Status shall be one of: started, stopped, destroyed."
,
},
self
.
json_response
)
self
.
assertPersonRequestSimulatorEmpty
()
def
test_correct
(
self
):
kwargs
=
{
'parameter'
:
{
'Custom1'
:
'one string'
,
'Custom2'
:
'one float'
,
'Custom3'
:
[
'abc'
,
'def'
]},
'title'
:
'My unique instance'
,
'software_release'
:
'http://example.com/example.cfg'
,
'status'
:
'started'
,
'sla'
:
{
'computer_id'
:
'COMP-0'
},
'software_type'
:
'type_provided_by_the_software'
,
'slave'
:
True
}
self
.
connection
.
request
(
method
=
'POST'
,
url
=
'/'
.
join
([
self
.
api_path
,
'instance'
]),
body
=
json
.
dumps
(
kwargs
),
headers
=
{
'REMOTE_USER'
:
self
.
customer_reference
})
self
.
prepareResponse
()
self
.
assertBasicResponse
()
self
.
assertResponseCode
(
202
)
self
.
assertResponseJson
()
kwargs
[
'parameter'
]
=
'<?xml version=
\
'
1.0
\
'
encoding=
\
'
utf-8
\
'
?>
\
n
<i'
\
'nstance>
\
n
<parameter id="Custom1">one string</parameter>
\
n
<paramet'
\
'er id="Custom2">one float</parameter>
\
n
<parameter id="Custom3">[u
\
'
a'
\
'bc
\
'
, u
\
'
def
\
'
]</parameter>
\
n
</instance>
\
n
'
kwargs
[
'sla'
]
=
'<?xml version=
\
'
1.0
\
'
encoding=
\
'
utf-8
\
'
?>
\
n
<instanc'
\
'e>
\
n
<parameter id="computer_id">COMP-0</parameter>
\
n
</instance>
\
n
'
self
.
assertPersonRequestSimulator
((),
kwargs
)
self
.
assertEqual
({
"status"
:
"processing"
,
},
self
.
json_response
)
def
test_additional_key_json
(
self
):
kw_request
=
{
'parameter'
:
{
'Custom1'
:
'one string'
,
'Custom2'
:
'one float'
,
'Custom3'
:
[
'abc'
,
'def'
]},
'title'
:
'My unique instance'
,
'software_release'
:
'http://example.com/example.cfg'
,
'status'
:
'started'
,
'sla'
:
{
'computer_id'
:
'COMP-0'
},
'software_type'
:
'type_provided_by_the_software'
,
'slave'
:
True
}
kwargs
=
kw_request
.
copy
()
kwargs
.
update
(
**
{
'wrong_key'
:
'Be ignored'
})
self
.
connection
.
request
(
method
=
'POST'
,
url
=
'/'
.
join
([
self
.
api_path
,
'instance'
]),
body
=
json
.
dumps
(
kwargs
),
headers
=
{
'REMOTE_USER'
:
self
.
customer_reference
})
self
.
prepareResponse
()
self
.
assertBasicResponse
()
self
.
assertResponseCode
(
202
)
self
.
assertResponseJson
()
kw_request
[
'parameter'
]
=
'<?xml version=
\
'
1.0
\
'
encoding=
\
'
utf-8
\
'
?>
\
n
<i'
\
'nstance>
\
n
<parameter id="Custom1">one string</parameter>
\
n
<paramet'
\
'er id="Custom2">one float</parameter>
\
n
<parameter id="Custom3">[u
\
'
a'
\
'bc
\
'
, u
\
'
def
\
'
]</parameter>
\
n
</instance>
\
n
'
kw_request
[
'sla'
]
=
'<?xml version=
\
'
1.0
\
'
encoding=
\
'
utf-8
\
'
?>
\
n
<instanc'
\
'e>
\
n
<parameter id="computer_id">COMP-0</parameter>
\
n
</instance>
\
n
'
self
.
assertPersonRequestSimulator
((),
kw_request
)
self
.
assertEqual
({
"status"
:
"processing"
,
},
self
.
json_response
)
def
test_correct_server_side_raise
(
self
):
self
.
customer
.
requestSoftwareInstance
=
\
RaisingSimulator
(
AttributeError
)
transaction
.
commit
()
kwargs
=
{
'parameter'
:
{
'Custom1'
:
'one string'
,
'Custom2'
:
'one float'
,
'Custom3'
:
[
'abc'
,
'def'
]},
'title'
:
'My unique instance'
,
'software_release'
:
'http://example.com/example.cfg'
,
'status'
:
'started'
,
'sla'
:
{
'computer_id'
:
'COMP-0'
},
'software_type'
:
'type_provided_by_the_software'
,
'slave'
:
True
}
self
.
connection
.
request
(
method
=
'POST'
,
url
=
'/'
.
join
([
self
.
api_path
,
'instance'
]),
body
=
json
.
dumps
(
kwargs
),
headers
=
{
'REMOTE_USER'
:
self
.
customer_reference
})
self
.
prepareResponse
()
self
.
assertBasicResponse
()
self
.
assertResponseCode
(
500
)
self
.
assertResponseJson
()
self
.
assertEqual
({
"error"
:
"There is system issue, please try again later."
,
},
self
.
json_response
)
self
.
assertPersonRequestSimulatorEmpty
()
def
test_content_negotiation_headers
(
self
):
self
.
connection
=
CustomHeaderHTTPConnection
(
host
=
self
.
api_netloc
,
custom_header
=
{
'Access-Control-Request-Headers'
:
self
.
access_control_allow_headers
})
kwargs
=
{
'parameter'
:
{
'Custom1'
:
'one string'
,
'Custom2'
:
'one float'
,
'Custom3'
:
[
'abc'
,
'def'
]},
'title'
:
'My unique instance'
,
'software_release'
:
'http://example.com/example.cfg'
,
'status'
:
'started'
,
'sla'
:
{
'computer_id'
:
'COMP-0'
},
'software_type'
:
'type_provided_by_the_software'
,
'slave'
:
True
}
self
.
connection
.
request
(
method
=
'POST'
,
url
=
'/'
.
join
([
self
.
api_path
,
'instance'
]),
body
=
json
.
dumps
(
kwargs
),
headers
=
{
'REMOTE_USER'
:
self
.
customer_reference
})
self
.
prepareResponse
()
self
.
assertBasicResponse
()
self
.
assertResponseCode
(
400
)
self
.
assertResponseJson
()
self
.
assertEqual
({
'Content-Type'
:
"Header with value '^application/json.*' is required."
},
self
.
json_response
)
self
.
assertPersonRequestSimulatorEmpty
()
# now check with incorrect headers
self
.
connection
.
request
(
method
=
'POST'
,
url
=
'/'
.
join
([
self
.
api_path
,
'instance'
]),
body
=
json
.
dumps
(
kwargs
),
headers
=
{
'REMOTE_USER'
:
self
.
customer_reference
,
'Content-Type'
:
'please/complain'
,
'Accept'
:
'be/silent'
})
self
.
prepareResponse
()
self
.
assertBasicResponse
()
self
.
assertResponseCode
(
400
)
self
.
assertResponseJson
()
self
.
assertEqual
({
'Content-Type'
:
"Header with value '^application/json.*' is required."
},
self
.
json_response
)
self
.
assertPersonRequestSimulatorEmpty
()
# and with correct ones are set by default
@
skip
(
'Undecided.'
)
class
TestInstanceOPTIONS
(
SlapOSRestAPIV1Mixin
):
def
test_OPTIONS_not_logged_in
(
self
):
self
.
connection
=
CustomHeaderHTTPConnection
(
host
=
self
.
api_netloc
,
custom_header
=
{
'Access-Control-Request-Headers'
:
self
.
access_control_allow_headers
})
self
.
connection
.
request
(
method
=
'OPTIONS'
,
url
=
'/'
.
join
([
self
.
api_path
,
'instance'
]))
self
.
prepareResponse
()
self
.
assertBasicResponse
()
self
.
assertResponseCode
(
204
)
self
.
assertResponseNoContentType
()
self
.
assertPersonRequestSimulatorEmpty
()
def
SlapOSRestAPIV1InstanceMixin_afterSetUp
(
self
):
SlapOSRestAPIV1Mixin_afterSetUp
(
self
)
self
.
software_instance
=
self
.
createSoftwareInstance
(
self
.
customer
)
class
SlapOSRestAPIV1InstanceMixin
(
SlapOSRestAPIV1Mixin
):
def
afterSetUp
(
self
):
self
.
_afterSetUp
()
SlapOSRestAPIV1InstanceMixin_afterSetUp
(
self
)
def
assertLastModifiedHeader
(
self
):
calculated
=
rfc1123_date
(
self
.
software_instance
.
getModificationDate
())
self
.
assertEqual
(
calculated
,
self
.
response
.
getheader
(
'Last-Modified'
))
def
createSoftwareInstance
(
self
,
person
):
software_instance
=
self
.
cloneByPath
(
'software_instance_module/template_software_instance'
)
hosting_subscription
=
self
.
cloneByPath
(
'hosting_subscription_module/template_hosting_subscription'
)
software_instance
.
edit
(
reference
=
'SI'
+
self
.
test_random_id
,
ssl_key
=
'SSL Key'
,
ssl_certificate
=
'SSL Certificate'
,
url_string
=
'http://url.of.software.release/'
)
software_instance
.
validate
()
hosting_subscription
.
edit
(
reference
=
'HS'
+
self
.
test_random_id
,
predecessor
=
software_instance
.
getRelativeUrl
(),
destination_section
=
person
.
getRelativeUrl
()
)
hosting_subscription
.
validate
()
hosting_subscription
.
manage_setLocalRoles
(
person
.
getReference
(),
[
'Assignee'
])
software_instance
.
manage_setLocalRoles
(
person
.
getReference
(),
[
'Assignee'
])
transaction
.
commit
()
hosting_subscription
.
recursiveImmediateReindexObject
()
software_instance
.
recursiveImmediateReindexObject
()
transaction
.
commit
()
return
software_instance
# needed to avoid calling interaction and being able to destroy XML
@
WorkflowMethod
.
disable
def
_destroySoftwareInstanceTextContentXml
(
self
,
software_instance
):
software_instance
.
setTextContent
(
'This is bad XML'
)
transaction
.
commit
()
software_instance
.
recursiveImmediateReindexObject
()
transaction
.
commit
()
@
skip
(
'Undecided.'
)
class
TestInstanceGET
(
SlapOSRestAPIV1InstanceMixin
):
def
test_non_existing
(
self
):
non_existing
=
'software_instance_module/'
+
self
.
generateNewId
()
try
:
self
.
portal
.
restrictedTraverse
(
non_existing
)
except
KeyError
:
pass
else
:
raise
AssertionError
(
'It was impossible to test'
)
self
.
connection
.
request
(
method
=
'GET'
,
url
=
'/'
.
join
([
self
.
api_path
,
'instance'
,
non_existing
]),
headers
=
{
'REMOTE_USER'
:
self
.
customer_reference
})
self
.
prepareResponse
()
self
.
assertBasicResponse
()
self
.
assertResponseCode
(
404
)
def
test_something_else
(
self
):
self
.
connection
.
request
(
method
=
'GET'
,
url
=
'/'
.
join
([
self
.
api_path
,
'instance'
,
self
.
software_instance
.
getPredecessorRelatedValue
().
getRelativeUrl
()]),
headers
=
{
'REMOTE_USER'
:
self
.
customer_reference
})
self
.
prepareResponse
()
self
.
assertBasicResponse
()
self
.
assertResponseCode
(
404
)
def
test_bad_xml
(
self
):
self
.
_destroySoftwareInstanceTextContentXml
(
self
.
software_instance
)
self
.
connection
.
request
(
method
=
'GET'
,
url
=
'/'
.
join
([
self
.
api_path
,
'instance'
,
self
.
software_instance
.
getRelativeUrl
()]),
headers
=
{
'REMOTE_USER'
:
self
.
customer_reference
})
self
.
prepareResponse
()
self
.
assertBasicResponse
()
self
.
assertResponseCode
(
500
)
self
.
assertResponseJson
()
self
.
assertEqual
({
"error"
:
"There is system issue, please try again later."
},
self
.
json_response
)
def
test
(
self
):
self
.
connection
.
request
(
method
=
'GET'
,
url
=
'/'
.
join
([
self
.
api_path
,
'instance'
,
self
.
software_instance
.
getRelativeUrl
()]),
headers
=
{
'REMOTE_USER'
:
self
.
customer_reference
})
self
.
prepareResponse
()
self
.
assertBasicResponse
()
self
.
assertResponseCode
(
200
)
self
.
assertLastModifiedHeader
()
self
.
assertCacheControlHeader
()
self
.
assertResponseJson
()
self
.
assertEqual
({
"status"
:
"draft"
,
"connection"
:
{
"parameter1"
:
"valueof1"
,
"parameter2"
:
"https://niut:pass@example.com:4567/arfarf/oink?m=1#4.5"
},
"partition"
:
{
"public_ip"
:
[],
"tap_interface"
:
""
,
"private_ip"
:
[]},
"slave"
:
False
,
"children_list"
:
[],
"title"
:
"Template Software Instance"
,
"software_type"
:
"RootSoftwareInstance"
,
"parameter"
:
{
"parameter1"
:
"valueof1"
,
"parameter2"
:
"valueof2"
},
"software_release"
:
"http://url.of.software.release/"
,
"sla"
:
{
"computer_guid"
:
"SOMECOMP"
}},
self
.
json_response
)
def
test_if_modified_since_equal
(
self
):
self
.
connection
.
request
(
method
=
'GET'
,
url
=
'/'
.
join
([
self
.
api_path
,
'instance'
,
self
.
software_instance
.
getRelativeUrl
()]),
headers
=
{
'REMOTE_USER'
:
self
.
customer_reference
,
'If-Modified-Since'
:
rfc1123_date
(
self
.
software_instance
\
.
getModificationDate
())})
self
.
prepareResponse
()
self
.
assertBasicResponse
()
self
.
assertResponseCode
(
304
)
def
test_if_modified_since_after
(
self
):
# wait three seconds before continuing in order to not hit time precision
# issue, as test needs to provide date with second precision after
# last modification of software instance and *before* now()
time
.
sleep
(
3
)
# add 2 seconds, as used rfc1123_date will ceil the second in response and
# one more second will be required in order to be *after* the modification time
if_modified
=
self
.
software_instance
.
getModificationDate
().
timeTime
()
+
2
# check the test: is calculated time *before* now?
self
.
assertTrue
(
int
(
if_modified
)
<
int
(
DateTime
().
timeTime
()))
self
.
connection
.
request
(
method
=
'GET'
,
url
=
'/'
.
join
([
self
.
api_path
,
'instance'
,
self
.
software_instance
.
getRelativeUrl
()]),
headers
=
{
'REMOTE_USER'
:
self
.
customer_reference
,
'If-Modified-Since'
:
rfc1123_date
(
DateTime
(
if_modified
))})
self
.
prepareResponse
()
self
.
assertBasicResponse
()
self
.
assertResponseCode
(
304
)
def
test_if_modified_since_before
(
self
):
self
.
connection
.
request
(
method
=
'GET'
,
url
=
'/'
.
join
([
self
.
api_path
,
'instance'
,
self
.
software_instance
.
getRelativeUrl
()]),
headers
=
{
'REMOTE_USER'
:
self
.
customer_reference
,
'If-Modified-Since'
:
rfc1123_date
(
self
.
software_instance
\
.
getModificationDate
()
-
1
)})
self
.
prepareResponse
()
self
.
assertBasicResponse
()
self
.
assertResponseCode
(
200
)
self
.
assertLastModifiedHeader
()
self
.
assertCacheControlHeader
()
self
.
assertResponseJson
()
self
.
assertEqual
({
"status"
:
"draft"
,
"connection"
:
{
"parameter1"
:
"valueof1"
,
"parameter2"
:
"https://niut:pass@example.com:4567/arfarf/oink?m=1#4.5"
},
"partition"
:
{
"public_ip"
:
[],
"tap_interface"
:
""
,
"private_ip"
:
[]},
"slave"
:
False
,
"children_list"
:
[],
"title"
:
"Template Software Instance"
,
"software_type"
:
"RootSoftwareInstance"
,
"parameter"
:
{
"parameter1"
:
"valueof1"
,
"parameter2"
:
"valueof2"
},
"software_release"
:
"http://url.of.software.release/"
,
"sla"
:
{
"computer_guid"
:
"SOMECOMP"
}},
self
.
json_response
)
def
test_if_modified_since_date_not_date
(
self
):
self
.
connection
.
request
(
method
=
'GET'
,
url
=
'/'
.
join
([
self
.
api_path
,
'instance'
,
self
.
software_instance
.
getRelativeUrl
()]),
headers
=
{
'REMOTE_USER'
:
self
.
customer_reference
,
'If-Modified-Since'
:
'This Is Not A date'
})
self
.
prepareResponse
()
self
.
assertBasicResponse
()
self
.
assertResponseCode
(
200
)
self
.
assertLastModifiedHeader
()
self
.
assertCacheControlHeader
()
self
.
assertResponseJson
()
self
.
assertEqual
({
"status"
:
"draft"
,
"connection"
:
{
"parameter1"
:
"valueof1"
,
"parameter2"
:
"https://niut:pass@example.com:4567/arfarf/oink?m=1#4.5"
},
"partition"
:
{
"public_ip"
:
[],
"tap_interface"
:
""
,
"private_ip"
:
[]},
"slave"
:
False
,
"children_list"
:
[],
"title"
:
"Template Software Instance"
,
"software_type"
:
"RootSoftwareInstance"
,
"parameter"
:
{
"parameter1"
:
"valueof1"
,
"parameter2"
:
"valueof2"
},
"software_release"
:
"http://url.of.software.release/"
,
"sla"
:
{
"computer_guid"
:
"SOMECOMP"
}},
self
.
json_response
)
def
test_if_modified_since_date_future
(
self
):
self
.
connection
.
request
(
method
=
'GET'
,
url
=
'/'
.
join
([
self
.
api_path
,
'instance'
,
self
.
software_instance
.
getRelativeUrl
()]),
headers
=
{
'REMOTE_USER'
:
self
.
customer_reference
,
'If-Modified-Since'
:
rfc1123_date
(
DateTime
()
+
1
)})
self
.
prepareResponse
()
self
.
assertBasicResponse
()
self
.
assertResponseCode
(
200
)
self
.
assertLastModifiedHeader
()
self
.
assertCacheControlHeader
()
self
.
assertResponseJson
()
self
.
assertEqual
({
"status"
:
"draft"
,
"connection"
:
{
"parameter1"
:
"valueof1"
,
"parameter2"
:
"https://niut:pass@example.com:4567/arfarf/oink?m=1#4.5"
},
"partition"
:
{
"public_ip"
:
[],
"tap_interface"
:
""
,
"private_ip"
:
[]},
"slave"
:
False
,
"children_list"
:
[],
"title"
:
"Template Software Instance"
,
"software_type"
:
"RootSoftwareInstance"
,
"parameter"
:
{
"parameter1"
:
"valueof1"
,
"parameter2"
:
"valueof2"
},
"software_release"
:
"http://url.of.software.release/"
,
"sla"
:
{
"computer_guid"
:
"SOMECOMP"
}},
self
.
json_response
)
def
test_other_one
(
self
):
person
,
person_reference
=
self
.
createPerson
()
self
.
connection
.
request
(
method
=
'GET'
,
url
=
'/'
.
join
([
self
.
api_path
,
'instance'
,
self
.
software_instance
.
getRelativeUrl
()]),
headers
=
{
'REMOTE_USER'
:
person_reference
})
self
.
prepareResponse
()
self
.
assertBasicResponse
()
self
.
assertResponseCode
(
404
)
@
skip
(
'Undecided.'
)
class
TestInstanceGETcertificate
(
SlapOSRestAPIV1InstanceMixin
):
def
test
(
self
):
self
.
connection
.
request
(
method
=
'GET'
,
url
=
'/'
.
join
([
self
.
api_path
,
'instance'
,
self
.
software_instance
.
getRelativeUrl
(),
'certificate'
]),
headers
=
{
'REMOTE_USER'
:
self
.
customer_reference
})
self
.
prepareResponse
()
self
.
assertBasicResponse
()
self
.
assertResponseCode
(
200
)
self
.
assertLastModifiedHeader
()
self
.
assertCacheControlHeader
()
self
.
assertResponseJson
()
self
.
assertEqual
({
"ssl_key"
:
"SSL Key"
,
"ssl_certificate"
:
"SSL Certificate"
},
self
.
json_response
)
def
test_bad_xml
(
self
):
self
.
_destroySoftwareInstanceTextContentXml
(
self
.
software_instance
)
self
.
connection
.
request
(
method
=
'GET'
,
url
=
'/'
.
join
([
self
.
api_path
,
'instance'
,
self
.
software_instance
.
getRelativeUrl
(),
'certificate'
]),
headers
=
{
'REMOTE_USER'
:
self
.
customer_reference
})
self
.
prepareResponse
()
self
.
assertBasicResponse
()
self
.
assertResponseCode
(
200
)
self
.
assertResponseJson
()
self
.
assertEqual
({
"ssl_key"
:
"SSL Key"
,
"ssl_certificate"
:
"SSL Certificate"
},
self
.
json_response
)
def
test_non_existing
(
self
):
non_existing
=
'software_instance_module/'
+
self
.
generateNewId
()
try
:
self
.
portal
.
restrictedTraverse
(
non_existing
)
except
KeyError
:
pass
else
:
raise
AssertionError
(
'It was impossible to test'
)
self
.
connection
.
request
(
method
=
'GET'
,
url
=
'/'
.
join
([
self
.
api_path
,
'instance'
,
non_existing
,
'certificate'
]),
headers
=
{
'REMOTE_USER'
:
self
.
customer_reference
})
self
.
prepareResponse
()
self
.
assertBasicResponse
()
self
.
assertResponseCode
(
404
)
def
test_something_else
(
self
):
self
.
connection
.
request
(
method
=
'GET'
,
url
=
'/'
.
join
([
self
.
api_path
,
'instance'
,
self
.
software_instance
.
getPredecessorRelatedValue
().
getRelativeUrl
(),
'certificate'
]),
headers
=
{
'REMOTE_USER'
:
self
.
customer_reference
})
self
.
prepareResponse
()
self
.
assertBasicResponse
()
self
.
assertResponseCode
(
404
)
def
test_other_one
(
self
):
person
,
person_reference
=
self
.
createPerson
()
self
.
connection
.
request
(
method
=
'GET'
,
url
=
'/'
.
join
([
self
.
api_path
,
'instance'
,
self
.
software_instance
.
getRelativeUrl
(),
'certificate'
]),
headers
=
{
'REMOTE_USER'
:
person_reference
})
self
.
prepareResponse
()
self
.
assertBasicResponse
()
self
.
assertResponseCode
(
404
)
class
TestInstanceAllocableGET
(
SlapOSRestAPIV1InstanceMixin
):
def
test_not_logged_in
(
self
):
self
.
connection
.
request
(
method
=
'GET'
,
url
=
'/'
.
join
([
self
.
api_path
,
'instance'
,
'request'
]))
self
.
prepareResponse
()
self
.
assertBasicResponse
()
self
.
assertResponseCode
(
401
)
self
.
assertTrue
(
self
.
response
.
getheader
(
'Location'
)
is
not
None
)
auth
=
self
.
response
.
getheader
(
'WWW-Authenticate'
)
self
.
assertTrue
(
auth
is
not
None
)
self
.
assertTrue
(
'Bearer realm="'
in
auth
)
def
test_empty_parameter
(
self
):
self
.
connection
.
request
(
method
=
'GET'
,
url
=
'/'
.
join
([
self
.
api_path
,
'instance'
,
'request'
]),
body
=
'{}'
,
headers
=
{
'REMOTE_USER'
:
self
.
customer_reference
})
self
.
prepareResponse
()
self
.
assertBasicResponse
()
self
.
assertResponseCode
(
400
)
self
.
assertResponseJson
()
self
.
assertEqual
({
"slave"
:
"Missing."
,
"software_release"
:
"Missing."
,
"software_type"
:
"Missing."
,
"sla"
:
"Missing."
},
self
.
json_response
)
def
test_bad_sla_json
(
self
):
kwargs
=
{
'software_release'
:
'http://example.com/example.cfg'
,
'sla'
:
'This is not JSON'
,
'software_type'
:
'type_provided_by_the_software'
,
'slave'
:
'true'
}
self
.
connection
.
request
(
method
=
'GET'
,
url
=
'/'
.
join
([
self
.
api_path
,
'instance'
,
'request'
])
+
\
'?%s'
%
urllib
.
urlencode
(
kwargs
),
headers
=
{
'REMOTE_USER'
:
self
.
customer_reference
})
self
.
prepareResponse
()
self
.
assertBasicResponse
()
self
.
assertResponseCode
(
400
)
self
.
assertResponseJson
()
self
.
assertEqual
({
'sla'
:
"Malformed value."
},
self
.
json_response
)
def
test_slave_not_bool
(
self
):
kwargs
=
{
'software_release'
:
'http://example.com/example.cfg'
,
'sla'
:
json
.
dumps
({
'computer_id'
:
'COMP-0'
}),
'software_type'
:
'type_provided_by_the_software'
,
'slave'
:
'this is not a JSON boolean'
}
self
.
connection
.
request
(
method
=
'GET'
,
url
=
'/'
.
join
([
self
.
api_path
,
'instance'
,
'request'
])
+
\
'?%s'
%
urllib
.
urlencode
(
kwargs
),
headers
=
{
'REMOTE_USER'
:
self
.
customer_reference
})
self
.
prepareResponse
()
self
.
assertBasicResponse
()
self
.
assertResponseCode
(
400
)
self
.
assertResponseJson
()
self
.
assertEqual
({
"slave"
:
"Malformed value."
,
},
self
.
json_response
)
def
test_correct
(
self
):
kwargs
=
{
'software_release'
:
'http://example.com/example.cfg'
,
'sla'
:
json
.
dumps
({
'computer_id'
:
'COMP-0'
}),
'software_type'
:
'type_provided_by_the_software'
,
'slave'
:
'true'
}
self
.
connection
.
request
(
method
=
'GET'
,
url
=
'/'
.
join
([
self
.
api_path
,
'instance'
,
'request'
])
+
\
'?%s'
%
urllib
.
urlencode
(
kwargs
),
headers
=
{
'REMOTE_USER'
:
self
.
customer_reference
})
self
.
prepareResponse
()
self
.
assertBasicResponse
()
self
.
assertResponseCode
(
200
)
self
.
assertResponseJson
()
def
test_additional_key_json
(
self
):
kw_request
=
{
'software_release'
:
'http://example.com/example.cfg'
,
'sla'
:
json
.
dumps
({
'computer_id'
:
'COMP-0'
}),
'software_type'
:
'type_provided_by_the_software'
,
'slave'
:
'true'
}
kwargs
=
kw_request
.
copy
()
kwargs
.
update
(
**
{
'wrong_key'
:
'Be ignored'
})
self
.
connection
.
request
(
method
=
'GET'
,
url
=
'/'
.
join
([
self
.
api_path
,
'instance'
,
'request'
])
+
\
'?%s'
%
urllib
.
urlencode
(
kwargs
),
headers
=
{
'REMOTE_USER'
:
self
.
customer_reference
})
self
.
prepareResponse
()
self
.
assertBasicResponse
()
self
.
assertResponseCode
(
200
)
self
.
assertResponseJson
()
# def test_correct_server_side_raise(self):
# self.customer.requestSoftwareInstance = \
# RaisingSimulator(AttributeError)
# transaction.commit()
# kwargs = {
# 'parameter': {
# 'Custom1': 'one string',
# 'Custom2': 'one float',
# 'Custom3': ['abc', 'def']},
# 'title': 'My unique instance',
# 'software_release': 'http://example.com/example.cfg',
# 'status': 'started',
# 'sla': {
# 'computer_id': 'COMP-0'},
# 'software_type': 'type_provided_by_the_software',
# 'slave': True}
# self.connection.request(method='GET',
# url='/'.join([self.api_path, 'instance', 'request']),
# body=json.dumps(kwargs),
# headers={'REMOTE_USER': self.customer_reference})
# self.prepareResponse()
# self.assertBasicResponse()
# self.assertResponseCode(500)
# self.assertResponseJson()
# self.assertEqual({
# "error": "There is system issue, please try again later.",
# },
# self.json_response)
# def test_content_negotiation_headers(self):
# self.connection = CustomHeaderHTTPConnection(host=self.api_netloc,
# custom_header={
# 'Access-Control-Request-Headers': self.access_control_allow_headers
# })
# kwargs = {
# 'parameter': {
# 'Custom1': 'one string',
# 'Custom2': 'one float',
# 'Custom3': ['abc', 'def']},
# 'title': 'My unique instance',
# 'software_release': 'http://example.com/example.cfg',
# 'status': 'started',
# 'sla': {
# 'computer_id': 'COMP-0'},
# 'software_type': 'type_provided_by_the_software',
# 'slave': True}
# self.connection.request(method='GET',
# url='/'.join([self.api_path, 'instance', 'request']),
# body=json.dumps(kwargs),
# headers={'REMOTE_USER': self.customer_reference})
# self.prepareResponse()
# self.assertBasicResponse()
# self.assertResponseCode(400)
# self.assertResponseJson()
# self.assertEqual({
# 'Content-Type': "Header with value '^application/json.*' is required."},
# self.json_response)
#
# # now check with incorrect headers
# self.connection.request(method='GET',
# url='/'.join([self.api_path, 'instance', 'request']),
# body=json.dumps(kwargs),
# headers={'REMOTE_USER': self.customer_reference,
# 'Content-Type': 'please/complain',
# 'Accept': 'be/silent'})
# self.prepareResponse()
# self.assertBasicResponse()
# self.assertResponseCode(400)
# self.assertResponseJson()
# self.assertEqual({
# 'Content-Type': "Header with value '^application/json.*' is required."},
# self.json_response)
# # and with correct ones are set by default
def
SlapOSRestAPIV1BangMixin_afterSetUp
(
self
):
SlapOSRestAPIV1BangMixin_afterSetUp
(
self
)
self
.
instance_bang_simulator
=
tempfile
.
mkstemp
()[
1
]
self
.
software_instance
.
bang
=
Simulator
(
self
.
instance_bang_simulator
,
'bang'
)
transaction
.
commit
()
def
SlapOSRestAPIV1BangMixin_beforeTearDown
(
self
):
SlapOSRestAPIV1BangMixin_beforeTearDown
()
if
os
.
path
.
exists
(
self
.
instance_bang_simulator
):
os
.
unlink
(
self
.
instance_bang_simulator
)
class
SlapOSRestAPIV1BangMixin
(
SlapOSRestAPIV1InstanceMixin
):
def
afterSetUp
(
self
):
self
.
_afterSetUp
()
SlapOSRestAPIV1BangMixin_afterSetUp
(
self
)
def
beforeTearDown
(
self
):
SlapOSRestAPIV1BangMixin_beforeTearDown
(
self
)
def
assertInstanceBangSimulatorEmpty
(
self
):
self
.
assertEqual
(
open
(
self
.
instance_bang_simulator
).
read
(),
''
)
def
assertInstanceBangSimulator
(
self
,
args
,
kwargs
):
stored
=
eval
(
open
(
self
.
instance_bang_simulator
).
read
())
# do the same translation magic as in workflow
kwargs
[
'comment'
]
=
kwargs
.
pop
(
'log'
)
self
.
assertEqual
(
stored
,
[{
'recargs'
:
args
,
'reckwargs'
:
kwargs
,
'recmethod'
:
'bang'
}])
@
skip
(
'Undecided.'
)
class
TestInstancePOSTbang
(
SlapOSRestAPIV1BangMixin
):
def
test
(
self
):
kwargs
=
{
'log'
:
'This is cool log!'
,
'bang_tree'
:
True
}
self
.
connection
.
request
(
method
=
'POST'
,
url
=
'/'
.
join
([
self
.
api_path
,
'instance'
,
self
.
software_instance
.
getRelativeUrl
(),
'bang'
]),
body
=
json
.
dumps
(
kwargs
),
headers
=
{
'REMOTE_USER'
:
self
.
customer_reference
})
self
.
prepareResponse
()
self
.
assertBasicResponse
()
self
.
assertResponseCode
(
204
)
self
.
assertInstanceBangSimulator
((),
kwargs
)
def
test_server_side_raise
(
self
):
self
.
software_instance
.
bang
=
RaisingSimulator
(
AttributeError
)
transaction
.
commit
()
kwargs
=
{
'log'
:
'This is cool log!'
}
self
.
connection
.
request
(
method
=
'POST'
,
url
=
'/'
.
join
([
self
.
api_path
,
'instance'
,
self
.
software_instance
.
getRelativeUrl
(),
'bang'
]),
body
=
json
.
dumps
(
kwargs
),
headers
=
{
'REMOTE_USER'
:
self
.
customer_reference
})
self
.
prepareResponse
()
self
.
assertBasicResponse
()
self
.
assertResponseCode
(
500
)
self
.
assertResponseJson
()
self
.
assertEqual
({
"error"
:
"There is system issue, please try again later."
,
},
self
.
json_response
)
self
.
assertInstanceBangSimulatorEmpty
()
def
test_bad_xml
(
self
):
self
.
_destroySoftwareInstanceTextContentXml
(
self
.
software_instance
)
kwargs
=
{
'log'
:
'This is cool log!'
,
'bang_tree'
:
True
}
self
.
connection
.
request
(
method
=
'POST'
,
url
=
'/'
.
join
([
self
.
api_path
,
'instance'
,
self
.
software_instance
.
getRelativeUrl
(),
'bang'
]),
body
=
json
.
dumps
(
kwargs
),
headers
=
{
'REMOTE_USER'
:
self
.
customer_reference
})
self
.
prepareResponse
()
self
.
assertBasicResponse
()
self
.
assertResponseCode
(
204
)
self
.
assertInstanceBangSimulator
((),
kwargs
)
def
test_non_existing
(
self
):
non_existing
=
'software_instance_module/'
+
self
.
generateNewId
()
try
:
self
.
portal
.
restrictedTraverse
(
non_existing
)
except
KeyError
:
pass
else
:
raise
AssertionError
(
'It was impossible to test'
)
kwargs
=
{
'log'
:
'This is cool log!'
}
self
.
connection
.
request
(
method
=
'POST'
,
url
=
'/'
.
join
([
self
.
api_path
,
'instance'
,
non_existing
,
'bang'
]),
body
=
json
.
dumps
(
kwargs
),
headers
=
{
'REMOTE_USER'
:
self
.
customer_reference
})
self
.
prepareResponse
()
self
.
assertBasicResponse
()
self
.
assertResponseCode
(
404
)
self
.
assertInstanceBangSimulatorEmpty
()
def
test_something_else
(
self
):
kwargs
=
{
'log'
:
'This is cool log!'
}
self
.
connection
.
request
(
method
=
'POST'
,
url
=
'/'
.
join
([
self
.
api_path
,
'instance'
,
self
.
software_instance
.
getPredecessorRelatedValue
().
getRelativeUrl
(),
'bang'
]),
body
=
json
.
dumps
(
kwargs
),
headers
=
{
'REMOTE_USER'
:
self
.
customer_reference
})
self
.
prepareResponse
()
self
.
assertBasicResponse
()
self
.
assertResponseCode
(
404
)
self
.
assertInstanceBangSimulatorEmpty
()
def
test_other_one
(
self
):
kwargs
=
{
'log'
:
'This is cool log!'
}
person
,
person_reference
=
self
.
createPerson
()
self
.
connection
.
request
(
method
=
'POST'
,
url
=
'/'
.
join
([
self
.
api_path
,
'instance'
,
self
.
software_instance
.
getPredecessorRelatedValue
().
getRelativeUrl
(),
'bang'
]),
body
=
json
.
dumps
(
kwargs
),
headers
=
{
'REMOTE_USER'
:
person_reference
})
self
.
prepareResponse
()
self
.
assertBasicResponse
()
self
.
assertResponseCode
(
404
)
self
.
assertInstanceBangSimulatorEmpty
()
def
test_no_json
(
self
):
self
.
connection
.
request
(
method
=
'POST'
,
url
=
'/'
.
join
([
self
.
api_path
,
'instance'
,
self
.
software_instance
.
getRelativeUrl
(),
'bang'
]),
headers
=
{
'REMOTE_USER'
:
self
.
customer_reference
})
self
.
prepareResponse
()
self
.
assertBasicResponse
()
self
.
assertResponseCode
(
400
)
self
.
assertResponseJson
()
self
.
assertEqual
({
'error'
:
"Data is not json object."
},
self
.
json_response
)
self
.
assertInstanceBangSimulatorEmpty
()
def
test_bad_json
(
self
):
kwargs
=
{
'wrong_key'
:
'This is cool log!'
}
self
.
connection
.
request
(
method
=
'POST'
,
url
=
'/'
.
join
([
self
.
api_path
,
'instance'
,
self
.
software_instance
.
getPredecessorRelatedValue
().
getRelativeUrl
(),
'bang'
]),
body
=
json
.
dumps
(
kwargs
),
headers
=
{
'REMOTE_USER'
:
self
.
customer_reference
})
self
.
prepareResponse
()
self
.
assertBasicResponse
()
self
.
assertResponseCode
(
400
)
self
.
assertResponseJson
()
self
.
assertEqual
({
'log'
:
'Missing.'
},
self
.
json_response
)
self
.
assertInstanceBangSimulatorEmpty
()
def
test_empty_json
(
self
):
kwargs
=
{}
self
.
connection
.
request
(
method
=
'POST'
,
url
=
'/'
.
join
([
self
.
api_path
,
'instance'
,
self
.
software_instance
.
getPredecessorRelatedValue
().
getRelativeUrl
(),
'bang'
]),
body
=
json
.
dumps
(
kwargs
),
headers
=
{
'REMOTE_USER'
:
self
.
customer_reference
})
self
.
prepareResponse
()
self
.
assertBasicResponse
()
self
.
assertResponseCode
(
400
)
self
.
assertResponseJson
()
self
.
assertEqual
({
'log'
:
'Missing.'
},
self
.
json_response
)
self
.
assertInstanceBangSimulatorEmpty
()
def
test_additional_key_json
(
self
):
kw_log
=
{
'log'
:
'This is cool log!'
,
'bang_tree'
:
True
}
kwargs
=
kw_log
.
copy
()
kwargs
.
update
(
**
{
'wrong_key'
:
'Be ignored'
})
self
.
connection
.
request
(
method
=
'POST'
,
url
=
'/'
.
join
([
self
.
api_path
,
'instance'
,
self
.
software_instance
.
getRelativeUrl
(),
'bang'
]),
body
=
json
.
dumps
(
kwargs
),
headers
=
{
'REMOTE_USER'
:
self
.
customer_reference
})
self
.
prepareResponse
()
self
.
assertBasicResponse
()
self
.
assertResponseCode
(
204
)
self
.
assertInstanceBangSimulator
((),
kw_log
)
def
test_log_not_string
(
self
):
kwargs
=
{
'log'
:
True
}
self
.
connection
.
request
(
method
=
'POST'
,
url
=
'/'
.
join
([
self
.
api_path
,
'instance'
,
self
.
software_instance
.
getPredecessorRelatedValue
().
getRelativeUrl
(),
'bang'
]),
body
=
json
.
dumps
(
kwargs
),
headers
=
{
'REMOTE_USER'
:
self
.
customer_reference
})
self
.
prepareResponse
()
self
.
assertBasicResponse
()
self
.
assertResponseCode
(
400
)
self
.
assertResponseJson
()
self
.
assertEqual
({
'log'
:
'bool is not unicode.'
},
self
.
json_response
)
self
.
assertInstanceBangSimulatorEmpty
()
@
skip
(
'Undecided.'
)
class
TestInstancePUT
(
SlapOSRestAPIV1InstanceMixin
):
def
afterSetUp
(
self
):
super
(
TestInstancePUT
,
self
).
afterSetUp
()
self
.
instance_put_simulator
=
tempfile
.
mkstemp
()[
1
]
self
.
software_instance
.
setTitle
=
Simulator
(
self
.
instance_put_simulator
,
'setTitle'
)
self
.
software_instance
.
setConnectionXml
=
Simulator
(
self
.
instance_put_simulator
,
'setConnectionXml'
)
transaction
.
commit
()
def
beforeTearDown
(
self
):
super
(
TestInstancePUT
,
self
).
beforeTearDown
()
if
os
.
path
.
exists
(
self
.
instance_put_simulator
):
os
.
unlink
(
self
.
instance_put_simulator
)
def
assertInstancePUTSimulator
(
self
,
l
):
stored
=
eval
(
open
(
self
.
instance_put_simulator
).
read
())
self
.
assertEqual
(
stored
,
l
)
self
.
assertEqual
(
set
([
type
(
q
)
for
q
in
l
[
0
][
'recargs'
]]),
set
([
str
])
)
def
assertInstancePUTSimulatorEmpty
(
self
):
self
.
assertEqual
(
''
,
open
(
self
.
instance_put_simulator
).
read
())
def
test
(
self
):
d
=
{
'title'
:
'New Title'
+
self
.
test_random_id
,
'connection'
:
{
'url'
:
'http://new'
+
self
.
test_random_id
}
}
self
.
connection
.
request
(
method
=
'PUT'
,
url
=
'/'
.
join
([
self
.
api_path
,
'instance'
,
self
.
software_instance
.
getRelativeUrl
()]),
body
=
json
.
dumps
(
d
),
headers
=
{
'REMOTE_USER'
:
self
.
customer_reference
})
self
.
prepareResponse
()
self
.
assertBasicResponse
()
self
.
assertResponseCode
(
200
)
self
.
assertResponseJson
()
self
.
assertEqual
({
"title"
:
"Modified."
,
"connection"
:
"Modified."
},
self
.
json_response
)
self
.
assertInstancePUTSimulator
([{
'recargs'
:
(
d
[
'title'
],),
'reckwargs'
:
{},
'recmethod'
:
'setTitle'
},
{
'recargs'
:
(
'<?xml version=
\
'
1.0
\
'
encoding=
\
'
utf-8
\
'
?>
\
n
<instance>
\
n
'
\
'<parameter id="url">http://new%s</parameter>
\
n
</instance>
\
n
'
%
self
.
test_random_id
,),
'reckwargs'
:
{},
'recmethod'
:
'setConnectionXml'
}])
def
test_same_title
(
self
):
d
=
{
'title'
:
self
.
software_instance
.
getTitle
(),
'connection'
:
{
'url'
:
'http://new'
+
self
.
test_random_id
}
}
self
.
connection
.
request
(
method
=
'PUT'
,
url
=
'/'
.
join
([
self
.
api_path
,
'instance'
,
self
.
software_instance
.
getRelativeUrl
()]),
body
=
json
.
dumps
(
d
),
headers
=
{
'REMOTE_USER'
:
self
.
customer_reference
})
self
.
prepareResponse
()
self
.
assertBasicResponse
()
self
.
assertResponseCode
(
200
)
self
.
assertResponseJson
()
self
.
assertEqual
({
"connection"
:
"Modified."
},
self
.
json_response
)
self
.
assertInstancePUTSimulator
([
{
'recargs'
:
(
'<?xml version=
\
'
1.0
\
'
encoding=
\
'
utf-8
\
'
?>
\
n
<instance>
\
n
'
\
'<parameter id="url">http://new%s</parameter>
\
n
</instance>
\
n
'
%
self
.
test_random_id
,),
'reckwargs'
:
{},
'recmethod'
:
'setConnectionXml'
}])
def
test_same_connection
(
self
):
d
=
{
'title'
:
'New Title 2'
+
self
.
test_random_id
,
'connection'
:
self
.
software_instance
.
getConnectionXmlAsDict
()
}
self
.
connection
.
request
(
method
=
'PUT'
,
url
=
'/'
.
join
([
self
.
api_path
,
'instance'
,
self
.
software_instance
.
getRelativeUrl
()]),
body
=
json
.
dumps
(
d
),
headers
=
{
'REMOTE_USER'
:
self
.
customer_reference
})
self
.
prepareResponse
()
self
.
assertBasicResponse
()
self
.
assertResponseCode
(
200
)
self
.
assertResponseJson
()
self
.
assertEqual
({
"title"
:
"Modified."
,
},
self
.
json_response
)
self
.
assertInstancePUTSimulator
([{
'recargs'
:
(
d
[
'title'
],),
'reckwargs'
:
{},
'recmethod'
:
'setTitle'
}])
def
test_same_title_connection
(
self
):
d
=
{
'title'
:
self
.
software_instance
.
getTitle
(),
'connection'
:
self
.
software_instance
.
getConnectionXmlAsDict
()
}
self
.
connection
.
request
(
method
=
'PUT'
,
url
=
'/'
.
join
([
self
.
api_path
,
'instance'
,
self
.
software_instance
.
getRelativeUrl
()]),
body
=
json
.
dumps
(
d
),
headers
=
{
'REMOTE_USER'
:
self
.
customer_reference
})
self
.
prepareResponse
()
self
.
assertBasicResponse
()
self
.
assertResponseCode
(
204
)
self
.
assertInstancePUTSimulatorEmpty
()
def
test_not_logged_in
(
self
):
self
.
connection
.
request
(
method
=
'PUT'
,
url
=
'/'
.
join
([
self
.
api_path
,
'instance'
,
self
.
software_instance
.
getRelativeUrl
()]))
self
.
prepareResponse
()
self
.
assertBasicResponse
()
self
.
assertResponseCode
(
401
)
self
.
assertTrue
(
self
.
response
.
getheader
(
'Location'
)
is
not
None
)
auth
=
self
.
response
.
getheader
(
'WWW-Authenticate'
)
self
.
assertTrue
(
auth
is
not
None
)
self
.
assertTrue
(
'Bearer realm="'
in
auth
)
self
.
assertInstancePUTSimulatorEmpty
()
def
test_no_json
(
self
):
self
.
connection
.
request
(
method
=
'PUT'
,
url
=
'/'
.
join
([
self
.
api_path
,
'instance'
,
self
.
software_instance
.
getRelativeUrl
()]),
headers
=
{
'REMOTE_USER'
:
self
.
customer_reference
})
self
.
prepareResponse
()
self
.
assertBasicResponse
()
self
.
assertResponseCode
(
400
)
self
.
assertResponseJson
()
self
.
assertEqual
({
'error'
:
"Data is not json object."
},
self
.
json_response
)
self
.
assertInstancePUTSimulatorEmpty
()
def
test_bad_json
(
self
):
self
.
connection
.
request
(
method
=
'PUT'
,
url
=
'/'
.
join
([
self
.
api_path
,
'instance'
,
self
.
software_instance
.
getRelativeUrl
()]),
body
=
'This is not JSON'
,
headers
=
{
'REMOTE_USER'
:
self
.
customer_reference
})
self
.
prepareResponse
()
self
.
assertBasicResponse
()
self
.
assertResponseCode
(
400
)
self
.
assertResponseJson
()
self
.
assertEqual
({
'error'
:
"Data is not json object."
},
self
.
json_response
)
self
.
assertInstancePUTSimulatorEmpty
()
def
test_empty_json
(
self
):
self
.
connection
.
request
(
method
=
'PUT'
,
url
=
'/'
.
join
([
self
.
api_path
,
'instance'
,
self
.
software_instance
.
getRelativeUrl
()]),
body
=
'{}'
,
headers
=
{
'REMOTE_USER'
:
self
.
customer_reference
})
self
.
prepareResponse
()
self
.
assertBasicResponse
()
self
.
assertResponseCode
(
204
)
self
.
assertInstancePUTSimulatorEmpty
()
def
test_future_compat
(
self
):
self
.
connection
.
request
(
method
=
'PUT'
,
url
=
'/'
.
join
([
self
.
api_path
,
'instance'
,
self
.
software_instance
.
getRelativeUrl
()]),
body
=
json
.
dumps
({
'ignore'
:
'me'
}),
headers
=
{
'REMOTE_USER'
:
self
.
customer_reference
})
self
.
prepareResponse
()
self
.
assertBasicResponse
()
self
.
assertResponseCode
(
204
)
self
.
assertInstancePUTSimulatorEmpty
()
@
skip
(
'Undecided.'
)
class
TestInstanceGETlist
(
SlapOSRestAPIV1InstanceMixin
):
def
assertLastModifiedHeader
(
self
):
calculated
=
rfc1123_date
(
self
.
portal
.
software_instance_module
\
.
bobobase_modification_time
())
self
.
assertEqual
(
calculated
,
self
.
response
.
getheader
(
'Last-Modified'
))
def
test_no_cache
(
self
):
# version of test which ignores cache to expose possible other errors
self
.
connection
.
request
(
method
=
'GET'
,
url
=
'/'
.
join
([
self
.
api_path
,
'instance'
]),
headers
=
{
'REMOTE_USER'
:
self
.
customer_reference
})
self
.
prepareResponse
()
self
.
assertBasicResponse
()
self
.
assertResponseCode
(
200
)
self
.
assertResponseJson
()
self
.
assertEqual
({
"list"
:
[
'/'
.
join
([
self
.
api_url
,
'instance'
,
self
.
software_instance
.
getRelativeUrl
()])]
},
self
.
json_response
)
def
test
(
self
):
self
.
test_no_cache
()
self
.
assertLastModifiedHeader
()
self
.
assertCacheControlHeader
()
def
test_if_modified_since_equal
(
self
):
self
.
connection
.
request
(
method
=
'GET'
,
url
=
'/'
.
join
([
self
.
api_path
,
'instance'
]),
headers
=
{
'REMOTE_USER'
:
self
.
customer_reference
,
'If-Modified-Since'
:
rfc1123_date
(
self
.
portal
.
software_instance_module
\
.
bobobase_modification_time
())})
self
.
prepareResponse
()
self
.
assertBasicResponse
()
self
.
assertResponseCode
(
304
)
def
test_if_modified_since_after
(
self
):
# wait three seconds before continuing in order to not hit time precision
# issue, as test needs to provide date with second precision after
# last modification of software instance and *before* now()
time
.
sleep
(
3
)
# add 2 seconds, as used rfc1123_date will ceil the second in response and
# one more second will be required in order to be *after* the modification time
if_modified
=
self
.
portal
.
software_instance_module
\
.
bobobase_modification_time
().
timeTime
()
+
2
# check the test: is calculated time *before* now?
self
.
assertTrue
(
int
(
if_modified
)
<
int
(
DateTime
().
timeTime
()))
self
.
connection
.
request
(
method
=
'GET'
,
url
=
'/'
.
join
([
self
.
api_path
,
'instance'
]),
headers
=
{
'REMOTE_USER'
:
self
.
customer_reference
,
'If-Modified-Since'
:
rfc1123_date
(
self
.
portal
.
software_instance_module
\
.
bobobase_modification_time
())})
self
.
prepareResponse
()
self
.
assertBasicResponse
()
self
.
assertResponseCode
(
304
)
def
test_if_modified_since_before
(
self
):
self
.
connection
.
request
(
method
=
'GET'
,
url
=
'/'
.
join
([
self
.
api_path
,
'instance'
]),
headers
=
{
'REMOTE_USER'
:
self
.
customer_reference
,
'If-Modified-Since'
:
rfc1123_date
(
self
.
portal
.
software_instance_module
\
.
bobobase_modification_time
()
-
1
)})
self
.
prepareResponse
()
self
.
assertBasicResponse
()
self
.
assertResponseCode
(
200
)
self
.
assertResponseJson
()
self
.
assertLastModifiedHeader
()
self
.
assertCacheControlHeader
()
self
.
assertEqual
({
"list"
:
[
'/'
.
join
([
self
.
api_url
,
'instance'
,
self
.
software_instance
.
getRelativeUrl
()])]
},
self
.
json_response
)
def
test_if_modified_since_date_not_date
(
self
):
self
.
connection
.
request
(
method
=
'GET'
,
url
=
'/'
.
join
([
self
.
api_path
,
'instance'
]),
headers
=
{
'REMOTE_USER'
:
self
.
customer_reference
,
'If-Modified-Since'
:
'This Is Not A date'
})
self
.
prepareResponse
()
self
.
assertBasicResponse
()
self
.
assertResponseCode
(
200
)
self
.
assertResponseJson
()
self
.
assertLastModifiedHeader
()
self
.
assertCacheControlHeader
()
self
.
assertEqual
({
"list"
:
[
'/'
.
join
([
self
.
api_url
,
'instance'
,
self
.
software_instance
.
getRelativeUrl
()])]
},
self
.
json_response
)
def
test_if_modified_since_date_future
(
self
):
self
.
connection
.
request
(
method
=
'GET'
,
url
=
'/'
.
join
([
self
.
api_path
,
'instance'
]),
headers
=
{
'REMOTE_USER'
:
self
.
customer_reference
,
'If-Modified-Since'
:
rfc1123_date
(
DateTime
()
+
1
)})
self
.
prepareResponse
()
self
.
assertBasicResponse
()
self
.
assertResponseCode
(
200
)
self
.
assertResponseJson
()
self
.
assertLastModifiedHeader
()
self
.
assertCacheControlHeader
()
self
.
assertEqual
({
"list"
:
[
'/'
.
join
([
self
.
api_url
,
'instance'
,
self
.
software_instance
.
getRelativeUrl
()])]
},
self
.
json_response
)
def
test_another_one
(
self
):
person
,
person_reference
=
self
.
createPerson
()
self
.
connection
.
request
(
method
=
'GET'
,
url
=
'/'
.
join
([
self
.
api_path
,
'instance'
]),
headers
=
{
'REMOTE_USER'
:
person_reference
})
self
.
prepareResponse
()
self
.
assertBasicResponse
()
self
.
assertResponseCode
(
204
)
def
test_empty
(
self
):
self
.
portal
.
portal_catalog
.
unindexObject
(
uid
=
self
.
software_instance
.
getUid
())
self
.
software_instance
.
getParentValue
().
deleteContent
(
self
.
software_instance
.
getId
())
transaction
.
commit
()
self
.
connection
.
request
(
method
=
'GET'
,
url
=
'/'
.
join
([
self
.
api_path
,
'instance'
]),
headers
=
{
'REMOTE_USER'
:
self
.
customer_reference
})
self
.
prepareResponse
()
self
.
assertBasicResponse
()
self
.
assertResponseCode
(
204
)
def
test_not_logged_in
(
self
):
self
.
connection
.
request
(
method
=
'GET'
,
url
=
'/'
.
join
([
self
.
api_path
,
'instance'
]))
self
.
prepareResponse
()
self
.
assertBasicResponse
()
self
.
assertResponseCode
(
401
)
self
.
assertTrue
(
self
.
response
.
getheader
(
'Location'
)
is
not
None
)
auth
=
self
.
response
.
getheader
(
'WWW-Authenticate'
)
self
.
assertTrue
(
auth
is
not
None
)
self
.
assertTrue
(
'Bearer realm="'
in
auth
)
self
.
assertPersonRequestSimulatorEmpty
()
@
skip
(
'Undecided.'
)
class
TestComputerPUT
(
SlapOSRestAPIV1MixinBase
):
def
createComputer
(
self
):
computer
=
self
.
cloneByPath
(
'computer_module/template_computer'
)
computer
.
edit
(
reference
=
'C'
+
self
.
test_random_id
)
computer
.
validate
()
computer
.
manage_setLocalRoles
(
computer
.
getReference
(),
[
'Assignor'
])
transaction
.
commit
()
computer
.
recursiveImmediateReindexObject
()
transaction
.
commit
()
return
computer
def
afterSetUp
(
self
):
super
(
TestComputerPUT
,
self
).
afterSetUp
()
self
.
computer
=
self
.
createComputer
()
self
.
computer_reference
=
self
.
computer
.
getReference
()
self
.
computer_put_simulator
=
tempfile
.
mkstemp
()[
1
]
self
.
computer
.
Computer_updateFromJson
=
Simulator
(
self
.
computer_put_simulator
,
'Computer_updateFromJson'
)
transaction
.
commit
()
def
beforeTearDown
(
self
):
super
(
TestComputerPUT
,
self
).
beforeTearDown
()
if
os
.
path
.
exists
(
self
.
computer_put_simulator
):
os
.
unlink
(
self
.
computer_put_simulator
)
def
assertComputerPUTSimulator
(
self
,
l
):
stored
=
eval
(
open
(
self
.
computer_put_simulator
).
read
())
self
.
assertEqual
(
stored
,
l
)
# check that method is called with strings, not unicodes
for
l_
in
l
[
0
][
'recargs'
][
0
].
itervalues
():
for
el
in
l_
:
self
.
assertEqual
(
set
([
type
(
q
)
for
q
in
el
.
itervalues
()]),
set
([
str
])
)
def
assertComputerPUTSimulatorEmpty
(
self
):
self
.
assertEqual
(
''
,
open
(
self
.
computer_put_simulator
).
read
())
def
test
(
self
):
d
=
{
"partition"
:
[
{
"title"
:
"part0"
,
"public_ip"
:
"::0"
,
"private_ip"
:
"127.0.0.0"
,
"tap_interface"
:
"tap0"
}
],
"software"
:
[
{
"software_release"
:
"software_release"
,
"status"
:
"uninstalled"
,
"log"
:
"Installation log"
}
]
}
self
.
connection
.
request
(
method
=
'PUT'
,
url
=
'/'
.
join
([
self
.
api_path
,
'computer'
,
self
.
computer
.
getRelativeUrl
()]),
body
=
json
.
dumps
(
d
),
headers
=
{
'REMOTE_USER'
:
self
.
computer_reference
})
self
.
prepareResponse
()
self
.
assertBasicResponse
()
self
.
assertResponseCode
(
204
)
self
.
assertComputerPUTSimulator
([
{
'recmethod'
:
'Computer_updateFromJson'
,
'recargs'
:
({
'partition'
:
[{
'public_ip'
:
'::0'
,
'tap_interface'
:
'tap0'
,
'private_ip'
:
'127.0.0.0'
,
'title'
:
'part0'
}],
'software'
:
[{
'status'
:
'uninstalled'
,
'software_release'
:
'software_release'
,
'log'
:
'Installation log'
}]},),
'reckwargs'
:
{}}])
def
test_not_logged_in
(
self
):
self
.
connection
.
request
(
method
=
'PUT'
,
url
=
'/'
.
join
([
self
.
api_path
,
'computer'
,
self
.
computer
.
getRelativeUrl
()]))
self
.
prepareResponse
()
self
.
assertBasicResponse
()
self
.
assertResponseCode
(
401
)
self
.
assertTrue
(
self
.
response
.
getheader
(
'Location'
)
is
not
None
)
auth
=
self
.
response
.
getheader
(
'WWW-Authenticate'
)
self
.
assertTrue
(
auth
is
not
None
)
self
.
assertTrue
(
'Bearer realm="'
in
auth
)
self
.
assertComputerPUTSimulatorEmpty
()
def
test_no_json
(
self
):
self
.
connection
.
request
(
method
=
'PUT'
,
url
=
'/'
.
join
([
self
.
api_path
,
'computer'
,
self
.
computer
.
getRelativeUrl
()]),
headers
=
{
'REMOTE_USER'
:
self
.
computer_reference
})
self
.
prepareResponse
()
self
.
assertBasicResponse
()
self
.
assertResponseCode
(
400
)
self
.
assertResponseJson
()
self
.
assertEqual
({
'error'
:
"Data is not json object."
},
self
.
json_response
)
self
.
assertComputerPUTSimulatorEmpty
()
def
test_bad_json
(
self
):
self
.
connection
.
request
(
method
=
'PUT'
,
url
=
'/'
.
join
([
self
.
api_path
,
'computer'
,
self
.
computer
.
getRelativeUrl
()]),
body
=
'This is not JSON'
,
headers
=
{
'REMOTE_USER'
:
self
.
computer_reference
})
self
.
prepareResponse
()
self
.
assertBasicResponse
()
self
.
assertResponseCode
(
400
)
self
.
assertResponseJson
()
self
.
assertEqual
({
'error'
:
"Data is not json object."
},
self
.
json_response
)
self
.
assertComputerPUTSimulatorEmpty
()
def
test_empty_json
(
self
):
self
.
connection
.
request
(
method
=
'PUT'
,
url
=
'/'
.
join
([
self
.
api_path
,
'computer'
,
self
.
computer
.
getRelativeUrl
()]),
body
=
'{}'
,
headers
=
{
'REMOTE_USER'
:
self
.
computer_reference
})
self
.
prepareResponse
()
self
.
assertBasicResponse
()
self
.
assertResponseCode
(
204
)
self
.
assertComputerPUTSimulatorEmpty
()
def
test_future_compat
(
self
):
self
.
connection
.
request
(
method
=
'PUT'
,
url
=
'/'
.
join
([
self
.
api_path
,
'computer'
,
self
.
computer
.
getRelativeUrl
()]),
body
=
json
.
dumps
({
'ignore'
:
'me'
}),
headers
=
{
'REMOTE_USER'
:
self
.
computer_reference
})
self
.
prepareResponse
()
self
.
assertBasicResponse
()
self
.
assertResponseCode
(
204
)
self
.
assertComputerPUTSimulatorEmpty
()
def
test_software_release_status
(
self
):
d
=
{
"partition"
:
[
{
"title"
:
"part0"
,
"public_ip"
:
"::0"
,
"private_ip"
:
"127.0.0.0"
,
"tap_interface"
:
"tap0"
}
],
"software"
:
[
{
"software_release"
:
"software_release"
,
"status"
:
"wrong status"
,
"log"
:
"Installation log"
}
]
}
self
.
connection
.
request
(
method
=
'PUT'
,
url
=
'/'
.
join
([
self
.
api_path
,
'computer'
,
self
.
computer
.
getRelativeUrl
()]),
body
=
json
.
dumps
(
d
),
headers
=
{
'REMOTE_USER'
:
self
.
computer_reference
})
self
.
prepareResponse
()
self
.
assertBasicResponse
()
self
.
assertResponseCode
(
400
)
self
.
assertResponseJson
()
self
.
assertEqual
({
'software_0'
:
[
'Status "wrong status" is incorrect.'
]},
self
.
json_response
)
self
.
assertComputerPUTSimulatorEmpty
()
def
test_only_partition
(
self
):
d
=
{
"partition"
:
[
{
"title"
:
"part0"
,
"public_ip"
:
"::0"
,
"private_ip"
:
"127.0.0.0"
,
"tap_interface"
:
"tap0"
}
]
}
self
.
connection
.
request
(
method
=
'PUT'
,
url
=
'/'
.
join
([
self
.
api_path
,
'computer'
,
self
.
computer
.
getRelativeUrl
()]),
body
=
json
.
dumps
(
d
),
headers
=
{
'REMOTE_USER'
:
self
.
computer_reference
})
self
.
prepareResponse
()
self
.
assertBasicResponse
()
self
.
assertResponseCode
(
204
)
self
.
assertComputerPUTSimulator
([
{
'recmethod'
:
'Computer_updateFromJson'
,
'recargs'
:
({
'partition'
:
[{
'public_ip'
:
'::0'
,
'tap_interface'
:
'tap0'
,
'private_ip'
:
'127.0.0.0'
,
'title'
:
'part0'
}],
},),
'reckwargs'
:
{}}])
def
test_only_software
(
self
):
d
=
{
"software"
:
[
{
"software_release"
:
"software_release"
,
"status"
:
"uninstalled"
,
"log"
:
"Installation log"
}
]
}
self
.
connection
.
request
(
method
=
'PUT'
,
url
=
'/'
.
join
([
self
.
api_path
,
'computer'
,
self
.
computer
.
getRelativeUrl
()]),
body
=
json
.
dumps
(
d
),
headers
=
{
'REMOTE_USER'
:
self
.
computer_reference
})
self
.
prepareResponse
()
self
.
assertBasicResponse
()
self
.
assertResponseCode
(
204
)
self
.
assertComputerPUTSimulator
([
{
'recmethod'
:
'Computer_updateFromJson'
,
'recargs'
:
({
'software'
:
[{
'status'
:
'uninstalled'
,
'software_release'
:
'software_release'
,
'log'
:
'Installation log'
}]},),
'reckwargs'
:
{}}])
def
test_partition_object_incorrect
(
self
):
d
=
{
"partition"
:
[
{
"title"
:
"part0"
,
"public_ip"
:
"::0"
,
"private_ip"
:
"127.0.0.0"
}
],
"software"
:
[
{
"software_release"
:
"software_release"
,
"status"
:
"uninstalled"
,
"log"
:
"Installation log"
}
]
}
self
.
connection
.
request
(
method
=
'PUT'
,
url
=
'/'
.
join
([
self
.
api_path
,
'computer'
,
self
.
computer
.
getRelativeUrl
()]),
body
=
json
.
dumps
(
d
),
headers
=
{
'REMOTE_USER'
:
self
.
computer_reference
})
self
.
prepareResponse
()
self
.
assertBasicResponse
()
self
.
assertResponseCode
(
400
)
self
.
assertResponseJson
()
self
.
assertEqual
({
'partition_0'
:
[
'Missing key "tap_interface".'
]},
self
.
json_response
)
self
.
assertComputerPUTSimulatorEmpty
()
def
test_software_object_incorrect
(
self
):
d
=
{
"partition"
:
[
{
"title"
:
"part0"
,
"public_ip"
:
"::0"
,
"private_ip"
:
"127.0.0.0"
,
"tap_interface"
:
"tap0"
}
],
"software"
:
[
{
"software_release"
:
"software_release"
,
"status"
:
"uninstalled"
,
}
]
}
self
.
connection
.
request
(
method
=
'PUT'
,
url
=
'/'
.
join
([
self
.
api_path
,
'computer'
,
self
.
computer
.
getRelativeUrl
()]),
body
=
json
.
dumps
(
d
),
headers
=
{
'REMOTE_USER'
:
self
.
computer_reference
})
self
.
prepareResponse
()
self
.
assertBasicResponse
()
self
.
assertResponseCode
(
400
)
self
.
assertResponseJson
()
self
.
assertEqual
({
'software_0'
:
[
'Missing key "log".'
]},
self
.
json_response
)
self
.
assertComputerPUTSimulatorEmpty
()
class
TestStatusGET
(
SlapOSRestAPIV1InstanceMixin
):
def
afterSetUp
(
self
):
self
.
_afterSetUp
()
SlapOSRestAPIV1Mixin_afterSetUp
(
self
)
def
createComputer
(
self
):
computer
=
self
.
cloneByPath
(
'computer_module/template_computer'
)
computer
.
edit
(
reference
=
'C'
+
self
.
test_random_id
)
computer
.
validate
()
computer
.
manage_setLocalRoles
(
self
.
customer_reference
,
[
'Assignee'
])
transaction
.
commit
()
computer
.
recursiveImmediateReindexObject
()
transaction
.
commit
()
return
computer
def
assertCacheControlHeader
(
self
):
self
.
assertEqual
(
'max-age=300, private'
,
self
.
response
.
getheader
(
'Cache-Control'
))
def
test_non_existing_status
(
self
):
non_existing
=
'system_event_module/'
+
self
.
generateNewId
()
try
:
self
.
portal
.
restrictedTraverse
(
non_existing
)
except
KeyError
:
pass
else
:
raise
AssertionError
(
'It was impossible to test'
)
self
.
connection
.
request
(
method
=
'GET'
,
url
=
'/'
.
join
([
self
.
api_path
,
'status'
,
non_existing
]),
headers
=
{
'REMOTE_USER'
:
self
.
customer_reference
})
self
.
prepareResponse
()
self
.
assertBasicResponse
()
self
.
assertResponseCode
(
404
)
def
test_something_else
(
self
):
self
.
connection
.
request
(
method
=
'GET'
,
url
=
'/'
.
join
([
self
.
api_path
,
'status'
,
self
.
customer
.
getRelativeUrl
()]),
headers
=
{
'REMOTE_USER'
:
self
.
customer_reference
})
self
.
prepareResponse
()
self
.
assertBasicResponse
()
self
.
assertResponseCode
(
404
)
def
_storeJson
(
self
,
key
,
json
):
memcached_dict
=
self
.
getPortalObject
().
portal_memcached
.
\
getMemcachedDict
(
key_prefix
=
'slap_tool'
,
plugin_path
=
'portal_memcached/default_memcached_plugin'
)
memcached_dict
[
key
]
=
json
def
test_on_computer
(
self
):
self
.
computer
=
self
.
createComputer
()
reference
=
self
.
computer
.
getReference
()
value
=
json
.
dumps
({
'foo'
:
reference
})
self
.
_storeJson
(
reference
,
value
)
transaction
.
commit
()
self
.
connection
.
request
(
method
=
'GET'
,
url
=
'/'
.
join
([
self
.
api_path
,
'status'
,
self
.
computer
.
getRelativeUrl
()]),
headers
=
{
'REMOTE_USER'
:
self
.
customer_reference
})
self
.
prepareResponse
()
self
.
assertBasicResponse
()
self
.
assertResponseCode
(
200
)
self
.
assertCacheControlHeader
()
self
.
assertResponseJson
()
value
=
json
.
loads
(
value
)
value
[
'@document'
]
=
self
.
computer
.
getRelativeUrl
()
self
.
assertEqual
(
value
,
self
.
json_response
)
def
test_on_instance
(
self
):
self
.
software_instance
=
self
.
createSoftwareInstance
(
self
.
customer
)
reference
=
self
.
software_instance
.
getReference
()
value
=
json
.
dumps
({
'bar'
:
reference
})
self
.
_storeJson
(
reference
,
value
)
transaction
.
commit
()
self
.
connection
.
request
(
method
=
'GET'
,
url
=
'/'
.
join
([
self
.
api_path
,
'status'
,
self
.
software_instance
.
getRelativeUrl
()]),
headers
=
{
'REMOTE_USER'
:
self
.
customer_reference
})
self
.
prepareResponse
()
self
.
assertBasicResponse
()
self
.
assertResponseCode
(
200
)
self
.
assertCacheControlHeader
()
self
.
assertResponseJson
()
value
=
json
.
loads
(
value
)
value
[
'@document'
]
=
self
.
software_instance
.
getRelativeUrl
()
self
.
assertEqual
(
value
,
self
.
json_response
)
def
test_no_data_in_memcached
(
self
):
self
.
computer
=
self
.
createComputer
()
self
.
connection
.
request
(
method
=
'GET'
,
url
=
'/'
.
join
([
self
.
api_path
,
'status'
,
self
.
computer
.
getRelativeUrl
()]),
headers
=
{
'REMOTE_USER'
:
self
.
customer_reference
})
self
.
prepareResponse
()
self
.
assertBasicResponse
()
self
.
assertResponseCode
(
200
)
self
.
assertCacheControlHeader
()
self
.
assertResponseJson
()
self
.
assertEquals
(
self
.
json_response
[
'user'
],
'SlapOS Master'
)
def
test_search_no_status
(
self
):
self
.
connection
.
request
(
method
=
'GET'
,
url
=
'/'
.
join
([
self
.
api_path
,
'status'
]),
headers
=
{
'REMOTE_USER'
:
self
.
customer_reference
})
self
.
prepareResponse
()
self
.
assertBasicResponse
()
self
.
assertResponseCode
(
204
)
def
test_search_existing_start_instance
(
self
):
self
.
software_instance
=
self
.
createSoftwareInstance
(
self
.
customer
)
self
.
software_instance
.
workflow_history
[
\
'instance_slap_interface_workflow'
].
append
({
'comment'
:
'Directly in Started state'
,
'error_message'
:
''
,
'actor'
:
'ERP5TypeTestCase'
,
'slap_state'
:
'start_requested'
,
'time'
:
DateTime
(),
'action'
:
'foo_transition'
})
transaction
.
commit
()
self
.
software_instance
.
recursiveImmediateReindexObject
()
transaction
.
commit
()
self
.
connection
.
request
(
method
=
'GET'
,
url
=
'/'
.
join
([
self
.
api_path
,
'status'
]),
headers
=
{
'REMOTE_USER'
:
self
.
customer_reference
})
self
.
prepareResponse
()
self
.
assertBasicResponse
()
self
.
assertResponseCode
(
200
)
self
.
assertCacheControlHeader
()
self
.
assertResponseJson
()
self
.
assertEqual
({
'list'
:
[
'/'
.
join
([
self
.
api_url
,
'status'
,
self
.
software_instance
.
getRelativeUrl
()])]
},
self
.
json_response
)
def
test_search_existing_stop_instance
(
self
):
self
.
software_instance
=
self
.
createSoftwareInstance
(
self
.
customer
)
self
.
software_instance
.
workflow_history
[
\
'instance_slap_interface_workflow'
].
append
({
'comment'
:
'Directly in stop state'
,
'error_message'
:
''
,
'actor'
:
'ERP5TypeTestCase'
,
'slap_state'
:
'stop_requested'
,
'time'
:
DateTime
(),
'action'
:
'foo_transition'
})
transaction
.
commit
()
self
.
software_instance
.
recursiveImmediateReindexObject
()
transaction
.
commit
()
self
.
connection
.
request
(
method
=
'GET'
,
url
=
'/'
.
join
([
self
.
api_path
,
'status'
]),
headers
=
{
'REMOTE_USER'
:
self
.
customer_reference
})
self
.
prepareResponse
()
self
.
assertBasicResponse
()
self
.
assertResponseCode
(
200
)
self
.
assertCacheControlHeader
()
self
.
assertResponseJson
()
self
.
assertEqual
({
'list'
:
[
'/'
.
join
([
self
.
api_url
,
'status'
,
self
.
software_instance
.
getRelativeUrl
()])]
},
self
.
json_response
)
def
test_check_no_destroyed_instance
(
self
):
self
.
software_instance
=
self
.
createSoftwareInstance
(
self
.
customer
)
self
.
software_instance
.
workflow_history
[
\
'instance_slap_interface_workflow'
].
append
({
'comment'
:
'Directly in destroyed state'
,
'error_message'
:
''
,
'actor'
:
'ERP5TypeTestCase'
,
'slap_state'
:
'destroy_requested'
,
'time'
:
DateTime
(),
'action'
:
'foo_transition'
})
transaction
.
commit
()
self
.
software_instance
.
recursiveImmediateReindexObject
()
transaction
.
commit
()
self
.
connection
.
request
(
method
=
'GET'
,
url
=
'/'
.
join
([
self
.
api_path
,
'status'
]),
headers
=
{
'REMOTE_USER'
:
self
.
customer_reference
})
self
.
prepareResponse
()
self
.
assertBasicResponse
()
self
.
assertResponseCode
(
204
)
master/bt5/slapos_rest_api/TestTemplateItem/portal_components/test.erp5.testSlapOSRestAPIV1.xml
deleted
100644 → 0
View file @
78407bb9
<?xml version="1.0"?>
<ZopeData>
<record
id=
"1"
aka=
"AAAAAAAAAAE="
>
<pickle>
<global
name=
"Test Component"
module=
"erp5.portal_type"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
default_reference
</string>
</key>
<value>
<string>
testSlapOSRestAPIV1
</string>
</value>
</item>
<item>
<key>
<string>
id
</string>
</key>
<value>
<string>
test.erp5.testSlapOSRestAPIV1
</string>
</value>
</item>
<item>
<key>
<string>
portal_type
</string>
</key>
<value>
<string>
Test Component
</string>
</value>
</item>
<item>
<key>
<string>
sid
</string>
</key>
<value>
<none/>
</value>
</item>
<item>
<key>
<string>
text_content_error_message
</string>
</key>
<value>
<tuple>
<string>
E:1013, 2: No value for argument \'self\' in function call (no-value-for-parameter)
</string>
</tuple>
</value>
</item>
<item>
<key>
<string>
text_content_warning_message
</string>
</key>
<value>
<tuple>
<string>
W: 41, 10: Use of eval (eval-used)
</string>
<string>
W:175, 13: Use of eval (eval-used)
</string>
<string>
W:753, 4: Unused variable \'person\' (unused-variable)
</string>
<string>
W:824, 4: Unused variable \'person\' (unused-variable)
</string>
<string>
W:1029, 13: Use of eval (eval-used)
</string>
<string>
W:1116, 4: Unused variable \'person\' (unused-variable)
</string>
<string>
W:1212, 13: Use of eval (eval-used)
</string>
<string>
W:1473, 4: Unused variable \'person\' (unused-variable)
</string>
<string>
W:1536, 13: Use of eval (eval-used)
</string>
<string>
W:1853, 28: Redefining name \'json\' from outer scope (line 9) (redefined-outer-name)
</string>
</tuple>
</value>
</item>
<item>
<key>
<string>
version
</string>
</key>
<value>
<string>
erp5
</string>
</value>
</item>
<item>
<key>
<string>
workflow_history
</string>
</key>
<value>
<persistent>
<string
encoding=
"base64"
>
AAAAAAAAAAI=
</string>
</persistent>
</value>
</item>
</dictionary>
</pickle>
</record>
<record
id=
"2"
aka=
"AAAAAAAAAAI="
>
<pickle>
<global
name=
"PersistentMapping"
module=
"Persistence.mapping"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
data
</string>
</key>
<value>
<dictionary>
<item>
<key>
<string>
component_validation_workflow
</string>
</key>
<value>
<persistent>
<string
encoding=
"base64"
>
AAAAAAAAAAM=
</string>
</persistent>
</value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
<record
id=
"3"
aka=
"AAAAAAAAAAM="
>
<pickle>
<global
name=
"WorkflowHistoryList"
module=
"Products.ERP5Type.patches.WorkflowTool"
/>
</pickle>
<pickle>
<tuple>
<none/>
<list>
<dictionary>
<item>
<key>
<string>
action
</string>
</key>
<value>
<string>
validate
</string>
</value>
</item>
<item>
<key>
<string>
validation_state
</string>
</key>
<value>
<string>
validated
</string>
</value>
</item>
</dictionary>
</list>
</tuple>
</pickle>
</record>
</ZopeData>
master/bt5/slapos_rest_api/ToolTemplateItem/portal_slapos_rest_api.xml
deleted
100644 → 0
View file @
78407bb9
<?xml version="1.0"?>
<ZopeData>
<record
id=
"1"
aka=
"AAAAAAAAAAE="
>
<pickle>
<global
name=
"SlapOS Rest API Tool"
module=
"erp5.portal_type"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
_Access_contents_information_Permission
</string>
</key>
<value>
<tuple>
<string>
Member
</string>
<string>
Manager
</string>
</tuple>
</value>
</item>
<item>
<key>
<string>
_Add_portal_content_Permission
</string>
</key>
<value>
<tuple>
<string>
Manager
</string>
</tuple>
</value>
</item>
<item>
<key>
<string>
_View_Permission
</string>
</key>
<value>
<tuple>
<string>
Manager
</string>
</tuple>
</value>
</item>
<item>
<key>
<string>
id
</string>
</key>
<value>
<string>
portal_slapos_rest_api
</string>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
master/bt5/slapos_rest_api/bt/copyright_list
deleted
100644 → 0
View file @
78407bb9
2012 Nexedi S.A.
\ No newline at end of file
master/bt5/slapos_rest_api/bt/dependency_list
deleted
100644 → 0
View file @
78407bb9
slapos_cloud
slapos_rest_api_tool_portal_type
\ No newline at end of file
master/bt5/slapos_rest_api/bt/description
deleted
100644 → 0
View file @
78407bb9
Tool and shared code for all versions of API.
\ No newline at end of file
master/bt5/slapos_rest_api/bt/license
deleted
100644 → 0
View file @
78407bb9
GPL
\ No newline at end of file
master/bt5/slapos_rest_api/bt/template_action_path_list
deleted
100644 → 0
View file @
78407bb9
System Preference | slapos_rest_api_preference
\ No newline at end of file
master/bt5/slapos_rest_api/bt/template_document_id_list
deleted
100644 → 0
View file @
78407bb9
SlapOSRestAPIV1
\ No newline at end of file
master/bt5/slapos_rest_api/bt/template_format_version
deleted
100644 → 0
View file @
78407bb9
1
\ No newline at end of file
master/bt5/slapos_rest_api/bt/template_property_sheet_id_list
deleted
100644 → 0
View file @
78407bb9
SlapOSRestAPISystemPreference
\ No newline at end of file
master/bt5/slapos_rest_api/bt/template_skin_id_list
deleted
100644 → 0
View file @
78407bb9
slapos_rest_api
\ No newline at end of file
master/bt5/slapos_rest_api/bt/template_test_id_list
deleted
100644 → 0
View file @
78407bb9
test.erp5.testSlapOSRestAPIV1
\ No newline at end of file
master/bt5/slapos_rest_api/bt/template_tool_id_list
deleted
100644 → 0
View file @
78407bb9
portal_slapos_rest_api
\ No newline at end of file
master/bt5/slapos_rest_api/bt/template_update_tool
deleted
100644 → 0
View file @
78407bb9
1
\ No newline at end of file
master/bt5/slapos_rest_api/bt/title
deleted
100644 → 0
View file @
78407bb9
slapos_rest_api
\ No newline at end of file
master/bt5/slapos_rest_api/bt/version
deleted
100644 → 0
View file @
78407bb9
0.1
\ No newline at end of file
master/bt5/slapos_rest_api_tool_portal_type/PortalTypeTemplateItem/portal_types/SlapOS%20Rest%20API%20Tool.xml
deleted
100644 → 0
View file @
78407bb9
<?xml version="1.0"?>
<ZopeData>
<record
id=
"1"
aka=
"AAAAAAAAAAE="
>
<pickle>
<global
name=
"Base Type"
module=
"erp5.portal_type"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
content_icon
</string>
</key>
<value>
<none/>
</value>
</item>
<item>
<key>
<string>
description
</string>
</key>
<value>
<none/>
</value>
</item>
<item>
<key>
<string>
id
</string>
</key>
<value>
<string>
SlapOS Rest API Tool
</string>
</value>
</item>
<item>
<key>
<string>
init_script
</string>
</key>
<value>
<none/>
</value>
</item>
<item>
<key>
<string>
permission
</string>
</key>
<value>
<none/>
</value>
</item>
<item>
<key>
<string>
portal_type
</string>
</key>
<value>
<string>
Base Type
</string>
</value>
</item>
<item>
<key>
<string>
type_class
</string>
</key>
<value>
<string>
SlapOSRestAPITool
</string>
</value>
</item>
<item>
<key>
<string>
type_interface
</string>
</key>
<value>
<tuple/>
</value>
</item>
<item>
<key>
<string>
type_mixin
</string>
</key>
<value>
<tuple/>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
master/bt5/slapos_rest_api_tool_portal_type/bt/copyright_list
deleted
100644 → 0
View file @
78407bb9
2012 Nexedi S.A.
\ No newline at end of file
master/bt5/slapos_rest_api_tool_portal_type/bt/description
deleted
100644 → 0
View file @
78407bb9
Workaround in order to have portal type in different Business Template then tool itself.
\ No newline at end of file
master/bt5/slapos_rest_api_tool_portal_type/bt/license
deleted
100644 → 0
View file @
78407bb9
GPL
\ No newline at end of file
master/bt5/slapos_rest_api_tool_portal_type/bt/template_format_version
deleted
100644 → 0
View file @
78407bb9
1
\ No newline at end of file
master/bt5/slapos_rest_api_tool_portal_type/bt/template_portal_type_id_list
deleted
100644 → 0
View file @
78407bb9
SlapOS Rest API Tool
\ No newline at end of file
master/bt5/slapos_rest_api_tool_portal_type/bt/template_update_tool
deleted
100644 → 0
View file @
78407bb9
1
\ No newline at end of file
master/bt5/slapos_rest_api_tool_portal_type/bt/title
deleted
100644 → 0
View file @
78407bb9
slapos_rest_api_tool_portal_type
\ No newline at end of file
master/bt5/slapos_rest_api_tool_portal_type/bt/version
deleted
100644 → 0
View file @
78407bb9
0.1
\ No newline at end of file
master/product/SlapOS/Tool/SlapOSRestAPITool.py
deleted
100644 → 0
View file @
78407bb9
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright (c) 2012 Nexedi SA and Contributors. All Rights Reserved.
# Łukasz Nowak <luke@nexedi.com>
# Romain Courteaud <romain@nexedi.com>
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsibility of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# guarantees and support are strongly advised to contract a Free Software
# Service Company
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
##############################################################################
from
Products.ERP5Type.Tool.BaseTool
import
BaseTool
from
AccessControl
import
ClassSecurityInfo
from
Products.ERP5Type.Globals
import
InitializeClass
from
Products.ERP5Type
import
Permissions
from
ComputedAttribute
import
ComputedAttribute
class
SlapOSRestAPITool
(
BaseTool
):
"""SlapOS REST API Tool
This is container for multiple versions of API.
"""
id
=
'portal_slapos_rest_api'
meta_type
=
'ERP5 SlapOS Rest API Tool'
portal_type
=
'SlapOS Rest API Tool'
security
=
ClassSecurityInfo
()
security
.
declareObjectProtected
(
Permissions
.
AccessContentsInformation
)
allowed_types
=
()
security
.
declarePublic
(
'v1'
)
@
ComputedAttribute
def
v1
(
self
):
"""API hooked"""
# XXX: It could be done better (more dynamic, configurable from UI)
from
erp5.component.document.SlapOSRestAPIV1
import
SlapOSRestAPIV1
return
SlapOSRestAPIV1
().
__of__
(
self
)
security
.
declarePrivate
(
'manage_afterAdd'
)
def
manage_afterAdd
(
self
,
item
,
container
)
:
"""Init permissions right after creation.
Permissions in slap tool are simple:
o Each member can access the tool.
o Only manager can view and create.
o Anonymous can not access
"""
item
.
manage_permission
(
Permissions
.
AddPortalContent
,
[
'Manager'
])
item
.
manage_permission
(
Permissions
.
AccessContentsInformation
,
[
'Member'
,
'Manager'
])
item
.
manage_permission
(
Permissions
.
View
,
[
'Manager'
,])
BaseTool
.
inheritedAttribute
(
'manage_afterAdd'
)(
self
,
item
,
container
)
InitializeClass
(
SlapOSRestAPITool
)
master/tests/__init__.py
View file @
794fca99
...
...
@@ -11,7 +11,6 @@ slapos_bt_list = [
'slapos_cloud'
,
'slapos_erp5'
,
'slapos_pdm'
,
'slapos_rest_api'
,
'slapos_slap_tool'
,
'slapos_web'
,
'slapos_crm'
,
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment