Skip to content
Merged
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
38 changes: 38 additions & 0 deletions SoftLayer/CLI/hardware/billing.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
"""Get billing for a hardware device."""
# :license: MIT, see LICENSE for more details.

import click

import SoftLayer
from SoftLayer.CLI import environment
from SoftLayer.CLI import formatting
from SoftLayer.CLI import helpers
from SoftLayer import utils


@click.command()
@click.argument('identifier')
@environment.pass_env
def cli(env, identifier):
"""Get billing for a hardware device."""
hardware = SoftLayer.HardwareManager(env.client)

hardware_id = helpers.resolve_id(hardware.resolve_ids, identifier, 'hardware')
result = hardware.get_hardware(hardware_id)
table = formatting.KeyValueTable(['name', 'value'])
table.align['name'] = 'r'
table.align['value'] = 'l'

table.add_row(['Id', identifier])

table.add_row(['Billing Item Id', utils.lookup(result, 'billingItem', 'id')])
table.add_row(['Recurring Fee', utils.lookup(result, 'billingItem', 'recurringFee')])
table.add_row(['Total', utils.lookup(result, 'billingItem', 'nextInvoiceTotalRecurringAmount')])
table.add_row(['Provision Date', utils.lookup(result, 'billingItem', 'provisionDate')])

price_table = formatting.Table(['Item', 'Recurring Price'])
for item in utils.lookup(result, 'billingItem', 'children') or []:
price_table.add_row([item['description'], item['nextInvoiceTotalRecurringAmount']])

table.add_row(['prices', price_table])
env.fout(table)
2 changes: 2 additions & 0 deletions SoftLayer/CLI/routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

('virtual', 'SoftLayer.CLI.virt'),
('virtual:bandwidth', 'SoftLayer.CLI.virt.bandwidth:cli'),
('virtual:billing', 'SoftLayer.CLI.virt.billing:cli'),
('virtual:cancel', 'SoftLayer.CLI.virt.cancel:cli'),
('virtual:capture', 'SoftLayer.CLI.virt.capture:cli'),
('virtual:create', 'SoftLayer.CLI.virt.create:cli'),
Expand Down Expand Up @@ -231,6 +232,7 @@
('hardware:create', 'SoftLayer.CLI.hardware.create:cli'),
('hardware:create-options', 'SoftLayer.CLI.hardware.create_options:cli'),
('hardware:detail', 'SoftLayer.CLI.hardware.detail:cli'),
('hardware:billing', 'SoftLayer.CLI.hardware.billing:cli'),
('hardware:edit', 'SoftLayer.CLI.hardware.edit:cli'),
('hardware:list', 'SoftLayer.CLI.hardware.list:cli'),
('hardware:power-cycle', 'SoftLayer.CLI.hardware.power:power_cycle'),
Expand Down
38 changes: 38 additions & 0 deletions SoftLayer/CLI/virt/billing.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
"""Get billing for a virtual device."""
# :license: MIT, see LICENSE for more details.

import click

import SoftLayer
from SoftLayer.CLI import environment
from SoftLayer.CLI import formatting
from SoftLayer.CLI import helpers
from SoftLayer import utils


@click.command()
@click.argument('identifier')
@environment.pass_env
def cli(env, identifier):
"""Get billing for a virtual device."""
virtual = SoftLayer.VSManager(env.client)

virtual_id = helpers.resolve_id(virtual.resolve_ids, identifier, 'virtual')
result = virtual.get_instance(virtual_id)
table = formatting.KeyValueTable(['name', 'value'])
table.align['name'] = 'r'
table.align['value'] = 'l'

table.add_row(['Id', identifier])

table.add_row(['Billing Item Id', utils.lookup(result, 'billingItem', 'id')])
table.add_row(['Recurring Fee', utils.lookup(result, 'billingItem', 'recurringFee')])
table.add_row(['Total', utils.lookup(result, 'billingItem', 'nextInvoiceTotalRecurringAmount')])
table.add_row(['Provision Date', utils.lookup(result, 'billingItem', 'provisionDate')])

price_table = formatting.Table(['Recurring Price'])
for item in utils.lookup(result, 'billingItem', 'children') or []:
price_table.add_row([item['nextInvoiceTotalRecurringAmount']])

table.add_row(['prices', price_table])
env.fout(table)
4 changes: 4 additions & 0 deletions docs/cli/hardware.rst
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@ Provides some basic functionality to order a server. `slcli order` has a more fu
:prog: hw detail
:show-nested:

.. click:: SoftLayer.CLI.hardware.billing:cli
:prog: hw billing
:show-nested:


.. click:: SoftLayer.CLI.hardware.edit:cli
:prog: hw edit
Expand Down
4 changes: 4 additions & 0 deletions docs/cli/vs.rst
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,10 @@ If no timezone is specified, IMS local time (CST) will be assumed, which might n
:prog: vs usage
:show-nested:

.. click:: SoftLayer.CLI.virt.billing:cli
:prog: vs billing
:show-nested:




