Add Octavia (load_balancer) amphora API
This patch adds the Octavia (load_balancer) amphora API support. Depends-On: https://review.openstack.org/#/c/632842/ Change-Id: Id5a2ab45c2600a52415387b81369d371b6182578
This commit is contained in:
parent
85f1e4c7f1
commit
1249d5fd26
@ -128,3 +128,14 @@ Flavor Operations
|
|||||||
.. automethod:: openstack.load_balancer.v2._proxy.Proxy.delete_flavor
|
.. automethod:: openstack.load_balancer.v2._proxy.Proxy.delete_flavor
|
||||||
.. automethod:: openstack.load_balancer.v2._proxy.Proxy.find_flavor
|
.. automethod:: openstack.load_balancer.v2._proxy.Proxy.find_flavor
|
||||||
.. automethod:: openstack.load_balancer.v2._proxy.Proxy.update_flavor
|
.. automethod:: openstack.load_balancer.v2._proxy.Proxy.update_flavor
|
||||||
|
|
||||||
|
Amphora Operations
|
||||||
|
^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
.. autoclass:: openstack.load_balancer.v2._proxy.Proxy
|
||||||
|
|
||||||
|
.. automethod:: openstack.load_balancer.v2._proxy.Proxy.amphorae
|
||||||
|
.. automethod:: openstack.load_balancer.v2._proxy.Proxy.get_amphora
|
||||||
|
.. automethod:: openstack.load_balancer.v2._proxy.Proxy.find_amphora
|
||||||
|
.. automethod:: openstack.load_balancer.v2._proxy.Proxy.configure_amphora
|
||||||
|
.. automethod:: openstack.load_balancer.v2._proxy.Proxy.failover_amphora
|
||||||
|
@ -14,3 +14,4 @@ Load Balancer Resources
|
|||||||
v2/provider
|
v2/provider
|
||||||
v2/flavor_profile
|
v2/flavor_profile
|
||||||
v2/flavor
|
v2/flavor
|
||||||
|
v2/amphora
|
||||||
|
30
doc/source/user/resources/load_balancer/v2/amphora.rst
Normal file
30
doc/source/user/resources/load_balancer/v2/amphora.rst
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
openstack.load_balancer.v2.amphora
|
||||||
|
==================================
|
||||||
|
|
||||||
|
.. automodule:: openstack.load_balancer.v2.amphora
|
||||||
|
|
||||||
|
The Amphora Class
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
The ``Amphora`` class inherits from :class:`~openstack.resource.Resource`.
|
||||||
|
|
||||||
|
.. autoclass:: openstack.load_balancer.v2.amphora.Amphora
|
||||||
|
:members:
|
||||||
|
|
||||||
|
The AmphoraConfig Class
|
||||||
|
-----------------------
|
||||||
|
|
||||||
|
The ``AmphoraConfig`` class inherits from
|
||||||
|
:class:`~openstack.resource.Resource`.
|
||||||
|
|
||||||
|
.. autoclass:: openstack.load_balancer.v2.amphora.AmphoraConfig
|
||||||
|
:members:
|
||||||
|
|
||||||
|
The AmphoraFailover Class
|
||||||
|
-------------------------
|
||||||
|
|
||||||
|
The ``AmphoraFailover`` class inherits from
|
||||||
|
:class:`~openstack.resource.Resource`.
|
||||||
|
|
||||||
|
.. autoclass:: openstack.load_balancer.v2.amphora.AmphoraFailover
|
||||||
|
: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 amphora as _amphora
|
||||||
from openstack.load_balancer.v2 import flavor as _flavor
|
from openstack.load_balancer.v2 import flavor as _flavor
|
||||||
from openstack.load_balancer.v2 import flavor_profile as _flavor_profile
|
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
|
||||||
@ -953,3 +954,54 @@ class Proxy(proxy.Proxy):
|
|||||||
:rtype: :class:`~openstack.load_balancer.v2.flavor.Flavor`
|
:rtype: :class:`~openstack.load_balancer.v2.flavor.Flavor`
|
||||||
"""
|
"""
|
||||||
return self._update(_flavor.Flavor, flavor, **attrs)
|
return self._update(_flavor.Flavor, flavor, **attrs)
|
||||||
|
|
||||||
|
def amphorae(self, **query):
|
||||||
|
"""Retrieve a generator of amphorae
|
||||||
|
|
||||||
|
:returns: A generator of amphora instances
|
||||||
|
"""
|
||||||
|
return self._list(_amphora.Amphora, **query)
|
||||||
|
|
||||||
|
def get_amphora(self, *attrs):
|
||||||
|
"""Get a amphora
|
||||||
|
|
||||||
|
:param amphora: The value can be the ID of an amphora
|
||||||
|
or :class:`~openstack.load_balancer.v2.amphora.Amphora` instance.
|
||||||
|
|
||||||
|
:returns: One
|
||||||
|
:class:`~openstack.load_balancer.v2.amphora.Amphora`
|
||||||
|
"""
|
||||||
|
return self._get(_amphora.Amphora, *attrs)
|
||||||
|
|
||||||
|
def find_amphora(self, amphora_id, ignore_missing=True):
|
||||||
|
"""Find a single amphora
|
||||||
|
|
||||||
|
:param amphora_id: The ID of a amphora
|
||||||
|
:param bool ignore_missing: When set to ``False``
|
||||||
|
:class:`~openstack.exceptions.ResourceNotFound` will be raised
|
||||||
|
when the amphora does not exist.
|
||||||
|
When set to ``True``, no exception will be set when attempting
|
||||||
|
to find a nonexistent amphora.
|
||||||
|
|
||||||
|
:returns: ``None``
|
||||||
|
"""
|
||||||
|
return self._find(_amphora.Amphora, amphora_id,
|
||||||
|
ignore_missing=ignore_missing)
|
||||||
|
|
||||||
|
def configure_amphora(self, amphora_id, **attrs):
|
||||||
|
"""Update the configuration of an amphora agent
|
||||||
|
|
||||||
|
:param amphora_id: The ID of an amphora
|
||||||
|
|
||||||
|
:returns: ``None``
|
||||||
|
"""
|
||||||
|
return self._update(_amphora.AmphoraConfig, amphora_id=amphora_id)
|
||||||
|
|
||||||
|
def failover_amphora(self, amphora_id, **attrs):
|
||||||
|
"""Failover an amphora
|
||||||
|
|
||||||
|
:param amphora_id: The ID of an amphora
|
||||||
|
|
||||||
|
:returns: ``None``
|
||||||
|
"""
|
||||||
|
return self._update(_amphora.AmphoraFailover, amphora_id=amphora_id)
|
||||||
|
148
openstack/load_balancer/v2/amphora.py
Normal file
148
openstack/load_balancer/v2/amphora.py
Normal file
@ -0,0 +1,148 @@
|
|||||||
|
# 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 Amphora(resource.Resource):
|
||||||
|
resource_key = 'amphora'
|
||||||
|
resources_key = 'amphorae'
|
||||||
|
base_path = '/octavia/amphorae'
|
||||||
|
|
||||||
|
# capabilities
|
||||||
|
allow_create = False
|
||||||
|
allow_fetch = True
|
||||||
|
allow_commit = False
|
||||||
|
allow_delete = False
|
||||||
|
allow_list = True
|
||||||
|
|
||||||
|
_query_mapping = resource.QueryParameters(
|
||||||
|
'id', 'loadbalancer_id', 'compute_id', 'lb_network_ip', 'vrrp_ip',
|
||||||
|
'ha_ip', 'vrrp_port_id', 'ha_port_id', 'cert_expiration', 'cert_busy',
|
||||||
|
'role', 'status', 'vrrp_interface', 'vrrp_id', 'vrrp_priority',
|
||||||
|
'cached_zone', 'created_at', 'updated_at', 'image_id', 'image_id'
|
||||||
|
)
|
||||||
|
|
||||||
|
# Properties
|
||||||
|
#: The ID of the amphora.
|
||||||
|
id = resource.Body('id')
|
||||||
|
#: The ID of the load balancer.
|
||||||
|
loadbalancer_id = resource.Body('loadbalancer_id')
|
||||||
|
#: The ID of the amphora resource in the compute system.
|
||||||
|
compute_id = resource.Body('compute_id')
|
||||||
|
#: The management IP of the amphora.
|
||||||
|
lb_network_ip = resource.Body('lb_network_ip')
|
||||||
|
#: The address of the vrrp port on the amphora.
|
||||||
|
vrrp_ip = resource.Body('vrrp_ip')
|
||||||
|
#: The IP address of the Virtual IP (VIP).
|
||||||
|
ha_ip = resource.Body('ha_ip')
|
||||||
|
#: The vrrp port's ID in the networking system.
|
||||||
|
vrrp_port_id = resource.Body('vrrp_port_id')
|
||||||
|
#: The ID of the Virtual IP (VIP) port.
|
||||||
|
ha_port_id = resource.Body('ha_port_id')
|
||||||
|
#: The date the certificate for the amphora expires.
|
||||||
|
cert_expiration = resource.Body('cert_expiration')
|
||||||
|
#: Whether the certificate is in the process of being replaced.
|
||||||
|
cert_busy = resource.Body('cert_busy')
|
||||||
|
#: The role configured for the amphora. One of STANDALONE, MASTER, BACKUP.
|
||||||
|
role = resource.Body('role')
|
||||||
|
#: The status of the amphora. One of: BOOTING, ALLOCATED, READY,
|
||||||
|
#: PENDING_CREATE, PENDING_DELETE, DELETED, ERROR.
|
||||||
|
status = resource.Body('status')
|
||||||
|
#: The bound interface name of the vrrp port on the amphora.
|
||||||
|
vrrp_interface = resource.Body('vrrp_interface')
|
||||||
|
#: The vrrp group's ID for the amphora.
|
||||||
|
vrrp_id = resource.Body('vrrp_id')
|
||||||
|
#: The priority of the amphora in the vrrp group.
|
||||||
|
vrrp_priority = resource.Body('vrrp_priority')
|
||||||
|
#: The availability zone of a compute instance, cached at create time.
|
||||||
|
cached_zone = resource.Body('cached_zone')
|
||||||
|
#: The UTC date and timestamp when the resource was created.
|
||||||
|
created_at = resource.Body('created_at')
|
||||||
|
#: The UTC date and timestamp when the resource was last updated.
|
||||||
|
updated_at = resource.Body('updated_at')
|
||||||
|
#: The ID of the glance image used for the amphora.
|
||||||
|
image_id = resource.Body('image_id')
|
||||||
|
#: The ID of the compute flavor used for the amphora.
|
||||||
|
compute_flavor = resource.Body('compute_flavor')
|
||||||
|
|
||||||
|
|
||||||
|
class AmphoraConfig(resource.Resource):
|
||||||
|
base_path = '/octavia/amphorae/%(amphora_id)s/config'
|
||||||
|
|
||||||
|
# capabilities
|
||||||
|
allow_create = False
|
||||||
|
allow_fetch = False
|
||||||
|
allow_commit = True
|
||||||
|
allow_delete = False
|
||||||
|
allow_list = False
|
||||||
|
|
||||||
|
requires_id = False
|
||||||
|
|
||||||
|
# Properties
|
||||||
|
#: The ID of the amphora.
|
||||||
|
amphora_id = resource.URI('amphora_id')
|
||||||
|
|
||||||
|
# The parent commit method assumes there is a header or body change,
|
||||||
|
# which we do not have here. The default _update code path also has no
|
||||||
|
# way to pass has_body into this function, so overriding the method here.
|
||||||
|
def commit(self, session, base_path=None):
|
||||||
|
kwargs = {}
|
||||||
|
request = self._prepare_request(prepend_key=False,
|
||||||
|
base_path=base_path,
|
||||||
|
**kwargs)
|
||||||
|
session = self._get_session(session)
|
||||||
|
kwargs = {}
|
||||||
|
microversion = self._get_microversion_for(session, 'commit')
|
||||||
|
response = session.put(request.url, json=request.body,
|
||||||
|
headers=request.headers,
|
||||||
|
microversion=microversion, **kwargs)
|
||||||
|
self.microversion = microversion
|
||||||
|
self._translate_response(response, has_body=False)
|
||||||
|
return self
|
||||||
|
|
||||||
|
|
||||||
|
class AmphoraFailover(resource.Resource):
|
||||||
|
base_path = '/octavia/amphorae/%(amphora_id)s/failover'
|
||||||
|
|
||||||
|
# capabilities
|
||||||
|
allow_create = False
|
||||||
|
allow_fetch = False
|
||||||
|
allow_commit = True
|
||||||
|
allow_delete = False
|
||||||
|
allow_list = False
|
||||||
|
|
||||||
|
requires_id = False
|
||||||
|
|
||||||
|
# Properties
|
||||||
|
#: The ID of the amphora.
|
||||||
|
amphora_id = resource.URI('amphora_id')
|
||||||
|
|
||||||
|
# The parent commit method assumes there is a header or body change,
|
||||||
|
# which we do not have here. The default _update code path also has no
|
||||||
|
# way to pass has_body into this function, so overriding the method here.
|
||||||
|
def commit(self, session, base_path=None):
|
||||||
|
kwargs = {}
|
||||||
|
request = self._prepare_request(prepend_key=False,
|
||||||
|
base_path=base_path,
|
||||||
|
**kwargs)
|
||||||
|
session = self._get_session(session)
|
||||||
|
kwargs = {}
|
||||||
|
microversion = self._get_microversion_for(session, 'commit')
|
||||||
|
response = session.put(request.url, json=request.body,
|
||||||
|
headers=request.headers,
|
||||||
|
microversion=microversion, **kwargs)
|
||||||
|
self.microversion = microversion
|
||||||
|
self._translate_response(response, has_body=False)
|
||||||
|
return self
|
@ -37,6 +37,7 @@ class TestLoadBalancer(base.BaseFunctionalTest):
|
|||||||
PROJECT_ID = None
|
PROJECT_ID = None
|
||||||
FLAVOR_PROFILE_ID = None
|
FLAVOR_PROFILE_ID = None
|
||||||
FLAVOR_ID = None
|
FLAVOR_ID = None
|
||||||
|
AMPHORA_ID = None
|
||||||
PROTOCOL = 'HTTP'
|
PROTOCOL = 'HTTP'
|
||||||
PROTOCOL_PORT = 80
|
PROTOCOL_PORT = 80
|
||||||
LB_ALGORITHM = 'ROUND_ROBIN'
|
LB_ALGORITHM = 'ROUND_ROBIN'
|
||||||
@ -117,6 +118,10 @@ class TestLoadBalancer(base.BaseFunctionalTest):
|
|||||||
wait=self._wait_for_timeout)
|
wait=self._wait_for_timeout)
|
||||||
self.LB_ID = test_lb.id
|
self.LB_ID = test_lb.id
|
||||||
|
|
||||||
|
amphorae = self.conn.load_balancer.amphorae(loadbalancer_id=self.LB_ID)
|
||||||
|
for amp in amphorae:
|
||||||
|
self.AMPHORA_ID = amp.id
|
||||||
|
|
||||||
test_listener = self.conn.load_balancer.create_listener(
|
test_listener = self.conn.load_balancer.create_listener(
|
||||||
name=self.LISTENER_NAME, protocol=self.PROTOCOL,
|
name=self.LISTENER_NAME, protocol=self.PROTOCOL,
|
||||||
protocol_port=self.PROTOCOL_PORT, loadbalancer_id=self.LB_ID)
|
protocol_port=self.PROTOCOL_PORT, loadbalancer_id=self.LB_ID)
|
||||||
@ -573,3 +578,25 @@ class TestLoadBalancer(base.BaseFunctionalTest):
|
|||||||
self.FLAVOR_ID, name=self.FLAVOR_NAME)
|
self.FLAVOR_ID, name=self.FLAVOR_NAME)
|
||||||
test_flavor = self.conn.load_balancer.get_flavor(self.FLAVOR_ID)
|
test_flavor = self.conn.load_balancer.get_flavor(self.FLAVOR_ID)
|
||||||
self.assertEqual(self.FLAVOR_NAME, test_flavor.name)
|
self.assertEqual(self.FLAVOR_NAME, test_flavor.name)
|
||||||
|
|
||||||
|
def test_amphora_list(self):
|
||||||
|
amp_ids = [amp.id for amp in self.conn.load_balancer.amphorae()]
|
||||||
|
self.assertIn(self.AMPHORA_ID, amp_ids)
|
||||||
|
|
||||||
|
def test_amphora_find(self):
|
||||||
|
test_amphora = self.conn.load_balancer.find_amphora(self.AMPHORA_ID)
|
||||||
|
self.assertEqual(self.AMPHORA_ID, test_amphora.id)
|
||||||
|
|
||||||
|
def test_amphora_get(self):
|
||||||
|
test_amphora = self.conn.load_balancer.get_amphora(self.AMPHORA_ID)
|
||||||
|
self.assertEqual(self.AMPHORA_ID, test_amphora.id)
|
||||||
|
|
||||||
|
def test_amphora_configure(self):
|
||||||
|
self.conn.load_balancer.configure_amphora(self.AMPHORA_ID)
|
||||||
|
test_amp = self.conn.load_balancer.get_amphora(self.AMPHORA_ID)
|
||||||
|
self.assertEqual(self.AMPHORA_ID, test_amp.id)
|
||||||
|
|
||||||
|
def test_amphora_failover(self):
|
||||||
|
self.conn.load_balancer.failover_amphora(self.AMPHORA_ID)
|
||||||
|
test_amp = self.conn.load_balancer.get_amphora(self.AMPHORA_ID)
|
||||||
|
self.assertEqual(self.AMPHORA_ID, test_amp.id)
|
||||||
|
142
openstack/tests/unit/load_balancer/test_amphora.py
Normal file
142
openstack/tests/unit/load_balancer/test_amphora.py
Normal file
@ -0,0 +1,142 @@
|
|||||||
|
# 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 amphora
|
||||||
|
|
||||||
|
IDENTIFIER = uuid.uuid4()
|
||||||
|
LB_ID = uuid.uuid4()
|
||||||
|
LISTENER_ID = uuid.uuid4()
|
||||||
|
COMPUTE_ID = uuid.uuid4()
|
||||||
|
VRRP_PORT_ID = uuid.uuid4()
|
||||||
|
HA_PORT_ID = uuid.uuid4()
|
||||||
|
IMAGE_ID = uuid.uuid4()
|
||||||
|
COMPUTE_FLAVOR = uuid.uuid4()
|
||||||
|
AMPHORA_ID = uuid.uuid4()
|
||||||
|
|
||||||
|
EXAMPLE = {
|
||||||
|
'id': IDENTIFIER,
|
||||||
|
'loadbalancer_id': LB_ID,
|
||||||
|
'compute_id': COMPUTE_ID,
|
||||||
|
'lb_network_ip': '192.168.1.2',
|
||||||
|
'vrrp_ip': '192.168.1.5',
|
||||||
|
'ha_ip': '192.168.1.10',
|
||||||
|
'vrrp_port_id': VRRP_PORT_ID,
|
||||||
|
'ha_port_id': HA_PORT_ID,
|
||||||
|
'cert_expiration': '2019-09-19 00:34:51',
|
||||||
|
'cert_busy': 0,
|
||||||
|
'role': 'MASTER',
|
||||||
|
'status': 'ALLOCATED',
|
||||||
|
'vrrp_interface': 'eth1',
|
||||||
|
'vrrp_id': 1,
|
||||||
|
'vrrp_priority': 100,
|
||||||
|
'cached_zone': 'zone1',
|
||||||
|
'created_at': '2017-05-10T18:14:44',
|
||||||
|
'updated_at': '2017-05-10T23:08:12',
|
||||||
|
'image_id': IMAGE_ID,
|
||||||
|
'compute_flavor': COMPUTE_FLAVOR
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class TestAmphora(base.TestCase):
|
||||||
|
|
||||||
|
def test_basic(self):
|
||||||
|
test_amphora = amphora.Amphora()
|
||||||
|
self.assertEqual('amphora', test_amphora.resource_key)
|
||||||
|
self.assertEqual('amphorae', test_amphora.resources_key)
|
||||||
|
self.assertEqual('/octavia/amphorae', test_amphora.base_path)
|
||||||
|
self.assertFalse(test_amphora.allow_create)
|
||||||
|
self.assertTrue(test_amphora.allow_fetch)
|
||||||
|
self.assertFalse(test_amphora.allow_commit)
|
||||||
|
self.assertFalse(test_amphora.allow_delete)
|
||||||
|
self.assertTrue(test_amphora.allow_list)
|
||||||
|
|
||||||
|
def test_make_it(self):
|
||||||
|
test_amphora = amphora.Amphora(**EXAMPLE)
|
||||||
|
self.assertEqual(IDENTIFIER, test_amphora.id)
|
||||||
|
self.assertEqual(LB_ID, test_amphora.loadbalancer_id)
|
||||||
|
self.assertEqual(COMPUTE_ID, test_amphora.compute_id)
|
||||||
|
self.assertEqual(EXAMPLE['lb_network_ip'], test_amphora.lb_network_ip)
|
||||||
|
self.assertEqual(EXAMPLE['vrrp_ip'], test_amphora.vrrp_ip)
|
||||||
|
self.assertEqual(EXAMPLE['ha_ip'], test_amphora.ha_ip)
|
||||||
|
self.assertEqual(VRRP_PORT_ID, test_amphora.vrrp_port_id)
|
||||||
|
self.assertEqual(HA_PORT_ID, test_amphora.ha_port_id)
|
||||||
|
self.assertEqual(EXAMPLE['cert_expiration'],
|
||||||
|
test_amphora.cert_expiration)
|
||||||
|
self.assertEqual(EXAMPLE['cert_busy'], test_amphora.cert_busy)
|
||||||
|
self.assertEqual(EXAMPLE['role'], test_amphora.role)
|
||||||
|
self.assertEqual(EXAMPLE['status'], test_amphora.status)
|
||||||
|
self.assertEqual(EXAMPLE['vrrp_interface'],
|
||||||
|
test_amphora.vrrp_interface)
|
||||||
|
self.assertEqual(EXAMPLE['vrrp_id'], test_amphora.vrrp_id)
|
||||||
|
self.assertEqual(EXAMPLE['vrrp_priority'], test_amphora.vrrp_priority)
|
||||||
|
self.assertEqual(EXAMPLE['cached_zone'], test_amphora.cached_zone)
|
||||||
|
self.assertEqual(EXAMPLE['created_at'], test_amphora.created_at)
|
||||||
|
self.assertEqual(EXAMPLE['updated_at'], test_amphora.updated_at)
|
||||||
|
self.assertEqual(IMAGE_ID, test_amphora.image_id)
|
||||||
|
self.assertEqual(COMPUTE_FLAVOR, test_amphora.compute_flavor)
|
||||||
|
|
||||||
|
self.assertDictEqual(
|
||||||
|
{'limit': 'limit',
|
||||||
|
'marker': 'marker',
|
||||||
|
'id': 'id',
|
||||||
|
'loadbalancer_id': 'loadbalancer_id',
|
||||||
|
'compute_id': 'compute_id',
|
||||||
|
'lb_network_ip': 'lb_network_ip',
|
||||||
|
'vrrp_ip': 'vrrp_ip',
|
||||||
|
'ha_ip': 'ha_ip',
|
||||||
|
'vrrp_port_id': 'vrrp_port_id',
|
||||||
|
'ha_port_id': 'ha_port_id',
|
||||||
|
'cert_expiration': 'cert_expiration',
|
||||||
|
'cert_busy': 'cert_busy',
|
||||||
|
'role': 'role',
|
||||||
|
'status': 'status',
|
||||||
|
'vrrp_interface': 'vrrp_interface',
|
||||||
|
'vrrp_id': 'vrrp_id',
|
||||||
|
'vrrp_priority': 'vrrp_priority',
|
||||||
|
'cached_zone': 'cached_zone',
|
||||||
|
'created_at': 'created_at',
|
||||||
|
'updated_at': 'updated_at',
|
||||||
|
'image_id': 'image_id',
|
||||||
|
'image_id': 'image_id'
|
||||||
|
},
|
||||||
|
test_amphora._query_mapping._mapping)
|
||||||
|
|
||||||
|
|
||||||
|
class TestAmphoraConfig(base.TestCase):
|
||||||
|
|
||||||
|
def test_basic(self):
|
||||||
|
test_amp_config = amphora.AmphoraConfig()
|
||||||
|
self.assertEqual('/octavia/amphorae/%(amphora_id)s/config',
|
||||||
|
test_amp_config.base_path)
|
||||||
|
self.assertFalse(test_amp_config.allow_create)
|
||||||
|
self.assertFalse(test_amp_config.allow_fetch)
|
||||||
|
self.assertTrue(test_amp_config.allow_commit)
|
||||||
|
self.assertFalse(test_amp_config.allow_delete)
|
||||||
|
self.assertFalse(test_amp_config.allow_list)
|
||||||
|
|
||||||
|
|
||||||
|
class TestAmphoraFailover(base.TestCase):
|
||||||
|
|
||||||
|
def test_basic(self):
|
||||||
|
test_amp_failover = amphora.AmphoraFailover()
|
||||||
|
self.assertEqual('/octavia/amphorae/%(amphora_id)s/failover',
|
||||||
|
test_amp_failover.base_path)
|
||||||
|
self.assertFalse(test_amp_failover.allow_create)
|
||||||
|
self.assertFalse(test_amp_failover.allow_fetch)
|
||||||
|
self.assertTrue(test_amp_failover.allow_commit)
|
||||||
|
self.assertFalse(test_amp_failover.allow_delete)
|
||||||
|
self.assertFalse(test_amp_failover.allow_list)
|
@ -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 amphora
|
||||||
from openstack.load_balancer.v2 import flavor
|
from openstack.load_balancer.v2 import flavor
|
||||||
from openstack.load_balancer.v2 import flavor_profile
|
from openstack.load_balancer.v2 import flavor_profile
|
||||||
from openstack.load_balancer.v2 import health_monitor
|
from openstack.load_balancer.v2 import health_monitor
|
||||||
@ -36,6 +37,7 @@ class TestLoadBalancerProxy(test_proxy_base.TestProxyBase):
|
|||||||
POOL_ID = uuid.uuid4()
|
POOL_ID = uuid.uuid4()
|
||||||
L7_POLICY_ID = uuid.uuid4()
|
L7_POLICY_ID = uuid.uuid4()
|
||||||
AMPHORA = 'amphora'
|
AMPHORA = 'amphora'
|
||||||
|
AMPHORA_ID = uuid.uuid4()
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super(TestLoadBalancerProxy, self).setUp()
|
super(TestLoadBalancerProxy, self).setUp()
|
||||||
@ -363,3 +365,26 @@ class TestLoadBalancerProxy(test_proxy_base.TestProxyBase):
|
|||||||
|
|
||||||
def test_flavor_update(self):
|
def test_flavor_update(self):
|
||||||
self.verify_update(self.proxy.update_flavor, flavor.Flavor)
|
self.verify_update(self.proxy.update_flavor, flavor.Flavor)
|
||||||
|
|
||||||
|
def test_amphorae(self):
|
||||||
|
self.verify_list(self.proxy.amphorae, amphora.Amphora)
|
||||||
|
|
||||||
|
def test_amphora_get(self):
|
||||||
|
self.verify_get(self.proxy.get_amphora, amphora.Amphora)
|
||||||
|
|
||||||
|
def test_amphora_find(self):
|
||||||
|
self.verify_find(self.proxy.find_amphora, amphora.Amphora)
|
||||||
|
|
||||||
|
def test_amphora_configure(self):
|
||||||
|
self.verify_update(self.proxy.configure_amphora,
|
||||||
|
amphora.AmphoraConfig,
|
||||||
|
value=[self.AMPHORA_ID],
|
||||||
|
expected_args=[],
|
||||||
|
expected_kwargs={'amphora_id': self.AMPHORA_ID})
|
||||||
|
|
||||||
|
def test_amphora_failover(self):
|
||||||
|
self.verify_update(self.proxy.failover_amphora,
|
||||||
|
amphora.AmphoraFailover,
|
||||||
|
value=[self.AMPHORA_ID],
|
||||||
|
expected_args=[],
|
||||||
|
expected_kwargs={'amphora_id': self.AMPHORA_ID})
|
||||||
|
@ -0,0 +1,4 @@
|
|||||||
|
---
|
||||||
|
features:
|
||||||
|
- |
|
||||||
|
Adds Octavia (load_balancer) support for the amphora APIs.
|
Loading…
Reference in New Issue
Block a user