Added support to pools and flavors

Python-zaqarclient had missing features for v1.1 which involved pools and flavors that
needed to be added.

I added support to pools by adding a 'pool_update' and a 'pool_list' function,
and add support to flavors by writing a 'flavor_update' and a 'flavor_list'
function.

Change-Id: I640d17c64be6448283c53ae0dbea6543484ff7a4
Depends-on: I36445838f532e9f282a4f839a0f583257c1f13d9
Partially-implements: # blueprint api-v1.1
This commit is contained in:
dynarro
2015-06-11 17:23:54 +02:00
parent 09de9ee381
commit e9a8d01cf8
8 changed files with 341 additions and 11 deletions

View File

@@ -28,7 +28,7 @@ def create_post_delete(queue_name, messages):
:params messages: Messages to post. :params messages: Messages to post.
:type messages: list :type messages: list
""" """
cli = client.Client(URL) cli = client.Client(URL, version=1.1)
queue = cli.queue(queue_name) queue = cli.queue(queue_name)
queue.post(messages) queue.post(messages)

View File

@@ -172,6 +172,26 @@ class V1(api.Api):
} }
}, },
'pool_update': {
'ref': 'pools/{pool_name}',
'method': 'PATCH',
'required': ['pool_name'],
'properties': {
'pool_name': {'type': 'string'}
}
},
'pool_list': {
'ref': 'pools',
'method': 'GET',
'properties': {
'pool_name': {'type': 'string'},
'marker': {'type': 'string'},
'limit': {'type': 'integer'},
'detailed': {'type': 'boolean'}
}
},
'pool_delete': { 'pool_delete': {
'ref': 'pools/{pool_name}', 'ref': 'pools/{pool_name}',
'method': 'DELETE', 'method': 'DELETE',
@@ -283,7 +303,29 @@ V1_1.schema.update({
'pop': {'type': 'integer'}, 'pop': {'type': 'integer'},
} }
}, },
'flavor_update': {
'ref': 'flavors/{flavor_name}',
'method': 'PATCH',
'required': ['flavor_name'],
'properties': {
'flavor_name': {'type': 'string'}
}
},
'flavor_list': {
'ref': 'flavors',
'method': 'GET',
'properties': {
'flavor_name': {'type': 'string'},
'marker': {'type': 'string'},
'limit': {'type': 'integer'},
'detailed': {'type': 'boolean'}
}
},
}) })
del V1_1.schema['queue_get_metadata'] del V1_1.schema['queue_get_metadata']
del V1_1.schema['queue_set_metadata'] del V1_1.schema['queue_set_metadata']

View File

@@ -140,6 +140,24 @@ class Client(object):
""" """
return pool.Pool(self, ref, **kwargs) return pool.Pool(self, ref, **kwargs)
def pools(self, **params):
"""Gets a list of pools from the server
:param params: Filters to use for getting pools
:type params: **kwargs dict.
:returns: A list of pools
:rtype: `list`
"""
req, trans = self._request_and_transport()
pool_list = core.pool_list(trans, req, **params)
return iterator._Iterator(self,
pool_list,
'pools',
pool.create_object(self))
@decorators.version(min_version=1.1) @decorators.version(min_version=1.1)
def flavor(self, ref, **kwargs): def flavor(self, ref, **kwargs):
"""Returns a flavor instance """Returns a flavor instance
@@ -152,6 +170,25 @@ class Client(object):
""" """
return flavor.Flavor(self, ref, **kwargs) return flavor.Flavor(self, ref, **kwargs)
@decorators.version(min_version=1.1)
def flavors(self, **params):
"""Gets a list of flavors from the server
:param params: Filters to use for getting flavors
:type params: **kwargs dict.
:returns: A list of flavors
:rtype: `list`
"""
req, trans = self._request_and_transport()
flavor_list = core.flavor_list(trans, req, **params)
return iterator._Iterator(self,
flavor_list,
'flavors',
flavor.create_object(self))
def health(self): def health(self):
"""Gets the health status of Zaqar server.""" """Gets the health status of Zaqar server."""
req, trans = self._request_and_transport() req, trans = self._request_and_transport()

View File

