Skip to content

Commit 052ac2d

Browse files
Daniel Cabero BarriosDaniel Cabero Barrios
authored andcommitted
Merge branch 'master' of https://github.com/softlayer/softlayer-python into issue887
2 parents 790b3b6 + 23a748a commit 052ac2d

Some content is hidden

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

54 files changed

+2197
-93
lines changed
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
name: softlayer
2+
3+
on:
4+
push:
5+
branches: [ master ]
6+
pull_request:
7+
branches: [ master ]
8+
jobs:
9+
build:
10+
runs-on: ubuntu-latest
11+
strategy:
12+
matrix:
13+
python-version: [3.8]
14+
15+
steps:
16+
- uses: actions/checkout@v2
17+
- name: Set up Python ${{ matrix.python-version }}
18+
uses: actions/setup-python@v1
19+
with:
20+
python-version: ${{ matrix.python-version }}
21+
- name: Install dependencies
22+
run: |
23+
python -m pip install --upgrade pip
24+
pip install -r tools/test-requirements.txt
25+
- name: Documentation Checks
26+
run: |
27+
python docCheck.py

CHANGELOG.md

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,21 @@
11
# Change Log
22

3-
4-
## [5.8.5] - 2012-01-29
3+
## [5.8.7] - 2020-03-26
4+
https://github.com/softlayer/softlayer-python/compare/v5.8.5...v5.8.7
5+
6+
- #1222 Get load balancer (LBaaS) by name
7+
- #1221 Added version checker
8+
- #1227 Updated unit test suite for TravisCI to run properly
9+
- #1225 Add note about using multiple colon symbols not working when setting tags.
10+
- #1228 Support ordering [Dependent Duplicate Volumes](https://cloud.ibm.com/docs/BlockStorage?topic=BlockStorage-dependentduplicate)
11+
- #1233 Refactored File/Block managers to reduce duplicated code.
12+
- #1231 Added Refresh functions for Dependent Duplicate Volumes
13+
- #801 Added support for JSON styled parameters and object filters
14+
- #1234 Added ability to change which datacenters an image template was stored in
15+
16+
## [5.8.6] - Skipped
17+
18+
## [5.8.5] - 2020-01-29
519
https://github.com/softlayer/softlayer-python/compare/v5.8.4...v5.8.5
620

721
- #1195 Fixed an issue with `slcli vs dns-sync --ptr`. Added `slcli hw dns-sync`
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
"""Lists all active billing items on this account. See https://cloud.ibm.com/billing/billing-items"""
2+
# :license: MIT, see LICENSE for more details.
3+
import click
4+
5+
from SoftLayer.CLI import environment
6+
from SoftLayer.CLI import formatting
7+
from SoftLayer.managers.account import AccountManager as AccountManager
8+
from SoftLayer import utils
9+
10+
11+
@click.command()
12+
@environment.pass_env
13+
def cli(env):
14+
"""Lists billing items with some other useful information.
15+
16+
Similiar to https://cloud.ibm.com/billing/billing-items
17+
"""
18+
19+
manager = AccountManager(env.client)
20+
items = manager.get_account_billing_items()
21+
table = item_table(items)
22+
23+
env.fout(table)
24+
25+
26+
def item_table(items):
27+
"""Formats a table for billing items"""
28+
table = formatting.Table([
29+
"Id",
30+
"Create Date",
31+
"Cost",
32+
"Category Code",
33+
"Ordered By",
34+
"Description",
35+
"Notes"
36+
], title="Billing Items")
37+
table.align['Description'] = 'l'
38+
table.align['Category Code'] = 'l'
39+
for item in items:
40+
description = item.get('description')
41+
fqdn = "{}.{}".format(item.get('hostName', ''), item.get('domainName', ''))
42+
if fqdn != ".":
43+
description = fqdn
44+
user = utils.lookup(item, 'orderItem', 'order', 'userRecord')
45+
ordered_by = "IBM"
46+
create_date = utils.clean_time(item.get('createDate'), in_format='%Y-%m-%d', out_format='%Y-%m-%d')
47+
if user:
48+
# ordered_by = "{} ({})".format(user.get('displayName'), utils.lookup(user, 'userStatus', 'name'))
49+
ordered_by = user.get('displayName')
50+
51+
table.add_row([
52+
item.get('id'),
53+
create_date,
54+
item.get('nextInvoiceTotalRecurringAmount'),
55+
item.get('categoryCode'),
56+
ordered_by,
57+
utils.trim_to(description, 50),
58+
utils.trim_to(item.get('notes', 'None'), 40),
59+
])
60+
return table
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
"""Cancels a billing item."""
2+
# :license: MIT, see LICENSE for more details.
3+
import click
4+
5+
from SoftLayer.CLI import environment
6+
from SoftLayer.managers.account import AccountManager as AccountManager
7+
8+
9+
@click.command()
10+
@click.argument('identifier')
11+
@environment.pass_env
12+
def cli(env, identifier):
13+
"""Cancels a billing item."""
14+
15+
manager = AccountManager(env.client)
16+
item = manager.cancel_item(identifier)
17+
18+
env.fout(item)
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
"""Gets some details about a specific billing item."""
2+
# :license: MIT, see LICENSE for more details.
3+
import click
4+
5+
from SoftLayer.CLI import environment
6+
from SoftLayer.CLI import formatting
7+
from SoftLayer.managers.account import AccountManager as AccountManager
8+
from SoftLayer import utils
9+
10+
11+
@click.command()
12+
@click.argument('identifier')
13+
@environment.pass_env
14+
def cli(env, identifier):
15+
"""Gets detailed information about a billing item."""
16+
manager = AccountManager(env.client)
17+
item = manager.get_billing_item(identifier)
18+
env.fout(item_table(item))
19+
20+
21+
def item_table(item):
22+
"""Formats a table for billing items"""
23+
24+
date_format = '%Y-%m-%d'
25+
table = formatting.KeyValueTable(["Key", "Value"], title="{}".format(item.get('description', 'Billing Item')))
26+
table.add_row(['createDate', utils.clean_time(item.get('createDate'), date_format, date_format)])
27+
table.add_row(['cycleStartDate', utils.clean_time(item.get('cycleStartDate'), date_format, date_format)])
28+
table.add_row(['cancellationDate', utils.clean_time(item.get('cancellationDate'), date_format, date_format)])
29+
table.add_row(['description', item.get('description')])
30+
fqdn = "{}.{}".format(item.get('hostName'), item.get('domain'))
31+
if fqdn != ".":
32+
table.add_row(['FQDN', fqdn])
33+
34+
if item.get('hourlyFlag', False):
35+
table.add_row(['hourlyRecurringFee', item.get('hourlyRecurringFee')])
36+
table.add_row(['hoursUsed', item.get('hoursUsed')])
37+
table.add_row(['currentHourlyCharge', item.get('currentHourlyCharge')])
38+
else:
39+
table.add_row(['recurringFee', item.get('recurringFee')])
40+
41+
ordered_by = "IBM"
42+
user = utils.lookup(item, 'orderItem', 'order', 'userRecord')
43+
if user:
44+
ordered_by = "{} ({})".format(user.get('displayName'), utils.lookup(user, 'userStatus', 'name'))
45+
table.add_row(['Ordered By', ordered_by])
46+
table.add_row(['Notes', item.get('notes')])
47+
table.add_row(['Location', utils.lookup(item, 'location', 'name')])
48+
if item.get('children'):
49+
for child in item.get('children'):
50+
table.add_row([child.get('categoryCode'), child.get('description')])
51+
52+
return table

SoftLayer/CLI/hardware/billing.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
"""Get billing 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+
@environment.pass_env
16+
def cli(env, identifier):
17+
"""Get billing for a hardware device."""
18+
hardware = SoftLayer.HardwareManager(env.client)
19+
20+
hardware_id = helpers.resolve_id(hardware.resolve_ids, identifier, 'hardware')
21+
result = hardware.get_hardware(hardware_id)
22+
table = formatting.KeyValueTable(['name', 'value'])
23+
table.align['name'] = 'r'
24+
table.align['value'] = 'l'
25+
26+
table.add_row(['Id', identifier])
27+
28+
table.add_row(['Billing Item Id', utils.lookup(result, 'billingItem', 'id')])
29+
table.add_row(['Recurring Fee', utils.lookup(result, 'billingItem', 'recurringFee')])
30+
table.add_row(['Total', utils.lookup(result, 'billingItem', 'nextInvoiceTotalRecurringAmount')])
31+
table.add_row(['Provision Date', utils.lookup(result, 'billingItem', 'provisionDate')])
32+
33+
price_table = formatting.Table(['Item', 'Recurring Price'])
34+
for item in utils.lookup(result, 'billingItem', 'children') or []:
35+
price_table.add_row([item['description'], item['nextInvoiceTotalRecurringAmount']])
36+
37+
table.add_row(['prices', price_table])
38+
env.fout(table)

SoftLayer/CLI/hardware/detail.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,23 @@ def cli(env, identifier, passwords, price):
2727
hardware_id = helpers.resolve_id(hardware.resolve_ids, identifier, 'hardware')
2828
result = hardware.get_hardware(hardware_id)
2929
result = utils.NestedDict(result)
30+
hard_drives = hardware.get_hard_drives(hardware_id)
3031

3132
operating_system = utils.lookup(result, 'operatingSystem', 'softwareLicense', 'softwareDescription') or {}
3233
memory = formatting.gb(result.get('memoryCapacity', 0))
3334
owner = None
3435
if utils.lookup(result, 'billingItem') != []:
3536
owner = utils.lookup(result, 'billingItem', 'orderItem', 'order', 'userRecord', 'username')
3637

38+
table_hard_drives = formatting.Table(['Name', 'Capacity', 'Serial #'])
39+
for drives in hard_drives:
40+
name = drives['hardwareComponentModel']['manufacturer'] + " " + drives['hardwareComponentModel']['name']
41+
capacity = str(drives['hardwareComponentModel']['hardwareGenericComponentModel']['capacity']) + " " + str(
42+
drives['hardwareComponentModel']['hardwareGenericComponentModel']['units'])
43+
serial = drives['serialNumber']
44+
45+
table_hard_drives.add_row([name, capacity, serial])
46+
3747
table.add_row(['id', result['id']])
3848
table.add_row(['guid', result['globalIdentifier'] or formatting.blank()])
3949
table.add_row(['hostname', result['hostname']])
@@ -43,6 +53,7 @@ def cli(env, identifier, passwords, price):
4353
table.add_row(['datacenter', result['datacenter']['name'] or formatting.blank()])
4454
table.add_row(['cores', result['processorPhysicalCoreAmount']])
4555
table.add_row(['memory', memory])
56+
table.add_row(['drives', table_hard_drives])
4657
table.add_row(['public_ip', result['primaryIpAddress'] or formatting.blank()])
4758
table.add_row(['private_ip', result['primaryBackendIpAddress'] or formatting.blank()])
4859
table.add_row(['ipmi_ip', result['networkManagementIpAddress'] or formatting.blank()])

SoftLayer/CLI/hardware/storage.py

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
"""Get storage details for a hardware server."""
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+
11+
12+
@click.command()
13+
@click.argument('identifier')
14+
@environment.pass_env
15+
def cli(env, identifier):
16+
"""Get storage details for a hardware server."""
17+
18+
hardware = SoftLayer.HardwareManager(env.client)
19+
hardware_id = helpers.resolve_id(hardware.resolve_ids, identifier, 'hardware')
20+
iscsi_storage_data = hardware.get_storage_details(hardware_id, "ISCSI")
21+
nas_storage_data = hardware.get_storage_details(hardware_id, "NAS")
22+
storage_credentials = hardware.get_storage_credentials(hardware_id)
23+
hard_drives = hardware.get_hard_drives(hardware_id)
24+
25+
table_credentials = formatting.Table(['Username', 'Password', 'IQN'], title="Block Storage Details \n iSCSI")
26+
if storage_credentials:
27+
table_credentials.add_row([storage_credentials['credential']['username'],
28+
storage_credentials['credential']['password'],
29+
storage_credentials['name']])
30+
31+
table_iscsi = formatting.Table(['LUN name', 'capacity', 'Target address', 'Location', 'Notes'])
32+
for iscsi in iscsi_storage_data:
33+
table_iscsi.add_row([iscsi['username'], iscsi['capacityGb'],
34+
iscsi['serviceResourceBackendIpAddress'],
35+
iscsi['allowedHardware'][0]['datacenter']['longName'],
36+
iscsi.get('notes', None)])
37+
38+
table_nas = formatting.Table(['Volume name', 'capacity', 'Host Name', 'Location', 'Notes'],
39+
title="File Storage Details")
40+
for nas in nas_storage_data:
41+
table_nas.add_row([nas['username'], nas['capacityGb'],
42+
nas['serviceResourceBackendIpAddress'],
43+
nas['allowedHardware'][0]['datacenter']['longName'],
44+
nas.get('notes', None)])
45+
46+
table_hard_drives = formatting.Table(['Type', 'Name', 'Capacity', 'Serial #'], title="Other storage details")
47+
for drives in hard_drives:
48+
type_drive = drives['hardwareComponentModel']['hardwareGenericComponentModel']['hardwareComponentType']['type']
49+
name = drives['hardwareComponentModel']['manufacturer'] + " " + drives['hardwareComponentModel']['name']
50+
capacity = str(drives['hardwareComponentModel']['hardwareGenericComponentModel']['capacity']) + " " + str(
51+
drives['hardwareComponentModel']['hardwareGenericComponentModel']['units'])
52+
serial = drives['serialNumber']
53+
54+
table_hard_drives.add_row([type_drive, name, capacity, serial])
55+
56+
env.fout(table_credentials)
57+
env.fout(table_iscsi)
58+
env.fout(table_nas)
59+
env.fout(table_hard_drives)

SoftLayer/CLI/image/datacenter.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
"""Edit details of an image."""
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+
10+
11+
@click.command()
12+
@click.argument('identifier')
13+
@click.option('--add/--remove', default=True,
14+
help="To add or remove Datacenter")
15+
@click.argument('locations', nargs=-1, required=True)
16+
@environment.pass_env
17+
def cli(env, identifier, add, locations):
18+
"""Add/Remove datacenter of an image."""
19+
20+
image_mgr = SoftLayer.ImageManager(env.client)
21+
image_id = helpers.resolve_id(image_mgr.resolve_ids, identifier, 'image')
22+
23+
if add:
24+
result = image_mgr.add_locations(image_id, locations)
25+
else:
26+
result = image_mgr.remove_locations(image_id, locations)
27+
28+
env.fout(result)

0 commit comments

Comments
 (0)