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
Léo-Paul Géneau
slapos.core
Commits
a0b00e8e
Commit
a0b00e8e
authored
Jul 17, 2019
by
Rafael Monnerat
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
slapos.slap: Re-write API to follow JIO API
This might evolve into a full jio api to written in python
parent
bda4f527
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
120 additions
and
45 deletions
+120
-45
slapos/slap/hateoas.py
slapos/slap/hateoas.py
+109
-42
slapos/slap/slap.py
slapos/slap/slap.py
+11
-3
No files found.
slapos/slap/hateoas.py
View file @
a0b00e8e
...
...
@@ -55,6 +55,13 @@ fallback_handler = logging.StreamHandler()
fallback_logger
.
setLevel
(
logging
.
INFO
)
fallback_logger
.
addHandler
(
fallback_handler
)
ALLOWED_JIO_FIELD_LIST
=
[
"StringField"
,
"EmailField"
,
"IntegerField"
,
"FloatField"
,
"TextAreaField"
]
class
TempDocument
(
object
):
pass
...
...
@@ -171,8 +178,6 @@ class HateoasNavigator(object):
Inspired by
https://git.erp5.org/gitweb/jio.git/blob/HEAD:/src/jio.storage/erp5storage.js
"""
# XXX: needs to be designed for real. For now, just a non-maintainable prototype.
# XXX: export to a standalone library, independant from slap.
def
__init__
(
self
,
slapgrid_uri
,
key_file
=
None
,
cert_file
=
None
,
master_ca_file
=
None
,
timeout
=
60
):
...
...
@@ -211,7 +216,6 @@ class HateoasNavigator(object):
return
json
.
loads
(
result
)
def
getRootDocument
(
self
):
# XXX what about cache?
cached_root_document
=
getattr
(
self
,
'root_document'
,
None
)
if
cached_root_document
:
return
cached_root_document
...
...
@@ -221,6 +225,82 @@ class HateoasNavigator(object):
)
return
self
.
root_document
def
_getSearchUrl
(
self
):
root_document
=
self
.
getRootDocument
()
return
root_document
[
"_links"
][
'raw_search'
][
'href'
]
def
_getTraverseUrl
(
self
):
root_document
=
self
.
getRootDocument
()
return
root_document
[
"_links"
][
'traverse'
][
'href'
]
def
_extractPropertyFromFormDict
(
self
,
form_dict
):
""" Reimplemenation in python of extractPropertyFromFormJSON of jio.js """
form
=
form_dict
[
"_embedded"
][
"_view"
]
form_data_dict
=
{}
converted_dict
=
{
"portal_type"
:
form_dict
[
"_links"
][
"type"
][
"name"
]
}
if
"parent"
in
form_dict
[
"_links"
]:
converted_dict
[
"parent_relative_url"
]
=
\
"/"
.
join
(
form_dict
[
"_links"
][
"parent"
][
"href"
].
split
(
"/"
)[
-
2
:])
form_data_dict
[
"form_id"
]
=
{
"key"
:
[
form
[
"form_id"
][
"key"
]],
"default"
:
form
[
"form_id"
][
"default"
]
}
for
key
in
form
:
field
=
form
[
key
]
if
key
.
startswith
(
"my_"
):
key
=
key
[
len
(
"my_"
):]
elif
key
.
startswith
(
"your_"
):
key
=
key
[
len
(
"your_"
):]
else
:
continue
if
field
[
"type"
]
in
ALLOWED_JIO_FIELD_LIST
:
form_data_dict
[
key
]
=
{
"default"
:
field
.
get
(
"default"
,
None
),
"key"
:
field
[
"key"
]
}
converted_dict
[
key
]
=
field
.
get
(
"default"
,
None
)
return
{
"data"
:
converted_dict
,
"form_data"
:
form_data_dict
}
def
jio_allDocs
(
self
,
query
):
search_url
=
self
.
_getSearchUrl
()
getter_link
=
expand
(
search_url
,
query
)
catalog_json
=
self
.
GET
(
getter_link
)
catalog_dict
=
json
.
loads
(
catalog_json
)
# Return the same data structure from jio api:
return
{
'data'
:
{
"rows"
:
catalog_dict
[
"_embedded"
][
"contents"
],
"total_rows"
:
len
(
catalog_dict
[
"_embedded"
][
"contents"
])
}
}
def
jio_get
(
self
,
key
):
traverse_url
=
self
.
_getTraverseUrl
()
# Hardcoded view, but it should come from a site configuration
view
=
"slaposjs_view"
getter_link
=
expand
(
traverse_url
,
{
"relative_url"
:
key
,
"view"
:
view
})
document_json
=
self
.
GET
(
getter_link
)
document_dict
=
json
.
loads
(
document_json
)
return
self
.
_extractPropertyFromFormDict
(
document_dict
)
def
getDocumentAndHateoas
(
self
,
relative_url
,
view
=
'view'
):
site_document
=
self
.
getRootDocument
()
return
expand
(
...
...
@@ -235,18 +315,16 @@ class HateoasNavigator(object):
return
json
.
loads
(
self
.
GET
(
person_url
))
class
SlapHateoasNavigator
(
HateoasNavigator
):
def
_hateoas_getHostingSubscriptionDict
(
self
):
action_object_slap_list
=
self
.
getMeDocument
()[
'_links'
][
'action_object_slap'
]
for
action
in
action_object_slap_list
:
if
action
.
get
(
'title'
)
==
'getHateoasHostingSubscriptionList'
:
getter_link
=
action
[
'href'
]
break
else
:
raise
Exception
(
'Hosting subscription not found.'
)
result
=
self
.
GET
(
getter_link
)
return
json
.
loads
(
result
)[
'_links'
][
'content'
]
def
_getHostingSubscriptionList
(
self
,
title
=
None
,
select_list
=
[
"title"
,
"url_string"
]):
query_str
=
'portal_type:"Hosting Subscription" AND validation_state:validated'
if
title
is
not
None
:
query_str
=
'portal_type:"Hosting Subscription" AND validation_state:validated AND title:="%s"'
%
title
result
=
self
.
jio_allDocs
(
query
=
{
"query"
:
query_str
,
"select_list"
:
select_list
})
return
result
[
'data'
][
'rows'
]
# XXX rename me to blablaUrl(self)
def
_hateoas_getRelatedHostingSubscription
(
self
):
action_object_slap_list
=
self
.
getMeDocument
()[
'_links'
][
'action_object_slap'
]
getter_link
=
self
.
hateoasGetLinkFromLinks
(
action_object_slap_list
,
'getHateoasRelatedHostingSubscription'
)
...
...
@@ -270,40 +348,36 @@ class SlapHateoasNavigator(HateoasNavigator):
return
instance_list
[
'_links'
][
'content'
]
def
getHostingSubscriptionDict
(
self
):
hosting_subscription_li
nk_list
=
self
.
_hateoas_getHostingSubscriptionDic
t
()
hosting_subscription_li
st
=
self
.
_getHostingSubscriptionLis
t
()
hosting_subscription_dict
=
{}
for
hosting_subscription_link
in
hosting_subscription_link_list
:
raw_information
=
self
.
getHostingSubscriptionRootSoftwareInstanceInformation
(
hosting_subscription_link
[
'title'
])
for
hosting_subscription
in
hosting_subscription_list
:
software_instance
=
TempDocument
()
# XXX redefine SoftwareInstance to be more consistent
for
key
,
value
in
raw_information
.
iteritems
():
if
key
in
[
'_links'
]:
for
key
,
value
in
hosting_subscription
.
iteritems
():
if
key
in
[
'_links'
,
'url_string'
]:
continue
setattr
(
software_instance
,
'_%s'
%
key
,
value
)
setattr
(
software_instance
,
'_software_release_url'
,
raw_information
[
'_links'
][
'software_release'
])
setattr
(
software_instance
,
'_software_release_url'
,
hosting_subscription
[
"url_string"
])
hosting_subscription_dict
[
software_instance
.
_title
]
=
software_instance
return
hosting_subscription_dict
def
getHostingSubscriptionRootSoftwareInstanceInformation
(
self
,
reference
):
hosting_subscription_list
=
self
.
_hateoas_getHostingSubscriptionDict
()
for
hosting_subscription
in
hosting_subscription_list
:
if
hosting_subscription
.
get
(
'title'
)
==
reference
:
hosting_subscription_url
=
hosting_subscription
[
'href'
]
hosting_subscription_list
=
self
.
_getHostingSubscriptionList
(
title
=
reference
,
select_list
=
[
"title"
,
"relative_url"
])
assert
len
(
hosting_subscription_list
)
==
1
,
\
"There are more them one Hosting Subscription for this reference"
for
hosting_subscription_candidate
in
hosting_subscription_list
:
if
hosting_subscription_candidate
.
get
(
'title'
)
==
reference
:
hosting_subscription_jio_key
=
hosting_subscription_candidate
[
'relative_url'
]
break
else
:
if
hosting_subscription_jio_key
is
None
:
raise
NotFoundError
(
'This document does not exist.'
)
hosting_subscription
=
json
.
loads
(
self
.
GET
(
hosting_subscription_url
))
software_instance_url
=
self
.
hateoasGetLinkFromLinks
(
hosting_subscription
[
'_links'
][
'action_object_slap'
],
'getHateoasRootInstance'
)
response
=
self
.
GET
(
software_instance_url
)
response
=
json
.
loads
(
response
)
software_instance_url
=
response
[
'_links'
][
'content'
][
0
][
'href'
]
return
self
.
_hateoasGetInformation
(
software_instance_url
)
return
self
.
jio_get
(
hosting_subscription_jio_key
)
def
getRelatedInstanceInformation
(
self
,
reference
):
related_hosting_subscription_url
=
self
.
_hateoas_getRelatedHostingSubscription
()
...
...
@@ -313,13 +387,6 @@ class SlapHateoasNavigator(HateoasNavigator):
return
instance
def
_hateoas_getComputer
(
self
,
reference
):
root_document
=
self
.
getRootDocument
()
search_url
=
root_document
[
"_links"
][
'raw_search'
][
'href'
]
getter_link
=
expand
(
search_url
,
{
"query"
:
"reference:%s AND portal_type:Computer"
%
reference
,
"select_list"
:
[
"relative_url"
],
"limit"
:
1
})
result
=
self
.
GET
(
getter_link
)
content_list
=
json
.
loads
(
result
)[
'_embedded'
][
'contents'
]
if
len
(
content_list
)
==
0
:
raise
Exception
(
'No Computer found.'
)
...
...
slapos/slap/slap.py
View file @
a0b00e8e
...
...
@@ -262,11 +262,19 @@ class OpenOrder(SlapRequester):
raw_information
=
self
.
_hateoas_navigator
.
getHostingSubscriptionRootSoftwareInstanceInformation
(
partition_reference
)
software_instance
=
SoftwareInstance
()
# XXX redefine SoftwareInstance to be more consistent
for
key
,
value
in
six
.
iteritems
(
raw_information
):
for
key
,
value
in
six
.
iteritems
(
raw_information
[
"data"
]
):
if
key
in
[
'_links'
]:
continue
setattr
(
software_instance
,
'_%s'
%
key
,
value
)
setattr
(
software_instance
,
'_software_release_url'
,
raw_information
[
'_links'
][
'software_release'
])
if
raw_information
[
"data"
].
get
(
"text_content"
,
None
)
is
not
None
:
setattr
(
software_instance
,
'_parameter_dict'
,
xml2dict
(
raw_information
[
"data"
][
'text_content'
]))
else
:
setattr
(
software_instance
,
'_parameter_dict'
,
{})
setattr
(
software_instance
,
'_requested_state'
,
raw_information
[
"data"
][
'slap_state'
])
setattr
(
software_instance
,
'_connection_dict'
,
raw_information
[
"data"
][
'connection_parameter_list'
])
setattr
(
software_instance
,
'_software_release_url'
,
raw_information
[
"data"
][
'url_string'
])
return
software_instance
def
requestComputer
(
self
,
computer_reference
):
...
...
@@ -509,7 +517,7 @@ class ComputerPartition(SlapRequester):
if
key
in
[
'_links'
]:
continue
setattr
(
software_instance
,
'_%s'
%
key
,
value
)
setattr
(
software_instance
,
'_software_release_url'
,
raw_information
[
'_links'
][
'software_release'
])
setattr
(
software_instance
,
'_software_release_url'
,
raw_information
[
"_links"
][
"software_release"
])
return
software_instance
...
...
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