Drop XML support in Magnum

This patch disables XML from the Magnum API. It's modeled after
a simliar Ironic patch found here:
https://review.openstack.org/#/c/169643/8.

To disable XML, we wrap wsmeext.pecan.expose() and replace all the
decorators with a call to magnum.api.expose.expose().

Change-Id: I53ee0ac4fa4a5d899d40cb87213e48ae84ec4970
Closes-bug: 1471507
This commit is contained in:
Michael Sambol 2015-07-12 19:43:30 -05:00
parent b00a0c4b74
commit 77397eecc6
11 changed files with 99 additions and 77 deletions

View File

@ -17,11 +17,11 @@
import pecan import pecan
from pecan import rest from pecan import rest
from wsme import types as wtypes from wsme import types as wtypes
import wsmeext.pecan as wsme_pecan
from magnum.api.controllers import base from magnum.api.controllers import base
from magnum.api.controllers import link from magnum.api.controllers import link
from magnum.api.controllers import v1 from magnum.api.controllers import v1
from magnum.api import expose
class Version(base.APIBase): class Version(base.APIBase):
@ -77,7 +77,7 @@ class RootController(rest.RestController):
v1 = v1.Controller() v1 = v1.Controller()
@wsme_pecan.wsexpose(Root) @expose.expose(Root)
def get(self): def get(self):
# NOTE: The reason why convert() it's being called for every # NOTE: The reason why convert() it's being called for every
# request is because we need to get the host url from # request is because we need to get the host url from

View File

@ -22,7 +22,6 @@ import pecan
from pecan import rest from pecan import rest
from webob import exc from webob import exc
from wsme import types as wtypes from wsme import types as wtypes
import wsmeext.pecan as wsme_pecan
from magnum.api.controllers import base as controllers_base from magnum.api.controllers import base as controllers_base
from magnum.api.controllers import link from magnum.api.controllers import link
@ -33,6 +32,7 @@ from magnum.api.controllers.v1 import node
from magnum.api.controllers.v1 import pod from magnum.api.controllers.v1 import pod
from magnum.api.controllers.v1 import replicationcontroller as rc from magnum.api.controllers.v1 import replicationcontroller as rc
from magnum.api.controllers.v1 import service from magnum.api.controllers.v1 import service
from magnum.api import expose
from magnum.i18n import _ from magnum.i18n import _
@ -165,7 +165,7 @@ class Controller(rest.RestController):
rcs = rc.ReplicationControllersController() rcs = rc.ReplicationControllersController()
services = service.ServicesController() services = service.ServicesController()
@wsme_pecan.wsexpose(V1) @expose.expose(V1)
def get(self): def get(self):
# NOTE: The reason why convert() it's being called for every # NOTE: The reason why convert() it's being called for every
# request is because we need to get the host url from # request is because we need to get the host url from

View File