@@ -451,6 +451,50 @@ def pool_create(transport, request, pool_name, pool_data):
transport.send(request) transport.send(request)
def pool_update(transport, request, pool_name, pool_data):
"""Updates the pool `pool_name`
:param transport: Transport instance to use
:type transport: `transport.base.Transport`
:param request: Request instance ready to be sent.
:type request: `transport.request.Request`
:param pool_name: Pool reference name.
:type pool_name: `six.text_type`
:param pool_data: Pool's properties, i.e: weight, uri, options.
:type pool_data: `dict`
"""
request.operation = 'pool_update'
request.params['pool_name'] = pool_name
request.content = json.dumps(pool_data)
resp = transport.send(request)
return resp.deserialized_content
def pool_list(transport, request, **kwargs):
"""Gets a list of pools
:param transport: Transport instance to use
:type transport: `transport.base.Transport`
:param request: Request instance ready to be sent.
:type request: `transport.request.Request`
:param kwargs: Optional arguments for this operation.
- marker: Where to start getting pools from.
- limit: Maximum number of pools to get.
"""
request.operation = 'pool_list'
request.params.update(kwargs)
resp = transport.send(request)
if not resp.content:
return {'links': [], 'pools': []}
return resp.deserialized_content
def pool_delete(transport, request, pool_name): def pool_delete(transport, request, pool_name):
"""Deletes the pool `pool_name` """Deletes the pool `pool_name`
@@ -505,6 +549,50 @@ def flavor_get(transport, request, flavor_name, callback=None):
return resp.deserialized_content return resp.deserialized_content
def flavor_update(transport, request, flavor_name, flavor_data):
"""Updates the flavor `flavor_name`
:param transport: Transport instance to use
:type transport: `transport.base.Transport`
:param request: Request instance ready to be sent.
:type request: `transport.request.Request`
:param flavor_name: Flavor reference name.
:type flavor_name: `six.text_type`
:param flavor_data: Flavor's properties, i.e: pool, capabilities.
:type flavor_data: `dict`
"""
request.operation = 'flavor_update'
request.params['flavor_name'] = flavor_name
request.content = json.dumps(flavor_data)
resp = transport.send(request)
return resp.deserialized_content
def flavor_list(transport, request, **kwargs):
"""Gets a list of flavors
:param transport: Transport instance to use
:type transport: `transport.base.Transport`
:param request: Request instance ready to be sent.
:type request: `transport.request.Request`
:param kwargs: Optional arguments for this operation.
- marker: Where to start getting flavors from.
- limit: Maximum number of flavors to get.
"""
request.operation = 'flavor_list'
request.params.update(kwargs)
resp = transport.send(request)
if not resp.content:
return {'links': [], 'flavors': []}
return resp.deserialized_content
def flavor_delete(transport, request, name): def flavor_delete(transport, request, name):
"""Deletes the flavor `name` """Deletes the flavor `name`

View File

@@ -51,6 +51,17 @@ class Flavor(object):
core.flavor_create(trans, req, self.name, data) core.flavor_create(trans, req, self.name, data)
def update(self, flavor_data):
req, trans = self.client._request_and_transport()
core.flavor_update(trans, req, self.name, flavor_data)
for key, value in flavor_data.items():
setattr(self, key, value)
def delete(self): def delete(self):
req, trans = self.client._request_and_transport() req, trans = self.client._request_and_transport()
core.flavor_delete(trans, req, self.name) core.flavor_delete(trans, req, self.name)
def create_object(parent):
return lambda args: Flavor(parent, args["name"], auto_create=False)

View File

@@ -60,6 +60,17 @@ class Pool(object):
core.pool_create(trans, req, self.name, data) core.pool_create(trans, req, self.name, data)
def update(self, pool_data):
req, trans = self.client._request_and_transport()
core.pool_update(trans, req, self.name, pool_data)
for key, value in pool_data.items():
setattr(self, key, value)
def delete(self): def delete(self):
req, trans = self.client._request_and_transport() req, trans = self.client._request_and_transport()
core.pool_delete(trans, req, self.name) core.pool_delete(trans, req, self.name)
def create_object(parent):
return lambda args: Pool(parent, args["name"], auto_create=False)

View File

@@ -16,6 +16,7 @@
import json import json
import mock import mock
from zaqarclient.queues.v1 import iterator
from zaqarclient.tests.queues import base from zaqarclient.tests.queues import base
from zaqarclient.transport import errors from zaqarclient.transport import errors
from zaqarclient.transport import response from zaqarclient.transport import response
@@ -58,6 +59,41 @@ class QueuesV1_1FlavorUnitTest(base.QueuesTestBase):
self.assertEqual(flavor.name, 'test') self.assertEqual(flavor.name, 'test')
self.assertEqual(flavor.pool, 'stomach') self.assertEqual(flavor.pool, 'stomach')
def test_flavor_update(self):
flavor_data = {'pool': 'stomach'}
updated_data = {'pool': 'belly'}
with mock.patch.object(self.transport, 'send',
autospec=True) as send_method:
resp = response.Response(None, json.dumps(updated_data))
send_method.return_value = resp
flavor = self.client.flavor('tasty', **flavor_data)
flavor.update({'pool': 'belly'})
self.assertEqual('belly', flavor.pool)
def test_flavor_list(self):
returned = {
'links': [{
'rel': 'next',
'href': '/v1.1/flavors?marker=6244-244224-783'
}],
'flavors': [{
'name': 'tasty',
'pool': 'stomach'
}]
}
with mock.patch.object(self.transport, 'send',
autospec=True) as send_method:
resp = response.Response(None, json.dumps(returned))
send_method.return_value = resp
flavor_var = self.client.flavors(limit=1)
self.assertIsInstance(flavor_var, iterator._Iterator)
self.assertEqual(1, len(list(flavor_var)))
def test_flavor_delete(self): def test_flavor_delete(self):
flavor_data = {'pool': 'stomach'} flavor_data = {'pool': 'stomach'}
@@ -84,33 +120,72 @@ class QueuesV1_1FlavorFunctionalTest(base.QueuesTestBase):
version = 1.1 version = 1.1
def test_flavor_create(self): def test_flavor_create(self):
pool_data = {'uri': 'sqlite://', pool_data = {'uri': 'mongodb://127.0.0.1:27017',
'weight': 10, 'weight': 10,
'group': 'us'} 'group': 'us'}
self.client.pool('stomach', **pool_data) pool = self.client.pool('stomach', **pool_data)
self.addCleanup(pool.delete)
flavor_data = {'pool': 'us'} flavor_data = {'pool': 'us'}
flavor = self.client.flavor('tasty', **flavor_data) flavor = self.client.flavor('tasty', **flavor_data)
self.addCleanup(flavor.delete)
self.assertEqual(flavor.name, 'tasty') self.assertEqual(flavor.name, 'tasty')
self.assertEqual(flavor.pool, 'us') self.assertEqual(flavor.pool, 'us')
def test_flavor_get(self): def test_flavor_get(self):
pool_data = {'weight': 10, pool_data = {'weight': 10,
'group': 'us', 'group': 'us',
'uri': 'sqlite://'} 'uri': 'mongodb://127.0.0.1:27017'}
self.client.pool('stomach', **pool_data) self.client.pool('stomach', **pool_data)
pool = self.client.pool('stomach', **pool_data)
self.addCleanup(pool.delete)
flavor_data = {'pool': 'us'} flavor_data = {'pool': 'us'}
self.client.flavor('tasty', **flavor_data) self.client.flavor('tasty', **flavor_data)
flavor = self.client.flavor('tasty') flavor = self.client.flavor('tasty')
self.addCleanup(flavor.delete)
self.assertEqual(flavor.name, 'tasty') self.assertEqual(flavor.name, 'tasty')
self.assertEqual(flavor.pool, 'us') self.assertEqual(flavor.pool, 'us')
def test_flavor_delete(self): def test_flavor_update(self):
pool_data = {'uri': 'sqlite://', pool_data = {'weight': 10,
'uri': 'mongodb://127.0.0.1:27017',
'group': 'us'}
pool = self.client.pool('stomach', **pool_data)
self.addCleanup(pool.delete)
flavor_data = {'pool': 'us'}
flavor = self.client.flavor('tasty', **flavor_data)
self.addCleanup(flavor.delete)
flavor.update({'pool': 'belly'})
self.assertEqual('belly', flavor.pool)
def test_flavor_list(self):
pool_data = {'uri': 'mongodb://127.0.0.1:27017',
'weight': 10, 'weight': 10,
'group': 'us'} 'group': 'us'}
self.client.pool('stomach', **pool_data)
pool = self.client.pool('stomach', **pool_data)
self.addCleanup(pool.delete)
flavor_data = {'pool': 'us'}
flavor = self.client.flavor("test_flavor", **flavor_data)
self.addCleanup(flavor.delete)
flavors = self.client.flavors()
self.assertTrue(isinstance(flavors, iterator._Iterator))
self.assertEqual(1, len(list(flavors)))
def test_flavor_delete(self):
pool_data = {'uri': 'mongodb://127.0.0.1:27017',
'weight': 10,
'group': 'us'}
pool = self.client.pool('stomach', **pool_data)
self.addCleanup(pool.delete)
flavor_data = {'pool': 'us'} flavor_data = {'pool': 'us'}
flavor = self.client.flavor('tasty', **flavor_data) flavor = self.client.flavor('tasty', **flavor_data)