Expand Down
52 changes: 34 additions & 18 deletions tests/CLI/modules/server_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -659,19 +659,19 @@ def test_dns_sync_both(self, confirm_mock):
'getResourceRecords')
getResourceRecords.return_value = []
createAargs = ({
'type': 'a',
'host': 'hardware-test1',
'domainId': 12345, # from SoftLayer_Account::getDomains
'data': '172.16.1.100',
'ttl': 7200
},)
'type': 'a',
'host': 'hardware-test1',
'domainId': 12345, # from SoftLayer_Account::getDomains
'data': '172.16.1.100',
'ttl': 7200
},)
createPTRargs = ({
'type': 'ptr',
'host': '100',
'domainId': 123456,
'data': 'hardware-test1.test.sftlyr.ws',
'ttl': 7200
},)
'type': 'ptr',
'host': '100',
'domainId': 123456,
'data': 'hardware-test1.test.sftlyr.ws',
'ttl': 7200
},)

result = self.run_command(['hw', 'dns-sync', '1000'])

Expand Down Expand Up @@ -714,12 +714,12 @@ def test_dns_sync_v6(self, confirm_mock):
}
}
createV6args = ({
'type': 'aaaa',
'host': 'hardware-test1',
'domainId': 12345, # from SoftLayer_Account::getDomains
'data': '2607:f0d0:1b01:0023:0000:0000:0000:0004',
'ttl': 7200
},)
'type': 'aaaa',
'host': 'hardware-test1',
'domainId': 12345, # from SoftLayer_Account::getDomains
'data': '2607:f0d0:1b01:0023:0000:0000:0000:0004',
'ttl': 7200
},)
server.return_value = test_server
result = self.run_command(['hw', 'dns-sync', '--aaaa-record', '1000'])
self.assert_no_fail(result)
Expand Down Expand Up @@ -826,3 +826,19 @@ def test_dns_sync_misc_exception(self, confirm_mock):
result = self.run_command(['hw', 'dns-sync', '-a', '1000'])
self.assertEqual(result.exit_code, 2)
self.assertIsInstance(result.exception, exceptions.CLIAbort)

def test_billing(self):
result = self.run_command(['hw', 'billing', '123456'])
billing_json = {
'Billing Item Id': 6327,
'Id': '123456',
'Provision Date': None,
'Recurring Fee': 1.54,
'Total': 16.08,
'prices': [{
'Item': 'test',
'Recurring Price': 1
}]
}
self.assert_no_fail(result)
self.assertEqual(json.loads(result.output), billing_json)
55 changes: 37 additions & 18 deletions tests/CLI/modules/vs/vs_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -320,19 +320,19 @@ def test_dns_sync_both(self, confirm_mock):
'getResourceRecords')
getResourceRecords.return_value = []
createAargs = ({
'type': 'a',
'host': 'vs-test1',
'domainId': 12345, # from SoftLayer_Account::getDomains
'data': '172.16.240.2',
'ttl': 7200
},)
'type': 'a',
'host': 'vs-test1',
'domainId': 12345, # from SoftLayer_Account::getDomains
'data': '172.16.240.2',
'ttl': 7200
},)
createPTRargs = ({
'type': 'ptr',
'host': '2',
'domainId': 123456,
'data': 'vs-test1.test.sftlyr.ws',
'ttl': 7200
},)
'type': 'ptr',
'host': '2',
'domainId': 123456,
'data': 'vs-test1.test.sftlyr.ws',
'ttl': 7200
},)

result = self.run_command(['vs', 'dns-sync', '100'])

Expand Down Expand Up @@ -375,12 +375,12 @@ def test_dns_sync_v6(self, confirm_mock):
}
}
createV6args = ({
'type': 'aaaa',
'host': 'vs-test1',
'domainId': 12345,
'data': '2607:f0d0:1b01:0023:0000:0000:0000:0004',
'ttl': 7200
},)
'type': 'aaaa',
'host': 'vs-test1',
'domainId': 12345,
'data': '2607:f0d0:1b01:0023:0000:0000:0000:0004',
'ttl': 7200
},)
guest.return_value = test_guest
result = self.run_command(['vs', 'dns-sync', '--aaaa-record', '100'])
self.assert_no_fail(result)
Expand Down Expand Up @@ -740,3 +740,22 @@ def test_bandwidth_vs_quite(self):
self.assertEqual(output_summary[1]['Max Date'], date)
self.assertEqual(output_summary[2]['Max GB'], 0.1172)
self.assertEqual(output_summary[3]['Sum GB'], 0.0009)

def test_billing(self):
result = self.run_command(['vs', 'billing', '123456'])
vir_billing = {
'Billing Item Id': 6327,
'Id': '123456',
'Provision Date': None,
'Recurring Fee': None,
'Total': 1.54,
'prices': [
{'Recurring Price': 1},
{'Recurring Price': 1},
{'Recurring Price': 1},
{'Recurring Price': 1},
{'Recurring Price': 1}
]
}
self.assert_no_fail(result)
self.assertEqual(json.loads(result.output), vir_billing)