Commit 5e4db4d1 authored by Rafael Monnerat's avatar Rafael Monnerat

slapos/slap: Implement Computer Token API and command line

  Now a user can get a token from a configured slapos client or slapos console.
parent 2c33ccfe
......@@ -112,6 +112,7 @@ setup(name=name,
'service list = slapos.cli.list:ListCommand',
'computer list = slapos.cli.computer_list:ListCommand',
'computer info = slapos.cli.computer_info:InfoCommand',
'computer token = slapos.cli.computer_token:TokenCommand',
'supply = slapos.cli.supply:SupplyCommand',
'remove = slapos.cli.remove:RemoveCommand',
'request = slapos.cli.request:RequestCommand',
......
......@@ -76,5 +76,6 @@ def do_info(logger, conf, local):
logger.warning('Computer %s does not exist.', conf.reference)
return(2)
import pdb;pdb.set_trace()
logger.info('Computer Reference: %s', computer._reference)
logger.info('Computer Title : %s', computer._title)
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright (c) 2010-2014 Vifib SARL and Contributors.
# All Rights Reserved.
#
# 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 adviced 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 Lesser General Public License
# as published by the Free Software Foundation; either version 2.1
# 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 Lesser 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.
#
##############################################################################
import logging
import pprint
import sys
from slapos.cli.config import ClientConfigCommand
from slapos.client import init, ClientConfig
from slapos.slap import ResourceNotReady, NotFoundError
def resetLogger(logger):
"""Remove all formatters, log files, etc."""
if not getattr(logger, 'parent', None):
return
handler = logger.parent.handlers[0]
logger.parent.removeHandler(handler)
logger.addHandler(logging.StreamHandler(sys.stdout))
class TokenCommand(ClientConfigCommand):
"""get token for setup a computer"""
def get_parser(self, prog_name):
ap = super(TokenCommand, self).get_parser(prog_name)
return ap
def take_action(self, args):
configp = self.fetch_config(args)
conf = ClientConfig(args, configp)
local = init(conf, self.app.log)
exit_code = do_token(self.app.log, conf, local)
if exit_code != 0:
exit(exit_code)
def do_token(logger, conf, local):
resetLogger(logger)
try:
token = local['slap'].registerToken().request()
except ResourceNotReady:
logger.warning('Computer does not exist or is not ready yet.')
return(2)
except NotFoundError:
logger.warning('Computer %s does not exist.', conf.reference)
return(2)
logger.info('Computer token: %s', token)
......@@ -170,8 +170,6 @@ class ConnectionHelper:
headers={'Content-type': content_type})
return req.text.encode('utf-8')
class HateoasNavigator(object):
"""
Navigator for HATEOAS-style APIs.
......@@ -302,7 +300,25 @@ class HateoasNavigator(object):
return self._extractPropertyFromFormDict(document_dict)
def jio_getAttachment(self, key, action, options):
pass
traverse_url = self._getTraverseUrl()
if action == "view":
view = "slaposjs_view"
getter_link = expand(traverse_url, {
"relative_url": key,
"view": view
})
elif action == "links":
raise NotImplementedError("links is not implemented for now")
elif action.startswith(self.slapos_master_hateoas_uri):
# This is a url, call it directly
getter_link = action
document_json = self.GET(getter_link)
document_dict = json.loads(document_json)
return document_dict
def getMeDocument(self):
person_relative_url = self.getRelativeUrlFromUrn(
......@@ -383,6 +399,14 @@ class SlapHateoasNavigator(HateoasNavigator):
return computer_dict
def getToken(self):
root_document = self.getRootDocument()
hateoas_url = root_document['_links']['self']['href']
token_json = self.jio_getAttachment(
"computer_module", hateoas_url + "computer_module/Base_getComputerToken", {})
return token_json["access_token"]
def getHostingSubscriptionRootSoftwareInstanceInformation(self, reference):
hosting_subscription_list = self._getHostingSubscriptionList(title=reference,
select_list=["title", "relative_url"])
......
......@@ -179,6 +179,13 @@ class ISoftwareProductCollection(Interface):
"""
class IToken(Interface):
"""
Classes which implement IToken are used by slap to represent
information about a Token.
"""
class ISoftwareInstance(Interface):
"""
Classes which implement ISoftwareRelease are used by slap to represent
......@@ -526,6 +533,11 @@ class slap(Interface):
software_release -- URI of the software release definition
"""
def registerToken():
"""
Instantiate an token in the slap library.
"""
def registerOpenOrder():
"""
Instantiate an open order in the slap library.
......@@ -546,3 +558,8 @@ class slap(Interface):
"""
Get the list of existing open orders (services) for the current user.
"""
def getComputerDict():
"""
Get the list of existing computer for the current user.
"""
......@@ -228,6 +228,10 @@ class Supply(SlapDocument):
raise NotFoundError("Computer %s has not been found by SlapOS Master."
% computer_guid)
@implementer(interface.IToken)
class Token(SlapDocument):
def request(self):
return self._hateoas_navigator.getToken()
@implementer(interface.IOpenOrder)
class OpenOrder(SlapRequester):
......@@ -235,25 +239,34 @@ class OpenOrder(SlapRequester):
def request(self, software_release, partition_reference,
partition_parameter_kw=None, software_type=None,
filter_kw=None, state=None, shared=False):
if partition_parameter_kw is None:
partition_parameter_kw = {}
elif not isinstance(partition_parameter_kw, dict):
raise ValueError("Unexpected type of partition_parameter_kw '%s'" %
partition_parameter_kw)
if filter_kw is None:
filter_kw = {}
elif not isinstance(filter_kw, dict):
raise ValueError("Unexpected type of filter_kw '%s'" %
filter_kw)
# Let enforce a default software type
if software_type is None:
software_type = DEFAULT_SOFTWARE_TYPE
request_dict = {
'software_release': software_release,
'partition_reference': partition_reference,
'partition_parameter_xml': dumps(partition_parameter_kw),
'filter_xml': dumps(filter_kw),
'software_type': software_type,
# XXX Cedric: Why state and shared are marshalled? First is a string
# And second is a boolean.
'state': dumps(state),
'shared_xml': dumps(shared),
}
if software_type is not None:
request_dict['software_type'] = software_type
else:
# Let's enforce a default software type
request_dict['software_type'] = DEFAULT_SOFTWARE_TYPE
return self._requestComputerPartition(request_dict)
def getInformation(self, partition_reference):
......@@ -371,8 +384,6 @@ class Computer(SlapDocument):
if key in ['_links']:
continue
setattr(computer, '_%s' % key, value)
return computer
......@@ -533,7 +544,6 @@ class ComputerPartition(SlapRequester):
setattr(software_instance, '_software_release_url', raw_information["_links"]["software_release"])
return software_instance
def getId(self):
if not getattr(self, '_partition_id', None):
raise ResourceNotReady()
......@@ -741,6 +751,20 @@ class slap:
hateoas_navigator=self._hateoas_navigator
)
def registerToken(self):
"""
Registers connected represenation of token and
return Token class object
"""
if not getattr(self, '_hateoas_navigator', None):
raise Exception('SlapOS Master Hateoas API required for this operation is not availble.')
return Token(
connection_helper=self._connection_helper,
hateoas_navigator=self._hateoas_navigator
)
def registerComputer(self, computer_guid):
"""
Registers connected representation of computer and
......
  • FAIL: test_Token_only_implements (slapos.tests.test_interface.TestInterface)
    ----------------------------------------------------------------------
    Traceback (most recent call last):
      File "/srv/slapgrid/slappart15/srv/testnode/ij/inst/test0-0/parts/slapos.core/slapos/tests/test_interface.py", line 42, in testMethod
        raise AssertionError("Unexpected methods %s" % implemented_method_list)
    AssertionError: Unexpected methods set(['request'])
  • Yes, I will merge the fix.

Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment