Introduce Base for Octavia (load balancing)

Change-Id: I3aa5b8af9e5f6dfbd3e71645fc7324e19933afef
This commit is contained in:
Ankur Gupta 2017-02-02 14:42:24 -06:00 committed by Nakul Dahiwade
parent 7822e33622
commit a4d75498b4
18 changed files with 455 additions and 0 deletions

View File

@ -0,0 +1,22 @@
Load Balancer v2 API
====================
.. automodule:: openstack.load_balancer.v2._proxy
The LoadBalancer Class
----------------------
The load_balancer high-level interface is available through the
``load_balancer`` member of a :class:`~openstack.connection.Connection` object.
The ``load_balancer`` member will only be added if the service is detected.
Load Balancer Operations
^^^^^^^^^^^^^^^^^^^^^^^^
.. autoclass:: openstack.load_balancer.v2._proxy.Proxy
.. automethod:: openstack.load_balancer.v2._proxy.Proxy.create_load_balancer
.. automethod:: openstack.load_balancer.v2._proxy.Proxy.get_load_balancer
.. automethod:: openstack.load_balancer.v2._proxy.Proxy.load_balancers
.. automethod:: openstack.load_balancer.v2._proxy.Proxy.delete_load_balancer
.. automethod:: openstack.load_balancer.v2._proxy.Proxy.find_load_balancer

View File

View File

@ -0,0 +1,26 @@
# 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 openstack import service_filter
class LoadBalancerService(service_filter.ServiceFilter):
"""The load balancer service."""
valid_versions = [service_filter.ValidVersion('v2')]
def __init__(self, version=None):
"""Create a load balancer service."""
super(LoadBalancerService, self).__init__(
service_type='load_balancer',
version=version
)

View File

View File

@ -0,0 +1,82 @@
# 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 openstack.load_balancer.v2 import load_balancer as _lb
from openstack import proxy2
class Proxy(proxy2.BaseProxy):
def create_load_balancer(self, **attrs):
"""Create a new load balancer from attributes
:param dict attrs: Keyword arguments which will be used to create
a :class:`~openstack.load_balancer.v2.
load_balancer.LoadBalancer`,
comprised of the properties on the
LoadBalancer class.
:returns: The results of load balancer creation
:rtype: :class:`~openstack.load_balancer.v2.load_balancer.LoadBalancer`
"""
return self._create(_lb.LoadBalancer, **attrs)
def get_load_balancer(self, *attrs):
"""Get a load balancer
:param load_balancer: The value can be the name of a load balancer
or :class:`~openstack.load_balancer.v2.load_balancer.LoadBalancer`
instance.
:returns: One
:class:`~openstack.load_balancer.v2.load_balancer.LoadBalancer`
"""
return self._get(_lb.LoadBalancer, *attrs)
def load_balancers(self, **query):
"""Retrieve a generator of load balancers
:returns: A generator of load balancer instances
"""
return self._list(_lb.LoadBalancer, paginated=True, **query)
def delete_load_balancer(self, load_balancer, ignore_missing=True):
"""Delete a load balancer
:param load_balancer: The load_balancer can be either the name or a
:class:`~openstack.load_balancer.v2.load_balancer.LoadBalancer`
instance
:param bool ignore_missing: When set to ``False``
:class:`~openstack.exceptions.ResourceNotFound` will be raised when
the load balancer does not exist.
When set to ``True``, no exception will be set when attempting to
delete a nonexistent load balancer.
:returns: ``None``
"""
return self._delete(_lb.LoadBalancer, load_balancer,
ignore_missing=ignore_missing)
def find_load_balancer(self, name_or_id, ignore_missing=True):
"""Find a single load balancer
:param name_or_id: The name or ID of a load balancer
:param bool ignore_missing: When set to ``False``
:class:`~openstack.exceptions.ResourceNotFound` will be raised
when the load balancer does not exist.
When set to ``True``, no exception will be set when attempting
to delete a nonexistent load balancer.
:returns: ``None``
"""
return self._find(_lb.LoadBalancer, name_or_id,
ignore_missing=ignore_missing)

View File

@ -0,0 +1,55 @@
# 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 openstack.load_balancer import load_balancer_service as lb_service
from openstack import resource2 as resource
class LoadBalancer(resource.Resource):
resource_key = 'loadbalancer'
resources_key = 'loadbalancers'
base_path = '/loadbalancers'
service = lb_service.LoadBalancerService()
# capabilities
allow_create = True
allow_list = True
allow_get = True
allow_delete = True
#: Properties
#: Timestamp when the load balancer was created
created_at = resource.Body('created_at')
#: The load balancer description
description = resource.Body('description')
#: The administrative state of the load balancer *Type: bool*
is_admin_state_up = resource.Body('admin_state_up', type=bool)
#: List of listeners associated with this load balancer
listeners = resource.Body('listeners', type=list)
#: The load balancer name
name = resource.Body('name')
#: Operating status of the load balancer
operating_status = resource.Body('operating_status')
#: List of pools associated with this load balancer
pools = resource.Body('pools', type=list)
#: The ID of the project this load balancer is associated with.
project_id = resource.Body('project_id')
#: The provisioning status of this load balancer
provisioning_status = resource.Body('provisioning_status')
#: VIP address of load balancer
vip_address = resource.Body('vip_address')
#: VIP port ID
vip_port_id = resource.Body('vip_port_id')
#: VIP subnet ID
vip_subnet_id = resource.Body('vip_subnet_id')
#: Timestamp when the load balancer was last updated
updated_at = resource.Body('updated_at')

View File

@ -0,0 +1,30 @@
# 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 openstack.load_balancer import load_balancer_service as lb_service
from openstack import resource2 as resource
class Version(resource.Resource):
resource_key = 'version'
resources_key = 'versions'
base_path = '/'
service = lb_service.LoadBalancerService(
version=lb_service.LoadBalancerService.UNVERSIONED
)
# capabilities
allow_list = True
# Properties
links = resource.Body('links')
status = resource.Body('status')

View File

@ -64,6 +64,7 @@ from openstack import exceptions
from openstack.identity import identity_service
from openstack.image import image_service
from openstack.key_manager import key_manager_service
from openstack.load_balancer import load_balancer_service as lb_service
from openstack.message import message_service
from openstack import module_loader
from openstack.network import network_service
@ -102,6 +103,7 @@ class Profile(object):
self._add_service(identity_service.IdentityService(version="v3"))
self._add_service(image_service.ImageService(version="v2"))
self._add_service(key_manager_service.KeyManagerService(version="v1"))
self._add_service(lb_service.LoadBalancerService(version="v2"))
self._add_service(message_service.MessageService(version="v1"))
self._add_service(network_service.NetworkService(version="v2"))
self._add_service(

View File

@ -0,0 +1,52 @@
# 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 uuid
from openstack.load_balancer.v2 import load_balancer
from openstack.tests.functional import base
class TestLoadBalancer(base.BaseFunctionalTest):
NAME = uuid.uuid4().hex
ID = None
VIP_SUBNET_ID = uuid.uuid4().hex
@classmethod
def setUpClass(cls):
super(TestLoadBalancer, cls).setUpClass()
test_lb = cls.conn.load_balancer.create_load_balancer(
name=cls.NAME, vip_subnet_id=cls.VIP_SUBNET_ID)
assert isinstance(test_lb, load_balancer.LoadBalancer)
cls.assertIs(cls.NAME, test_lb.name)
cls.ID = test_lb.id
@classmethod
def tearDownClass(cls):
test_lb = cls.conn.load_balancer.delete_load_balancer(
cls.ID, ignore_missing=False)
cls.assertIs(None, test_lb)
def test_find(self):
test_lb = self.conn.load_balancer.find_load_balancer(self.NAME)
self.assertEqual(self.ID, test_lb.id)
def test_get(self):
test_lb = self.conn.load_balancer.get_load_balancer(self.ID)
self.assertEqual(self.NAME, test_lb.name)
self.assertEqual(self.ID, test_lb.id)
self.assertEqual(self.VIP_SUBNET_ID, test_lb.vip_subnet_id)
def test_list(self):
names = [lb.name for lb in self.conn.load_balancer.load_balancers()]
self.assertIn(self.NAME, names)

View File

@ -0,0 +1,69 @@
# 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 testtools
from openstack.load_balancer.v2 import load_balancer
IDENTIFIER = 'IDENTIFIER'
EXAMPLE = {
'admin_state_up': True,
'created_at': '3',
'description': 'fake_description',
'id': IDENTIFIER,
'listeners': [{'id', '4'}],
'name': 'test_load_balancer',
'operating_status': '6',
'provisioning_status': '7',
'project_id': '8',
'vip_address': '9',
'vip_subnet_id': '10',
'vip_port_id': '11',
'pools': [{'id', '13'}],
}
class TestLoadBalancer(testtools.TestCase):
def test_basic(self):
test_load_balancer = load_balancer.LoadBalancer()
self.assertEqual('loadbalancer', test_load_balancer.resource_key)
self.assertEqual('loadbalancers', test_load_balancer.resources_key)
self.assertEqual('/loadbalancers', test_load_balancer.base_path)
self.assertEqual('load_balancer',
test_load_balancer.service.service_type)
self.assertTrue(test_load_balancer.allow_create)
self.assertTrue(test_load_balancer.allow_get)
self.assertTrue(test_load_balancer.allow_delete)
self.assertTrue(test_load_balancer.allow_list)
def test_make_it(self):
test_load_balancer = load_balancer.LoadBalancer(**EXAMPLE)
self.assertTrue(test_load_balancer.is_admin_state_up)
self.assertEqual(EXAMPLE['created_at'], test_load_balancer.created_at),
self.assertEqual(EXAMPLE['description'],
test_load_balancer.description)
self.assertEqual(EXAMPLE['id'], test_load_balancer.id)
self.assertEqual(EXAMPLE['listeners'], test_load_balancer.listeners)
self.assertEqual(EXAMPLE['name'], test_load_balancer.name)
self.assertEqual(EXAMPLE['operating_status'],
test_load_balancer.operating_status)
self.assertEqual(EXAMPLE['provisioning_status'],
test_load_balancer.provisioning_status)
self.assertEqual(EXAMPLE['project_id'], test_load_balancer.project_id)
self.assertEqual(EXAMPLE['vip_address'],
test_load_balancer.vip_address)
self.assertEqual(EXAMPLE['vip_subnet_id'],
test_load_balancer.vip_subnet_id)
self.assertEqual(EXAMPLE['vip_port_id'],
test_load_balancer.vip_port_id)
self.assertEqual(EXAMPLE['pools'], test_load_balancer.pools)

View File

@ -0,0 +1,28 @@
# 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 testtools
from openstack.load_balancer import load_balancer_service as lb_service
class TestLoadBalancingService(testtools.TestCase):
def test_service(self):
sot = lb_service.LoadBalancerService()
self.assertEqual('load_balancer', sot.service_type)
self.assertEqual('public', sot.interface)
self.assertIsNone(sot.region)
self.assertIsNone(sot.service_name)
self.assertEqual(1, len(sot.valid_versions))
self.assertEqual('v2', sot.valid_versions[0].module)
self.assertEqual('v2', sot.valid_versions[0].path)

View File

@ -0,0 +1,42 @@
# 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 openstack.load_balancer.v2 import _proxy
from openstack.load_balancer.v2 import load_balancer as lb
from openstack.tests.unit import test_proxy_base2
class TestLoadBalancerProxy(test_proxy_base2.TestProxyBase):
def setUp(self):
super(TestLoadBalancerProxy, self).setUp()
self.proxy = _proxy.Proxy(self.session)
def test_load_balancers(self):
self.verify_list(self.proxy.load_balancers,
lb.LoadBalancer,
paginated=True)
def test_load_balancer_get(self):
self.verify_get(self.proxy.get_load_balancer,
lb.LoadBalancer)
def test_load_balancer_create(self):
self.verify_create(self.proxy.create_load_balancer,
lb.LoadBalancer)
def test_load_balancer_delete(self):
self.verify_delete(self.proxy.delete_load_balancer,
lb.LoadBalancer, True)
def test_load_balancer_find(self):
self.verify_find(self.proxy.find_load_balancer,
lb.LoadBalancer)

View File

@ -0,0 +1,43 @@
# 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 testtools
from openstack.load_balancer import version
IDENTIFIER = 'IDENTIFIER'
EXAMPLE = {
'id': IDENTIFIER,
'links': '2',
'status': '3',
}
class TestVersion(testtools.TestCase):
def test_basic(self):
sot = version.Version()
self.assertEqual('version', sot.resource_key)
self.assertEqual('versions', sot.resources_key)
self.assertEqual('/', sot.base_path)
self.assertEqual('load_balancer', sot.service.service_type)
self.assertFalse(sot.allow_create)
self.assertFalse(sot.allow_get)
self.assertFalse(sot.allow_update)
self.assertFalse(sot.allow_delete)
self.assertTrue(sot.allow_list)
def test_make_it(self):
sot = version.Version(**EXAMPLE)
self.assertEqual(EXAMPLE['id'], sot.id)
self.assertEqual(EXAMPLE['links'], sot.links)
self.assertEqual(EXAMPLE['status'], sot.status)

View File

@ -147,6 +147,8 @@ class TestConnection(base.TestCase):
conn.network.__class__.__module__)
self.assertEqual('openstack.object_store.v1._proxy',
conn.object_store.__class__.__module__)
self.assertEqual('openstack.load_balancer.v2._proxy',
conn.load_balancer.__class__.__module__)
self.assertEqual('openstack.orchestration.v1._proxy',
conn.orchestration.__class__.__module__)
self.assertEqual('openstack.telemetry.v2._proxy',

View File

@ -27,6 +27,7 @@ class TestProfile(base.TestCase):
'identity',
'image',
'key-manager',
'load_balancer',
'messaging',
'metering',
'network',
@ -45,6 +46,7 @@ class TestProfile(base.TestCase):
self.assertEqual('v1', prof.get_filter('database').version)
self.assertEqual('v3', prof.get_filter('identity').version)
self.assertEqual('v2', prof.get_filter('image').version)
self.assertEqual('v2', prof.get_filter('load_balancer').version)
self.assertEqual('v2', prof.get_filter('network').version)
self.assertEqual('v1', prof.get_filter('object-store').version)
self.assertEqual('v1', prof.get_filter('orchestration').version)