Skip to content

Commit 33cfbfd

Browse files
author
Fernando Ojeda
committed
2 parents 44fb9ff + 0803951 commit 33cfbfd

Some content is hidden

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

49 files changed

+1392
-300
lines changed

.readthedocs.yml

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# .readthedocs.yml
2+
# Read the Docs configuration file
3+
# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
4+
5+
# Required
6+
version: 2
7+
8+
# Build documentation in the docs/ directory with Sphinx
9+
sphinx:
10+
builder: htmldir
11+
configuration: docs/conf.py
12+
13+
# Build documentation with MkDocs
14+
#mkdocs:
15+
# configuration: mkdocs.yml
16+
17+
# Optionally build your docs in additional formats such as PDF and ePub
18+
formats: all
19+
20+
# Optionally set the version of Python and requirements required to build your docs
21+
python:
22+
version: 3.7
23+
install:
24+
- requirements: docs/requirements.txt

.travis.yml

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,20 @@
1+
# https://docs.travis-ci.com/user/languages/python/#python-37-and-higher
2+
dist: xenial
13
language: python
24
sudo: false
35
matrix:
46
include:
5-
- python: "2.7"
6-
env: TOX_ENV=py27
77
- python: "3.5"
88
env: TOX_ENV=py35
99
- python: "3.6"
1010
env: TOX_ENV=py36
11-
- python: "pypy2.7-5.8.0"
11+
- python: "3.7"
12+
env: TOX_ENV=py37
13+
- python: "pypy3.5"
1214
env: TOX_ENV=pypy
13-
- python: "2.7"
15+
- python: "3.6"
1416
env: TOX_ENV=analysis
15-
- python: "2.7"
17+
- python: "3.6"
1618
env: TOX_ENV=coverage
1719
install:
1820
- pip install tox

CHANGELOG.md

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,38 @@
11
# Change Log
22

3+
4+
## [5.7.2] - 2019-05-03
5+
- https://github.com/softlayer/softlayer-python/compare/v5.7.1...v5.7.2
6+
7+
+ #1107 Added exception to handle json parsing error when ordering
8+
+ #1068 Support for -1 when changing port speed
9+
+ #1109 Fixed docs about placement groups
10+
+ #1112 File storage endurance iops upgrade
11+
+ #1101 Handle the new user creation exceptions
12+
+ #1116 Fix order place quantity option
13+
+ #1002 Invoice commands
14+
* account invoices
15+
* account invoice-detail
16+
* account summary
17+
+ #1004 Event Notification Management commands
18+
* account events
19+
* account event-detail
20+
+ #1117 Two PCIe items can be added at order time
21+
+ #1121 Fix object storage apiType for S3 and Swift.
22+
+ #1100 Event Log performance improvements.
23+
+ #872 column 'name' was renamed to 'hostname'
24+
+ #1127 Fix object storage credentials.
25+
+ #1129 Fixed unexpected errors in slcli subnet create
26+
+ #1134 Change encrypt parameters for importing of images. Adds root-key-crn
27+
+ #208 Quote ordering commands
28+
* order quote
29+
* order quote-detail
30+
* order quote-list
31+
+ #1113 VS usage information command
32+
* virtual usage
33+
+ #1131 made sure config_tests dont actually make api calls.
34+
35+
336
## [5.7.1] - 2019-02-26
437
- https://github.com/softlayer/softlayer-python/compare/v5.7.0...v5.7.1
538

README.rst

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,9 @@ http://softlayer.github.io/softlayer-python/.
3131
Additional API documentation can be found on the SoftLayer Development Network:
3232

3333
* `SoftLayer API reference
34-
<http://developer.softlayer.com/reference/softlayerapi>`_
34+
<https://sldn.softlayer.com/reference/softlayerapi>`_
3535
* `Object mask information and examples
36-
<http://developer.softlayer.com/article/Object-Masks>`_
36+
<https://sldn.softlayer.com/article/object-masks>`_
3737
* `Code Examples
3838
<https://softlayer.github.io/python/>`_
3939

@@ -132,12 +132,12 @@ System Requirements
132132
Python Packages
133133
---------------
134134
* six >= 1.7.0
135-
* prettytable >= 0.7.0
136-
* click >= 5, < 7
137-
* requests >= 2.18.4
138-
* prompt_toolkit >= 0.53
135+
* ptable >= 0.9.2
136+
* click >= 7
137+
* requests >= 2.20.0
138+
* prompt_toolkit >= 2
139139
* pygments >= 2.0.0
140-
* urllib3 >= 1.22
140+
* urllib3 >= 1.24
141141

142142
Copyright
143143
---------

RELEASE.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,13 @@
33
* Update version constants (find them by running `git grep [VERSION_NUMBER]`)
44
* Create changelog entry (edit CHANGELOG.md with a one-liner for each closed issue going in the release)
55
* Commit and push changes to master with the message: "Version Bump to v[VERSION_NUMBER]"
6-
* Push tag and PyPi `fab release:[VERSION_NUMBER]`. Before you do this, make sure you have the organization repository set up as upstream remote & fabric installed (`pip install fabric`), also make sure that you have pip set up with your PyPi user credentials. The easiest way to do that is to create a file at `~/.pypirc` with the following contents:
6+
* Make sure your `upstream` repo is set
7+
```
8+
git remote -v
9+
upstream git@github.com:softlayer/softlayer-python.git (fetch)
10+
upstream git@github.com:softlayer/softlayer-python.git (push)
11+
```
12+
* Push tag and PyPi `python fabfile.py 5.7.2`. Before you do this, make sure you have the organization repository set up as upstream remote, also make sure that you have pip set up with your PyPi user credentials. The easiest way to do that is to create a file at `~/.pypirc` with the following contents:
713

814
```
915
[server-login]
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
"""Get details for a hardware device."""
2+
# :license: MIT, see LICENSE for more details.
3+
4+
import click
5+
6+
import SoftLayer
7+
from SoftLayer.CLI import environment
8+
from SoftLayer.CLI import helpers
9+
from SoftLayer.CLI.virt.bandwidth import create_bandwidth_table
10+
11+
12+
@click.command()
13+
@click.argument('identifier')
14+
@click.option('--start_date', '-s', type=click.STRING, required=True,
15+
help="Start Date YYYY-MM-DD, YYYY-MM-DDTHH:mm:ss,")
16+
@click.option('--end_date', '-e', type=click.STRING, required=True,
17+
help="End Date YYYY-MM-DD, YYYY-MM-DDTHH:mm:ss")
18+
@click.option('--summary_period', '-p', type=click.INT, default=3600, show_default=True,
19+
help="300, 600, 1800, 3600, 43200 or 86400 seconds")
20+
@click.option('--quite_summary', '-q', is_flag=True, default=False, show_default=True,
21+
help="Only show the summary table")
22+
@environment.pass_env
23+
def cli(env, identifier, start_date, end_date, summary_period, quite_summary):
24+
"""Bandwidth data over date range. Bandwidth is listed in GB
25+
26+
Using just a date might get you times off by 1 hour, use T00:01 to get just the specific days data
27+
Timezones can also be included with the YYYY-MM-DDTHH:mm:ss.00000-HH:mm format.
28+
29+
Due to some rounding and date alignment details, results here might be slightly different than
30+
results in the control portal.
31+
32+
Example::
33+
34+
slcli hw bandwidth 1234 -s 2019-05-01T00:01 -e 2019-05-02T00:00:01.00000-12:00
35+
"""
36+
hardware = SoftLayer.HardwareManager(env.client)
37+
hardware_id = helpers.resolve_id(hardware.resolve_ids, identifier, 'hardware')
38+
data = hardware.get_bandwidth_data(hardware_id, start_date, end_date, None, summary_period)
39+
40+
title = "Bandwidth Report: %s - %s" % (start_date, end_date)
41+
table, sum_table = create_bandwidth_table(data, summary_period, title)
42+
43+
env.fout(sum_table)
44+
if not quite_summary:
45+
env.fout(table)

SoftLayer/CLI/hardware/detail.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,10 @@ def cli(env, identifier, passwords, price):
5757

5858
table.add_row(['vlans', vlan_table])
5959

60+
bandwidth = hardware.get_bandwidth_allocation(hardware_id)
61+
bw_table = _bw_table(bandwidth)
62+
table.add_row(['Bandwidth', bw_table])
63+
6064
if result.get('notes'):
6165
table.add_row(['notes', result['notes']])
6266

@@ -85,3 +89,17 @@ def cli(env, identifier, passwords, price):
8589
table.add_row(['tags', formatting.tags(result['tagReferences'])])
8690

8791
env.fout(table)
92+
93+
94+
def _bw_table(bw_data):
95+
"""Generates a bandwidth useage table"""
96+
table = formatting.Table(['Type', 'In GB', 'Out GB', 'Allotment'])
97+
for bw_point in bw_data.get('useage'):
98+
bw_type = 'Private'
99+
allotment = 'N/A'
100+
if bw_point['type']['alias'] == 'PUBLIC_SERVER_BW':
101+
bw_type = 'Public'
102+
allotment = bw_data['allotment'].get('amount', '-')
103+
104+
table.add_row([bw_type, bw_point['amountIn'], bw_point['amountOut'], allotment])
105+
return table

SoftLayer/CLI/routes.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
('account:summary', 'SoftLayer.CLI.account.summary:cli'),
2020

2121
('virtual', 'SoftLayer.CLI.virt'),
22+
('virtual:bandwidth', 'SoftLayer.CLI.virt.bandwidth:cli'),
2223
('virtual:cancel', 'SoftLayer.CLI.virt.cancel:cli'),
2324
('virtual:capture', 'SoftLayer.CLI.virt.capture:cli'),
2425
('virtual:create', 'SoftLayer.CLI.virt.create:cli'),
@@ -36,6 +37,7 @@
3637
('virtual:reboot', 'SoftLayer.CLI.virt.power:reboot'),
3738
('virtual:reload', 'SoftLayer.CLI.virt.reload:cli'),
3839
('virtual:upgrade', 'SoftLayer.CLI.virt.upgrade:cli'),
40+
('virtual:usage', 'SoftLayer.CLI.virt.usage:cli'),
3941
('virtual:credentials', 'SoftLayer.CLI.virt.credentials:cli'),
4042
('virtual:capacity', 'SoftLayer.CLI.virt.capacity:cli'),
4143
('virtual:placementgroup', 'SoftLayer.CLI.virt.placementgroup:cli'),
@@ -212,6 +214,7 @@
212214
('rwhois:show', 'SoftLayer.CLI.rwhois.show:cli'),
213215

214216
('hardware', 'SoftLayer.CLI.hardware'),
217+
('hardware:bandwidth', 'SoftLayer.CLI.hardware.bandwidth:cli'),
215218
('hardware:cancel', 'SoftLayer.CLI.hardware.cancel:cli'),
216219
('hardware:cancel-reasons', 'SoftLayer.CLI.hardware.cancel_reasons:cli'),
217220
('hardware:create', 'SoftLayer.CLI.hardware.create:cli'),

SoftLayer/CLI/subnet/create.py

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,25 +10,33 @@
1010

1111

1212
@click.command(short_help="Add a new subnet to your account")
13-
@click.argument('network', type=click.Choice(['public', 'private']))
13+
@click.argument('network', type=click.Choice(['static', 'public', 'private']))
1414
@click.argument('quantity', type=click.INT)
15-
@click.argument('vlan-id')
15+
@click.argument('endpoint-id', type=click.INT)
1616
@click.option('--ipv6', '--v6', is_flag=True, help="Order IPv6 Addresses")
1717
@click.option('--test',
1818
is_flag=True,
1919
help="Do not order the subnet; just get a quote")
2020
@environment.pass_env
21-
def cli(env, network, quantity, vlan_id, ipv6, test):
21+
def cli(env, network, quantity, endpoint_id, ipv6, test):
2222
"""Add a new subnet to your account. Valid quantities vary by type.
2323
2424
\b
25-
Type - Valid Quantities (IPv4)
26-
public - 4, 8, 16, 32
27-
private - 4, 8, 16, 32, 64
25+
IPv4
26+
static - 1, 2, 4, 8, 16, 32, 64, 128, 256
27+
public - 4, 8, 16, 32, 64, 128, 256
28+
private - 4, 8, 16, 32, 64, 128, 256
2829
2930
\b
30-
Type - Valid Quantities (IPv6)
31+
IPv6
32+
static - 64
3133
public - 64
34+
35+
\b
36+
endpoint-id
37+
static - Network_Subnet_IpAddress identifier.
38+
public - Network_Vlan identifier
39+
private - Network_Vlan identifier
3240
"""
3341

3442
mgr = SoftLayer.NetworkManager(env.client)
@@ -43,9 +51,13 @@ def cli(env, network, quantity, vlan_id, ipv6, test):
4351
version = 6
4452

4553
try:
46-
result = mgr.add_subnet(network, quantity=quantity, vlan_id=vlan_id, version=version, test_order=test)
47-
except SoftLayer.SoftLayerAPIError:
48-
raise exceptions.CLIAbort('There is no price id for {} {} ipv{}'.format(quantity, network, version))
54+
result = mgr.add_subnet(network, quantity=quantity, endpoint_id=endpoint_id, version=version, test_order=test)
55+
56+
except SoftLayer.SoftLayerAPIError as error:
57+
raise exceptions.CLIAbort('Unable to order {} {} ipv{} , error: {}'.format(quantity,
58+
network,
59+
version,
60+
error.faultString))
4961

5062
table = formatting.Table(['Item', 'cost'])
5163
table.align['Item'] = 'r'

SoftLayer/CLI/virt/bandwidth.py

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
"""Get details for a hardware device."""
2+
# :license: MIT, see LICENSE for more details.
3+
4+
import click
5+
6+
import SoftLayer
7+
from SoftLayer.CLI import environment
8+
from SoftLayer.CLI import formatting
9+
from SoftLayer.CLI import helpers
10+
from SoftLayer import utils
11+
12+
13+
@click.command()
14+
@click.argument('identifier')
15+
@click.option('--start_date', '-s', type=click.STRING, required=True,
16+
help="Start Date YYYY-MM-DD, YYYY-MM-DDTHH:mm:ss,")
17+
@click.option('--end_date', '-e', type=click.STRING, required=True,
18+
help="End Date YYYY-MM-DD, YYYY-MM-DDTHH:mm:ss")
19+
@click.option('--summary_period', '-p', type=click.INT, default=3600, show_default=True,
20+
help="300, 600, 1800, 3600, 43200 or 86400 seconds")
21+
@click.option('--quite_summary', '-q', is_flag=True, default=False, show_default=True,
22+
help="Only show the summary table")
23+
@environment.pass_env
24+
def cli(env, identifier, start_date, end_date, summary_period, quite_summary):
25+
"""Bandwidth data over date range. Bandwidth is listed in GB
26+
27+
Using just a date might get you times off by 1 hour, use T00:01 to get just the specific days data
28+
Timezones can also be included with the YYYY-MM-DDTHH:mm:ss.00000-HH:mm format.
29+
30+
Due to some rounding and date alignment details, results here might be slightly different than
31+
results in the control portal.
32+
33+
Example::
34+
35+
slcli hw bandwidth 1234 -s 2019-05-01T00:01 -e 2019-05-02T00:00:01.00000-12:00
36+
"""
37+
vsi = SoftLayer.VSManager(env.client)
38+
vsi_id = helpers.resolve_id(vsi.resolve_ids, identifier, 'VS')
39+
data = vsi.get_bandwidth_data(vsi_id, start_date, end_date, None, summary_period)
40+
41+
title = "Bandwidth Report: %s - %s" % (start_date, end_date)
42+
table, sum_table = create_bandwidth_table(data, summary_period, title)
43+
44+
env.fout(sum_table)
45+
if not quite_summary:
46+
env.fout(table)
47+
48+
49+
def create_bandwidth_table(data, summary_period, title="Bandwidth Report"):
50+
"""Create 2 tables, bandwidth and sumamry. Used here and in hw bandwidth command"""
51+
52+
formatted_data = {}
53+
for point in data:
54+
key = utils.clean_time(point['dateTime'])
55+
data_type = point['type']
56+
# conversion from byte to megabyte
57+
value = round(float(point['counter']) / 2 ** 20, 4)
58+
if formatted_data.get(key) is None:
59+
formatted_data[key] = {}
60+
formatted_data[key][data_type] = float(value)
61+
62+
table = formatting.Table(['Date', 'Pub In', 'Pub Out', 'Pri In', 'Pri Out'], title=title)
63+
64+
sum_table = formatting.Table(['Type', 'Sum GB', 'Average MBps', 'Max GB', 'Max Date'], title="Summary")
65+
66+
# Required to specify keyName because getBandwidthTotals returns other counter types for some reason.
67+
bw_totals = [
68+
{'keyName': 'publicIn_net_octet', 'sum': 0.0, 'max': 0, 'name': 'Pub In'},
69+
{'keyName': 'publicOut_net_octet', 'sum': 0.0, 'max': 0, 'name': 'Pub Out'},
70+
{'keyName': 'privateIn_net_octet', 'sum': 0.0, 'max': 0, 'name': 'Pri In'},
71+
{'keyName': 'privateOut_net_octet', 'sum': 0.0, 'max': 0, 'name': 'Pri Out'},
72+
]
73+
74+
for point in formatted_data:
75+
new_row = [point]
76+
for bw_type in bw_totals:
77+
counter = formatted_data[point].get(bw_type['keyName'], 0)
78+
new_row.append(mb_to_gb(counter))
79+
bw_type['sum'] = bw_type['sum'] + counter
80+
if counter > bw_type['max']:
81+
bw_type['max'] = counter
82+
bw_type['maxDate'] = point
83+
table.add_row(new_row)
84+
85+
for bw_type in bw_totals:
86+
total = bw_type.get('sum', 0.0)
87+
average = 0
88+
if total > 0:
89+
average = round(total / len(formatted_data) / summary_period, 4)
90+
sum_table.add_row([
91+
bw_type.get('name'),
92+
mb_to_gb(total),
93+
average,
94+
mb_to_gb(bw_type.get('max')),
95+
bw_type.get('maxDate')
96+
])
97+
98+
return table, sum_table
99+
100+
101+
def mb_to_gb(mbytes):
102+
"""Converts a MegaByte int to GigaByte. mbytes/2^10"""
103+
return round(mbytes / 2 ** 10, 4)

0 commit comments

Comments
 (0)