Merge "Add amphora stats show API and CLI"
This commit is contained in:
commit
23d123d42a
|
@ -46,6 +46,7 @@ BASE_AMPHORA_URL = BASE_OCTAVIA_ENDPOINT + "/amphorae"
|
||||||
BASE_SINGLE_AMPHORA_URL = BASE_AMPHORA_URL + "/{uuid}"
|
BASE_SINGLE_AMPHORA_URL = BASE_AMPHORA_URL + "/{uuid}"
|
||||||
BASE_AMPHORA_CONFIGURE_URL = BASE_SINGLE_AMPHORA_URL + '/config'
|
BASE_AMPHORA_CONFIGURE_URL = BASE_SINGLE_AMPHORA_URL + '/config'
|
||||||
BASE_AMPHORA_FAILOVER_URL = BASE_SINGLE_AMPHORA_URL + '/failover'
|
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_URL = BASE_LBAAS_ENDPOINT + "/providers"
|
||||||
BASE_PROVIDER_FLAVOR_CAPABILITY_URL = (
|
BASE_PROVIDER_FLAVOR_CAPABILITY_URL = (
|
||||||
|
|
|
@ -778,6 +778,19 @@ class OctaviaAPI(api.BaseAPI):
|
||||||
|
|
||||||
return response
|
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):
|
def provider_list(self):
|
||||||
"""List all providers
|
"""List all providers
|
||||||
|
|
||||||
|
|
|
@ -194,3 +194,51 @@ class FailoverAmphora(command.Command):
|
||||||
amphora_show),
|
amphora_show),
|
||||||
res_id=amp_id
|
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={})))
|
||||||
|
|
|
@ -154,6 +154,7 @@ SINGLE_HM_UPDATE = {'healthmonitor': {'admin_state_up': False}}
|
||||||
SINGLE_QT_RESP = {'quota': {'pool': -1}}
|
SINGLE_QT_RESP = {'quota': {'pool': -1}}
|
||||||
SINGLE_QT_UPDATE = {'quota': {'pool': -1}}
|
SINGLE_QT_UPDATE = {'quota': {'pool': -1}}
|
||||||
SINGLB_AMP_RESP = {'amphora': {'id': FAKE_AMP}}
|
SINGLB_AMP_RESP = {'amphora': {'id': FAKE_AMP}}
|
||||||
|
SINGLE_AMP_STATS_RESP = {'bytes_in': '0'}
|
||||||
|
|
||||||
SINGLE_PROVIDER_CAPABILITY_RESP = {
|
SINGLE_PROVIDER_CAPABILITY_RESP = {
|
||||||
'flavor_capabilities':
|
'flavor_capabilities':
|
||||||
|
@ -968,6 +969,16 @@ class TestLoadBalancer(TestOctaviaClient):
|
||||||
self.api.amphora_configure,
|
self.api.amphora_configure,
|
||||||
FAKE_AMP)
|
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):
|
def test_failover_amphora(self):
|
||||||
self.requests_mock.register_uri(
|
self.requests_mock.register_uri(
|
||||||
'PUT',
|
'PUT',
|
||||||
|
|
|
@ -14,6 +14,7 @@ import copy
|
||||||
from unittest import mock
|
from unittest import mock
|
||||||
|
|
||||||
import osc_lib.tests.utils as osc_test_utils
|
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 amphora
|
||||||
from octaviaclient.osc.v2 import constants
|
from octaviaclient.osc.v2 import constants
|
||||||
|
@ -212,3 +213,59 @@ class TestAmphoraFailover(TestAmphora):
|
||||||
res_id=self._amp.id,
|
res_id=self._amp.id,
|
||||||
sleep_time=mock.ANY,
|
sleep_time=mock.ANY,
|
||||||
status_field='provisioning_status')
|
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)
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
---
|
||||||
|
features:
|
||||||
|
- |
|
||||||
|
Adds support for querying the amphora statistics.
|
|
@ -85,6 +85,7 @@ openstack.load_balancer.v2 =
|
||||||
loadbalancer_amphora_show = octaviaclient.osc.v2.amphora:ShowAmphora
|
loadbalancer_amphora_show = octaviaclient.osc.v2.amphora:ShowAmphora
|
||||||
loadbalancer_amphora_configure = octaviaclient.osc.v2.amphora:ConfigureAmphora
|
loadbalancer_amphora_configure = octaviaclient.osc.v2.amphora:ConfigureAmphora
|
||||||
loadbalancer_amphora_failover = octaviaclient.osc.v2.amphora:FailoverAmphora
|
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_list = octaviaclient.osc.v2.provider:ListProvider
|
||||||
loadbalancer_provider_capability_list = octaviaclient.osc.v2.provider:ListProviderCapability
|
loadbalancer_provider_capability_list = octaviaclient.osc.v2.provider:ListProviderCapability
|
||||||
loadbalancer_flavorprofile_create = octaviaclient.osc.v2.flavorprofile:CreateFlavorProfile
|
loadbalancer_flavorprofile_create = octaviaclient.osc.v2.flavorprofile:CreateFlavorProfile
|
||||||
|
|
Loading…
Reference in New Issue