Merge "Neutron LBaaS: Pools Client"

This commit is contained in:
Jenkins 2014-08-15 15:30:05 +00:00 committed by Gerrit Code Review
commit 6116024196
2 changed files with 309 additions and 0 deletions

View File

@ -0,0 +1,158 @@
"""
Copyright 2014 Rackspace
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.
"""
from cloudcafe.networking.lbaas.common.client import BaseLoadBalancersClient
from cloudcafe.networking.lbaas.lbaas_api.models.request.pool import \
CreatePool, UpdatePool
from cloudcafe.networking.lbaas.lbaas_api.models.response.pool import \
Pool, Pools
class PoolsClient(BaseLoadBalancersClient):
"""
Pools Client
@summary: Pools are groupings of backend member servers to which client
requests are forwarded.
"""
_POOLS_URL = "{base_url}/pools"
_POOL_URL = "{base_url}/pools/{pool_id}"
def create_pool(self, name, tenant_id, protocol, lb_algorithm,
description=None, session_persistence=None,
healthmonitor_id=None, admin_state_up=None,
requestslib_kwargs=None):
"""Create Pool
@summary: Creates an instance of a pool given the
provided parameters
@param name: Name of the Pool that will be created
@type name: str
@param tenant_id: Tenant that will own the pool.
@type tenant_id: str
@param protocol: Protocol use to connect to members: HTTP, HTTPS, TCP
@type protocol: str
@param lb_algorithm: round-robin, least-connections, etc. (load
balancing provider dependent, but round-robin must be supported).
@type lb_algorithm: str
@param description: Description of a pool.
@type description: str
@param session_persistence: Session persistence algorithm that should
be used (if any). This is a dictionary that has keys of
"type" and "cookie_name".
Default: {}
@type session_persistence: dict
@param healthmonitor_id: ID of existing health monitor.
Default: null
@type healthmonitor_id: str
@param admin_state_up: Enabled or Disabled
Default: "true"
@type admin_state_up: bool
@return: Response Object containing response code and the
load balancer domain object
@rtype: Requests.response
"""
full_url = self._POOLS_URL.format(base_url=self.url)
pool_request_object = CreatePool(
name=name, tenant_id=tenant_id, protocol=protocol,
lb_algorithm=lb_algorithm, description=description,
session_persistence=session_persistence,
healthmonitor_id=healthmonitor_id, admin_state_up=admin_state_up)
return self.request('POST', full_url,
response_entity_type=Pool,
request_entity=pool_request_object,
requestslib_kwargs=requestslib_kwargs)
def list_pools(self, requestslib_kwargs=None):
"""List Pools
@summary: List all pools configured for the account.
@rtype: Requests.response
@note: This operation does not require a request body.
"""
full_url = self._POOLS_URL.format(base_url=self.url)
return self.request('GET', full_url,
response_entity_type=Pools,
requestslib_kwargs=requestslib_kwargs)
def update_pool(self, pool_id, name=None, description=None,
session_persistence=None, lb_algorithm=None,
healthmonitor_id=None, admin_state_up=None,
requestslib_kwargs=None):
"""Update Pool
@summary: Update the properties of a pool given the
provided parameters
@param name: Name of the Pool that will be created
@type name: str
@param description: Description of a pool.
@type description: str
@param session_persistence: Session persistence algorithm that should
be used (if any). This is a dictionary that has keys of
"type" and "cookie_name".
Default: {}
@type session_persistence: dict
@param lb_algorithm: round-robin, least-connections, etc. (load
balancing provider dependent, but round-robin must be supported).
@type lb_algorithm: str
@param healthmonitor_id: ID of existing health monitor.
Default: null
@type healthmonitor_id: str
@param admin_state_up: Enabled or Disabled
Default: "true"
@type admin_state_up: bool
@return: Response Object containing response code.
@rtype: Requests.response
"""
update_pool = UpdatePool(
name=name, description=description,
session_persistence=session_persistence,
lb_algorithm=lb_algorithm, healthmonitor_id=healthmonitor_id,
admin_state_up=admin_state_up)
full_url = self._POOL_URL.format(base_url=self.url, pool_id=pool_id)
return self.request('PUT', full_url,
request_entity=update_pool,
response_entity_type=Pool,
requestslib_kwargs=requestslib_kwargs)
def get_pool(self, pool_id, requestslib_kwargs=None):
"""Get Pool Details
@summary: List details of the specified pool.
@param pool_id: ID of the pool to get details from.
@type pool_id: str
@return: Response Object containing response code and the
pool domain object.
@rtype: Requests.response
@note: This operation does not require a request body.
"""
full_url = self._POOL_URL.format(base_url=self.url, pool_id=pool_id)
return self.request('GET', full_url,
response_entity_type=Pool,
requestslib_kwargs=requestslib_kwargs)
def delete_pool(self, pool_id, requestslib_kwargs=None):
"""Delete Pool
@summary: Deletes an orphaned pool. Will return an error if pool is
still in use by any listeners. Upon successful deletion,
any child primitives that this pool is using will be detached but
not deleted.
@param pool_id: ID of the pool to delete.
@type pool_id: str
@return: Response Object containing response code.
@rtype: Requests.response
@note: Returns an error if it's still in use by any pools.
"""
full_url = self._POOL_URL.format(base_url=self.url, pool_id=pool_id)
return self.request('DELETE', full_url,
requestslib_kwargs=requestslib_kwargs)