View File

@@ -16,6 +16,7 @@
import json import json
import mock import mock
from zaqarclient.queues.v1 import iterator
from zaqarclient.tests.queues import base from zaqarclient.tests.queues import base
from zaqarclient.transport import errors from zaqarclient.transport import errors
from zaqarclient.transport import response from zaqarclient.transport import response
@@ -58,6 +59,48 @@ class QueuesV1PoolUnitTest(base.QueuesTestBase):
self.assertEqual(pool.name, 'test') self.assertEqual(pool.name, 'test')
self.assertEqual(pool.weight, 10) self.assertEqual(pool.weight, 10)
def test_pool_update(self):
pool_data = {'weight': 10,
'uri': 'sqlite://',
'options': {}}
updated_data = {'weight': 20,
'uri': 'sqlite://',
'options': {}}
with mock.patch.object(self.transport, 'send',
autospec=True) as send_method:
resp = response.Response(None, json.dumps(updated_data))
send_method.return_value = resp
pool = self.client.pool('test', **pool_data)
pool.update({'weight': 20})
self.assertEqual(20, pool.weight)
def test_pool_list(self):
returned = {
'links': [{
'rel': 'next',
'href': '/v1.1/pools?marker=6244-244224-783'
}],
'pools': [{
'name': 'stomach',
'weight': 20,
'uri': 'sqlite://',
'options': {}
}]
}
with mock.patch.object(self.transport, 'send',
autospec=True) as send_method:
resp = response.Response(None, json.dumps(returned))
send_method.return_value = resp
pools_var = self.client.pools(limit=1)
self.assertIsInstance(pools_var, iterator._Iterator)
self.assertEqual(1, len(list(pools_var)))
def test_pool_delete(self): def test_pool_delete(self):
pool_data = {'weight': 10, pool_data = {'weight': 10,
'uri': 'sqlite://', 'uri': 'sqlite://',
@@ -84,25 +127,48 @@ class QueuesV1PoolFunctionalTest(base.QueuesTestBase):
def test_pool_get(self): def test_pool_get(self):
pool_data = {'weight': 10, pool_data = {'weight': 10,
'uri': 'sqlite://'} 'uri': 'mongodb://127.0.0.1:27017'}
self.client.pool('test', **pool_data) self.client.pool('test', **pool_data)
pool = self.client.pool('test') pool = self.client.pool('test')
self.assertEqual(pool.name, 'test') self.assertEqual(pool.name, 'test')
self.assertEqual(pool.weight, 10) self.assertEqual(pool.weight, 10)
self.assertEqual(pool.uri, 'sqlite://') self.assertEqual(pool.uri, 'mongodb://127.0.0.1:27017')
def test_pool_create(self): def test_pool_create(self):
pool_data = {'weight': 10, pool_data = {'weight': 10,
'uri': 'sqlite://'} 'uri': 'mongodb://127.0.0.1:27017'}
pool = self.client.pool('test', **pool_data) pool = self.client.pool('test', **pool_data)
self.addCleanup(pool.delete)
self.assertEqual(pool.name, 'test') self.assertEqual(pool.name, 'test')
self.assertEqual(pool.weight, 10) self.assertEqual(pool.weight, 10)
def test_pool_update(self):
pool_data = {'weight': 10,
'uri': 'mongodb://127.0.0.1:27017',
'options': {}}
pool = self.client.pool('test', **pool_data)
self.addCleanup(pool.delete)
pool.update({'weight': 20})
self.assertEqual(20, pool.weight)
def test_pool_list(self):
pool_data = {'weight': 10,
'uri': 'mongodb://127.0.0.1:27017',
'options': {}}
pool = self.client.pool('test', **pool_data)
self.addCleanup(pool.delete)
pools = self.client.pools()
self.assertTrue(isinstance(pools, iterator._Iterator))
self.assertEqual(1, len(list(pools)))
def test_pool_delete(self): def test_pool_delete(self):
pool_data = {'weight': 10, pool_data = {'weight': 10,
'uri': 'sqlite://'} 'uri': 'mongodb://127.0.0.1:27017'}
pool = self.client.pool('test', **pool_data) pool = self.client.pool('test', **pool_data)
pool.delete() pool.delete()