Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 55 additions & 0 deletions SoftLayer/CLI/block/count.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
"""List number of block storage volumes per datacenter."""
# :license: MIT, see LICENSE for more details.

import click
import SoftLayer
from SoftLayer.CLI import columns as column_helper
from SoftLayer.CLI import environment
from SoftLayer.CLI import formatting

COLUMNS = [
column_helper.Column('Datacenter',
('serviceResource', 'datacenter', 'name'),
mask="serviceResource.datacenter.name"),
column_helper.Column('Count',
'',
mask=None)
]

DEFAULT_COLUMNS = [
'Datacenter',
'Count'
]


@click.command()
@click.option('--datacenter', '-d', help='Datacenter shortname')
@click.option('--sortby', help='Column to sort by', default='Datacenter')
@click.option('--columns',
callback=column_helper.get_formatter(COLUMNS),
help='Columns to display. Options: {0}'.format(
', '.join(column.name for column in COLUMNS)),
default=','.join(DEFAULT_COLUMNS))
@environment.pass_env
def cli(env, sortby, columns, datacenter):
"""List number of block storage volumes per datacenter."""
block_manager = SoftLayer.BlockStorageManager(env.client)
block_volumes = block_manager.list_block_volumes(datacenter=datacenter,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same comment as in the file volume-count CLI command

mask=columns.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 = service_resource['datacenter']['name']
if datacenter not in datacenters.keys():
datacenters[datacenter] = 1
else:
datacenters[datacenter] += 1

table = formatting.KeyValueTable(columns.columns)
table.sortby = sortby
for datacenter in datacenters:
table.add_row([datacenter, datacenters[datacenter]])
env.fout(table)
1 change: 0 additions & 1 deletion SoftLayer/CLI/block/detail.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ def cli(env, volume_id):
block_manager = SoftLayer.BlockStorageManager(env.client)
block_volume = block_manager.get_block_volume_details(volume_id)
block_volume = utils.NestedDict(block_volume)

table = formatting.KeyValueTable(['Name', 'Value'])
table.align['Name'] = 'r'
table.align['Value'] = 'l'
Expand Down
5 changes: 4 additions & 1 deletion SoftLayer/CLI/block/list.py
Original file line number Diff line number Diff line change
Expand Up @@ -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')),
Expand All @@ -42,7 +44,8 @@
'bytes_used',
'ip_addr',
'lunId',
'active_transactions'
'active_transactions',
'rep_partner_count'
]


Expand Down
55 changes: 55 additions & 0 deletions SoftLayer/CLI/file/count.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
"""List number of file storage volumes per datacenter."""
# :license: MIT, see LICENSE for more details.

import click
import SoftLayer
from SoftLayer.CLI import columns as column_helper
from SoftLayer.CLI import environment
from SoftLayer.CLI import formatting

COLUMNS = [
column_helper.Column('Datacenter',
('serviceResource', 'datacenter', 'name'),
mask="serviceResource.datacenter.name"),
column_helper.Column('Count',
'',
mask=None)
]

DEFAULT_COLUMNS = [
'Datacenter',
'Count'
]


@click.command()
@click.option('--datacenter', '-d', help='Datacenter shortname')
@click.option('--sortby', help='Column to sort by', default='Datacenter')
@click.option('--columns',
callback=column_helper.get_formatter(COLUMNS),
help='Columns to display. Options: {0}'.format(
', '.join(column.name for column in COLUMNS)),
default=','.join(DEFAULT_COLUMNS))
@environment.pass_env
def cli(env, sortby, columns, datacenter):
"""List number of file storage volumes per datacenter."""

file_manager = SoftLayer.FileStorageManager(env.client)
file_volumes = file_manager.list_file_volumes(datacenter=datacenter,
mask=columns.mask())
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

instead of modifying the mask in the manager, just do something like this. fix the line width so tox doesn't complain about it too.

    mask = "mask[serviceResource[datacenter[name]],replicationPartners[serviceResource[datacenter[name]]]]"
    block_volumes = block_manager.list_block_volumes(datacenter=datacenter,
                                                     mask=mask)