View File

@ -0,0 +1,151 @@
"""
Copyright 2014 Rackspace
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 mock
import unittest
from cloudcafe.networking.lbaas.lbaas_api.clients.pool.client import \
PoolsClient
from cloudcafe.networking.lbaas.lbaas_api.models.request.pool import \
CreatePool, UpdatePool
from cloudcafe.networking.lbaas.lbaas_api.models.response.pool import \
Pool, Pools
class PoolsClientFixture(unittest.TestCase):
"""
@summary: Pool Client Tests
"""
@classmethod
def setUpClass(cls):
super(PoolsClientFixture, cls).setUpClass()
cls.auth_token = "fake_auth_token"
cls.url = "http://fake.url.endpoint"
cls.pool_id = "12345"
cls.name = "Example HTTPS Pool"
cls.description = "Example HTTPS Pool Description"
cls.tenant_id = "352686b7-c4b2-44ec-a458-84239713f685"
cls.protocol = "HTTPS"
cls.lb_algorithm = "ROUND_ROBIN"
cls.healthmonitor_id = "health_monitor_123"
cls.admin_state_up = True
cls.sp_type = "COOKIE"
cls.sp_cookie_name = "session_persistence_cookie"
cls.session_persistence = {"type": cls.sp_type,
"cookie_name": cls.sp_cookie_name}
cls.full_url_pools = (
PoolsClient._POOLS_URL.format(
base_url=cls.url))
cls.full_url_pool = (
PoolsClient._POOL_URL.format(
base_url=cls.url,
pool_id=cls.pool_id))
cls.pools_client = PoolsClient(
url=cls.url,
auth_token=cls.auth_token,
serialize_format=cls.SERIALIZE,
deserialize_format=cls.DESERIALIZE)
class PoolsClientTests(object):
@mock.patch.object(PoolsClient, 'request', autospec=True)
def test_create_pool(self, mock_request):
create_pool_kwargs = (
{'name': self.name,
'tenant_id': self.tenant_id,
'protocol': self.protocol,
'lb_algorithm': self.lb_algorithm,
'description': self.description,
'session_persistence': self.session_persistence,
'healthmonitor_id': self.healthmonitor_id,
'admin_state_up': self.admin_state_up})
self.pools_client.create_pool(**create_pool_kwargs)
create_pool_request = CreatePool(**create_pool_kwargs)
mock_request.assert_called_once_with(
self.pools_client,
'POST',
self.full_url_pools,
request_entity=create_pool_request,
response_entity_type=Pool,
requestslib_kwargs=None)
@mock.patch.object(PoolsClient, 'request', autospec=True)
def test_list_pool(self, mock_request):
self.pools_client.list_pools()
mock_request.assert_called_once_with(
self.pools_client,
'GET',
self.full_url_pools,
response_entity_type=Pools,
requestslib_kwargs=None)
@mock.patch.object(PoolsClient, 'request', autospec=True)
def test_get_pool(self, mock_request):
self.pools_client.get_pool(pool_id=self.pool_id)
mock_request.assert_called_once_with(
self.pools_client,
'GET',
self.full_url_pool,
response_entity_type=Pool,
requestslib_kwargs=None)
@mock.patch.object(PoolsClient, 'request', autospec=True)
def test_update_pool(self, mock_request):
update_pool_kwargs = (
{'name': self.name,
'description': self.description,
'session_persistence': self.session_persistence,
'lb_algorithm': self.lb_algorithm,
'healthmonitor_id': self.healthmonitor_id,
'admin_state_up': self.admin_state_up})
self.pools_client.update_pool(pool_id=self.pool_id,
**update_pool_kwargs)
update_pool_request = UpdatePool(**update_pool_kwargs)
mock_request.assert_called_once_with(
self.pools_client,
'PUT',
self.full_url_pool,
request_entity=update_pool_request,
response_entity_type=Pool,
requestslib_kwargs=None)
@mock.patch.object(PoolsClient, 'request', autospec=True)
def test_delete_pool(self, mock_request):
self.pools_client.delete_pool(pool_id=self.pool_id)
mock_request.assert_called_once_with(self.pools_client,
'DELETE',
self.full_url_pool,
requestslib_kwargs=None)
class PoolsClientTestsXML(PoolsClientFixture, PoolsClientTests):
SERIALIZE = 'xml'
DESERIALIZE = 'xml'
class PoolsClientTestsJSON(PoolsClientFixture, PoolsClientTests):
SERIALIZE = 'json'
DESERIALIZE = 'json'