@ -19,13 +19,13 @@ import pecan
from pecan import rest from pecan import rest
import wsme import wsme
from wsme import types as wtypes from wsme import types as wtypes
import wsmeext.pecan as wsme_pecan
from magnum.api.controllers import base from magnum.api.controllers import base
from magnum.api.controllers import link from magnum.api.controllers import link
from magnum.api.controllers.v1 import collection from magnum.api.controllers.v1 import collection
from magnum.api.controllers.v1 import types from magnum.api.controllers.v1 import types
from magnum.api.controllers.v1 import utils as api_utils from magnum.api.controllers.v1 import utils as api_utils
from magnum.api import expose
from magnum.common import exception from magnum.common import exception
from magnum.common import policy from magnum.common import policy
from magnum import objects from magnum import objects
@ -205,8 +205,8 @@ class BaysController(rest.RestController):
sort_dir=sort_dir) sort_dir=sort_dir)
@policy.enforce_wsgi("bay") @policy.enforce_wsgi("bay")
@wsme_pecan.wsexpose(BayCollection, types.uuid, @expose.expose(BayCollection, types.uuid,
types.uuid, int, wtypes.text, wtypes.text) types.uuid, int, wtypes.text, wtypes.text)
def get_all(self, bay_uuid=None, marker=None, limit=None, def get_all(self, bay_uuid=None, marker=None, limit=None,
sort_key='id', sort_dir='asc'): sort_key='id', sort_dir='asc'):
"""Retrieve a list of bays. """Retrieve a list of bays.
@ -220,8 +220,8 @@ class BaysController(rest.RestController):
sort_dir) sort_dir)
@policy.enforce_wsgi("bay") @policy.enforce_wsgi("bay")
@wsme_pecan.wsexpose(BayCollection, types.uuid, @expose.expose(BayCollection, types.uuid,
types.uuid, int, wtypes.text, wtypes.text) types.uuid, int, wtypes.text, wtypes.text)
def detail(self, bay_uuid=None, marker=None, limit=None, def detail(self, bay_uuid=None, marker=None, limit=None,
sort_key='id', sort_dir='asc'): sort_key='id', sort_dir='asc'):
"""Retrieve a list of bays with detail. """Retrieve a list of bays with detail.
@ -244,7 +244,7 @@ class BaysController(rest.RestController):
resource_url) resource_url)
@policy.enforce_wsgi("bay", "get") @policy.enforce_wsgi("bay", "get")
@wsme_pecan.wsexpose(Bay, types.uuid_or_name) @expose.expose(Bay, types.uuid_or_name)
def get_one(self, bay_ident): def get_one(self, bay_ident):
"""Retrieve information about the given bay. """Retrieve information about the given bay.
@ -255,7 +255,7 @@ class BaysController(rest.RestController):
return Bay.convert_with_links(rpc_bay) return Bay.convert_with_links(rpc_bay)
@policy.enforce_wsgi("bay", "create") @policy.enforce_wsgi("bay", "create")
@wsme_pecan.wsexpose(Bay, body=Bay, status_code=201) @expose.expose(Bay, body=Bay, status_code=201)
def post(self, bay): def post(self, bay):
"""Create a new bay. """Create a new bay.
@ -278,7 +278,7 @@ class BaysController(rest.RestController):
@policy.enforce_wsgi("bay", "update") @policy.enforce_wsgi("bay", "update")
@wsme.validate(types.uuid, [BayPatchType]) @wsme.validate(types.uuid, [BayPatchType])
@wsme_pecan.wsexpose(Bay, types.uuid_or_name, body=[BayPatchType]) @expose.expose(Bay, types.uuid_or_name, body=[BayPatchType])
def patch(self, bay_ident, patch): def patch(self, bay_ident, patch):
"""Update an existing bay. """Update an existing bay.
@ -308,7 +308,7 @@ class BaysController(rest.RestController):
return Bay.convert_with_links(res_bay) return Bay.convert_with_links(res_bay)
@policy.enforce_wsgi("bay", "delete") @policy.enforce_wsgi("bay", "delete")
@wsme_pecan.wsexpose(None, types.uuid_or_name, status_code=204) @expose.expose(None, types.uuid_or_name, status_code=204)
def delete(self, bay_ident): def delete(self, bay_ident):
"""Delete a bay. """Delete a bay.

View File

@ -19,13 +19,13 @@ import pecan
from pecan import rest from pecan import rest
import wsme import wsme
from wsme import types as wtypes from wsme import types as wtypes
import wsmeext.pecan as wsme_pecan
from magnum.api.controllers import base from magnum.api.controllers import base
from magnum.api.controllers import link from magnum.api.controllers import link
from magnum.api.controllers.v1 import collection from magnum.api.controllers.v1 import collection
from magnum.api.controllers.v1 import types from magnum.api.controllers.v1 import types
from magnum.api.controllers.v1 import utils as api_utils from magnum.api.controllers.v1 import utils as api_utils
from magnum.api import expose
from magnum.common import clients from magnum.common import clients
from magnum.common import exception from magnum.common import exception
from magnum.common import policy from magnum.common import policy
@ -220,8 +220,8 @@ class BayModelsController(rest.RestController):
raise exception.ImageNotAuthorized(image_id=image_ident) raise exception.ImageNotAuthorized(image_id=image_ident)
@policy.enforce_wsgi("baymodel") @policy.enforce_wsgi("baymodel")
@wsme_pecan.wsexpose(BayModelCollection, types.uuid, @expose.expose(BayModelCollection, types.uuid,
types.uuid, int, wtypes.text, wtypes.text) types.uuid, int, wtypes.text, wtypes.text)
def get_all(self, baymodel_uuid=None, marker=None, limit=None, def get_all(self, baymodel_uuid=None, marker=None, limit=None,
sort_key='id', sort_dir='asc'): sort_key='id', sort_dir='asc'):
"""Retrieve a list of baymodels. """Retrieve a list of baymodels.
@ -235,8 +235,8 @@ class BayModelsController(rest.RestController):
sort_dir) sort_dir)
@policy.enforce_wsgi("baymodel") @policy.enforce_wsgi("baymodel")
@wsme_pecan.wsexpose(BayModelCollection, types.uuid, @expose.expose(BayModelCollection, types.uuid,
types.uuid, int, wtypes.text, wtypes.text) types.uuid, int, wtypes.text, wtypes.text)
def detail(self, baymodel_uuid=None, marker=None, limit=None, def detail(self, baymodel_uuid=None, marker=None, limit=None,
sort_key='id', sort_dir='asc'): sort_key='id', sort_dir='asc'):
"""Retrieve a list of baymodels with detail. """Retrieve a list of baymodels with detail.
@ -260,7 +260,7 @@ class BayModelsController(rest.RestController):
resource_url) resource_url)
@policy.enforce_wsgi("baymodel", "get") @policy.enforce_wsgi("baymodel", "get")
@wsme_pecan.wsexpose(BayModel, types.uuid_or_name) @expose.expose(BayModel, types.uuid_or_name)
def get_one(self, baymodel_ident): def get_one(self, baymodel_ident):
"""Retrieve information about the given baymodel. """Retrieve information about the given baymodel.
@ -270,7 +270,7 @@ class BayModelsController(rest.RestController):
return BayModel.convert_with_links(rpc_baymodel) return BayModel.convert_with_links(rpc_baymodel)
@policy.enforce_wsgi("baymodel", "create") @policy.enforce_wsgi("baymodel", "create")
@wsme_pecan.wsexpose(BayModel, body=BayModel, status_code=201) @expose.expose(BayModel, body=BayModel, status_code=201)
def post(self, baymodel): def post(self, baymodel):
"""Create a new baymodel. """Create a new baymodel.
@ -296,7 +296,7 @@ class BayModelsController(rest.RestController):
@policy.enforce_wsgi("baymodel", "update") @policy.enforce_wsgi("baymodel", "update")
@wsme.validate(types.uuid, [BayModelPatchType]) @wsme.validate(types.uuid, [BayModelPatchType])
@wsme_pecan.wsexpose(BayModel, types.uuid, body=[BayModelPatchType]) @expose.expose(BayModel, types.uuid, body=[BayModelPatchType])
def patch(self, baymodel_uuid, patch): def patch(self, baymodel_uuid, patch):
"""Update an existing baymodel. """Update an existing baymodel.
@ -329,7 +329,7 @@ class BayModelsController(rest.RestController):
return BayModel.convert_with_links(rpc_baymodel) return BayModel.convert_with_links(rpc_baymodel)
@policy.enforce_wsgi("baymodel") @policy.enforce_wsgi("baymodel")
@wsme_pecan.wsexpose(None, types.uuid_or_name, status_code=204) @expose.expose(None, types.uuid_or_name, status_code=204)
def delete(self, baymodel_ident): def delete(self, baymodel_ident):
"""Delete a baymodel. """Delete a baymodel.

