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.
:type messages: list
"""
cli = client.Client(URL)
cli = client.Client(URL, version=1.1)
queue = cli.queue(queue_name)
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': {
'ref': 'pools/{pool_name}',
'method': 'DELETE',
@ -283,7 +303,29 @@ V1_1.schema.update({
'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_set_metadata']

View File

@ -140,6 +140,24 @@ class Client(object):
"""
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)
def flavor(self, ref, **kwargs):
"""Returns a flavor instance
@ -152,6 +170,25 @@ class Client(object):
"""
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):
"""Gets the health status of Zaqar server."""
req, trans = self._request_and_transport()

View File

@ -451,6 +451,50 @@ def pool_create(transport, request, pool_name, pool_data):
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):
"""Deletes the pool `pool_name`
@ -505,6 +549,50 @@ def flavor_get(transport, request, flavor_name, callback=None):
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):
"""Deletes the flavor `name`

View File

@ -51,6 +51,17 @@ class Flavor(object):
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):
req, trans = self.client._request_and_transport()
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)
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):
req, trans = self.client._request_and_transport()
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 mock
from zaqarclient.queues.v1 import iterator
from zaqarclient.tests.queues import base
from zaqarclient.transport import errors
from zaqarclient.transport import response
@ -58,6 +59,41 @@ class QueuesV1_1FlavorUnitTest(base.QueuesTestBase):
self.assertEqual(flavor.name, 'test')
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):
flavor_data = {'pool': 'stomach'}
@ -84,33 +120,72 @@ class QueuesV1_1FlavorFunctionalTest(base.QueuesTestBase):
version = 1.1
def test_flavor_create(self):
pool_data = {'uri': 'sqlite://',
pool_data = {'uri': 'mongodb://127.0.0.1:27017',
'weight': 10,
'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('tasty', **flavor_data)
self.addCleanup(flavor.delete)
self.assertEqual(flavor.name, 'tasty')
self.assertEqual(flavor.pool, 'us')
def test_flavor_get(self):
pool_data = {'weight': 10,
'group': 'us',
'uri': 'sqlite://'}
'uri': 'mongodb://127.0.0.1:27017'}
self.client.pool('stomach', **pool_data)
pool = self.client.pool('stomach', **pool_data)
self.addCleanup(pool.delete)
flavor_data = {'pool': 'us'}
self.client.flavor('tasty', **flavor_data)
flavor = self.client.flavor('tasty')
self.addCleanup(flavor.delete)
self.assertEqual(flavor.name, 'tasty')
self.assertEqual(flavor.pool, 'us')
def test_flavor_delete(self):
pool_data = {'uri': 'sqlite://',
def test_flavor_update(self):
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,
'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 = self.client.flavor('tasty', **flavor_data)

View File

@ -16,6 +16,7 @@
import json
import mock
from zaqarclient.queues.v1 import iterator
from zaqarclient.tests.queues import base
from zaqarclient.transport import errors
from zaqarclient.transport import response
@ -58,6 +59,48 @@ class QueuesV1PoolUnitTest(base.QueuesTestBase):
self.assertEqual(pool.name, 'test')
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):
pool_data = {'weight': 10,
'uri': 'sqlite://',
@ -84,25 +127,48 @@ class QueuesV1PoolFunctionalTest(base.QueuesTestBase):
def test_pool_get(self):
pool_data = {'weight': 10,
'uri': 'sqlite://'}
'uri': 'mongodb://127.0.0.1:27017'}
self.client.pool('test', **pool_data)
pool = self.client.pool('test')
self.assertEqual(pool.name, 'test')
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):
pool_data = {'weight': 10,
'uri': 'sqlite://'}
'uri': 'mongodb://127.0.0.1:27017'}
pool = self.client.pool('test', **pool_data)
self.addCleanup(pool.delete)
self.assertEqual(pool.name, 'test')
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):
pool_data = {'weight': 10,
'uri': 'sqlite://'}
'uri': 'mongodb://127.0.0.1:27017'}
pool = self.client.pool('test', **pool_data)
pool.delete()