Merge "Update load_balancer for v2 API"

This commit is contained in:
Jenkins 2017-08-10 21:15:09 +00:00 committed by Gerrit Code Review
commit 4790d09a61
17 changed files with 197 additions and 38 deletions

View File

@ -36,6 +36,7 @@ def get_proxy_methods():
"openstack.image.v1._proxy",
"openstack.image.v2._proxy",
"openstack.key_manager.v1._proxy",
"openstack.load_balancer.v2._proxy",
"openstack.message.v1._proxy",
"openstack.message.v2._proxy",
"openstack.metric.v1._proxy",

View File

@ -114,6 +114,7 @@ The following services have exposed *Resource* classes.
Identity <resources/identity/index>
Image <resources/image/index>
Key Management <resources/key_manager/index>
Load Balancer <resources/load_balancer/index>
Metric <resources/metric/index>
Network <resources/network/index>
Orchestration <resources/orchestration/index>

View File

@ -16,7 +16,8 @@ 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
.. 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.update_load_balancer

View File

@ -0,0 +1,7 @@
Load Balancer Resources
=======================
.. toctree::
:maxdepth: 1
v2/load_balancer

View File

@ -0,0 +1,13 @@
openstack.load_balancer.v2.load_balancer
========================================
.. automodule:: openstack.load_balancer.v2.load_balancer
The LoadBalancer Class
----------------------
The ``LoadBalancer`` class inherits from :class:`~openstack.resource.Resource`.
.. autoclass:: openstack.load_balancer.v2.load_balancer.LoadBalancer
:members:

View File

@ -16,11 +16,11 @@ from openstack import service_filter
class LoadBalancerService(service_filter.ServiceFilter):
"""The load balancer service."""
valid_versions = [service_filter.ValidVersion('v2')]
valid_versions = [service_filter.ValidVersion('v2', 'v2.0')]
def __init__(self, version=None):
"""Create a load balancer service."""
super(LoadBalancerService, self).__init__(
service_type='load_balancer',
service_type='load-balancer',
version=version
)

View File