View File

@ -20,13 +20,13 @@ import pecan
from pecan import rest from pecan import rest
import wsme import wsme
from wsme import types as wtypes from wsme import types as wtypes
import wsmeext.pecan as wsme_pecan
from magnum.api.controllers import base from magnum.api.controllers import base
from magnum.api.controllers import link from magnum.api.controllers import link
from magnum.api.controllers.v1 import collection from magnum.api.controllers.v1 import collection
from magnum.api.controllers.v1 import types from magnum.api.controllers.v1 import types
from magnum.api.controllers.v1 import utils as api_utils from magnum.api.controllers.v1 import utils as api_utils
from magnum.api import expose
from magnum.api import validation from magnum.api import validation
from magnum.common import exception from magnum.common import exception
from magnum import objects from magnum import objects
@ -158,7 +158,7 @@ class ContainerCollection(collection.Collection):
class StartController(object): class StartController(object):
@wsme_pecan.wsexpose(types.uuid_or_name, wtypes.text) @expose.expose(types.uuid_or_name, wtypes.text)
def _default(self, container_ident): def _default(self, container_ident):
if pecan.request.method != 'PUT': if pecan.request.method != 'PUT':
pecan.abort(405, ('HTTP method %s is not allowed' pecan.abort(405, ('HTTP method %s is not allowed'
@ -172,7 +172,7 @@ class StartController(object):
class StopController(object): class StopController(object):
@wsme_pecan.wsexpose(types.uuid_or_name, wtypes.text) @expose.expose(types.uuid_or_name, wtypes.text)
def _default(self, container_ident): def _default(self, container_ident):
if pecan.request.method != 'PUT': if pecan.request.method != 'PUT':
pecan.abort(405, ('HTTP method %s is not allowed' pecan.abort(405, ('HTTP method %s is not allowed'
@ -185,7 +185,7 @@ class StopController(object):
class RebootController(object): class RebootController(object):
@wsme_pecan.wsexpose(types.uuid_or_name, wtypes.text) @expose.expose(types.uuid_or_name, wtypes.text)
def _default(self, container_ident): def _default(self, container_ident):
if pecan.request.method != 'PUT': if pecan.request.method != 'PUT':
pecan.abort(405, ('HTTP method %s is not allowed' pecan.abort(405, ('HTTP method %s is not allowed'
@ -198,7 +198,7 @@ class RebootController(object):
class PauseController(object): class PauseController(object):
@wsme_pecan.wsexpose(types.uuid_or_name, wtypes.text) @expose.expose(types.uuid_or_name, wtypes.text)
def _default(self, container_ident): def _default(self, container_ident):
if pecan.request.method != 'PUT': if pecan.request.method != 'PUT':
pecan.abort(405, ('HTTP method %s is not allowed' pecan.abort(405, ('HTTP method %s is not allowed'
@ -211,7 +211,7 @@ class PauseController(object):
class UnpauseController(object): class UnpauseController(object):
@wsme_pecan.wsexpose(types.uuid_or_name, wtypes.text) @expose.expose(types.uuid_or_name, wtypes.text)
def _default(self, container_ident): def _default(self, container_ident):
if pecan.request.method != 'PUT': if pecan.request.method != 'PUT':
pecan.abort(405, ('HTTP method %s is not allowed' pecan.abort(405, ('HTTP method %s is not allowed'
@ -224,7 +224,7 @@ class UnpauseController(object):
class LogsController(object): class LogsController(object):
@wsme_pecan.wsexpose(types.uuid_or_name, wtypes.text) @expose.expose(types.uuid_or_name, wtypes.text)
def _default(self, container_ident): def _default(self, container_ident):
if pecan.request.method != 'GET': if pecan.request.method != 'GET':
pecan.abort(405, ('HTTP method %s is not allowed' pecan.abort(405, ('HTTP method %s is not allowed'
@ -237,7 +237,7 @@ class LogsController(object):
class ExecuteController(object): class ExecuteController(object):
@wsme_pecan.wsexpose(types.uuid_or_name, wtypes.text, wtypes.text) @expose.expose(types.uuid_or_name, wtypes.text, wtypes.text)
def _default(self, container_ident, command): def _default(self, container_ident, command):
if pecan.request.method != 'PUT': if pecan.request.method != 'PUT':
pecan.abort(405, ('HTTP method %s is not allowed' pecan.abort(405, ('HTTP method %s is not allowed'
@ -291,8 +291,8 @@ class ContainersController(rest.RestController):
sort_key=sort_key, sort_key=sort_key,
sort_dir=sort_dir) sort_dir=sort_dir)
@wsme_pecan.wsexpose(ContainerCollection, types.uuid, @expose.expose(ContainerCollection, types.uuid,
types.uuid, int, wtypes.text, wtypes.text) types.uuid, int, wtypes.text, wtypes.text)
def get_all(self, container_uuid=None, marker=None, limit=None, def get_all(self, container_uuid=None, marker=None, limit=None,
sort_key='id', sort_dir='asc'): sort_key='id', sort_dir='asc'):
"""Retrieve a list of containers. """Retrieve a list of containers.
@ -305,8 +305,8 @@ class ContainersController(rest.RestController):
return self._get_containers_collection(marker, limit, sort_key, return self._get_containers_collection(marker, limit, sort_key,
sort_dir) sort_dir)
@wsme_pecan.wsexpose(ContainerCollection, types.uuid, @expose.expose(ContainerCollection, types.uuid,
types.uuid, int, wtypes.text, wtypes.text) types.uuid, int, wtypes.text, wtypes.text)
def detail(self, container_uuid=None, marker=None, limit=None, def detail(self, container_uuid=None, marker=None, limit=None,
sort_key='id', sort_dir='asc'): sort_key='id', sort_dir='asc'):
"""Retrieve a list of containers with detail. """Retrieve a list of containers with detail.
@ -328,7 +328,7 @@ class ContainersController(rest.RestController):
sort_key, sort_dir, expand, sort_key, sort_dir, expand,
resource_url) resource_url)
@wsme_pecan.wsexpose(Container, types.uuid_or_name) @expose.expose(Container, types.uuid_or_name)
def get_one(self, container_ident): def get_one(self, container_ident):
"""Retrieve information about the given container. """Retrieve information about the given container.
@ -339,7 +339,7 @@ class ContainersController(rest.RestController):
res_container = pecan.request.rpcapi.container_show(rpc_container.uuid) res_container = pecan.request.rpcapi.container_show(rpc_container.uuid)
return Container.convert_with_links(res_container) return Container.convert_with_links(res_container)
@wsme_pecan.wsexpose(Container, body=Container, status_code=201) @expose.expose(Container, body=Container, status_code=201)
@validation.enforce_bay_types('swarm') @validation.enforce_bay_types('swarm')
def post(self, container): def post(self, container):
"""Create a new container. """Create a new container.
@ -363,8 +363,8 @@ class ContainersController(rest.RestController):
return Container.convert_with_links(res_container) return Container.convert_with_links(res_container)
@wsme.validate(types.uuid, [ContainerPatchType]) @wsme.validate(types.uuid, [ContainerPatchType])
@wsme_pecan.wsexpose(Container, types.uuid_or_name, @expose.expose(Container, types.uuid_or_name,
body=[ContainerPatchType]) body=[ContainerPatchType])
def patch(self, container_ident, patch): def patch(self, container_ident, patch):
"""Update an existing container. """Update an existing container.
@ -395,7 +395,7 @@ class ContainersController(rest.RestController):
rpc_container.save() rpc_container.save()
return Container.convert_with_links(rpc_container) return Container.convert_with_links(rpc_container)
@wsme_pecan.wsexpose(None, types.uuid_or_name, status_code=204) @expose.expose(None, types.uuid_or_name, status_code=204)
def delete(self, container_ident): def delete(self, container_ident):
"""Delete a container. """Delete a container.

View File

@ -19,13 +19,13 @@ import pecan
from pecan import rest from pecan import rest
import wsme import wsme
from wsme import types as wtypes from wsme import types as wtypes
import wsmeext.pecan as wsme_pecan
from magnum.api.controllers import base from magnum.api.controllers import base
from magnum.api.controllers import link from magnum.api.controllers import link
from magnum.api.controllers.v1 import collection from magnum.api.controllers.v1 import collection
from magnum.api.controllers.v1 import types from magnum.api.controllers.v1 import types
from magnum.api.controllers.v1 import utils as api_utils from magnum.api.controllers.v1 import utils as api_utils
from magnum.api import expose
from magnum.common import exception from magnum.common import exception
from magnum.common import policy from magnum.common import policy
from magnum import objects from magnum import objects
@ -149,8 +149,8 @@ class NodesController(rest.RestController):
sort_dir=sort_dir) sort_dir=sort_dir)
@policy.enforce_wsgi("node") @policy.enforce_wsgi("node")
@wsme_pecan.wsexpose(NodeCollection, types.uuid, @expose.expose(NodeCollection, types.uuid,
types.uuid, int, wtypes.text, wtypes.text) types.uuid, int, wtypes.text, wtypes.text)
def get_all(self, node_uuid=None, marker=None, limit=None, def get_all(self, node_uuid=None, marker=None, limit=None,
sort_key='id', sort_dir='asc'): sort_key='id', sort_dir='asc'):
"""Retrieve a list of nodes. """Retrieve a list of nodes.
@ -164,8 +164,8 @@ class NodesController(rest.RestController):
sort_dir) sort_dir)
@policy.enforce_wsgi("node") @policy.enforce_wsgi("node")
@wsme_pecan.wsexpose(NodeCollection, types.uuid, @expose.expose(NodeCollection, types.uuid,
types.uuid, int, wtypes.text, wtypes.text) types.uuid, int, wtypes.text, wtypes.text)
def detail(self, node_uuid=None, marker=None, limit=None, def detail(self, node_uuid=None, marker=None, limit=None,
sort_key='id', sort_dir='asc'): sort_key='id', sort_dir='asc'):
"""Retrieve a list of nodes with detail. """Retrieve a list of nodes with detail.
@ -188,7 +188,7 @@ class NodesController(rest.RestController):
resource_url) resource_url)
@policy.enforce_wsgi("node", "get") @policy.enforce_wsgi("node", "get")
@wsme_pecan.wsexpose(Node, types.uuid) @expose.expose(Node, types.uuid)
def get_one(self, node_uuid): def get_one(self, node_uuid):
"""Retrieve information about the given node. """Retrieve information about the given node.
@ -198,7 +198,7 @@ class NodesController(rest.RestController):
return Node.convert_with_links(rpc_node) return Node.convert_with_links(rpc_node)
@policy.enforce_wsgi("node", "create") @policy.enforce_wsgi("node", "create")
@wsme_pecan.wsexpose(Node, body=Node, status_code=201) @expose.expose(Node, body=Node, status_code=201)
def post(self, node): def post(self, node):
"""Create a new node. """Create a new node.
@ -217,7 +217,7 @@ class NodesController(rest.RestController):
@policy.enforce_wsgi("node", "update") @policy.enforce_wsgi("node", "update")
@wsme.validate(types.uuid, [NodePatchType]) @wsme.validate(types.uuid, [NodePatchType])
@wsme_pecan.wsexpose(Node, types.uuid, body=[NodePatchType]) @expose.expose(Node, types.uuid, body=[NodePatchType])
def patch(self, node_uuid, patch): def patch(self, node_uuid, patch):
"""Update an existing node. """Update an existing node.
@ -247,7 +247,7 @@ class NodesController(rest.RestController):
return Node.convert_with_links(rpc_node) return Node.convert_with_links(rpc_node)
@policy.enforce_wsgi("node", "delete") @policy.enforce_wsgi("node", "delete")
@wsme_pecan.wsexpose(None, types.uuid, status_code=204) @expose.expose(None, types.uuid, status_code=204)
def delete(self, node_uuid): def delete(self, node_uuid):
"""Delete a node. """Delete a node.

View File

@ -17,13 +17,13 @@ import pecan
from pecan import rest from pecan import rest
import wsme import wsme
from wsme import types as wtypes from wsme import types as wtypes
import wsmeext.pecan as wsme_pecan
from magnum.api.controllers import link from magnum.api.controllers import link
from magnum.api.controllers.v1 import base as v1_base from magnum.api.controllers.v1 import base as v1_base
from magnum.api.controllers.v1 import collection from magnum.api.controllers.v1 import collection
from magnum.api.controllers.v1 import types from magnum.api.controllers.v1 import types
from magnum.api.controllers.v1 import utils as api_utils from magnum.api.controllers.v1 import utils as api_utils
from magnum.api import expose
from magnum.api import validation from magnum.api import validation
from magnum.common import exception from magnum.common import exception
from magnum.common import k8s_manifest from magnum.common import k8s_manifest
@ -195,8 +195,8 @@ class PodsController(rest.RestController):
sort_key=sort_key, sort_key=sort_key,
sort_dir=sort_dir) sort_dir=sort_dir)
@wsme_pecan.wsexpose(PodCollection, types.uuid, @expose.expose(PodCollection, types.uuid,
types.uuid, int, wtypes.text, wtypes.text) types.uuid, int, wtypes.text, wtypes.text)
def get_all(self, pod_uuid=None, marker=None, limit=None, def get_all(self, pod_uuid=None, marker=None, limit=None,
sort_key='id', sort_dir='asc'): sort_key='id', sort_dir='asc'):
"""Retrieve a list of pods. """Retrieve a list of pods.
@ -209,8 +209,8 @@ class PodsController(rest.RestController):
return self._get_pods_collection(marker, limit, sort_key, return self._get_pods_collection(marker, limit, sort_key,
sort_dir) sort_dir)
@wsme_pecan.wsexpose(PodCollection, types.uuid, @expose.expose(PodCollection, types.uuid,
types.uuid, int, wtypes.text, wtypes.text) types.uuid, int, wtypes.text, wtypes.text)
def detail(self, pod_uuid=None, marker=None, limit=None, def detail(self, pod_uuid=None, marker=None, limit=None,
sort_key='id', sort_dir='asc'): sort_key='id', sort_dir='asc'):
"""Retrieve a list of pods with detail. """Retrieve a list of pods with detail.
@ -232,7 +232,7 @@ class PodsController(rest.RestController):
sort_key, sort_dir, expand, sort_key, sort_dir, expand,
resource_url) resource_url)
@wsme_pecan.wsexpose(Pod, types.uuid_or_name) @expose.expose(Pod, types.uuid_or_name)
def get_one(self, pod_ident): def get_one(self, pod_ident):
"""Retrieve information about the given pod. """Retrieve information about the given pod.
@ -242,7 +242,7 @@ class PodsController(rest.RestController):
return Pod.convert_with_links(rpc_pod) return Pod.convert_with_links(rpc_pod)
@wsme_pecan.wsexpose(Pod, body=Pod, status_code=201) @expose.expose(Pod, body=Pod, status_code=201)
@validation.enforce_bay_types('kubernetes') @validation.enforce_bay_types('kubernetes')
def post(self, pod): def post(self, pod):
"""Create a new pod. """Create a new pod.
@ -262,7 +262,7 @@ class PodsController(rest.RestController):
return Pod.convert_with_links(new_pod) return Pod.convert_with_links(new_pod)
@wsme.validate(types.uuid, [PodPatchType]) @wsme.validate(types.uuid, [PodPatchType])
@wsme_pecan.wsexpose(Pod, types.uuid_or_name, body=[PodPatchType]) @expose.expose(Pod, types.uuid_or_name, body=[PodPatchType])
def patch(self, pod_ident, patch): def patch(self, pod_ident, patch):
"""Update an existing pod. """Update an existing pod.
@ -300,7 +300,7 @@ class PodsController(rest.RestController):
rpc_pod.save() rpc_pod.save()
return Pod.convert_with_links(rpc_pod) return Pod.convert_with_links(rpc_pod)
@wsme_pecan.wsexpose(None, types.uuid_or_name, status_code=204) @expose.expose(None, types.uuid_or_name, status_code=204)
def delete(self, pod_ident): def delete(self, pod_ident):
"""Delete a pod. """Delete a pod.

View File

@ -18,13 +18,13 @@ import pecan
from pecan import rest from pecan import rest
import wsme import wsme
from wsme import types as wtypes from wsme import types as wtypes
import wsmeext.pecan as wsme_pecan
from magnum.api.controllers import link from magnum.api.controllers import link
from magnum.api.controllers.v1 import base as v1_base from magnum.api.controllers.v1 import base as v1_base
from magnum.api.controllers.v1 import collection from magnum.api.controllers.v1 import collection
from magnum.api.controllers.v1 import types from magnum.api.controllers.v1 import types
from magnum.api.controllers.v1 import utils as api_utils from magnum.api.controllers.v1 import utils as api_utils
from magnum.api import expose
from magnum.api import validation from magnum.api import validation
from magnum.common import exception from magnum.common import exception
from magnum.common import k8s_manifest from magnum.common import k8s_manifest
@ -228,8 +228,8 @@ class ReplicationControllersController(rest.RestController):
sort_key=sort_key, sort_key=sort_key,
sort_dir=sort_dir) sort_dir=sort_dir)
@wsme_pecan.wsexpose(ReplicationControllerCollection, types.uuid, @expose.expose(ReplicationControllerCollection, types.uuid,
types.uuid, int, wtypes.text, wtypes.text) types.uuid, int, wtypes.text, wtypes.text)
def get_all(self, rc_uuid=None, marker=None, limit=None, def get_all(self, rc_uuid=None, marker=None, limit=None,
sort_key='id', sort_dir='asc'): sort_key='id', sort_dir='asc'):
"""Retrieve a list of ReplicationControllers. """Retrieve a list of ReplicationControllers.
@ -242,8 +242,8 @@ class ReplicationControllersController(rest.RestController):
return self._get_rcs_collection(marker, limit, sort_key, return self._get_rcs_collection(marker, limit, sort_key,
sort_dir) sort_dir)
@wsme_pecan.wsexpose(ReplicationControllerCollection, types.uuid, @expose.expose(ReplicationControllerCollection, types.uuid,
types.uuid, int, wtypes.text, wtypes.text) types.uuid, int, wtypes.text, wtypes.text)
def detail(self, rc_uuid=None, marker=None, limit=None, def detail(self, rc_uuid=None, marker=None, limit=None,
sort_key='id', sort_dir='asc'): sort_key='id', sort_dir='asc'):
"""Retrieve a list of ReplicationControllers with detail. """Retrieve a list of ReplicationControllers with detail.
@ -266,7 +266,7 @@ class ReplicationControllersController(rest.RestController):
sort_key, sort_dir, expand, sort_key, sort_dir, expand,
resource_url) resource_url)
@wsme_pecan.wsexpose(ReplicationController, types.uuid_or_name) @expose.expose(ReplicationController, types.uuid_or_name)
def get_one(self, rc_ident): def get_one(self, rc_ident):
"""Retrieve information about the given ReplicationController. """Retrieve information about the given ReplicationController.
@ -275,8 +275,8 @@ class ReplicationControllersController(rest.RestController):
rpc_rc = api_utils.get_rpc_resource('ReplicationController', rc_ident) rpc_rc = api_utils.get_rpc_resource('ReplicationController', rc_ident)
return ReplicationController.convert_with_links(rpc_rc) return ReplicationController.convert_with_links(rpc_rc)
@wsme_pecan.wsexpose(ReplicationController, body=ReplicationController, @expose.expose(ReplicationController, body=ReplicationController,
status_code=201) status_code=201)
@validation.enforce_bay_types('kubernetes') @validation.enforce_bay_types('kubernetes')
def post(self, rc): def post(self, rc):
"""Create a new ReplicationController. """Create a new ReplicationController.
@ -299,8 +299,8 @@ class ReplicationControllersController(rest.RestController):
return ReplicationController.convert_with_links(new_rc) return ReplicationController.convert_with_links(new_rc)
@wsme.validate(types.uuid, [ReplicationControllerPatchType]) @wsme.validate(types.uuid, [ReplicationControllerPatchType])
@wsme_pecan.wsexpose(ReplicationController, types.uuid_or_name, @expose.expose(ReplicationController, types.uuid_or_name,
body=[ReplicationControllerPatchType]) body=[ReplicationControllerPatchType])
def patch(self, rc_ident, patch): def patch(self, rc_ident, patch):
"""Update an existing rc. """Update an existing rc.
@ -339,7 +339,7 @@ class ReplicationControllersController(rest.RestController):
rpc_rc.save() rpc_rc.save()
return ReplicationController.convert_with_links(rpc_rc) return ReplicationController.convert_with_links(rpc_rc)
@wsme_pecan.wsexpose(None, types.uuid_or_name, status_code=204) @expose.expose(None, types.uuid_or_name, status_code=204)
def delete(self, rc_ident): def delete(self, rc_ident):
"""Delete a ReplicationController. """Delete a ReplicationController.

View File

@ -16,13 +16,13 @@ import pecan
from pecan import rest from pecan import rest
import wsme import wsme
from wsme import types as wtypes from wsme import types as wtypes
import wsmeext.pecan as wsme_pecan
from magnum.api.controllers import link from magnum.api.controllers import link
from magnum.api.controllers.v1 import base as v1_base from magnum.api.controllers.v1 import base as v1_base
from magnum.api.controllers.v1 import collection from magnum.api.controllers.v1 import collection
from magnum.api.controllers.v1 import types from magnum.api.controllers.v1 import types
from magnum.api.controllers.v1 import utils as api_utils from magnum.api.controllers.v1 import utils as api_utils
from magnum.api import expose
from magnum.api import validation from magnum.api import validation
from magnum.common import exception from magnum.common import exception
from magnum.common import k8s_manifest from magnum.common import k8s_manifest
@ -205,8 +205,8 @@ class ServicesController(rest.RestController):
sort_key=sort_key, sort_key=sort_key,
sort_dir=sort_dir) sort_dir=sort_dir)
@wsme_pecan.wsexpose(ServiceCollection, types.uuid, @expose.expose(ServiceCollection, types.uuid,
types.uuid, int, wtypes.text, wtypes.text) types.uuid, int, wtypes.text, wtypes.text)
def get_all(self, service_uuid=None, marker=None, limit=None, def get_all(self, service_uuid=None, marker=None, limit=None,
sort_key='id', sort_dir='asc'): sort_key='id', sort_dir='asc'):
"""Retrieve a list of services. """Retrieve a list of services.
@ -219,8 +219,8 @@ class ServicesController(rest.RestController):
return self._get_services_collection(marker, limit, sort_key, return self._get_services_collection(marker, limit, sort_key,
sort_dir) sort_dir)
@wsme_pecan.wsexpose(ServiceCollection, types.uuid, @expose.expose(ServiceCollection, types.uuid,
types.uuid, int, wtypes.text, wtypes.text) types.uuid, int, wtypes.text, wtypes.text)
def detail(self, service_uuid=None, marker=None, limit=None, def detail(self, service_uuid=None, marker=None, limit=None,
sort_key='id', sort_dir='asc'): sort_key='id', sort_dir='asc'):
"""Retrieve a list of services with detail. """Retrieve a list of services with detail.
@ -243,7 +243,7 @@ class ServicesController(rest.RestController):
sort_key, sort_dir, expand, sort_key, sort_dir, expand,
resource_url) resource_url)
@wsme_pecan.wsexpose(Service, types.uuid_or_name) @expose.expose(Service, types.uuid_or_name)
def get_one(self, service_ident): def get_one(self, service_ident):
"""Retrieve information about the given service. """Retrieve information about the given service.
@ -253,7 +253,7 @@ class ServicesController(rest.RestController):
return Service.convert_with_links(rpc_service) return Service.convert_with_links(rpc_service)
@wsme_pecan.wsexpose(Service, body=Service, status_code=201) @expose.expose(Service, body=Service, status_code=201)
@validation.enforce_bay_types('kubernetes') @validation.enforce_bay_types('kubernetes')
def post(self, service): def post(self, service):
"""Create a new service. """Create a new service.
@ -276,7 +276,7 @@ class ServicesController(rest.RestController):
return Service.convert_with_links(new_service) return Service.convert_with_links(new_service)
@wsme.validate(types.uuid, [ServicePatchType]) @wsme.validate(types.uuid, [ServicePatchType])
@wsme_pecan.wsexpose(Service, types.uuid_or_name, body=[ServicePatchType]) @expose.expose(Service, types.uuid_or_name, body=[ServicePatchType])
def patch(self, service_ident, patch): def patch(self, service_ident, patch):
"""Update an existing service. """Update an existing service.
@ -314,7 +314,7 @@ class ServicesController(rest.RestController):
rpc_service.save() rpc_service.save()
return Service.convert_with_links(rpc_service) return Service.convert_with_links(rpc_service)
@wsme_pecan.wsexpose(None, types.uuid_or_name, status_code=204) @expose.expose(None, types.uuid_or_name, status_code=204)
def delete(self, service_ident): def delete(self, service_ident):
"""Delete a service. """Delete a service.

20
magnum/api/expose.py Normal file
View File

@ -0,0 +1,20 @@
# 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 wsmeext.pecan as wsme_pecan
def expose(*args, **kwargs):
"""Ensure that only JSON, and not XML, is supported."""
if 'rest_content_types' not in kwargs:
kwargs['rest_content_types'] = ('json',)
return wsme_pecan.wsexpose(*args, **kwargs)

View File

@ -32,6 +32,8 @@ class AuthTokenMiddleware(auth_token.AuthProtocol):
def __init__(self, app, conf, public_api_routes=None): def __init__(self, app, conf, public_api_routes=None):
if public_api_routes is None: if public_api_routes is None:
public_api_routes = [] public_api_routes = []
# TODO(?): Remove .xml and ensure it doesn't result in a
# 401 Authentication Required instead of 404 Not Found
route_pattern_tpl = '%s(\.json|\.xml)?$' route_pattern_tpl = '%s(\.json|\.xml)?$'
try: try: