From 23d8188131cf0959cdf65da0e64b101c6542e01e Mon Sep 17 00:00:00 2001 From: Fernando Ojeda Date: Tue, 23 Apr 2019 17:56:13 -0400 Subject: [PATCH 1/3] Feature usage vs information. --- SoftLayer/CLI/routes.py | 1 + SoftLayer/CLI/virt/usage.py | 53 +++++++++++++++++++ .../SoftLayer_Metric_Tracking_Object.py | 12 +++++ SoftLayer/fixtures/SoftLayer_Virtual_Guest.py | 2 + SoftLayer/managers/vs.py | 21 ++++++++ tests/CLI/modules/vs/vs_tests.py | 27 ++++++++++ tests/managers/vs/vs_tests.py | 28 ++++++++++ 7 files changed, 144 insertions(+) create mode 100644 SoftLayer/CLI/virt/usage.py create mode 100644 SoftLayer/fixtures/SoftLayer_Metric_Tracking_Object.py diff --git a/SoftLayer/CLI/routes.py b/SoftLayer/CLI/routes.py index 81ba46672..6736b233b 100644 --- a/SoftLayer/CLI/routes.py +++ b/SoftLayer/CLI/routes.py @@ -36,6 +36,7 @@ ('virtual:reboot', 'SoftLayer.CLI.virt.power:reboot'), ('virtual:reload', 'SoftLayer.CLI.virt.reload:cli'), ('virtual:upgrade', 'SoftLayer.CLI.virt.upgrade:cli'), + ('virtual:usage', 'SoftLayer.CLI.virt.usage:cli'), ('virtual:credentials', 'SoftLayer.CLI.virt.credentials:cli'), ('virtual:capacity', 'SoftLayer.CLI.virt.capacity:cli'), ('virtual:placementgroup', 'SoftLayer.CLI.virt.placementgroup:cli'), diff --git a/SoftLayer/CLI/virt/usage.py b/SoftLayer/CLI/virt/usage.py new file mode 100644 index 000000000..fdee54d2a --- /dev/null +++ b/SoftLayer/CLI/virt/usage.py @@ -0,0 +1,53 @@ +"""Usage information of a virtual server.""" +# :license: MIT, see LICENSE for more details. + +import click + +import SoftLayer +from SoftLayer.CLI import environment +from SoftLayer.CLI import formatting +from SoftLayer.CLI import helpers +from SoftLayer.utils import clean_time + + +@click.command() +@click.argument('identifier') +@click.option('--start_date', '-s', type=click.STRING, required=True, help="Start Date e.g. 2019-3-4 (yyyy-MM-dd)") +@click.option('--end_date', '-e', type=click.STRING, required=True, help="End Date e.g. 2019-4-2 (yyyy-MM-dd)") +@click.option('--valid_type', '-t', type=click.STRING, required=True, + help="Metric_Data_Type keyName e.g. CPU0, CPU1, MEMORY_USAGE, etc.") +@click.option('--summary_period', '-p', type=click.INT, default=1800, + help="300, 600, 1800, 3600, 43200 or 86400 seconds") +@environment.pass_env +def cli(env, identifier, start_date, end_date, valid_type, summary_period): + """Usage information of a virtual server.""" + + vsi = SoftLayer.VSManager(env.client) + table = formatting.Table(['counter', 'dateTime', 'type']) + table_average = formatting.Table(['Average']) + + vs_id = helpers.resolve_id(vsi.resolve_ids, identifier, 'VS') + + result = vsi.get_summary_data_usage(vs_id, start_date=start_date, end_date=end_date, + valid_type=valid_type, summary_period=summary_period) + + count = 0 + counter = 0.0 + for data in result: + table.add_row([ + data['counter'], + clean_time(data['dateTime']), + data['type'], + ]) + counter = counter + float(data['counter']) + count = count + 1 + + if type == "MEMORY_USAGE": + average = (counter / count) / 2 ** 30 + else: + average = counter / count + + env.fout(table_average.add_row([average])) + + env.fout(table_average) + env.fout(table) diff --git a/SoftLayer/fixtures/SoftLayer_Metric_Tracking_Object.py b/SoftLayer/fixtures/SoftLayer_Metric_Tracking_Object.py new file mode 100644 index 000000000..6a0a031a2 --- /dev/null +++ b/SoftLayer/fixtures/SoftLayer_Metric_Tracking_Object.py @@ -0,0 +1,12 @@ +getSummaryData = [ + { + "counter": 1.44, + "dateTime": "2019-03-04T00:00:00-06:00", + "type": "cpu0" + }, + { + "counter": 1.53, + "dateTime": "2019-03-04T00:05:00-06:00", + "type": "cpu0" + }, +] diff --git a/SoftLayer/fixtures/SoftLayer_Virtual_Guest.py b/SoftLayer/fixtures/SoftLayer_Virtual_Guest.py index c01fd17a8..49433b01f 100644 --- a/SoftLayer/fixtures/SoftLayer_Virtual_Guest.py +++ b/SoftLayer/fixtures/SoftLayer_Virtual_Guest.py @@ -626,3 +626,5 @@ } }, ] + +getMetricTrackingObjectId = 1000 diff --git a/SoftLayer/managers/vs.py b/SoftLayer/managers/vs.py index 00b738d0c..073b8aeab 100644 --- a/SoftLayer/managers/vs.py +++ b/SoftLayer/managers/vs.py @@ -1002,6 +1002,27 @@ def _get_price_id_for_upgrade_option(self, upgrade_prices, option, value, public else: return price.get('id') + def get_summary_data_usage(self, instance_id, start_date=None, end_date=None, valid_type=None, summary_period=None): + """Retrieve the usage information of a virtual server. + + :param string instance_id: a string identifier used to resolve ids + :param string start_date: the start data to retrieve the vs usage information + :param string end_date: the start data to retrieve the vs usage information + :param string string valid_type: the Metric_Data_Type keyName. + :param int summary_period: summary period. + """ + valid_types = [ + { + "keyName": valid_type, + "summaryType": "max" + } + ] + + metric_tracking_id = self.guest.getMetricTrackingObjectId(id=instance_id) + + return self.client.call('Metric_Tracking_Object', 'getSummaryData', start_date, end_date, valid_types, + summary_period, id=metric_tracking_id, iter=True) + # pylint: disable=inconsistent-return-statements def _get_price_id_for_upgrade(self, package_items, option, value, public=True): """Find the price id for the option and value to upgrade. diff --git a/tests/CLI/modules/vs/vs_tests.py b/tests/CLI/modules/vs/vs_tests.py index ce1bb9d73..9c5d155fc 100644 --- a/tests/CLI/modules/vs/vs_tests.py +++ b/tests/CLI/modules/vs/vs_tests.py @@ -660,3 +660,30 @@ def test_vs_capture(self): result = self.run_command(['vs', 'capture', '100', '--name', 'TestName']) self.assert_no_fail(result) self.assert_called_with('SoftLayer_Virtual_Guest', 'createArchiveTransaction', identifier=100) + + @mock.patch('SoftLayer.CLI.formatting.no_going_back') + def test_usage_no_confirm(self, confirm_mock): + confirm_mock.return_value = False + + result = self.run_command(['vs', 'usage', '100']) + self.assertEqual(result.exit_code, 2) + + def test_usage_vs(self): + result = self.run_command( + ['vs', 'usage', '100']) + self.assertEqual(result.exit_code, 2) + + def test_usage_vs_cpu(self): + result = self.run_command( + ['vs', 'usage', '100', '--start_date=2019-3-4', '--end_date=2019-4-2', '--valid_type=CPU0', + '--summary_period=300']) + + self.assert_no_fail(result) + + def test_usage_vs_memory(self): + + result = self.run_command( + ['vs', 'usage', '100', '--start_date=2019-3-4', '--end_date=2019-4-2', '--valid_type=MEMORY_USAGE', + '--summary_period=300']) + + self.assert_no_fail(result) diff --git a/tests/managers/vs/vs_tests.py b/tests/managers/vs/vs_tests.py index f13c3e7b9..47674345f 100644 --- a/tests/managers/vs/vs_tests.py +++ b/tests/managers/vs/vs_tests.py @@ -830,3 +830,31 @@ def test_capture_additional_disks(self): 'createArchiveTransaction', args=args, identifier=1) + + def test_usage_vs_cpu(self): + result = self.vs.get_summary_data_usage('100', + start_date='2019-3-4', + end_date='2019-4-2', + valid_type='CPU0', + summary_period=300) + + expected = fixtures.SoftLayer_Metric_Tracking_Object.getSummaryData + self.assertEqual(result, expected) + + args = ('2019-3-4', '2019-4-2', [{"keyName": "CPU0", "summaryType": "max"}], 300) + + self.assert_called_with('SoftLayer_Metric_Tracking_Object', 'getSummaryData', args=args, identifier=1000) + + def test_usage_vs_memory(self): + result = self.vs.get_summary_data_usage('100', + start_date='2019-3-4', + end_date='2019-4-2', + valid_type='MEMORY_USAGE', + summary_period=300) + + expected = fixtures.SoftLayer_Metric_Tracking_Object.getSummaryData + self.assertEqual(result, expected) + + args = ('2019-3-4', '2019-4-2', [{"keyName": "MEMORY_USAGE", "summaryType": "max"}], 300) + + self.assert_called_with('SoftLayer_Metric_Tracking_Object', 'getSummaryData', args=args, identifier=1000) From a911fac51589216af15f667c256cce303681b349 Mon Sep 17 00:00:00 2001 From: Fernando Ojeda Date: Tue, 23 Apr 2019 18:01:11 -0400 Subject: [PATCH 2/3] Refactor usage vs information. --- SoftLayer/CLI/virt/usage.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SoftLayer/CLI/virt/usage.py b/SoftLayer/CLI/virt/usage.py index fdee54d2a..68981705c 100644 --- a/SoftLayer/CLI/virt/usage.py +++ b/SoftLayer/CLI/virt/usage.py @@ -42,7 +42,7 @@ def cli(env, identifier, start_date, end_date, valid_type, summary_period): counter = counter + float(data['counter']) count = count + 1 - if type == "MEMORY_USAGE": + if valid_type == "MEMORY_USAGE": average = (counter / count) / 2 ** 30 else: average = counter / count From d27a94e51ccae312ad11b0beac86473f15e6701b Mon Sep 17 00:00:00 2001 From: Fernando Ojeda Date: Mon, 29 Apr 2019 15:15:26 -0400 Subject: [PATCH 3/3] Refactor usage vs information. --- SoftLayer/CLI/virt/usage.py | 22 ++++++++++++++-------- tests/CLI/modules/vs/vs_tests.py | 11 ++++++++++- 2 files changed, 24 insertions(+), 9 deletions(-) diff --git a/SoftLayer/CLI/virt/usage.py b/SoftLayer/CLI/virt/usage.py index 68981705c..ec9702216 100644 --- a/SoftLayer/CLI/virt/usage.py +++ b/SoftLayer/CLI/virt/usage.py @@ -5,6 +5,7 @@ import SoftLayer from SoftLayer.CLI import environment +from SoftLayer.CLI import exceptions from SoftLayer.CLI import formatting from SoftLayer.CLI import helpers from SoftLayer.utils import clean_time @@ -31,23 +32,28 @@ def cli(env, identifier, start_date, end_date, valid_type, summary_period): result = vsi.get_summary_data_usage(vs_id, start_date=start_date, end_date=end_date, valid_type=valid_type, summary_period=summary_period) + if len(result) == 0: + raise exceptions.CLIAbort('No metric data for this range of dates provided') + count = 0 - counter = 0.0 + counter = 0.00 for data in result: + if valid_type == "MEMORY_USAGE": + usage_counter = data['counter'] / 2 ** 30 + else: + usage_counter = data['counter'] + table.add_row([ - data['counter'], + round(usage_counter, 2), clean_time(data['dateTime']), data['type'], ]) - counter = counter + float(data['counter']) + counter = counter + usage_counter count = count + 1 - if valid_type == "MEMORY_USAGE": - average = (counter / count) / 2 ** 30 - else: - average = counter / count + average = counter / count - env.fout(table_average.add_row([average])) + env.fout(table_average.add_row([round(average, 2)])) env.fout(table_average) env.fout(table) diff --git a/tests/CLI/modules/vs/vs_tests.py b/tests/CLI/modules/vs/vs_tests.py index 9c5d155fc..7b03bb084 100644 --- a/tests/CLI/modules/vs/vs_tests.py +++ b/tests/CLI/modules/vs/vs_tests.py @@ -681,9 +681,18 @@ def test_usage_vs_cpu(self): self.assert_no_fail(result) def test_usage_vs_memory(self): - result = self.run_command( ['vs', 'usage', '100', '--start_date=2019-3-4', '--end_date=2019-4-2', '--valid_type=MEMORY_USAGE', '--summary_period=300']) self.assert_no_fail(result) + + def test_usage_metric_data_empty(self): + usage_vs = self.set_mock('SoftLayer_Metric_Tracking_Object', 'getSummaryData') + test_usage = [] + usage_vs.return_value = test_usage + result = self.run_command( + ['vs', 'usage', '100', '--start_date=2019-3-4', '--end_date=2019-4-2', '--valid_type=CPU0', + '--summary_period=300']) + self.assertEqual(result.exit_code, 2) + self.assertIsInstance(result.exception, exceptions.CLIAbort)