diff --git a/SoftLayer/CLI/block/count.py b/SoftLayer/CLI/block/count.py new file mode 100644 index 000000000..dc4fb89c1 --- /dev/null +++ b/SoftLayer/CLI/block/count.py @@ -0,0 +1,42 @@ +"""List number of block storage volumes per datacenter.""" +# :license: MIT, see LICENSE for more details. + +import click +import SoftLayer +from SoftLayer.CLI import environment +from SoftLayer.CLI import formatting + +DEFAULT_COLUMNS = [ + 'Datacenter', + 'Count' +] + + +@click.command() +@click.option('--datacenter', '-d', help='Datacenter shortname') +@click.option('--sortby', help='Column to sort by', default='Datacenter') +@environment.pass_env +def cli(env, sortby, datacenter): + """List number of block storage volumes per datacenter.""" + block_manager = SoftLayer.BlockStorageManager(env.client) + mask = "mask[serviceResource[datacenter[name]],"\ + "replicationPartners[serviceResource[datacenter[name]]]]" + block_volumes = block_manager.list_block_volumes(datacenter=datacenter, + mask=mask) + + # cycle through all block volumes and count datacenter occurences. + datacenters = dict() + for volume in block_volumes: + service_resource = volume['serviceResource'] + if 'datacenter' in service_resource: + datacenter_name = service_resource['datacenter']['name'] + if datacenter_name not in datacenters.keys(): + datacenters[datacenter_name] = 1 + else: + datacenters[datacenter_name] += 1 + + table = formatting.KeyValueTable(DEFAULT_COLUMNS) + table.sortby = sortby + for datacenter_name in datacenters: + table.add_row([datacenter_name, datacenters[datacenter_name]]) + env.fout(table) diff --git a/SoftLayer/CLI/block/list.py b/SoftLayer/CLI/block/list.py index 41e09ca30..4cc9afd2b 100644 --- a/SoftLayer/CLI/block/list.py +++ b/SoftLayer/CLI/block/list.py @@ -28,6 +28,8 @@ column_helper.Column('lunId', ('lunId',), mask="lunId"), column_helper.Column('active_transactions', ('activeTransactionCount',), mask="activeTransactionCount"), + column_helper.Column('rep_partner_count', ('replicationPartnerCount',), + mask="replicationPartnerCount"), column_helper.Column( 'created_by', ('billingItem', 'orderItem', 'order', 'userRecord', 'username')), @@ -42,7 +44,8 @@ 'bytes_used', 'ip_addr', 'lunId', - 'active_transactions' + 'active_transactions', + 'rep_partner_count' ] diff --git a/SoftLayer/CLI/file/count.py b/SoftLayer/CLI/file/count.py new file mode 100644 index 000000000..addb14300 --- /dev/null +++ b/SoftLayer/CLI/file/count.py @@ -0,0 +1,41 @@ +"""List number of file storage volumes per datacenter.""" +# :license: MIT, see LICENSE for more details. + +import click +import SoftLayer +from SoftLayer.CLI import environment +from SoftLayer.CLI import formatting + +DEFAULT_COLUMNS = [ + 'Datacenter', + 'Count' +] + + +@click.command() +@click.option('--datacenter', '-d', help='Datacenter shortname') +@click.option('--sortby', help='Column to sort by', default='Datacenter') +@environment.pass_env +def cli(env, sortby, datacenter): + """List number of file storage volumes per datacenter.""" + file_manager = SoftLayer.FileStorageManager(env.client) + mask = "mask[serviceResource[datacenter[name]],"\ + "replicationPartners[serviceResource[datacenter[name]]]]" + file_volumes = file_manager.list_file_volumes(datacenter=datacenter, + mask=mask) + + datacenters = dict() + for volume in file_volumes: + service_resource = volume['serviceResource'] + if 'datacenter' in service_resource: + datacenter_name = service_resource['datacenter']['name'] + if datacenter_name not in datacenters.keys(): + datacenters[datacenter_name] = 1 + else: + datacenters[datacenter_name] += 1 + + table = formatting.KeyValueTable(DEFAULT_COLUMNS) + table.sortby = sortby + for datacenter_name in datacenters: + table.add_row([datacenter_name, datacenters[datacenter_name]]) + env.fout(table) diff --git a/SoftLayer/CLI/file/detail.py b/SoftLayer/CLI/file/detail.py index 3c9af3f23..9bfb37f0c 100644 --- a/SoftLayer/CLI/file/detail.py +++ b/SoftLayer/CLI/file/detail.py @@ -16,8 +16,6 @@ def cli(env, volume_id): file_manager = SoftLayer.FileStorageManager(env.client) file_volume = file_manager.get_file_volume_details(volume_id) file_volume = utils.NestedDict(file_volume) - used_space = int(file_volume['bytesUsed'])\ - if file_volume['bytesUsed'] else 0 table = formatting.KeyValueTable(['Name', 'Value']) table.align['Name'] = 'r' @@ -29,6 +27,8 @@ def cli(env, volume_id): table.add_row(['Type', storage_type]) table.add_row(['Capacity (GB)', "%iGB" % file_volume['capacityGb']]) + used_space = int(file_volume['bytesUsed'])\ + if file_volume['bytesUsed'] else 0 if used_space < (1 << 10): table.add_row(['Used Space', "%dB" % used_space]) elif used_space < (1 << 20): diff --git a/SoftLayer/CLI/file/list.py b/SoftLayer/CLI/file/list.py index 40399538c..86028f4ee 100644 --- a/SoftLayer/CLI/file/list.py +++ b/SoftLayer/CLI/file/list.py @@ -29,6 +29,8 @@ mask="activeTransactionCount"), column_helper.Column('mount_addr', ('fileNetworkMountAddress',), mask="fileNetworkMountAddress",), + column_helper.Column('rep_partner_count', ('replicationPartnerCount',), + mask="replicationPartnerCount"), column_helper.Column( 'created_by', ('billingItem', 'orderItem', 'order', 'userRecord', 'username')), @@ -43,7 +45,8 @@ 'bytes_used', 'ip_addr', 'active_transactions', - 'mount_addr' + 'mount_addr', + 'rep_partner_count' ] diff --git a/SoftLayer/CLI/routes.py b/SoftLayer/CLI/routes.py index fe2bb12f8..682b36651 100644 --- a/SoftLayer/CLI/routes.py +++ b/SoftLayer/CLI/routes.py @@ -76,6 +76,7 @@ ('block:snapshot-order', 'SoftLayer.CLI.block.snapshot.order:cli'), ('block:snapshot-restore', 'SoftLayer.CLI.block.snapshot.restore:cli'), ('block:volume-cancel', 'SoftLayer.CLI.block.cancel:cli'), + ('block:volume-count', 'SoftLayer.CLI.block.count:cli'), ('block:volume-detail', 'SoftLayer.CLI.block.detail:cli'), ('block:volume-duplicate', 'SoftLayer.CLI.block.duplicate:cli'), ('block:volume-list', 'SoftLayer.CLI.block.list:cli'), @@ -100,6 +101,7 @@ ('file:snapshot-order', 'SoftLayer.CLI.file.snapshot.order:cli'), ('file:snapshot-restore', 'SoftLayer.CLI.file.snapshot.restore:cli'), ('file:volume-cancel', 'SoftLayer.CLI.file.cancel:cli'), + ('file:volume-count', 'SoftLayer.CLI.file.count:cli'), ('file:volume-detail', 'SoftLayer.CLI.file.detail:cli'), ('file:volume-duplicate', 'SoftLayer.CLI.file.duplicate:cli'), ('file:volume-list', 'SoftLayer.CLI.file.list:cli'), diff --git a/SoftLayer/fixtures/SoftLayer_Account.py b/SoftLayer/fixtures/SoftLayer_Account.py index 561ff3926..b8005e0ee 100644 --- a/SoftLayer/fixtures/SoftLayer_Account.py +++ b/SoftLayer/fixtures/SoftLayer_Account.py @@ -536,7 +536,7 @@ 'notes': """{'status': 'available'}""", 'password': '', 'serviceProviderId': 1, - 'serviceResource': {'datacenter': {'id': 449500}}, + 'serviceResource': {'datacenter': {'name': 'dal05', 'id': 449500}}, 'serviceResourceBackendIpAddress': '10.1.2.3', 'serviceResourceName': 'Storage Type 01 Aggregate staaspar0101_pc01', 'username': 'username', diff --git a/SoftLayer/managers/block.py b/SoftLayer/managers/block.py index 37e73d6f4..33bb1810b 100644 --- a/SoftLayer/managers/block.py +++ b/SoftLayer/managers/block.py @@ -43,7 +43,8 @@ def list_block_volumes(self, datacenter=None, username=None, 'bytesUsed', 'serviceResource.datacenter[name]', 'serviceResourceBackendIpAddress', - 'activeTransactionCount' + 'activeTransactionCount', + 'replicationPartnerCount' ] kwargs['mask'] = ','.join(items) diff --git a/SoftLayer/managers/file.py b/SoftLayer/managers/file.py index 6caf1f5f1..61e434d43 100644 --- a/SoftLayer/managers/file.py +++ b/SoftLayer/managers/file.py @@ -38,7 +38,8 @@ def list_file_volumes(self, datacenter=None, username=None, 'serviceResource.datacenter[name]', 'serviceResourceBackendIpAddress', 'activeTransactionCount', - 'fileNetworkMountAddress' + 'fileNetworkMountAddress', + 'replicationPartnerCount' ] kwargs['mask'] = ','.join(items) diff --git a/tests/CLI/modules/block_tests.py b/tests/CLI/modules/block_tests.py index c754e25dc..fc9da044f 100644 --- a/tests/CLI/modules/block_tests.py +++ b/tests/CLI/modules/block_tests.py @@ -102,16 +102,35 @@ def test_volume_list(self): { 'bytes_used': None, 'capacity_gb': 20, - 'datacenter': None, + 'datacenter': 'dal05', 'id': 100, 'ip_addr': '10.1.2.3', 'lunId': None, + 'rep_partner_count': None, 'storage_type': 'ENDURANCE', 'username': 'username', 'active_transactions': None }], json.loads(result.output)) + @mock.patch('SoftLayer.BlockStorageManager.list_block_volumes') + def test_volume_count(self, list_mock): + list_mock.return_value = [ + {'serviceResource': {'datacenter': {'name': 'dal05'}}}, + {'serviceResource': {'datacenter': {'name': 'ams01'}}}, + {'serviceResource': {'datacenter': {'name': 'dal05'}}} + ] + + result = self.run_command(['block', 'volume-count']) + + self.assert_no_fail(result) + self.assertEqual( + { + 'dal05': 2, + 'ams01': 1 + }, + json.loads(result.output)) + def test_volume_order_performance_iops_not_given(self): result = self.run_command(['block', 'volume-order', '--storage-type=performance', '--size=20', @@ -354,6 +373,7 @@ def test_replication_locations(self): def test_replication_locations_unsuccessful(self, locations_mock): locations_mock.return_value = False result = self.run_command(['block', 'replica-locations', '1234']) + self.assert_no_fail(result) self.assertEqual('No data centers compatible for replication.\n', result.output) diff --git a/tests/CLI/modules/file_tests.py b/tests/CLI/modules/file_tests.py index 4c96706c5..161d6b0ca 100644 --- a/tests/CLI/modules/file_tests.py +++ b/tests/CLI/modules/file_tests.py @@ -48,10 +48,29 @@ def test_volume_list(self): 'storage_type': 'ENDURANCE', 'username': 'user', 'active_transactions': None, - 'mount_addr': '127.0.0.1:/TEST' + 'mount_addr': '127.0.0.1:/TEST', + 'rep_partner_count': None }], json.loads(result.output)) + @mock.patch('SoftLayer.FileStorageManager.list_file_volumes') + def test_volume_count(self, list_mock): + list_mock.return_value = [ + {'serviceResource': {'datacenter': {'name': 'dal09'}}}, + {'serviceResource': {'datacenter': {'name': 'ams01'}}}, + {'serviceResource': {'datacenter': {'name': 'ams01'}}} + ] + + result = self.run_command(['file', 'volume-count']) + + self.assert_no_fail(result) + self.assertEqual( + { + 'ams01': 2, + 'dal09': 1 + }, + json.loads(result.output)) + def test_snapshot_list(self): result = self.run_command(['file', 'snapshot-list', '1234']) @@ -399,6 +418,7 @@ def test_replication_locations(self): def test_replication_locations_unsuccessful(self, locations_mock): locations_mock.return_value = False result = self.run_command(['file', 'replica-locations', '1234']) + self.assert_no_fail(result) self.assertEqual('No data centers compatible for replication.\n', result.output)