Add amphora update service client and API test
This patch adds a service client for the amphora agent configuration update API and adds an API test for the amphora configuration update API. It also adds the service client for amphora failover and cleans up some client credintials in the amphora scenario tests. Change-Id: I4b1a1f48d2f619b883619811539ddb262d6b5f45
This commit is contained in:
parent
2734ffe0ea
commit
2b10e0a447
|
@ -157,3 +157,73 @@ class AmphoraClient(base_client.BaseLBaaSClient):
|
|||
return jsonutils.loads(body.decode('utf-8'))[self.stats_root_tag]
|
||||
else:
|
||||
return jsonutils.loads(body.decode('utf-8'))
|
||||
|
||||
def update_amphora_config(self, amphora_id):
|
||||
"""Update the amphora agent configuration.
|
||||
|
||||
:param amphora_id: The ID of the amphora to update.
|
||||
:raises AssertionError: if the expected_code isn't a valid http success
|
||||
response code
|
||||
:raises BadRequest: If a 400 response code is received
|
||||
:raises Conflict: If a 409 response code is received
|
||||
:raises Forbidden: If a 403 response code is received
|
||||
:raises Gone: If a 410 response code is received
|
||||
:raises InvalidContentType: If a 415 response code is received
|
||||
:raises InvalidHTTPResponseBody: The response body wasn't valid JSON
|
||||
:raises InvalidHttpSuccessCode: if the read code isn't an expected
|
||||
http success code
|
||||
:raises NotFound: If a 404 response code is received
|
||||
:raises NotImplemented: If a 501 response code is received
|
||||
:raises OverLimit: If a 413 response code is received and over_limit is
|
||||
not in the response body
|
||||
:raises RateLimitExceeded: If a 413 response code is received and
|
||||
over_limit is in the response body
|
||||
:raises ServerFault: If a 500 response code is received
|
||||
:raises Unauthorized: If a 401 response code is received
|
||||
:raises UnexpectedContentType: If the content-type of the response
|
||||
isn't an expect type
|
||||
:raises UnexpectedResponseCode: If a response code above 400 is
|
||||
received and it doesn't fall into any
|
||||
of the handled checks
|
||||
:raises UnprocessableEntity: If a 422 response code is received and
|
||||
couldn't be parsed
|
||||
:returns: None
|
||||
"""
|
||||
uri = '{0}/{1}/config'.format(self.uri, amphora_id)
|
||||
response, body = self.put(uri, '')
|
||||
self.expected_success(202, response.status)
|
||||
|
||||
def amphora_failover(self, amphora_id):
|
||||
"""Failover an amphora.
|
||||
|
||||
:param amphora_id: The ID of the amphora to failover.
|
||||
:raises AssertionError: if the expected_code isn't a valid http success
|
||||
response code
|
||||
:raises BadRequest: If a 400 response code is received
|
||||
:raises Conflict: If a 409 response code is received
|
||||
:raises Forbidden: If a 403 response code is received
|
||||
:raises Gone: If a 410 response code is received
|
||||
:raises InvalidContentType: If a 415 response code is received
|
||||
:raises InvalidHTTPResponseBody: The response body wasn't valid JSON
|
||||
:raises InvalidHttpSuccessCode: if the read code isn't an expected
|
||||
http success code
|
||||
:raises NotFound: If a 404 response code is received
|
||||
:raises NotImplemented: If a 501 response code is received
|
||||
:raises OverLimit: If a 413 response code is received and over_limit is
|
||||
not in the response body
|
||||
:raises RateLimitExceeded: If a 413 response code is received and
|
||||
over_limit is in the response body
|
||||
:raises ServerFault: If a 500 response code is received
|
||||
:raises Unauthorized: If a 401 response code is received
|
||||
:raises UnexpectedContentType: If the content-type of the response
|
||||
isn't an expect type
|
||||
:raises UnexpectedResponseCode: If a response code above 400 is
|
||||
received and it doesn't fall into any
|
||||
of the handled checks
|
||||
:raises UnprocessableEntity: If a 422 response code is received and
|
||||
couldn't be parsed
|
||||
:returns: None
|
||||
"""
|
||||
uri = '{0}/{1}/failover'.format(self.uri, amphora_id)
|
||||
response, body = self.put(uri, '')
|
||||
self.expected_success(202, response.status)
|
||||
|
|
|
@ -0,0 +1,98 @@
|
|||
# Copyright 2019 Rackspace US Inc. All rights reserved.
|
||||
#
|
||||
# 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 tempest import config
|
||||
from tempest.lib.common.utils import data_utils
|
||||
from tempest.lib import decorators
|
||||
from tempest.lib import exceptions
|
||||
|
||||
from octavia_tempest_plugin.common import constants as const
|
||||
from octavia_tempest_plugin.tests import test_base
|
||||
from octavia_tempest_plugin.tests import waiters
|
||||
|
||||
CONF = config.CONF
|
||||
|
||||
|
||||
class AmphoraAPITest(test_base.LoadBalancerBaseTest):
|
||||
"""Test the amphora object API."""
|
||||
|
||||
@classmethod
|
||||
def skip_checks(cls):
|
||||
super(AmphoraAPITest, cls).skip_checks()
|
||||
|
||||
if CONF.load_balancer.provider not in ['amphora', 'octavia']:
|
||||
raise cls.skipException("Amphora tests require provider 'amphora' "
|
||||
"or 'octavia' (alias to 'amphora', "
|
||||
" deprecated) set.")
|
||||
|
||||
@classmethod
|
||||
def resource_setup(cls):
|
||||
"""Setup resources needed by the tests."""
|
||||
super(AmphoraAPITest, cls).resource_setup()
|
||||
|
||||
lb_name = data_utils.rand_name("lb_member_lb1-amphora-api")
|
||||
lb_kwargs = {const.PROVIDER: CONF.load_balancer.provider,
|
||||
const.NAME: lb_name}
|
||||
|
||||
cls._setup_lb_network_kwargs(lb_kwargs)
|
||||
|
||||
lb = cls.mem_lb_client.create_loadbalancer(**lb_kwargs)
|
||||
cls.lb_id = lb[const.ID]
|
||||
cls.addClassResourceCleanup(
|
||||
cls.mem_lb_client.cleanup_loadbalancer,
|
||||
cls.lb_id)
|
||||
|
||||
waiters.wait_for_status(cls.mem_lb_client.show_loadbalancer,
|
||||
cls.lb_id, const.PROVISIONING_STATUS,
|
||||
const.ACTIVE,
|
||||
CONF.load_balancer.lb_build_interval,
|
||||
CONF.load_balancer.lb_build_timeout)
|
||||
|
||||
@decorators.idempotent_id('b7fc231b-dcfa-47a5-99f3-ec5ddcc48f30')
|
||||
def test_amphora_update(self):
|
||||
"""Tests the amphora agent configuration update API
|
||||
|
||||
* Tests that users without the loadbalancer admin role cannot
|
||||
update an amphora.
|
||||
* Update the amphora.
|
||||
"""
|
||||
|
||||
# We have to do this here as the api_version and clients are not
|
||||
# setup in time to use a decorator or the skip_checks mixin
|
||||
if not self.lb_admin_amphora_client.is_version_supported(
|
||||
self.api_version, '2.7'):
|
||||
raise self.skipException('Amphora update is only available on '
|
||||
'Octavia API version 2.7 or newer.')
|
||||
|
||||
amphorae = self.lb_admin_amphora_client.list_amphorae(
|
||||
query_params='{loadbalancer_id}={lb_id}'.format(
|
||||
loadbalancer_id=const.LOADBALANCER_ID, lb_id=self.lb_id))
|
||||
amphora_1 = amphorae[0]
|
||||
|
||||
# Test that a user without the load balancer admin role cannot
|
||||
# create a flavor
|
||||
if CONF.load_balancer.RBAC_test_type == const.ADVANCED:
|
||||
self.assertRaises(
|
||||
exceptions.Forbidden,
|
||||
self.os_primary.amphora_client.update_amphora_config,
|
||||
amphora_1[const.ID])
|
||||
|
||||
self.lb_admin_amphora_client.update_amphora_config(amphora_1[const.ID])
|
||||
|
||||
# TODO(johnsom) Assert that an amphora config setting updated
|
||||
# when we have a setting to check.
|
||||
|
||||
amp = self.lb_admin_amphora_client.show_amphora(amphora_1[const.ID])
|
||||
|
||||
self.assertEqual(const.STATUS_ALLOCATED, amp[const.STATUS])
|
|
@ -115,11 +115,11 @@ class AmphoraScenarioTest(test_base.LoadBalancerBaseTest):
|
|||
|
||||
# Test that a user with cloud admin role can list the amphorae
|
||||
if not CONF.load_balancer.RBAC_test_type == const.NONE:
|
||||
adm = self.os_admin.amphora_client.list_amphorae()
|
||||
adm = self.lb_admin_amphora_client.list_amphorae()
|
||||
self.assertTrue(len(adm) >= 2 * self._expected_amp_count(adm))
|
||||
|
||||
# Get an actual list of the amphorae
|
||||
amphorae = self.os_admin.amphora_client.list_amphorae()
|
||||
amphorae = self.lb_admin_amphora_client.list_amphorae()
|
||||
|
||||
# There should be AT LEAST 2, there may be more depending on the
|
||||
# configured topology, or if there are other LBs created besides ours
|
||||
|
@ -127,7 +127,7 @@ class AmphoraScenarioTest(test_base.LoadBalancerBaseTest):
|
|||
len(amphorae) >= 2 * self._expected_amp_count(amphorae))
|
||||
|
||||
show_amphora_response_fields = const.SHOW_AMPHORA_RESPONSE_FIELDS
|
||||
if self.mem_amphora_client.is_version_supported(
|
||||
if self.lb_admin_amphora_client.is_version_supported(
|
||||
self.api_version, '2.1'):
|
||||
show_amphora_response_fields.append('created_at')
|
||||
show_amphora_response_fields.append('updated_at')
|
||||
|
@ -140,7 +140,7 @@ class AmphoraScenarioTest(test_base.LoadBalancerBaseTest):
|
|||
self.assertIn(field, amp)
|
||||
|
||||
amp_id = amp[const.ID]
|
||||
amp_obj = self.os_admin.amphora_client.show_amphora(
|
||||
amp_obj = self.lb_admin_amphora_client.show_amphora(
|
||||
amphora_id=amp_id)
|
||||
|
||||
# Make sure all of the fields exist on the amp show record
|
||||
|
@ -148,7 +148,7 @@ class AmphoraScenarioTest(test_base.LoadBalancerBaseTest):
|
|||
self.assertIn(field, amp_obj)
|
||||
|
||||
# Verify a few of the fields are the right type
|
||||
if self.mem_amphora_client.is_version_supported(
|
||||
if self.lb_admin_amphora_client.is_version_supported(
|
||||
self.api_version, '2.1'):
|
||||
parser.parse(amp_obj[const.CREATED_AT])
|
||||
parser.parse(amp_obj[const.UPDATED_AT])
|
||||
|
@ -175,13 +175,13 @@ class AmphoraScenarioTest(test_base.LoadBalancerBaseTest):
|
|||
self.assertEqual(amp[field], amp_obj[field])
|
||||
|
||||
# Test filtering by loadbalancer_id
|
||||
amphorae = self.os_admin.amphora_client.list_amphorae(
|
||||
amphorae = self.lb_admin_amphora_client.list_amphorae(
|
||||
query_params='{loadbalancer_id}={lb_id}'.format(
|
||||
loadbalancer_id=const.LOADBALANCER_ID, lb_id=self.lb_id))
|
||||
self.assertEqual(self._expected_amp_count(amphorae), len(amphorae))
|
||||
self.assertEqual(self.lb_id, amphorae[0][const.LOADBALANCER_ID])
|
||||
|
||||
amphorae = self.os_admin.amphora_client.list_amphorae(
|
||||
amphorae = self.lb_admin_amphora_client.list_amphorae(
|
||||
query_params='{loadbalancer_id}={lb_id}'.format(
|
||||
loadbalancer_id=const.LOADBALANCER_ID, lb_id=lb_id))
|
||||
self.assertEqual(self._expected_amp_count(amphorae), len(amphorae))
|
||||
|
|
|
@ -121,7 +121,7 @@ class LoadBalancerBaseTest(test.BaseTestCase):
|
|||
cls.os_roles_lb_member.healthmonitor_client)
|
||||
cls.mem_l7policy_client = cls.os_roles_lb_member.l7policy_client
|
||||
cls.mem_l7rule_client = cls.os_roles_lb_member.l7rule_client
|
||||
cls.mem_amphora_client = cls.os_roles_lb_member.amphora_client
|
||||
cls.lb_admin_amphora_client = cls.os_roles_lb_admin.amphora_client
|
||||
cls.lb_admin_flavor_profile_client = (
|
||||
cls.os_roles_lb_admin.flavor_profile_client)
|
||||
cls.lb_admin_flavor_client = cls.os_roles_lb_admin.flavor_client
|
||||
|
|
Loading…
Reference in New Issue