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

View File

@ -22,7 +22,6 @@ import pecan
from pecan import rest
from webob import exc
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 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 replicationcontroller as rc
from magnum.api.controllers.v1 import service
from magnum.api import expose
from magnum.i18n import _
@ -165,7 +165,7 @@ class Controller(rest.RestController):
rcs = rc.ReplicationControllersController()
services = service.ServicesController()
@wsme_pecan.wsexpose(V1)
@expose.expose(V1)
def get(self):
# NOTE: The reason why convert() it's being called for every
# request is because we need to get the host url from

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -16,13 +16,13 @@ import pecan
from pecan import rest
import wsme
from wsme import types as wtypes
import wsmeext.pecan as wsme_pecan
from magnum.api.controllers import link
from magnum.api.controllers.v1 import base as v1_base
from magnum.api.controllers.v1 import collection
from magnum.api.controllers.v1 import types
from magnum.api.controllers.v1 import utils as api_utils
from magnum.api import expose
from magnum.api import validation
from magnum.common import exception
from magnum.common import k8s_manifest
@ -205,8 +205,8 @@ class ServicesController(rest.RestController):
sort_key=sort_key,
sort_dir=sort_dir)
@wsme_pecan.wsexpose(ServiceCollection, types.uuid,
types.uuid, int, wtypes.text, wtypes.text)
@expose.expose(ServiceCollection, types.uuid,
types.uuid, int, wtypes.text, wtypes.text)
def get_all(self, service_uuid=None, marker=None, limit=None,
sort_key='id', sort_dir='asc'):
"""Retrieve a list of services.
@ -219,8 +219,8 @@ class ServicesController(rest.RestController):
return self._get_services_collection(marker, limit, sort_key,
sort_dir)
@wsme_pecan.wsexpose(ServiceCollection, types.uuid,
types.uuid, int, wtypes.text, wtypes.text)
@expose.expose(ServiceCollection, types.uuid,
types.uuid, int, wtypes.text, wtypes.text)
def detail(self, service_uuid=None, marker=None, limit=None,
sort_key='id', sort_dir='asc'):
"""Retrieve a list of services with detail.
@ -243,7 +243,7 @@ class ServicesController(rest.RestController):
sort_key, sort_dir, expand,
resource_url)
@wsme_pecan.wsexpose(Service, types.uuid_or_name)
@expose.expose(Service, types.uuid_or_name)
def get_one(self, service_ident):
"""Retrieve information about the given service.
@ -253,7 +253,7 @@ class ServicesController(rest.RestController):
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')
def post(self, service):
"""Create a new service.
@ -276,7 +276,7 @@ class ServicesController(rest.RestController):
return Service.convert_with_links(new_service)
@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):
"""Update an existing service.
@ -314,7 +314,7 @@ class ServicesController(rest.RestController):
rpc_service.save()
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):
"""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):
if public_api_routes is None:
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)?$'
try: