Merge "Add amphora stats show API and CLI"

This commit is contained in:
Zuul 2020-04-07 23:51:20 +00:00 committed by Gerrit Code Review
commit 23d123d42a
7 changed files with 135 additions and 0 deletions

View File

@ -46,6 +46,7 @@ BASE_AMPHORA_URL = BASE_OCTAVIA_ENDPOINT + "/amphorae"
BASE_SINGLE_AMPHORA_URL = BASE_AMPHORA_URL + "/{uuid}"
BASE_AMPHORA_CONFIGURE_URL = BASE_SINGLE_AMPHORA_URL + '/config'
BASE_AMPHORA_FAILOVER_URL = BASE_SINGLE_AMPHORA_URL + '/failover'
BASE_AMPHORA_STATS_URL = BASE_SINGLE_AMPHORA_URL + '/stats'
BASE_PROVIDER_URL = BASE_LBAAS_ENDPOINT + "/providers"
BASE_PROVIDER_FLAVOR_CAPABILITY_URL = (

View File

@ -778,6 +778,19 @@ class OctaviaAPI(api.BaseAPI):
return response
def amphora_stats_show(self, amphora_id, **kwargs):
"""Show the current statistics for an amphora
:param string amphora_id:
ID of the amphora to show
:return:
A ``list`` of ``dict`` of the specified amphora's statistics
"""
url = const.BASE_AMPHORA_STATS_URL.format(uuid=amphora_id)
response = self._list(path=url, **kwargs)
return response
def provider_list(self):
"""List all providers

View File

@ -194,3 +194,51 @@ class FailoverAmphora(command.Command):
amphora_show),
res_id=amp_id
)
class ShowAmphoraStats(command.ShowOne):
"""Shows the current statistics for an amphora."""
def get_parser(self, prog_name):
parser = super(ShowAmphoraStats, self).get_parser(prog_name)
parser.add_argument(
'--listener',
metavar='<listener>',
help='Filter by listener (name or ID)',
)
parser.add_argument(
'amphora_id',
metavar='<amphora-id>',
help='UUID of the amphora'
)
return parser
def take_action(self, parsed_args):
rows = const.LOAD_BALANCER_STATS_ROWS
listener_id = None
if parsed_args.listener is not None:
attrs = v2_utils.get_listener_attrs(
self.app.client_manager,
parsed_args)
listener_id = attrs.pop('listener_id')
data = self.app.client_manager.load_balancer.amphora_stats_show(
amphora_id=parsed_args.amphora_id
)
total_stats = {
key: 0
for key in rows
}
for stats in data['amphora_stats']:
if listener_id is None or listener_id == stats['listener_id']:
for key in stats:
if key in rows:
total_stats[key] += stats[key]
return (rows, (utils.get_dict_properties(
total_stats, rows, formatters={})))

View File

@ -154,6 +154,7 @@ SINGLE_HM_UPDATE = {'healthmonitor': {'admin_state_up': False}}
SINGLE_QT_RESP = {'quota': {'pool': -1}}
SINGLE_QT_UPDATE = {'quota': {'pool': -1}}
SINGLB_AMP_RESP = {'amphora': {'id': FAKE_AMP}}
SINGLE_AMP_STATS_RESP = {'bytes_in': '0'}
SINGLE_PROVIDER_CAPABILITY_RESP = {
'flavor_capabilities':
@ -968,6 +969,16 @@ class TestLoadBalancer(TestOctaviaClient):
self.api.amphora_configure,
FAKE_AMP)
def test_stats_show_amphora(self):
self.requests_mock.register_uri(
'GET',
FAKE_OCTAVIA_URL + 'amphorae/' + FAKE_AMP + '/stats',
json=SINGLE_AMP_STATS_RESP,
status_code=200
)
ret = self.api.amphora_stats_show(FAKE_AMP)
self.assertEqual(SINGLE_AMP_STATS_RESP, ret)
def test_failover_amphora(self):
self.requests_mock.register_uri(
'PUT',

View File

@ -14,6 +14,7 @@ import copy
from unittest import mock
import osc_lib.tests.utils as osc_test_utils
from oslo_utils import uuidutils
from octaviaclient.osc.v2 import amphora
from octaviaclient.osc.v2 import constants
@ -212,3 +213,59 @@ class TestAmphoraFailover(TestAmphora):
res_id=self._amp.id,
sleep_time=mock.ANY,
status_field='provisioning_status')
class TestAmphoraStatsShow(TestAmphora):
def setUp(self):
super(TestAmphoraStatsShow, self).setUp()
# map fake listener_id to fake bytes_in counter
self.stats = {
uuidutils.generate_uuid(): 12,
uuidutils.generate_uuid(): 34,
}
amphora_stats_info = [
{'listener_id': k, 'bytes_in': self.stats[k]}
for k in self.stats]
self.api_mock.amphora_stats_show.return_value = {
'amphora_stats': amphora_stats_info}
lb_client = self.app.client_manager
lb_client.load_balancer = self.api_mock
self.cmd = amphora.ShowAmphoraStats(self.app, None)
def test_amphora_stats_show(self):
arglist = [self._amp.id]
verifylist = [
('amphora_id', self._amp.id),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
columns, data = self.cmd.take_action(parsed_args)
self.api_mock.amphora_stats_show.assert_called_with(
amphora_id=self._amp.id)
column_idx = columns.index('bytes_in')
total_bytes_in = sum(self.stats.values())
self.assertEqual(data[column_idx], total_bytes_in)
@mock.patch('octaviaclient.osc.v2.utils.get_listener_attrs')
def test_amphora_stats_show_with_listener_id(self,
mock_get_listener_attrs):
listener_id = list(self.stats)[0]
arglist = ['--listener', listener_id, self._amp.id]
verifylist = [
('amphora_id', self._amp.id),
]
mock_get_listener_attrs.return_value = {
'listener_id': listener_id
}
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
columns, data = self.cmd.take_action(parsed_args)
self.api_mock.amphora_stats_show.assert_called_with(
amphora_id=self._amp.id)
column_idx = columns.index('bytes_in')
bytes_in = self.stats[listener_id]
self.assertEqual(data[column_idx], bytes_in)

View File

@ -0,0 +1,4 @@
---
features:
- |
Adds support for querying the amphora statistics.

View File

@ -85,6 +85,7 @@ openstack.load_balancer.v2 =
loadbalancer_amphora_show = octaviaclient.osc.v2.amphora:ShowAmphora
loadbalancer_amphora_configure = octaviaclient.osc.v2.amphora:ConfigureAmphora
loadbalancer_amphora_failover = octaviaclient.osc.v2.amphora:FailoverAmphora
loadbalancer_amphora_stats_show = octaviaclient.osc.v2.amphora:ShowAmphoraStats
loadbalancer_provider_list = octaviaclient.osc.v2.provider:ListProvider
loadbalancer_provider_capability_list = octaviaclient.osc.v2.provider:ListProviderCapability
loadbalancer_flavorprofile_create = octaviaclient.osc.v2.flavorprofile:CreateFlavorProfile