Container logs should use HTTP GET other actions use PUT

We need to tighten the check on which HTTP methods are allowed
and raise appropriate HTTP error. /logs should respond only
to HTTP GET and not HTTP PUT. other actions should respond
only to HTTP PUT and error out on HTTP GET.

Also see related change in python client:
I1cff0b33d3be1eedeb373fda7ef223a1ba596b59

Closes-Bug: #1409316
Change-Id: Ia78d8a246a8d9d06f949a2d893331e967d64913e
This commit is contained in:
Davanum Srinivas 2015-02-08 11:07:34 -05:00 committed by Davanum Srinivas (dims)
parent 2300776161
commit f51fd3bb4f
2 changed files with 36 additions and 1 deletions

View File

@ -127,6 +127,9 @@ backend_api = api.API(context=context.RequestContext())
class StartController(object):
@wsme_pecan.wsexpose(wtypes.text, wtypes.text)
def _default(self, container_uuid):
if pecan.request.method != 'PUT':
pecan.abort(405, ('HTTP method %s is not allowed'
% pecan.request.method))
LOG.debug('Calling backend_api.container_start with %s' %
container_uuid)
return backend_api.container_start(container_uuid)
@ -135,6 +138,9 @@ class StartController(object):
class StopController(object):
@wsme_pecan.wsexpose(wtypes.text, wtypes.text)
def _default(self, container_uuid, *remainder):
if pecan.request.method != 'PUT':
pecan.abort(405, ('HTTP method %s is not allowed'
% pecan.request.method))
LOG.debug('Calling backend_api.container_stop with %s' %
container_uuid)
return backend_api.container_stop(container_uuid)
@ -143,6 +149,9 @@ class StopController(object):
class RebootController(object):
@wsme_pecan.wsexpose(wtypes.text, wtypes.text)
def _default(self, container_uuid, *remainder):
if pecan.request.method != 'PUT':
pecan.abort(405, ('HTTP method %s is not allowed'
% pecan.request.method))
LOG.debug('Calling backend_api.container_reboot with %s' %
container_uuid)
return backend_api.container_reboot(container_uuid)
@ -151,6 +160,9 @@ class RebootController(object):
class PauseController(object):
@wsme_pecan.wsexpose(wtypes.text, wtypes.text)
def _default(self, container_uuid, *remainder):
if pecan.request.method != 'PUT':
pecan.abort(405, ('HTTP method %s is not allowed'
% pecan.request.method))
LOG.debug('Calling backend_api.container_pause with %s' %
container_uuid)
return backend_api.container_pause(container_uuid)
@ -159,6 +171,9 @@ class PauseController(object):
class UnpauseController(object):
@wsme_pecan.wsexpose(wtypes.text, wtypes.text)
def _default(self, container_uuid, *remainder):
if pecan.request.method != 'PUT':
pecan.abort(405, ('HTTP method %s is not allowed'
% pecan.request.method))
LOG.debug('Calling backend_api.container_unpause with %s' %
container_uuid)
return backend_api.container_unpause(container_uuid)
@ -167,6 +182,9 @@ class UnpauseController(object):
class LogsController(object):
@wsme_pecan.wsexpose(wtypes.text, wtypes.text)
def _default(self, container_uuid, *remainder):
if pecan.request.method != 'GET':
pecan.abort(405, ('HTTP method %s is not allowed'
% pecan.request.method))
LOG.debug('Calling backend_api.container_logs with %s' %
container_uuid)
return backend_api.container_logs(container_uuid)
@ -175,6 +193,9 @@ class LogsController(object):
class ExecuteController(object):
@wsme_pecan.wsexpose(wtypes.text, wtypes.text, wtypes.text)
def _default(self, container_uuid, command, *remainder):
if pecan.request.method != 'PUT':
pecan.abort(405, ('HTTP method %s is not allowed'
% pecan.request.method))
LOG.debug('Calling backend_api.container_execute with %s command %s'
% (container_uuid, command))
return backend_api.container_execute(container_uuid, command)

View File

@ -12,6 +12,7 @@
from magnum.tests.db import base as db_base
from mock import patch
from webtest.app import AppError
class TestContainerController(db_base.DbTestCase):
@ -72,12 +73,25 @@ class TestContainerController(db_base.DbTestCase):
# Execute some actions
actions = ['start', 'stop', 'pause', 'unpause',
'reboot', 'logs']
'reboot']
for action in actions:
response = self.app.put('/v1/containers/%s/%s' % (c.get('uuid'),
action))
self.assertEqual(response.status_int, 200)
# Only PUT should work, others like GET should fail
self.assertRaises(AppError, self.app.get,
('/v1/containers/%s/%s' %
(c.get('uuid'), action)))
# Fetch the logs
response = self.app.get('/v1/containers/%s/logs' % c.get('uuid'))
self.assertEqual(response.status_int, 200)
# Fetch the logs should fail with put
self.assertRaises(AppError, self.app.put,
('/v1/containers/%s/logs' % c.get('uuid')))
# Execute command in docker container
response = self.app.put('/v1/containers/%s/%s' % (c.get('uuid'),
'execute'), {'command': 'ls'})