datacenters = dict()
for volume in file_volumes:
service_resource = volume['serviceResource']
if 'datacenter' in service_resource:
datacenter = service_resource['datacenter']['name']
if datacenter not in datacenters.keys():
datacenters[datacenter] = 1
else:
datacenters[datacenter] += 1

table = formatting.KeyValueTable(columns.columns)
table.sortby = sortby
for datacenter in datacenters:
table.add_row([datacenter, datacenters[datacenter]])
env.fout(table)
5 changes: 4 additions & 1 deletion SoftLayer/CLI/file/list.py
Original file line number Diff line number Diff line change
Expand Up @@ -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')),
Expand All @@ -43,7 +45,8 @@
'bytes_used',
'ip_addr',
'active_transactions',
'mount_addr'
'mount_addr',
'rep_partner_count'
]


Expand Down
2 changes: 2 additions & 0 deletions SoftLayer/CLI/routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@
('block:volume-detail', 'SoftLayer.CLI.block.detail:cli'),
('block:volume-list', 'SoftLayer.CLI.block.list:cli'),
('block:volume-order', 'SoftLayer.CLI.block.order:cli'),
('block:volume-count', 'SoftLayer.CLI.block.count:cli'),

('file', 'SoftLayer.CLI.file'),
('file:access-authorize', 'SoftLayer.CLI.file.access.authorize:cli'),
Expand All @@ -100,6 +101,7 @@
('file:volume-detail', 'SoftLayer.CLI.file.detail:cli'),
('file:volume-list', 'SoftLayer.CLI.file.list:cli'),
('file:volume-order', 'SoftLayer.CLI.file.order:cli'),
('file:volume-count', 'SoftLayer.CLI.file.count:cli'),

('firewall', 'SoftLayer.CLI.firewall'),
('firewall:add', 'SoftLayer.CLI.firewall.add:cli'),
Expand Down
2 changes: 1 addition & 1 deletion SoftLayer/fixtures/SoftLayer_Account.py
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand Down
18 changes: 17 additions & 1 deletion SoftLayer/managers/block.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,17 +41,33 @@ def list_block_volumes(self, datacenter=None, username=None,
'bytesUsed',
'serviceResource.datacenter[name]',
'serviceResourceBackendIpAddress',
'activeTransactionCount'
'activeTransactionCount',
'replicationPartnerCount',
',replicationPartners[id,username,'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"," at the start and end of the lines are not needed, as they are added by the join at the botton

'serviceResourceBackendIpAddress,'
'serviceResource[datacenter[name]],'
'storageType,capacityGb,lunId,bytesUsed,'
'activeTransactionCount,'
'replicationSchedule[type[keyname]]]',
]
kwargs['mask'] = ','.join(items)

# Retrieve relevant replicant information to be displayed.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These items are already in the mask above. Remove this section.

kwargs['mask'] += ',replicationPartners[id,username,'\
'serviceResourceBackendIpAddress,'\
'serviceResource[datacenter[name]],'\
'storageType,capacityGb,lunId,bytesUsed,'\
'activeTransactionCount,'\
'replicationSchedule[type[keyname]]]'

_filter = utils.NestedDict(kwargs.get('filter') or {})

_filter['iscsiNetworkStorage']['serviceResource']['type']['type'] = \
(utils.query_filter('!~ ISCSI'))

_filter['iscsiNetworkStorage']['storageType']['keyName'] = (
utils.query_filter('*BLOCK_STORAGE*'))

if storage_type:
_filter['iscsiNetworkStorage']['storageType']['keyName'] = (
utils.query_filter('%s_BLOCK_STORAGE' % storage_type.upper()))
Expand Down
17 changes: 16 additions & 1 deletion SoftLayer/managers/file.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,25 @@ def list_file_volumes(self, datacenter=None, username=None,
'serviceResource.datacenter[name]',
'serviceResourceBackendIpAddress',
'activeTransactionCount',
'fileNetworkMountAddress'
'fileNetworkMountAddress',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same comments as the block section

'replicationPartnerCount',
',replicationPartners[id,username,'
'serviceResourceBackendIpAddress,'
'serviceResource[datacenter[name]],'
'storageType,capacityGb,lunId,bytesUsed,'
'activeTransactionCount,'
'replicationSchedule[type[keyname]]]',
]
kwargs['mask'] = ','.join(items)

