Add Octavia (load_balancer) flavor profile API
This patch adds the Octavia (load_balancer) flavor profile API support. Change-Id: I1358d89b07917726451bf311c1323e57f381f853
This commit is contained in:
parent
b27f0c579e
commit
1b884947bc
@ -104,3 +104,15 @@ Provider Operations
|
|||||||
|
|
||||||
.. automethod:: openstack.load_balancer.v2._proxy.Proxy.providers
|
.. automethod:: openstack.load_balancer.v2._proxy.Proxy.providers
|
||||||
.. automethod:: openstack.load_balancer.v2._proxy.Proxy.provider_flavor_capabilities
|
.. automethod:: openstack.load_balancer.v2._proxy.Proxy.provider_flavor_capabilities
|
||||||
|
|
||||||
|
Flavor Profile Operations
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
.. autoclass:: openstack.load_balancer.v2._proxy.Proxy
|
||||||
|
|
||||||
|
.. automethod:: openstack.load_balancer.v2._proxy.Proxy.create_flavor_profile
|
||||||
|
.. automethod:: openstack.load_balancer.v2._proxy.Proxy.get_flavor_profile
|
||||||
|
.. automethod:: openstack.load_balancer.v2._proxy.Proxy.flavor_profiles
|
||||||
|
.. automethod:: openstack.load_balancer.v2._proxy.Proxy.delete_flavor_profile
|
||||||
|
.. automethod:: openstack.load_balancer.v2._proxy.Proxy.find_flavor_profile
|
||||||
|
.. automethod:: openstack.load_balancer.v2._proxy.Proxy.update_flavor_profile
|
||||||
|
@ -12,3 +12,4 @@ Load Balancer Resources
|
|||||||
v2/l7_policy
|
v2/l7_policy
|
||||||
v2/l7_rule
|
v2/l7_rule
|
||||||
v2/provider
|
v2/provider
|
||||||
|
v2/flavor_profile
|
||||||
|
@ -0,0 +1,13 @@
|
|||||||
|
openstack.load_balancer.v2.flavor_profile
|
||||||
|
=========================================
|
||||||
|
|
||||||
|
.. automodule:: openstack.load_balancer.v2.flavor_profile
|
||||||
|
|
||||||
|
The FlavorProfile Class
|
||||||
|
-----------------------
|
||||||
|
|
||||||
|
The ``FlavorProfile`` class inherits from
|
||||||
|
:class:`~openstack.resource.Resource`.
|
||||||
|
|
||||||
|
.. autoclass:: openstack.load_balancer.v2.flavor_profile.FlavorProfile
|
||||||
|
:members:
|
@ -10,6 +10,7 @@
|
|||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
|
from openstack.load_balancer.v2 import flavor_profile as _flavor_profile
|
||||||
from openstack.load_balancer.v2 import health_monitor as _hm
|
from openstack.load_balancer.v2 import health_monitor as _hm
|
||||||
from openstack.load_balancer.v2 import l7_policy as _l7policy
|
from openstack.load_balancer.v2 import l7_policy as _l7policy
|
||||||
from openstack.load_balancer.v2 import l7_rule as _l7rule
|
from openstack.load_balancer.v2 import l7_rule as _l7rule
|
||||||
@ -795,3 +796,85 @@ class Proxy(proxy.Proxy):
|
|||||||
"""
|
"""
|
||||||
return self._list(_provider.ProviderFlavorCapabilities,
|
return self._list(_provider.ProviderFlavorCapabilities,
|
||||||
provider=provider, **query)
|
provider=provider, **query)
|
||||||
|
|
||||||
|
def create_flavor_profile(self, **attrs):
|
||||||
|
"""Create a new flavor profile from attributes
|
||||||
|
|
||||||
|
:param dict attrs: Keyword arguments which will be used to create
|
||||||
|
a :class:`~openstack.load_balancer.v2.
|
||||||
|
flavor_profile.FlavorProfile`,
|
||||||
|
comprised of the properties on the
|
||||||
|
FlavorProfile class.
|
||||||
|
|
||||||
|
:returns: The results of profile creation creation
|
||||||
|
:rtype: :class:`~openstack.load_balancer.v2.flavor_profile.
|
||||||
|
FlavorProfile`
|
||||||
|
"""
|
||||||
|
return self._create(_flavor_profile.FlavorProfile, **attrs)
|
||||||
|
|
||||||
|
def get_flavor_profile(self, *attrs):
|
||||||
|
"""Get a flavor profile
|
||||||
|
|
||||||
|
:param flavor_profile: The value can be the name of a flavor profile
|
||||||
|
or :class:`~openstack.load_balancer.v2.flavor_profile.
|
||||||
|
FlavorProfile` instance.
|
||||||
|
|
||||||
|
:returns: One
|
||||||
|
:class:`~openstack.load_balancer.v2.flavor_profile.FlavorProfile`
|
||||||
|
"""
|
||||||
|
return self._get(_flavor_profile.FlavorProfile, *attrs)
|
||||||
|
|
||||||
|
def flavor_profiles(self, **query):
|
||||||
|
"""Retrieve a generator of flavor profiles
|
||||||
|
|
||||||
|
:returns: A generator of flavor profiles instances
|
||||||
|
"""
|
||||||
|
return self._list(_flavor_profile.FlavorProfile, **query)
|
||||||
|
|
||||||
|
def delete_flavor_profile(self, flavor_profile, ignore_missing=True):
|
||||||
|
"""Delete a flavor profile
|
||||||
|
|
||||||
|
:param flavor_profile: The flavor_profile can be either the name or a
|
||||||
|
:class:`~openstack.load_balancer.v2.flavor_profile.FlavorProfile`
|
||||||
|
instance
|
||||||
|
:param bool ignore_missing: When set to ``False``
|
||||||
|
:class:`~openstack.exceptions.ResourceNotFound` will be raised when
|
||||||
|
the flavor profile does not exist.
|
||||||
|
When set to ``True``, no exception will be set when attempting to
|
||||||
|
delete a nonexistent load balancer.
|
||||||
|
|
||||||
|
:returns: ``None``
|
||||||
|
"""
|
||||||
|
self._delete(_flavor_profile.FlavorProfile, flavor_profile,
|
||||||
|
ignore_missing=ignore_missing)
|
||||||
|
|
||||||
|
def find_flavor_profile(self, name_or_id, ignore_missing=True):
|
||||||
|
"""Find a single flavor profile
|
||||||
|
|
||||||
|
:param name_or_id: The name or ID of a flavor profile
|
||||||
|
:param bool ignore_missing: When set to ``False``
|
||||||
|
:class:`~openstack.exceptions.ResourceNotFound` will be raised
|
||||||
|
when the flavor profile does not exist.
|
||||||
|
When set to ``True``, no exception will be set when attempting
|
||||||
|
to delete a nonexistent flavor profile.
|
||||||
|
|
||||||
|
:returns: ``None``
|
||||||
|
"""
|
||||||
|
return self._find(_flavor_profile.FlavorProfile, name_or_id,
|
||||||
|
ignore_missing=ignore_missing)
|
||||||
|
|
||||||
|
def update_flavor_profile(self, flavor_profile, **attrs):
|
||||||
|
"""Update a flavor profile
|
||||||
|
|
||||||
|
:param flavor_profile: The flavor_profile can be either the name or a
|
||||||
|
:class:`~openstack.load_balancer.v2.flavor_profile.FlavorProfile`
|
||||||
|
instance
|
||||||
|
:param dict attrs: The attributes to update on the flavor profile
|
||||||
|
represented by ``flavor_profile``.
|
||||||
|
|
||||||
|
:returns: The updated flavor profile
|
||||||
|
:rtype: :class:`~openstack.load_balancer.v2.flavor_profile.
|
||||||
|
FlavorProfile`
|
||||||
|
"""
|
||||||
|
return self._update(_flavor_profile.FlavorProfile, flavor_profile,
|
||||||
|
**attrs)
|
||||||
|
42
openstack/load_balancer/v2/flavor_profile.py
Normal file
42
openstack/load_balancer/v2/flavor_profile.py
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
# Copyright 2019 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.
|
||||||
|
|
||||||
|
from openstack import resource
|
||||||
|
|
||||||
|
|
||||||
|
class FlavorProfile(resource.Resource):
|
||||||
|
resource_key = 'flavorprofile'
|
||||||
|
resources_key = 'flavorprofiles'
|
||||||
|
base_path = '/lbaas/flavorprofiles'
|
||||||
|
|
||||||
|
# capabilities
|
||||||
|
allow_create = True
|
||||||
|
allow_fetch = True
|
||||||
|
allow_commit = True
|
||||||
|
allow_delete = True
|
||||||
|
allow_list = True
|
||||||
|
|
||||||
|
_query_mapping = resource.QueryParameters(
|
||||||
|
'id', 'name', 'provider_name', 'flavor_data'
|
||||||
|
)
|
||||||
|
|
||||||
|
# Properties
|
||||||
|
#: The ID of the flavor profile.
|
||||||
|
id = resource.Body('id')
|
||||||
|
#: The name of the flavor profile.
|
||||||
|
name = resource.Body('name')
|
||||||
|
#: The provider this flavor profile is for.
|
||||||
|
provider_name = resource.Body('provider_name')
|
||||||
|
#: The JSON string containing the flavor metadata.
|
||||||
|
flavor_data = resource.Body('flavor_data')
|
@ -12,6 +12,7 @@
|
|||||||
|
|
||||||
import os
|
import os
|
||||||
|
|
||||||
|
from openstack.load_balancer.v2 import flavor_profile
|
||||||
from openstack.load_balancer.v2 import health_monitor
|
from openstack.load_balancer.v2 import health_monitor
|
||||||
from openstack.load_balancer.v2 import l7_policy
|
from openstack.load_balancer.v2 import l7_policy
|
||||||
from openstack.load_balancer.v2 import l7_rule
|
from openstack.load_balancer.v2 import l7_rule
|
||||||
@ -33,6 +34,7 @@ class TestLoadBalancer(base.BaseFunctionalTest):
|
|||||||
POOL_ID = None
|
POOL_ID = None
|
||||||
VIP_SUBNET_ID = None
|
VIP_SUBNET_ID = None
|
||||||
PROJECT_ID = None
|
PROJECT_ID = None
|
||||||
|
FLAVOR_PROFILE_ID = None
|
||||||
PROTOCOL = 'HTTP'
|
PROTOCOL = 'HTTP'
|
||||||
PROTOCOL_PORT = 80
|
PROTOCOL_PORT = 80
|
||||||
LB_ALGORITHM = 'ROUND_ROBIN'
|
LB_ALGORITHM = 'ROUND_ROBIN'
|
||||||
@ -48,6 +50,7 @@ class TestLoadBalancer(base.BaseFunctionalTest):
|
|||||||
L7RULE_TYPE = 'HOST_NAME'
|
L7RULE_TYPE = 'HOST_NAME'
|
||||||
L7RULE_VALUE = 'example'
|
L7RULE_VALUE = 'example'
|
||||||
AMPHORA = 'amphora'
|
AMPHORA = 'amphora'
|
||||||
|
FLAVOR_DATA = '{"loadbalancer_topology": "SINGLE"}'
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def setUpClass(cls):
|
def setUpClass(cls):
|
||||||
@ -71,6 +74,7 @@ class TestLoadBalancer(base.BaseFunctionalTest):
|
|||||||
self.MEMBER_NAME = self.getUniqueString()
|
self.MEMBER_NAME = self.getUniqueString()
|
||||||
self.POOL_NAME = self.getUniqueString()
|
self.POOL_NAME = self.getUniqueString()
|
||||||
self.UPDATE_NAME = self.getUniqueString()
|
self.UPDATE_NAME = self.getUniqueString()
|
||||||
|
self.FLAVOR_PROFILE_NAME = self.getUniqueString()
|
||||||
subnets = list(self.conn.network.subnets())
|
subnets = list(self.conn.network.subnets())
|
||||||
self.VIP_SUBNET_ID = subnets[0].id
|
self.VIP_SUBNET_ID = subnets[0].id
|
||||||
self.PROJECT_ID = self.conn.session.get_project_id()
|
self.PROJECT_ID = self.conn.session.get_project_id()
|
||||||
@ -82,6 +86,14 @@ class TestLoadBalancer(base.BaseFunctionalTest):
|
|||||||
'member': 100})
|
'member': 100})
|
||||||
assert isinstance(test_quota, quota.Quota)
|
assert isinstance(test_quota, quota.Quota)
|
||||||
self.assertEqual(self.PROJECT_ID, test_quota.id)
|
self.assertEqual(self.PROJECT_ID, test_quota.id)
|
||||||
|
|
||||||
|
test_profile = self.conn.load_balancer.create_flavor_profile(
|
||||||
|
name=self.FLAVOR_PROFILE_NAME, provider_name=self.AMPHORA,
|
||||||
|
flavor_data=self.FLAVOR_DATA)
|
||||||
|
assert isinstance(test_profile, flavor_profile.FlavorProfile)
|
||||||
|
self.assertEqual(self.FLAVOR_PROFILE_NAME, test_profile.name)
|
||||||
|
self.FLAVOR_PROFILE_ID = test_profile.id
|
||||||
|
|
||||||
test_lb = self.conn.load_balancer.create_load_balancer(
|
test_lb = self.conn.load_balancer.create_load_balancer(
|
||||||
name=self.LB_NAME, vip_subnet_id=self.VIP_SUBNET_ID,
|
name=self.LB_NAME, vip_subnet_id=self.VIP_SUBNET_ID,
|
||||||
project_id=self.PROJECT_ID)
|
project_id=self.PROJECT_ID)
|
||||||
@ -191,6 +203,9 @@ class TestLoadBalancer(base.BaseFunctionalTest):
|
|||||||
self.LB_ID, ignore_missing=False)
|
self.LB_ID, ignore_missing=False)
|
||||||
super(TestLoadBalancer, self).tearDown()
|
super(TestLoadBalancer, self).tearDown()
|
||||||
|
|
||||||
|
self.conn.load_balancer.delete_flavor_profile(self.FLAVOR_PROFILE_ID,
|
||||||
|
ignore_missing=False)
|
||||||
|
|
||||||
def test_lb_find(self):
|
def test_lb_find(self):
|
||||||
test_lb = self.conn.load_balancer.find_load_balancer(self.LB_NAME)
|
test_lb = self.conn.load_balancer.find_load_balancer(self.LB_NAME)
|
||||||
self.assertEqual(self.LB_ID, test_lb.id)
|
self.assertEqual(self.LB_ID, test_lb.id)
|
||||||
@ -488,3 +503,33 @@ class TestLoadBalancer(base.BaseFunctionalTest):
|
|||||||
# Make sure a known capability is in the default provider
|
# Make sure a known capability is in the default provider
|
||||||
self.assertTrue(any(
|
self.assertTrue(any(
|
||||||
cap['name'] == 'loadbalancer_topology' for cap in capabilities))
|
cap['name'] == 'loadbalancer_topology' for cap in capabilities))
|
||||||
|
|
||||||
|
def test_flavor_profile_find(self):
|
||||||
|
test_profile = self.conn.load_balancer.find_flavor_profile(
|
||||||
|
self.FLAVOR_PROFILE_NAME)
|
||||||
|
self.assertEqual(self.FLAVOR_PROFILE_ID, test_profile.id)
|
||||||
|
|
||||||
|
def test_flavor_profile_get(self):
|
||||||
|
test_flavor_profile = self.conn.load_balancer.get_flavor_profile(
|
||||||
|
self.FLAVOR_PROFILE_ID)
|
||||||
|
self.assertEqual(self.FLAVOR_PROFILE_NAME, test_flavor_profile.name)
|
||||||
|
self.assertEqual(self.FLAVOR_PROFILE_ID, test_flavor_profile.id)
|
||||||
|
self.assertEqual(self.AMPHORA, test_flavor_profile.provider_name)
|
||||||
|
self.assertEqual(self.FLAVOR_DATA, test_flavor_profile.flavor_data)
|
||||||
|
|
||||||
|
def test_flavor_profile_list(self):
|
||||||
|
names = [fv.name for fv in self.conn.load_balancer.flavor_profiles()]
|
||||||
|
self.assertIn(self.FLAVOR_PROFILE_NAME, names)
|
||||||
|
|
||||||
|
def test_flavor_profile_update(self):
|
||||||
|
self.conn.load_balancer.update_flavor_profile(
|
||||||
|
self.FLAVOR_PROFILE_ID, name=self.UPDATE_NAME)
|
||||||
|
test_flavor_profile = self.conn.load_balancer.get_flavor_profile(
|
||||||
|
self.FLAVOR_PROFILE_ID)
|
||||||
|
self.assertEqual(self.UPDATE_NAME, test_flavor_profile.name)
|
||||||
|
|
||||||
|
self.conn.load_balancer.update_flavor_profile(
|
||||||
|
self.FLAVOR_PROFILE_ID, name=self.FLAVOR_PROFILE_NAME)
|
||||||
|
test_flavor_profile = self.conn.load_balancer.get_flavor_profile(
|
||||||
|
self.FLAVOR_PROFILE_ID)
|
||||||
|
self.assertEqual(self.FLAVOR_PROFILE_NAME, test_flavor_profile.name)
|
||||||
|
55
openstack/tests/unit/load_balancer/test_flavor_profile.py
Normal file
55
openstack/tests/unit/load_balancer/test_flavor_profile.py
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
# Copyright 2019 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.
|
||||||
|
|
||||||
|
from openstack.tests.unit import base
|
||||||
|
import uuid
|
||||||
|
|
||||||
|
from openstack.load_balancer.v2 import flavor_profile
|
||||||
|
|
||||||
|
IDENTIFIER = uuid.uuid4()
|
||||||
|
EXAMPLE = {
|
||||||
|
'id': IDENTIFIER,
|
||||||
|
'name': 'acidic',
|
||||||
|
'provider_name': 'best',
|
||||||
|
'flavor_data': '{"loadbalancer_topology": "SINGLE"}'}
|
||||||
|
|
||||||
|
|
||||||
|
class TestFlavorProfile(base.TestCase):
|
||||||
|
|
||||||
|
def test_basic(self):
|
||||||
|
test_profile = flavor_profile.FlavorProfile()
|
||||||
|
self.assertEqual('flavorprofile', test_profile.resource_key)
|
||||||
|
self.assertEqual('flavorprofiles', test_profile.resources_key)
|
||||||
|
self.assertEqual('/lbaas/flavorprofiles', test_profile.base_path)
|
||||||
|
self.assertTrue(test_profile.allow_create)
|
||||||
|
self.assertTrue(test_profile.allow_fetch)
|
||||||
|
self.assertTrue(test_profile.allow_commit)
|
||||||
|
self.assertTrue(test_profile.allow_delete)
|
||||||
|
self.assertTrue(test_profile.allow_list)
|
||||||
|
|
||||||
|
def test_make_it(self):
|
||||||
|
test_profile = flavor_profile.FlavorProfile(**EXAMPLE)
|
||||||
|
self.assertEqual(EXAMPLE['id'], test_profile.id)
|
||||||
|
self.assertEqual(EXAMPLE['name'], test_profile.name)
|
||||||
|
self.assertEqual(EXAMPLE['provider_name'], test_profile.provider_name)
|
||||||
|
self.assertEqual(EXAMPLE['flavor_data'], test_profile.flavor_data)
|
||||||
|
|
||||||
|
self.assertDictEqual(
|
||||||
|
{'limit': 'limit',
|
||||||
|
'marker': 'marker',
|
||||||
|
'id': 'id',
|
||||||
|
'name': 'name',
|
||||||
|
'provider_name': 'provider_name',
|
||||||
|
'flavor_data': 'flavor_data'},
|
||||||
|
test_profile._query_mapping._mapping)
|
@ -14,6 +14,7 @@ import uuid
|
|||||||
import mock
|
import mock
|
||||||
|
|
||||||
from openstack.load_balancer.v2 import _proxy
|
from openstack.load_balancer.v2 import _proxy
|
||||||
|
from openstack.load_balancer.v2 import flavor_profile
|
||||||
from openstack.load_balancer.v2 import health_monitor
|
from openstack.load_balancer.v2 import health_monitor
|
||||||
from openstack.load_balancer.v2 import l7_policy
|
from openstack.load_balancer.v2 import l7_policy
|
||||||
from openstack.load_balancer.v2 import l7_rule
|
from openstack.load_balancer.v2 import l7_rule
|
||||||
@ -319,3 +320,27 @@ class TestLoadBalancerProxy(test_proxy_base.TestProxyBase):
|
|||||||
provider.ProviderFlavorCapabilities,
|
provider.ProviderFlavorCapabilities,
|
||||||
method_args=[self.AMPHORA],
|
method_args=[self.AMPHORA],
|
||||||
expected_kwargs={'provider': self.AMPHORA})
|
expected_kwargs={'provider': self.AMPHORA})
|
||||||
|
|
||||||
|
def test_flavor_profiles(self):
|
||||||
|
self.verify_list(self.proxy.flavor_profiles,
|
||||||
|
flavor_profile.FlavorProfile)
|
||||||
|
|
||||||
|
def test_flavor_profile_get(self):
|
||||||
|
self.verify_get(self.proxy.get_flavor_profile,
|
||||||
|
flavor_profile.FlavorProfile)
|
||||||
|
|
||||||
|
def test_flavor_profile_create(self):
|
||||||
|
self.verify_create(self.proxy.create_flavor_profile,
|
||||||
|
flavor_profile.FlavorProfile)
|
||||||
|
|
||||||
|
def test_flavor_profile_delete(self):
|
||||||
|
self.verify_delete(self.proxy.delete_flavor_profile,
|
||||||
|
flavor_profile.FlavorProfile, True)
|
||||||
|
|
||||||
|
def test_flavor_profile_find(self):
|
||||||
|
self.verify_find(self.proxy.find_flavor_profile,
|
||||||
|
flavor_profile.FlavorProfile)
|
||||||
|
|
||||||
|
def test_flavor_profile_update(self):
|
||||||
|
self.verify_update(self.proxy.update_flavor_profile,
|
||||||
|
flavor_profile.FlavorProfile)
|
||||||
|
@ -0,0 +1,4 @@
|
|||||||
|
---
|
||||||
|
features:
|
||||||
|
- |
|
||||||
|
Adds Octavia (load_balancer) support for the flavor profile APIs.
|
Loading…
Reference in New Issue
Block a user