Merge "Move the Capsule API from Experimental to V1"
This commit is contained in:
commit
0cf31381e7
@ -141,7 +141,6 @@ function upload_sandbox_image {
|
|||||||
function create_zun_accounts {
|
function create_zun_accounts {
|
||||||
|
|
||||||
create_service_user "zun" "admin"
|
create_service_user "zun" "admin"
|
||||||
create_service_user "zun-experimental" "admin"
|
|
||||||
|
|
||||||
if is_service_enabled zun-api; then
|
if is_service_enabled zun-api; then
|
||||||
|
|
||||||
@ -154,18 +153,11 @@ function create_zun_accounts {
|
|||||||
|
|
||||||
local zun_service=$(get_or_create_service "zun" \
|
local zun_service=$(get_or_create_service "zun" \
|
||||||
"container" "Container As Service")
|
"container" "Container As Service")
|
||||||
local zun_experimental_service=$(get_or_create_service "zun-experimental" \
|
|
||||||
"container-experimental" "Container As Service - Experimental")
|
|
||||||
get_or_create_endpoint $zun_service \
|
get_or_create_endpoint $zun_service \
|
||||||
"$REGION_NAME" \
|
"$REGION_NAME" \
|
||||||
"$zun_api_url/v1" \
|
"$zun_api_url/v1" \
|
||||||
"$zun_api_url/v1" \
|
"$zun_api_url/v1" \
|
||||||
"$zun_api_url/v1"
|
"$zun_api_url/v1"
|
||||||
get_or_create_endpoint $zun_experimental_service \
|
|
||||||
"$REGION_NAME" \
|
|
||||||
"$zun_api_url/experimental" \
|
|
||||||
"$zun_api_url/experimental" \
|
|
||||||
"$zun_api_url/experimental"
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -46,32 +46,7 @@ The diagram below is an overview of the structure of ``capsule``.
|
|||||||
| |
|
| |
|
||||||
+-----------------------------------------------------------+
|
+-----------------------------------------------------------+
|
||||||
|
|
||||||
Capsule API is currently in experimental phase, so you have to
|
Capsule API is currently in v1 phase now.
|
||||||
specify ``--experimental-api`` option in each of the commands below. They will
|
|
||||||
be moved to stable API once they become stable.
|
|
||||||
|
|
||||||
.. note::
|
|
||||||
|
|
||||||
Please make sure that every capsule commands have ``--experimental-api``
|
|
||||||
flags in client side.
|
|
||||||
|
|
||||||
Experimental API is a separated API. After users deploy Zun by devstack,
|
|
||||||
a separated set of API endpoints and service type will be created in
|
|
||||||
service catalog. Zun stable API endpoints will have service name ``zun`` and
|
|
||||||
service type ``container``, while Zun experimental API endpoints will have
|
|
||||||
service name ``zun-experimental`` and service type ``container-experimental``.
|
|
||||||
We can see the service and endpoint information as below::
|
|
||||||
|
|
||||||
+------------------+------------------------+---------+-----------+--------------------------------------+
|
|
||||||
| Service Name | Service Type | Enabled | Interface | URL |
|
|
||||||
+------------------+------------------------+---------+-----------+--------------------------------------+
|
|
||||||
| zun | container | True | public | http://***/container/v1 |
|
|
||||||
| zun | container | True | internal | http://***/container/v1 |
|
|
||||||
| zun | container | True | admin | http://***/container/v1 |
|
|
||||||
| zun-experimental | container-experimental | True | public | http://***/container/experimental |
|
|
||||||
| zun-experimental | container-experimental | True | internal | http://***/container/experimental |
|
|
||||||
| zun-experimental | container-experimental | True | admin | http://***/container/experimental |
|
|
||||||
+------------------+------------------------+---------+-----------+--------------------------------------+
|
|
||||||
|
|
||||||
Now basic capsule functions are supported. Capsule API methods:
|
Now basic capsule functions are supported. Capsule API methods:
|
||||||
|
|
||||||
@ -175,7 +150,7 @@ Create capsule, it will create capsule based on capsule.yaml:
|
|||||||
.. code-block:: console
|
.. code-block:: console
|
||||||
|
|
||||||
$ source ~/devstack/openrc demo demo
|
$ source ~/devstack/openrc demo demo
|
||||||
$ zun --experimental-api capsule-create -f capsule.yaml
|
$ zun capsule-create -f capsule.yaml
|
||||||
|
|
||||||
If you want to get access to the port, you need to set the security group
|
If you want to get access to the port, you need to set the security group
|
||||||
rules for it.
|
rules for it.
|
||||||
@ -193,21 +168,21 @@ Delete capsule:
|
|||||||
|
|
||||||
.. code-block:: console
|
.. code-block:: console
|
||||||
|
|
||||||
$ zun --experimental-api capsule-delete <uuid>
|
$ zun capsule-delete <uuid>
|
||||||
$ zun --experimental-api capsule-delete <capsule-name>
|
$ zun capsule-delete <capsule-name>
|
||||||
|
|
||||||
List capsule:
|
List capsule:
|
||||||
|
|
||||||
.. code-block:: console
|
.. code-block:: console
|
||||||
|
|
||||||
$ zun --experimental-api capsule-list
|
$ zun capsule-list
|
||||||
|
|
||||||
Describe capsule:
|
Describe capsule:
|
||||||
|
|
||||||
.. code-block:: console
|
.. code-block:: console
|
||||||
|
|
||||||
$ zun --experimental-api capsule-describe <uuid>
|
$ zun capsule-describe <uuid>
|
||||||
$ zun --experimental-api capsule-describe <capsule-name>
|
$ zun capsule-describe <capsule-name>
|
||||||
|
|
||||||
To DO
|
To DO
|
||||||
---------
|
---------
|
||||||
|
@ -1,153 +0,0 @@
|
|||||||
# Copyright 2017 ARM Holdings.
|
|
||||||
#
|
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
|
||||||
# not use this file except in compliance with the License. You may obtain
|
|
||||||
# a copy of the License at
|
|
||||||
#
|
|
||||||
# http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
#
|
|
||||||
# Unless required by applicable law or agreed to in writing, software
|
|
||||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
||||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
||||||
# License for the specific language governing permissions and limitations
|
|
||||||
# under the License.
|
|
||||||
|
|
||||||
"""
|
|
||||||
Experimental of the Zun API
|
|
||||||
|
|
||||||
NOTE: IN PROGRESS AND NOT FULLY IMPLEMENTED.
|
|
||||||
"""
|
|
||||||
|
|
||||||
from oslo_log import log as logging
|
|
||||||
import pecan
|
|
||||||
|
|
||||||
from zun.api.controllers import base as controllers_base
|
|
||||||
from zun.api.controllers.experimental import capsules as capsule_controller
|
|
||||||
from zun.api.controllers import link
|
|
||||||
from zun.api.controllers import versions as ver
|
|
||||||
from zun.api import http_error
|
|
||||||
from zun.common.i18n import _
|
|
||||||
|
|
||||||
LOG = logging.getLogger(__name__)
|
|
||||||
|
|
||||||
|
|
||||||
BASE_VERSION = 1
|
|
||||||
|
|
||||||
MIN_VER_STR = '%s %s' % (ver.Version.service_string, ver.BASE_VER)
|
|
||||||
|
|
||||||
MAX_VER_STR = '%s %s' % (ver.Version.service_string, ver.CURRENT_MAX_VER)
|
|
||||||
|
|
||||||
MIN_VER = ver.Version({ver.Version.string: MIN_VER_STR},
|
|
||||||
MIN_VER_STR, MAX_VER_STR)
|
|
||||||
MAX_VER = ver.Version({ver.Version.string: MAX_VER_STR},
|
|
||||||
MIN_VER_STR, MAX_VER_STR)
|
|
||||||
|
|
||||||
|
|
||||||
class MediaType(controllers_base.APIBase):
|
|
||||||
"""A media type representation."""
|
|
||||||
|
|
||||||
fields = (
|
|
||||||
'base',
|
|
||||||
'type',
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class Experimental(controllers_base.APIBase):
|
|
||||||
"""The representation of the version experimental of the API."""
|
|
||||||
|
|
||||||
fields = (
|
|
||||||
'id',
|
|
||||||
'media_types',
|
|
||||||
'links',
|
|
||||||
'capsules'
|
|
||||||
)
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def convert():
|
|
||||||
experimental = Experimental()
|
|
||||||
experimental.id = "experimental"
|
|
||||||
experimental.links = [link.make_link('self', pecan.request.host_url,
|
|
||||||
'experimental', '',
|
|
||||||
bookmark=True),
|
|
||||||
link.make_link('describedby',
|
|
||||||
'https://docs.openstack.org',
|
|
||||||
'developer/zun/dev',
|
|
||||||
'api-spec-v1.html',
|
|
||||||
bookmark=True,
|
|
||||||
type='text/html')]
|
|
||||||
experimental.media_types = \
|
|
||||||
[MediaType(base='application/json',
|
|
||||||
type='application/vnd.openstack.'
|
|
||||||
'zun.experimental+json')]
|
|
||||||
experimental.capsules = [link.make_link('self',
|
|
||||||
pecan.request.host_url,
|
|
||||||
'experimental/capsules', '',
|
|
||||||
bookmark=True),
|
|
||||||
link.make_link('bookmark',
|
|
||||||
pecan.request.host_url,
|
|
||||||
'capsules', '',
|
|
||||||
bookmark=True)]
|
|
||||||
return experimental
|
|
||||||
|
|
||||||
|
|
||||||
class Controller(controllers_base.Controller):
|
|
||||||
"""Version expereimental API controller root."""
|
|
||||||
|
|
||||||
capsules = capsule_controller.CapsuleController()
|
|
||||||
|
|
||||||
@pecan.expose('json')
|
|
||||||
def get(self):
|
|
||||||
return Experimental.convert()
|
|
||||||
|
|
||||||
def _check_version(self, version, headers=None):
|
|
||||||
if headers is None:
|
|
||||||
headers = {}
|
|
||||||
# ensure that major version in the URL matches the header
|
|
||||||
if version.major != BASE_VERSION:
|
|
||||||
raise http_error.HTTPNotAcceptableAPIVersion(_(
|
|
||||||
"Mutually exclusive versions requested. Version %(ver)s "
|
|
||||||
"requested but not supported by this service. "
|
|
||||||
"The supported version range is: "
|
|
||||||
"[%(min)s, %(max)s].") % {'ver': version,
|
|
||||||
'min': MIN_VER_STR,
|
|
||||||
'max': MAX_VER_STR},
|
|
||||||
headers=headers,
|
|
||||||
max_version=str(MAX_VER),
|
|
||||||
min_version=str(MIN_VER))
|
|
||||||
# ensure the minor version is within the supported range
|
|
||||||
if version < MIN_VER or version > MAX_VER:
|
|
||||||
raise http_error.HTTPNotAcceptableAPIVersion(_(
|
|
||||||
"Version %(ver)s was requested but the minor version is not "
|
|
||||||
"supported by this service. The supported version range is: "
|
|
||||||
"[%(min)s, %(max)s].") % {'ver': version, 'min': MIN_VER_STR,
|
|
||||||
'max': MAX_VER_STR},
|
|
||||||
headers=headers,
|
|
||||||
max_version=str(MAX_VER),
|
|
||||||
min_version=str(MIN_VER))
|
|
||||||
|
|
||||||
@pecan.expose()
|
|
||||||
def _route(self, args):
|
|
||||||
version = ver.Version(
|
|
||||||
pecan.request.headers, MIN_VER_STR, MAX_VER_STR)
|
|
||||||
|
|
||||||
# Always set the basic version headers
|
|
||||||
pecan.response.headers[ver.Version.min_string] = MIN_VER_STR
|
|
||||||
pecan.response.headers[ver.Version.max_string] = MAX_VER_STR
|
|
||||||
pecan.response.headers[ver.Version.string] = " ".join(
|
|
||||||
[ver.Version.service_string, str(version)])
|
|
||||||
pecan.response.headers["vary"] = ver.Version.string
|
|
||||||
|
|
||||||
# assert that requested version is supported
|
|
||||||
self._check_version(version, pecan.response.headers)
|
|
||||||
pecan.request.version = version
|
|
||||||
if pecan.request.body:
|
|
||||||
msg = ("Processing request: url: %(url)s, %(method)s, "
|
|
||||||
"body: %(body)s" %
|
|
||||||
{'url': pecan.request.url,
|
|
||||||
'method': pecan.request.method,
|
|
||||||
'body': pecan.request.body})
|
|
||||||
LOG.debug(msg)
|
|
||||||
|
|
||||||
return super(Controller, self)._route(args)
|
|
||||||
|
|
||||||
__all__ = (Controller)
|
|
@ -1,43 +0,0 @@
|
|||||||
# Copyright 2017 ARM Holdings.
|
|
||||||
#
|
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
|
||||||
# not use this file except in compliance with the License. You may obtain
|
|
||||||
# a copy of the License at
|
|
||||||
#
|
|
||||||
# http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
#
|
|
||||||
# Unless required by applicable law or agreed to in writing, software
|
|
||||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
||||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
||||||
# License for the specific language governing permissions and limitations
|
|
||||||
# under the License.
|
|
||||||
|
|
||||||
import pecan
|
|
||||||
|
|
||||||
from zun.api.controllers import base
|
|
||||||
from zun.api.controllers import link
|
|
||||||
|
|
||||||
|
|
||||||
class Collection(base.APIBase):
|
|
||||||
|
|
||||||
@property
|
|
||||||
def collection(self):
|
|
||||||
return getattr(self, self._type)
|
|
||||||
|
|
||||||
def has_next(self, limit):
|
|
||||||
"""Return whether collection has more items."""
|
|
||||||
return len(self.collection) and len(self.collection) == limit
|
|
||||||
|
|
||||||
def get_next(self, limit, url=None, **kwargs):
|
|
||||||
"""Return a link to the next subset of the collection."""
|
|
||||||
if not self.has_next(limit):
|
|
||||||
return None
|
|
||||||
|
|
||||||
resource_url = url or self._type
|
|
||||||
q_args = ''.join(['%s=%s&' % (key, kwargs[key]) for key in kwargs])
|
|
||||||
next_args = '?%(args)slimit=%(limit)d&marker=%(marker)s' % {
|
|
||||||
'args': q_args, 'limit': limit,
|
|
||||||
'marker': self.collection[-1]['uuid']}
|
|
||||||
|
|
||||||
return link.make_link('next', pecan.request.host_url,
|
|
||||||
resource_url, next_args)['href']
|
|
@ -14,7 +14,6 @@ import pecan
|
|||||||
from pecan import rest
|
from pecan import rest
|
||||||
|
|
||||||
from zun.api.controllers import base
|
from zun.api.controllers import base
|
||||||
from zun.api.controllers import experimental
|
|
||||||
from zun.api.controllers import link
|
from zun.api.controllers import link
|
||||||
from zun.api.controllers import v1
|
from zun.api.controllers import v1
|
||||||
from zun.api.controllers import versions
|
from zun.api.controllers import versions
|
||||||
@ -70,14 +69,13 @@ class Root(base.APIBase):
|
|||||||
|
|
||||||
class RootController(rest.RestController):
|
class RootController(rest.RestController):
|
||||||
|
|
||||||
_versions = ['v1', 'experimental']
|
_versions = ['v1']
|
||||||
"""All supported API versions"""
|
"""All supported API versions"""
|
||||||
|
|
||||||
_default_version = 'v1'
|
_default_version = 'v1'
|
||||||
"""The default API version"""
|
"""The default API version"""
|
||||||
|
|
||||||
v1 = v1.Controller()
|
v1 = v1.Controller()
|
||||||
experimental = experimental.Controller()
|
|
||||||
|
|
||||||
@pecan.expose('json')
|
@pecan.expose('json')
|
||||||
def get(self):
|
def get(self):
|
||||||
|
@ -22,8 +22,8 @@ from oslo_log import log as logging
|
|||||||
import pecan
|
import pecan
|
||||||
|
|
||||||
from zun.api.controllers import base as controllers_base
|
from zun.api.controllers import base as controllers_base
|
||||||
from zun.api.controllers.experimental import capsules as capsule_controller
|
|
||||||
from zun.api.controllers import link
|
from zun.api.controllers import link
|
||||||
|
from zun.api.controllers.v1 import capsules as capsule_controller
|
||||||
from zun.api.controllers.v1 import containers as container_controller
|
from zun.api.controllers.v1 import containers as container_controller
|
||||||
from zun.api.controllers.v1 import hosts as host_controller
|
from zun.api.controllers.v1 import hosts as host_controller
|
||||||
from zun.api.controllers.v1 import images as image_controller
|
from zun.api.controllers.v1 import images as image_controller
|
||||||
@ -66,7 +66,8 @@ class V1(controllers_base.APIBase):
|
|||||||
'services',
|
'services',
|
||||||
'containers',
|
'containers',
|
||||||
'images',
|
'images',
|
||||||
'hosts'
|
'hosts',
|
||||||
|
'capsules'
|
||||||
)
|
)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
@ -106,6 +107,12 @@ class V1(controllers_base.APIBase):
|
|||||||
pecan.request.host_url,
|
pecan.request.host_url,
|
||||||
'hosts', '',
|
'hosts', '',
|
||||||
bookmark=True)]
|
bookmark=True)]
|
||||||
|
v1.capsules = [link.make_link('self', pecan.request.host_url,
|
||||||
|
'capsules', ''),
|
||||||
|
link.make_link('bookmark',
|
||||||
|
pecan.request.host_url,
|
||||||
|
'capsules', '',
|
||||||
|
bookmark=True)]
|
||||||
return v1
|
return v1
|
||||||
|
|
||||||
|
|
||||||
|
@ -13,14 +13,15 @@
|
|||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
from oslo_log import log as logging
|
from oslo_log import log as logging
|
||||||
|
|
||||||
import pecan
|
import pecan
|
||||||
import six
|
import six
|
||||||
|
|
||||||
from zun.api.controllers import base
|
from zun.api.controllers import base
|
||||||
from zun.api.controllers.experimental import collection
|
|
||||||
from zun.api.controllers.experimental.schemas import capsules as schema
|
|
||||||
from zun.api.controllers.experimental.views import capsules_view as view
|
|
||||||
from zun.api.controllers import link
|
from zun.api.controllers import link
|
||||||
|
from zun.api.controllers.v1 import collection
|
||||||
|
from zun.api.controllers.v1.schemas import capsules as schema
|
||||||
|
from zun.api.controllers.v1.views import capsules_view as view
|
||||||
from zun.api import utils as api_utils
|
from zun.api import utils as api_utils
|
||||||
from zun.common import consts
|
from zun.common import consts
|
||||||
from zun.common import exception
|
from zun.common import exception
|
@ -1,19 +0,0 @@
|
|||||||
[pipeline:main]
|
|
||||||
pipeline = cors request_id authtoken api_experimental
|
|
||||||
|
|
||||||
[app:api_experimental]
|
|
||||||
paste.app_factory = zun.api.app:app_factory
|
|
||||||
|
|
||||||
[filter:authtoken]
|
|
||||||
acl_public_routes = /experimental
|
|
||||||
paste.filter_factory = zun.api.middleware.auth_token:AuthTokenMiddleware.factory
|
|
||||||
|
|
||||||
[filter:request_id]
|
|
||||||
paste.filter_factory = oslo_middleware:RequestId.factory
|
|
||||||
|
|
||||||
[filter:cors]
|
|
||||||
paste.filter_factory = oslo_middleware.cors:filter_factory
|
|
||||||
oslo_config_project = zun
|
|
||||||
latent_allow_methods = GET, PUT, POST, DELETE
|
|
||||||
latent_allow_headers = X-Auth-Token, X-Identity-Status, X-Roles, X-Service-Catalog, X-User-Id, X-Tenant-Id, X-OpenStack-Request-ID
|
|
||||||
latent_expose_headers = X-Auth-Token, X-Subject-Token, X-Service-Token, X-OpenStack-Request-ID
|
|
@ -67,20 +67,8 @@ class TestRootController(api_base.FunctionalTest):
|
|||||||
'images': [{'href': 'http://localhost/v1/images/',
|
'images': [{'href': 'http://localhost/v1/images/',
|
||||||
'rel': 'self'},
|
'rel': 'self'},
|
||||||
{'href': 'http://localhost/images/',
|
{'href': 'http://localhost/images/',
|
||||||
'rel': 'bookmark'}]}
|
'rel': 'bookmark'}],
|
||||||
|
'capsules': [{'href': 'http://localhost/v1/capsules/',
|
||||||
self.experimental_expected = {
|
|
||||||
'media_types':
|
|
||||||
[{'base': 'application/json',
|
|
||||||
'type': 'application/vnd.openstack.zun.experimental+json'}],
|
|
||||||
'links': [{'href': 'http://localhost/experimental/',
|
|
||||||
'rel': 'self'},
|
|
||||||
{'href':
|
|
||||||
'https://docs.openstack.org/developer'
|
|
||||||
'/zun/dev/api-spec-v1.html',
|
|
||||||
'type': 'text/html', 'rel': 'describedby'}],
|
|
||||||
'id': 'experimental',
|
|
||||||
'capsules': [{'href': 'http://localhost/experimental/capsules/',
|
|
||||||
'rel': 'self'},
|
'rel': 'self'},
|
||||||
{'href': 'http://localhost/capsules/',
|
{'href': 'http://localhost/capsules/',
|
||||||
'rel': 'bookmark'}]}
|
'rel': 'bookmark'}]}
|
||||||
@ -98,10 +86,6 @@ class TestRootController(api_base.FunctionalTest):
|
|||||||
response = self.app.get('/v1/')
|
response = self.app.get('/v1/')
|
||||||
self.assertEqual(self.v1_expected, response.json)
|
self.assertEqual(self.v1_expected, response.json)
|
||||||
|
|
||||||
def test_experimental_controller(self):
|
|
||||||
response = self.app.get('/experimental/')
|
|
||||||
self.assertEqual(self.experimental_expected, response.json)
|
|
||||||
|
|
||||||
def test_get_not_found(self):
|
def test_get_not_found(self):
|
||||||
response = self.app.get('/a/bogus/url', expect_errors=True)
|
response = self.app.get('/a/bogus/url', expect_errors=True)
|
||||||
assert response.status_int == 404
|
assert response.status_int == 404
|
||||||
@ -159,14 +143,3 @@ class TestRootController(api_base.FunctionalTest):
|
|||||||
|
|
||||||
response = app.get('/v1/containers', expect_errors=True)
|
response = app.get('/v1/containers', expect_errors=True)
|
||||||
self.assertEqual(401, response.status_int)
|
self.assertEqual(401, response.status_int)
|
||||||
|
|
||||||
def test_auth_with_experimental_access(self):
|
|
||||||
paste_file = \
|
|
||||||
"zun/tests/unit/api/controllers/auth-experimental-access.ini"
|
|
||||||
app = self.make_app(paste_file)
|
|
||||||
|
|
||||||
response = app.get('/', expect_errors=True)
|
|
||||||
self.assertEqual(401, response.status_int)
|
|
||||||
|
|
||||||
response = app.get('/experimental/')
|
|
||||||
self.assertEqual(self.experimental_expected, response.json)
|
|
||||||
|
@ -42,7 +42,7 @@ class TestCapsuleController(api_base.FunctionalTest):
|
|||||||
' "name": "capsule-example"}'
|
' "name": "capsule-example"}'
|
||||||
' }'
|
' }'
|
||||||
'}')
|
'}')
|
||||||
response = self.post('/capsules/',
|
response = self.post('/v1/capsules/',
|
||||||
params=params,
|
params=params,
|
||||||
content_type='application/json')
|
content_type='application/json')
|
||||||
return_value = response.json
|
return_value = response.json
|
||||||
@ -79,7 +79,7 @@ class TestCapsuleController(api_base.FunctionalTest):
|
|||||||
' "name": "capsule-example"}'
|
' "name": "capsule-example"}'
|
||||||
' }'
|
' }'
|
||||||
'}')
|
'}')
|
||||||
response = self.post('/capsules/',
|
response = self.post('/v1/capsules/',
|
||||||
params=params,
|
params=params,
|
||||||
content_type='application/json')
|
content_type='application/json')
|
||||||
return_value = response.json
|
return_value = response.json
|
||||||
@ -156,7 +156,7 @@ class TestCapsuleController(api_base.FunctionalTest):
|
|||||||
'"name": "capsule-example"}}}')
|
'"name": "capsule-example"}}}')
|
||||||
mock_check_template.side_effect = exception.InvalidCapsuleTemplate(
|
mock_check_template.side_effect = exception.InvalidCapsuleTemplate(
|
||||||
"Container image is needed")
|
"Container image is needed")
|
||||||
self.assertRaises(AppError, self.post, '/capsules/',
|
self.assertRaises(AppError, self.post, '/v1/capsules/',
|
||||||
params=params, content_type='application/json')
|
params=params, content_type='application/json')
|
||||||
self.assertFalse(mock_capsule_create.called)
|
self.assertFalse(mock_capsule_create.called)
|
||||||
|
|
||||||
@ -193,7 +193,7 @@ class TestCapsuleController(api_base.FunctionalTest):
|
|||||||
' "name": "capsule-example"}'
|
' "name": "capsule-example"}'
|
||||||
' }'
|
' }'
|
||||||
'}')
|
'}')
|
||||||
response = self.post('/capsules/',
|
response = self.post('/v1/capsules/',
|
||||||
params=params,
|
params=params,
|
||||||
content_type='application/json')
|
content_type='application/json')
|
||||||
return_value = response.json
|
return_value = response.json
|
||||||
@ -247,7 +247,7 @@ class TestCapsuleController(api_base.FunctionalTest):
|
|||||||
' "name": "capsule-example"}'
|
' "name": "capsule-example"}'
|
||||||
' }'
|
' }'
|
||||||
'}')
|
'}')
|
||||||
response = self.post('/capsules/',
|
response = self.post('/v1/capsules/',
|
||||||
params=params,
|
params=params,
|
||||||
content_type='application/json')
|
content_type='application/json')
|
||||||
return_value = response.json
|
return_value = response.json
|
||||||
@ -310,7 +310,7 @@ class TestCapsuleController(api_base.FunctionalTest):
|
|||||||
' "name": "capsule-example"}'
|
' "name": "capsule-example"}'
|
||||||
' }'
|
' }'
|
||||||
'}')
|
'}')
|
||||||
response = self.post('/capsules/',
|
response = self.post('/v1/capsules/',
|
||||||
params=params,
|
params=params,
|
||||||
content_type='application/json')
|
content_type='application/json')
|
||||||
return_value = response.json
|
return_value = response.json
|
||||||
@ -347,7 +347,7 @@ class TestCapsuleController(api_base.FunctionalTest):
|
|||||||
test_capsule_obj = objects.Capsule(self.context, **test_capsule)
|
test_capsule_obj = objects.Capsule(self.context, **test_capsule)
|
||||||
mock_capsule_get_by_uuid.return_value = test_capsule_obj
|
mock_capsule_get_by_uuid.return_value = test_capsule_obj
|
||||||
|
|
||||||
response = self.get('/capsules/%s/' % test_capsule['uuid'])
|
response = self.get('/v1/capsules/%s/' % test_capsule['uuid'])
|
||||||
|
|
||||||
context = mock_capsule_get_by_uuid.call_args[0][0]
|
context = mock_capsule_get_by_uuid.call_args[0][0]
|
||||||
self.assertIs(False, context.all_projects)
|
self.assertIs(False, context.all_projects)
|
||||||
@ -399,7 +399,7 @@ class TestCapsuleController(api_base.FunctionalTest):
|
|||||||
mock_capsule_delete.return_value = True
|
mock_capsule_delete.return_value = True
|
||||||
|
|
||||||
capsule_uuid = test_capsule.get('uuid')
|
capsule_uuid = test_capsule.get('uuid')
|
||||||
response = self.app.delete('/capsules/%s' % capsule_uuid)
|
response = self.app.delete('/v1/capsules/%s' % capsule_uuid)
|
||||||
|
|
||||||
self.assertTrue(mock_capsule_delete.called)
|
self.assertTrue(mock_capsule_delete.called)
|
||||||
self.assertEqual(204, response.status_int)
|
self.assertEqual(204, response.status_int)
|
||||||
@ -431,7 +431,7 @@ class TestCapsuleController(api_base.FunctionalTest):
|
|||||||
|
|
||||||
capsule_uuid = test_capsule.get('uuid')
|
capsule_uuid = test_capsule.get('uuid')
|
||||||
response = self.app.delete(
|
response = self.app.delete(
|
||||||
'/capsules/%s/?all_projects=1' % capsule_uuid)
|
'/v1/capsules/%s/?all_projects=1' % capsule_uuid)
|
||||||
|
|
||||||
self.assertTrue(mock_capsule_delete.called)
|
self.assertTrue(mock_capsule_delete.called)
|
||||||
self.assertEqual(204, response.status_int)
|
self.assertEqual(204, response.status_int)
|
||||||
@ -463,7 +463,7 @@ class TestCapsuleController(api_base.FunctionalTest):
|
|||||||
mock_capsule_delete.return_value = True
|
mock_capsule_delete.return_value = True
|
||||||
|
|
||||||
capsule_name = test_capsule.get('meta_name')
|
capsule_name = test_capsule.get('meta_name')
|
||||||
response = self.app.delete('/capsules/%s/' %
|
response = self.app.delete('/v1/capsules/%s/' %
|
||||||
capsule_name)
|
capsule_name)
|
||||||
|
|
||||||
self.assertTrue(mock_capsule_delete.called)
|
self.assertTrue(mock_capsule_delete.called)
|
||||||
@ -487,7 +487,7 @@ class TestCapsuleController(api_base.FunctionalTest):
|
|||||||
mock_capsule_list.return_value = [test_capsule_obj]
|
mock_capsule_list.return_value = [test_capsule_obj]
|
||||||
mock_container_show.return_value = test_container_obj
|
mock_container_show.return_value = test_container_obj
|
||||||
|
|
||||||
response = self.app.get('/capsules/')
|
response = self.app.get('/v1/capsules/')
|
||||||
|
|
||||||
mock_capsule_list.assert_called_once_with(mock.ANY,
|
mock_capsule_list.assert_called_once_with(mock.ANY,
|
||||||
1000, None, 'id', 'asc',
|
1000, None, 'id', 'asc',
|
||||||
@ -517,7 +517,7 @@ class TestCapsuleController(api_base.FunctionalTest):
|
|||||||
mock_capsule_list.return_value = [test_capsule_obj]
|
mock_capsule_list.return_value = [test_capsule_obj]
|
||||||
mock_container_show.return_value = test_container_obj
|
mock_container_show.return_value = test_container_obj
|
||||||
|
|
||||||
response = self.app.get('/capsules/?all_projects=1')
|
response = self.app.get('/v1/capsules/?all_projects=1')
|
||||||
|
|
||||||
mock_capsule_list.assert_called_once_with(mock.ANY,
|
mock_capsule_list.assert_called_once_with(mock.ANY,
|
||||||
1000, None, 'id', 'asc',
|
1000, None, 'id', 'asc',
|
||||||
@ -544,7 +544,7 @@ class TestCapsuleController(api_base.FunctionalTest):
|
|||||||
test_capsule_obj = objects.Capsule(self.context, **test_capsule)
|
test_capsule_obj = objects.Capsule(self.context, **test_capsule)
|
||||||
mock_capsule_list.return_value = [test_capsule_obj]
|
mock_capsule_list.return_value = [test_capsule_obj]
|
||||||
|
|
||||||
response = self.app.get('/capsules/')
|
response = self.app.get('/v1/capsules/')
|
||||||
|
|
||||||
mock_capsule_list.assert_called_once_with(mock.ANY,
|
mock_capsule_list.assert_called_once_with(mock.ANY,
|
||||||
1000, None, 'id', 'asc',
|
1000, None, 'id', 'asc',
|
||||||
@ -582,7 +582,7 @@ class TestCapsuleController(api_base.FunctionalTest):
|
|||||||
mock_container_show.return_value = capsule_list[-1]
|
mock_container_show.return_value = capsule_list[-1]
|
||||||
mock_capsule_save.return_value = True
|
mock_capsule_save.return_value = True
|
||||||
|
|
||||||
response = self.app.get('/capsules/?limit=3&marker=%s'
|
response = self.app.get('/v1/capsules/?limit=3&marker=%s'
|
||||||
% capsule_list[2].uuid)
|
% capsule_list[2].uuid)
|
||||||
|
|
||||||
self.assertEqual(200, response.status_int)
|
self.assertEqual(200, response.status_int)
|
Loading…
Reference in New Issue
Block a user