@ -80,3 +80,17 @@ class Proxy(proxy2.BaseProxy):
"""
return self._find(_lb.LoadBalancer, name_or_id,
ignore_missing=ignore_missing)
def update_load_balancer(self, load_balancer, **attrs):
"""Update 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 dict attrs: The attributes to update on the load balancer
represented by ``load_balancer``.
:returns: The updated load_balancer
:rtype: :class:`~openstack.load_balancer.v2.load_balancer.LoadBalancer`
"""
return self._update(_lb.LoadBalancer, load_balancer, **attrs)

View File

@ -17,22 +17,31 @@ from openstack import resource2 as resource
class LoadBalancer(resource.Resource):
resource_key = 'loadbalancer'
resources_key = 'loadbalancers'
base_path = '/loadbalancers'
base_path = '/v2.0/lbaas/loadbalancers'
service = lb_service.LoadBalancerService()
# capabilities
allow_create = True
allow_list = True
allow_get = True
allow_update = True
allow_delete = True
allow_list = True
_query_mapping = resource.QueryParameters(
'description', 'flavor', 'name', 'project_id', 'provider',
'vip_address', 'vip_network_id', 'vip_port_id', 'vip_subnet_id',
is_admin_state_up='admin_state_up'
)
#: Properties
#: The administrative state of the load balancer *Type: bool*
is_admin_state_up = resource.Body('admin_state_up', type=bool)
#: 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)
#: The load balancer flavor
flavor = resource.Body('flavor')
#: List of listeners associated with this load balancer
listeners = resource.Body('listeners', type=list)
#: The load balancer name
@ -43,13 +52,17 @@ class LoadBalancer(resource.Resource):
pools = resource.Body('pools', type=list)
#: The ID of the project this load balancer is associated with.
project_id = resource.Body('project_id')
#: Provider name for the load balancer.
provider = resource.Body('provider')
#: The provisioning status of this load balancer
provisioning_status = resource.Body('provisioning_status')
#: Timestamp when the load balancer was last updated
updated_at = resource.Body('updated_at')
#: VIP address of load balancer
vip_address = resource.Body('vip_address')
#: VIP netowrk ID
vip_network_id = resource.Body('vip_network_id')
#: 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

@ -330,6 +330,11 @@ class Session(_session.Session):
self.endpoint_cache[key] = sc_endpoint
return sc_endpoint
# We just want what is returned from catalog
if service_type == "load-balancer":
self.endpoint_cache[key] = sc_endpoint
return sc_endpoint
endpoint = self._get_endpoint_versions(service_type, sc_endpoint)
profile_version = self._parse_version(filt.version)

View File

@ -0,0 +1,63 @@
# Copyright 2017 Rackspace, US Inc.
# 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 time
from openstack import exceptions
from openstack.tests.functional import base
class BaseLBFunctionalTest(base.BaseFunctionalTest):
@classmethod
def setUpClass(cls):
super(BaseLBFunctionalTest, cls).setUpClass()
@classmethod
def lb_wait_for_status(cls, lb, status, failures, interval=1, wait=120):
"""Wait for load balancer to be in a particular provisioning status.
:param lb: The load balancer to wait on to reach the status.
:type lb: :class:`~openstack.load_blanacer.v2.load_balancer
:param status: Desired status of the resource.
:param list failures: Statuses that would indicate the transition
failed such as 'ERROR'.
:param interval: Number of seconds to wait between checks.
:param wait: Maximum number of seconds to wait for transition.
Note, most actions should easily finish in 120 seconds,
but for load balancer create slow hosts can take up to
ten minutes for nova to fully boot a VM.
:return: None
:raises: :class:`~openstack.exceptions.ResourceTimeout` transition
to status failed to occur in wait seconds.
:raises: :class:`~openstack.exceptions.ResourceFailure` resource
transitioned to one of the failure states.
"""
total_sleep = 0
if failures is None:
failures = []
while total_sleep < wait:
lb = cls.conn.load_balancer.get_load_balancer(lb.id)
if lb.provisioning_status == status:
return None
if lb.provisioning_status in failures:
msg = ("Load Balancer %s transitioned to failure state %s" %
(lb.id, lb.provisioning_status))
raise exceptions.ResourceFailure(msg)
time.sleep(interval)
total_sleep += interval
msg = "Timeout waiting for Load Balancer %s to transition to %s" % (
lb.id, status)
raise exceptions.ResourceTimeout(msg)

View File

@ -15,30 +15,43 @@ import uuid
from openstack.load_balancer.v2 import load_balancer
from openstack.tests.functional import base
from openstack.tests.functional.load_balancer import base as lb_base
@unittest.skipUnless(base.service_exists(service_type='load_balancer'),
'Load-balancing service does not exist')
class TestLoadBalancer(base.BaseFunctionalTest):
@unittest.skipUnless(base.service_exists(service_type='load-balancer'),
'Load-balancer service does not exist')
class TestLoadBalancer(lb_base.BaseLBFunctionalTest):
NAME = uuid.uuid4().hex
ID = None
VIP_SUBNET_ID = uuid.uuid4().hex
VIP_SUBNET_ID = None
PROJECT_ID = None
UPDATE_NAME = uuid.uuid4().hex
@classmethod
def setUpClass(cls):
super(TestLoadBalancer, cls).setUpClass()
subnets = list(cls.conn.network.subnets())
cls.VIP_SUBNET_ID = subnets[0].id
cls.PROJECT_ID = cls.conn.session.get_project_id()
test_lb = cls.conn.load_balancer.create_load_balancer(
name=cls.NAME, vip_subnet_id=cls.VIP_SUBNET_ID)
name=cls.NAME, vip_subnet_id=cls.VIP_SUBNET_ID,
project_id=cls.PROJECT_ID)
assert isinstance(test_lb, load_balancer.LoadBalancer)
cls.assertIs(cls.NAME, test_lb.name)
# Wait for the LB to go ACTIVE. On non-virtualization enabled hosts
# it can take nova up to ten minutes to boot a VM.
cls.lb_wait_for_status(test_lb, status='ACTIVE',
failures=['ERROR'], interval=1, wait=600)
cls.ID = test_lb.id
@classmethod
def tearDownClass(cls):
test_lb = cls.conn.load_balancer.delete_load_balancer(
test_lb = cls.conn.load_balancer.get_load_balancer(cls.ID)
cls.lb_wait_for_status(test_lb, status='ACTIVE',
failures=['ERROR'])
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)
@ -53,3 +66,11 @@ class TestLoadBalancer(base.BaseFunctionalTest):
def test_list(self):
names = [lb.name for lb in self.conn.load_balancer.load_balancers()]
self.assertIn(self.NAME, names)
def test_update(self):
update_lb = self.conn.load_balancer.update_load_balancer(
self.ID, name=self.UPDATE_NAME)
self.lb_wait_for_status(update_lb, status='ACTIVE',
failures=['ERROR'])
test_lb = self.conn.load_balancer.get_load_balancer(self.ID)
self.assertEqual(self.UPDATE_NAME, test_lb.name)

View File

@ -11,24 +11,29 @@
# under the License.
import testtools
import uuid
from openstack.load_balancer.v2 import load_balancer
IDENTIFIER = 'IDENTIFIER'
EXAMPLE = {
'admin_state_up': True,
'created_at': '3',
'created_at': '2017-07-17T12:14:57.233772',
'description': 'fake_description',
'flavor': uuid.uuid4(),
'id': IDENTIFIER,
'listeners': [{'id', '4'}],
'listeners': [{'id', uuid.uuid4()}],
'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'}],
'operating_status': 'ONLINE',
'pools': [{'id', uuid.uuid4()}],
'project_id': uuid.uuid4(),
'provider': 'fake_provider',
'provisioning_status': 'ACTIVE',
'updated_at': '2017-07-17T12:16:57.233772',
'vip_address': '192.0.2.5',
'vip_network_id': uuid.uuid4(),
'vip_port_id': uuid.uuid4(),
'vip_subnet_id': uuid.uuid4(),
}
@ -38,13 +43,15 @@ class TestLoadBalancer(testtools.TestCase):
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',
self.assertEqual('/v2.0/lbaas/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)
self.assertTrue(test_load_balancer.allow_update)
def test_make_it(self):
test_load_balancer = load_balancer.LoadBalancer(**EXAMPLE)
@ -52,18 +59,23 @@ class TestLoadBalancer(testtools.TestCase):
self.assertEqual(EXAMPLE['created_at'], test_load_balancer.created_at),
self.assertEqual(EXAMPLE['description'],
test_load_balancer.description)
self.assertEqual(EXAMPLE['flavor'], test_load_balancer.flavor)
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['pools'], test_load_balancer.pools)
self.assertEqual(EXAMPLE['project_id'], test_load_balancer.project_id)
self.assertEqual(EXAMPLE['provider'], test_load_balancer.provider)
self.assertEqual(EXAMPLE['provisioning_status'],
test_load_balancer.provisioning_status)
self.assertEqual(EXAMPLE['project_id'], test_load_balancer.project_id)
self.assertEqual(EXAMPLE['updated_at'], test_load_balancer.updated_at),
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_network_id'],
test_load_balancer.vip_network_id)
self.assertEqual(EXAMPLE['vip_port_id'],
test_load_balancer.vip_port_id)
self.assertEqual(EXAMPLE['pools'], test_load_balancer.pools)
self.assertEqual(EXAMPLE['vip_subnet_id'],
test_load_balancer.vip_subnet_id)

View File

@ -19,10 +19,10 @@ class TestLoadBalancingService(testtools.TestCase):
def test_service(self):
sot = lb_service.LoadBalancerService()
self.assertEqual('load_balancer', sot.service_type)
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)
self.assertEqual('v2.0', sot.valid_versions[0].path)

View File

@ -40,3 +40,7 @@ class TestLoadBalancerProxy(test_proxy_base2.TestProxyBase):
def test_load_balancer_find(self):
self.verify_find(self.proxy.find_load_balancer,
lb.LoadBalancer)
def test_load_balancer_update(self):
self.verify_update(self.proxy.update_load_balancer,
lb.LoadBalancer)

View File

@ -29,7 +29,7 @@ class TestVersion(testtools.TestCase):
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.assertEqual('load-balancer', sot.service.service_type)
self.assertFalse(sot.allow_create)
self.assertFalse(sot.allow_get)
self.assertFalse(sot.allow_update)

View File

@ -27,7 +27,7 @@ class TestProfile(base.TestCase):
'identity',
'image',
'key-manager',
'load_balancer',
'load-balancer',
'messaging',
'metering',
'network',
@ -46,7 +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('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)

View File

@ -14,7 +14,11 @@ cat /etc/openstack/clouds.yaml
cd ${DIR}
echo '=functional=============================================='
tox -e functional
if [[ -n "$1" ]]; then
tox -e functional -- $1
else
tox -e functional
fi
FUNCTIONAL_RESULT=\$?
echo '=examples================================================'
tox -e examples