Skip to content

Commit 2e5ed6b

Browse files
author
Han Z
committed
msg
2 parents e629bdb + aa3879e commit 2e5ed6b

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

63 files changed

+2175
-312
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,5 @@ dist/*
1414
*.egg-info
1515
.cache
1616
.idea
17+
.pytest_cache/*
18+
slcli

CHANGELOG.md

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,24 @@
11
# Change Log
22

3+
## [5.5.0] - 2018-07-09
4+
- Changes: https://github.com/softlayer/softlayer-python/compare/v5.4.4...master
5+
6+
- Added a warning when ordering legacy storage volumes
7+
- Added documentation link to volume-order
8+
- Increased slcli output width limit to 999 characters
9+
- More unit tests
10+
- Fixed an issue canceling some block storage volumes
11+
- Fixed `slcli order` to work with network gateways
12+
- Fixed an issue showing hardware credentials when they do not exist
13+
- Fixed an issue showing addressSpace when listing virtual servers
14+
- Updated ordering class to support baremetal servers with multiple GPU
15+
- Updated prompt-toolkit as a fix for `slcli shell`
16+
- Fixed `slcli vlan detail` to not fail when objects don't have a hostname
17+
- Added user management
18+
319

420
## [5.4.4] - 2018-04-18
5-
- Changes: https://github.com/softlayer/softlayer-python/compare/v5.4.3...master
21+
- Changes: https://github.com/softlayer/softlayer-python/compare/v5.4.3...v5.4.4
622

723
- fixed hw list not showing transactions
824
- Re-factored RestTransport and XMLRPCTransport, logging is now only done in the DebugTransport

README.rst

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,49 @@ Bugs and feature requests about this library should have a `GitHub issue <https:
7272

7373
Issues with the Softlayer API itself should be addressed by opening a ticket.
7474

75+
76+
Examples
77+
--------
78+
79+
A curated list of examples on how to use this library can be found at `softlayer.github.io <https://softlayer.github.io/python/>`_
80+
81+
Debugging
82+
---------
83+
To get the exact API call that this library makes, you can do the following.
84+
85+
For the CLI, just use the -vvv option. If you are using the REST endpoint, this will print out a curl command that you can use, if using XML, this will print the minimal python code to make the request without the softlayer library.
86+
87+
.. code-block:: bash
88+
$ slcli -vvv vs list
89+
90+
91+
If you are using the library directly in python, you can do something like this.
92+
93+
.. code-bock:: python
94+
import SoftLayer
95+
import logging
96+
97+
class invoices():
98+
99+
def __init__(self):
100+
self.client = SoftLayer.Client()
101+
debugger = SoftLayer.DebugTransport(self.client.transport)
102+
self.client.transport = debugger
103+
104+
def main(self):
105+
mask = "mask[id]"
106+
account = self.client.call('Account', 'getObject', mask=mask);
107+
print("AccountID: %s" % account['id'])
108+
109+
def debug(self):
110+
for call in self.client.transport.get_last_calls():
111+
print(self.client.transport.print_reproduceable(call))
112+
113+
if __name__ == "__main__":
114+
main = example()
115+
main.main()
116+
main.debug()
117+
75118
System Requirements
76119
-------------------
77120
* Python 2.7, 3.3, 3.4, 3.5 or 3.6.

SoftLayer/API.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -333,6 +333,7 @@ class Service(object):
333333
:param name str: The service name
334334
335335
"""
336+
336337
def __init__(self, client, name):
337338
self.client = client
338339
self.name = name

SoftLayer/CLI/block/list.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
mask="storageType.keyName"),
2424
column_helper.Column('capacity_gb', ('capacityGb',), mask="capacityGb"),
2525
column_helper.Column('bytes_used', ('bytesUsed',), mask="bytesUsed"),
26+
column_helper.Column('iops', ('iops',), mask="iops"),
2627
column_helper.Column('ip_addr', ('serviceResourceBackendIpAddress',),
2728
mask="serviceResourceBackendIpAddress"),
2829
column_helper.Column('lunId', ('lunId',), mask="lunId"),
@@ -42,6 +43,7 @@
4243
'storage_type',
4344
'capacity_gb',
4445
'bytes_used',
46+
'iops',
4547
'ip_addr',
4648
'lunId',
4749
'active_transactions',

SoftLayer/CLI/columns.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
class Column(object):
1616
"""Column desctribes an attribute and how to fetch/display it."""
17+
1718
def __init__(self, name, path, mask=None):
1819
self.name = name
1920
self.path = path
@@ -26,6 +27,7 @@ def __init__(self, name, path, mask=None):
2627

2728
class ColumnFormatter(object):
2829
"""Maps each column using a function"""
30+
2931
def __init__(self):
3032
self.columns = []
3133
self.column_funcs = []

SoftLayer/CLI/core.py

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -115,17 +115,22 @@ def cli(env,
115115
**kwargs):
116116
"""Main click CLI entry-point."""
117117

118-
logger = logging.getLogger()
119-
logger.addHandler(logging.StreamHandler())
120-
logger.setLevel(DEBUG_LOGGING_MAP.get(verbose, logging.DEBUG))
121-
122118
# Populate environement with client and set it as the context object
123119
env.skip_confirmations = really
124120
env.config_file = config
125121
env.format = format
126122
env.ensure_client(config_file=config, is_demo=demo, proxy=proxy)
127-
128123
env.vars['_start'] = time.time()
124+
logger = logging.getLogger()
125+
126+
if demo is False:
127+
logger.addHandler(logging.StreamHandler())
128+
else:
129+
# This section is for running CLI tests.
130+
logging.getLogger("urllib3").setLevel(logging.WARNING)
131+
logger.addHandler(logging.NullHandler())
132+
133+
logger.setLevel(DEBUG_LOGGING_MAP.get(verbose, logging.DEBUG))
129134
env.vars['_timings'] = SoftLayer.DebugTransport(env.client.transport)
130135
env.client.transport = env.vars['_timings']
131136

SoftLayer/CLI/exceptions.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
# pylint: disable=keyword-arg-before-vararg
1111
class CLIHalt(SystemExit):
1212
"""Smoothly halt the execution of the command. No error."""
13+
1314
def __init__(self, code=0, *args):
1415
super(CLIHalt, self).__init__(*args)
1516
self.code = code
@@ -23,13 +24,15 @@ def __str__(self):
2324

2425
class CLIAbort(CLIHalt):
2526
"""Halt the execution of the command. Gives an exit code of 2."""
27+
2628
def __init__(self, msg, *args):
2729
super(CLIAbort, self).__init__(code=2, *args)
2830
self.message = msg
2931

3032

3133
class ArgumentError(CLIAbort):
3234
"""Halt the execution of the command because of invalid arguments."""
35+
3336
def __init__(self, msg, *args):
3437
super(ArgumentError, self).__init__(msg, *args)
3538
self.message = "Argument Error: %s" % msg

SoftLayer/CLI/file/snapshot/schedule_list.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ def cli(env, volume_id):
6363
file_schedule_type,
6464
replication,
6565
schedule.get('createDate', '')
66-
]
66+
]
6767
table_row.extend(schedule_properties)
6868
table.add_row(table_row)
6969

SoftLayer/CLI/formatting.py

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,21 @@
11
"""
22
SoftLayer.formatting
33
~~~~~~~~~~~~~~~~~~~~
4-
Provider classes and helper functions to display output onto a
5-
command-line.
4+
Provider classes and helper functions to display output onto a command-line.
65
7-
:license: MIT, see LICENSE for more details.
86
"""
97
# pylint: disable=E0202, consider-merging-isinstance, arguments-differ, keyword-arg-before-vararg
108
import collections
119
import json
1210
import os
1311

1412
import click
15-
import prettytable
13+
14+
# If both PTable and prettytable are installed, its impossible to use the new version
15+
try:
16+
from prettytable import prettytable
17+
except ImportError:
18+
import prettytable
1619

1720
from SoftLayer.CLI import exceptions
1821
from SoftLayer import utils
@@ -229,6 +232,7 @@ class SequentialOutput(list):
229232
230233
:param separator str: string to use as a default separator
231234
"""
235+
232236
def __init__(self, separator=os.linesep, *args, **kwargs):
233237
self.separator = separator
234238
super(SequentialOutput, self).__init__(*args, **kwargs)
@@ -243,6 +247,7 @@ def __str__(self):
243247

244248
class CLIJSONEncoder(json.JSONEncoder):
245249
"""A JSON encoder which is able to use a .to_python() method on objects."""
250+
246251
def default(self, obj):
247252
"""Encode object if it implements to_python()."""
248253
if hasattr(obj, 'to_python'):
@@ -255,7 +260,8 @@ class Table(object):
255260
256261
:param list columns: a list of column names
257262
"""
258-
def __init__(self, columns):
263+
264+
def __init__(self, columns, title=None):
259265
duplicated_cols = [col for col, count
260266
in collections.Counter(columns).items()
261267
if count > 1]
@@ -267,6 +273,7 @@ def __init__(self, columns):
267273
self.rows = []
268274
self.align = {}
269275
self.sortby = None
276+
self.title = title
270277

271278
def add_row(self, row):
272279
"""Add a row to the table.
@@ -287,6 +294,7 @@ def to_python(self):
287294
def prettytable(self):
288295
"""Returns a new prettytable instance."""
289296
table = prettytable.PrettyTable(self.columns)
297+
290298
if self.sortby:
291299
if self.sortby in self.columns:
292300
table.sortby = self.sortby
@@ -296,6 +304,8 @@ def prettytable(self):
296304
for a_col, alignment in self.align.items():
297305
table.align[a_col] = alignment
298306

307+
if self.title:
308+
table.title = self.title
299309
# Adding rows
300310
for row in self.rows:
301311
table.add_row(row)
@@ -304,6 +314,7 @@ def prettytable(self):
304314

305315
class KeyValueTable(Table):
306316
"""A table that is oriented towards key-value pairs."""
317+
307318
def to_python(self):
308319
"""Decode this KeyValueTable object to standard Python types."""
309320
mapping = {}
@@ -318,6 +329,7 @@ class FormattedItem(object):
318329
:param original: raw (machine-readable) value
319330
:param string formatted: human-readable value
320331
"""
332+
321333
def __init__(self, original, formatted=None):
322334
self.original = original
323335
if formatted is not None:

0 commit comments

Comments
 (0)