# Retrieve relevant replicant information to be displayed.
kwargs['mask'] += ',replicationPartners[id,username,'\
'serviceResourceBackendIpAddress,'\
'serviceResource[datacenter[name]],'\
'storageType,capacityGb,lunId,bytesUsed,'\
'activeTransactionCount,'\
'replicationSchedule[type[keyname]]]'

_filter = utils.NestedDict(kwargs.get('filter') or {})

_filter['nasNetworkStorage']['serviceResource']['type']['type'] = \
Expand Down
90 changes: 48 additions & 42 deletions docs/cli.rst
Original file line number Diff line number Diff line change
Expand Up @@ -58,48 +58,54 @@ To discover the available commands, simply type `slcli`.
::

$ slcli
Usage: slcli [OPTIONS] COMMAND [ARGS]...

SoftLayer Command-line Client

Options:
--format [table|raw|json] Output format
-C, --config PATH Config file location
--debug [0|1|2|3] Sets the debug noise level
-v, --verbose Sets the debug noise level
--timings Time each API call and display after results
--proxy TEXT HTTP[S] proxy to be use to make API calls
-y, --really Confirm all prompt actions
--fixtures Use fixtures instead of actually making API calls
--version Show the version and exit.
--help Show this message and exit.

Commands:
call-api Call arbitrary API endpoints.
cdn Content Delivery Network.
config CLI configuration.
dns Domain Name System.
firewall Firewalls.
globalip Global IP addresses.
image Compute images.
iscsi iSCSI storage.
loadbal Load balancers.
messaging Message queue service.
metadata Find details about this machine.
nas Network Attached Storage.
rwhois Referral Whois.
server Hardware servers.
snapshot Snapshots.
sshkey SSH Keys.
ssl SSL Certificates.
subnet Network subnets.
summary Account summary.
ticket Support tickets.
vlan Network VLANs.
vs Virtual Servers.

To use most commands your SoftLayer username and api_key need to be
configured. The easiest way to do that is to use: 'slcli setup'
Usage: slcli [OPTIONS] COMMAND [ARGS]...

SoftLayer Command-line Client

Options:
--format [table|raw|json|jsonraw]
Output format [default: table]
-C, --config PATH Config file location [default:
~/.softlayer]
-v, --verbose Sets the debug noise level, specify multiple
times for more verbosity.
--proxy TEXT HTTP[S] proxy to be use to make API calls
-y, --really / --not-really Confirm all prompt actions
--demo / --no-demo Use demo data instead of actually making API
calls
--version Show the version and exit.
-h, --help Show this message and exit.

Commands:
block Block Storage.
call-api Call arbitrary API endpoints.
cdn Content Delivery Network.
config CLI configuration.
dns Domain Name System.
file File Storage.
firewall Firewalls.
globalip Global IP addresses.
hardware Hardware servers.
image Compute images.
loadbal Load balancers.
messaging Message queue service.
metadata Find details about this machine.
nas Network Attached Storage.
object-storage Object Storage.
report Reports.
rwhois Referral Whois.
setup Edit configuration.
shell Enters a shell for slcli.
sshkey SSH Keys.
ssl SSL Certificates.
subnet Network subnets.
summary Account summary.
ticket Support tickets.
virtual Virtual Servers.
vlan Network VLANs.

To use most commands your SoftLayer username and api_key need to be
configured. The easiest way to do that is to use: 'slcli setup'

As you can see, there are a number of commands/sections. To look at the list of
subcommands for virtual servers type `slcli vs`. For example:
Expand Down
14 changes: 13 additions & 1 deletion tests/CLI/modules/block_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,16 +105,27 @@ 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))

def test_volume_count(self):
result = self.run_command(['block', 'volume-count'])

self.assert_no_fail(result)
self.assertEqual(
{
'dal05': 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',
Expand Down Expand Up @@ -357,6 +368,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)

Expand Down
Loading