Skip to content

Add a table result for the hw upgrade. #1488

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Jun 3, 2021
Merged
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
97 changes: 93 additions & 4 deletions SoftLayer/CLI/hardware/upgrade.py
Original file line number Diff line number Diff line change
@@ -2,6 +2,7 @@
# :license: MIT, see LICENSE for more details.

import click
from SoftLayer import utils

import SoftLayer
from SoftLayer.CLI import environment
@@ -35,6 +36,9 @@ def cli(env, identifier, memory, network, drive_controller, public_bandwidth, ad
"""Upgrade a Hardware Server."""

mgr = SoftLayer.HardwareManager(env.client)
table = formatting.KeyValueTable(['name', 'value'])
table.align['name'] = 'r'
table.align['value'] = 'l'

if not any([memory, network, drive_controller, public_bandwidth, add_disk, resize_disk]):
raise exceptions.ArgumentError("Must provide "
@@ -57,7 +61,92 @@ def cli(env, identifier, memory, network, drive_controller, public_bandwidth, ad
disks = {'description': 'resize_disk', 'capacity': guest_disk[0], 'number': guest_disk[1]}
disk_list.append(disks)

if not mgr.upgrade(hw_id, memory=memory, nic_speed=network, drive_controller=drive_controller,
public_bandwidth=public_bandwidth, disk=disk_list, test=test):
raise exceptions.CLIAbort('Hardware Server Upgrade Failed')
env.fout('Successfully Upgraded.')
response = mgr.upgrade(hw_id, memory=memory, nic_speed=network, drive_controller=drive_controller,
public_bandwidth=public_bandwidth, disk=disk_list, test=test)

if response:
if test:
add_data_to_table(response, table)
else:
table.add_row(['Order Date', response.get('orderDate')])
table.add_row(['Order Id', response.get('orderId')])
add_data_to_table(response['orderDetails'], table)
place_order_table = get_place_order_information(response)
table.add_row(['Place Order Information', place_order_table])
order_detail_table = get_order_detail(response)
table.add_row(['Order Detail (Billing Information)', order_detail_table])

env.fout(table)


def add_data_to_table(response, table):
"""Add the hardware server upgrade result to the table"""
table.add_row(['location', utils.lookup(response, 'locationObject', 'longName')])
table.add_row(['quantity', response.get('quantity')])
table.add_row(['Package Id', response.get('packageId')])
table.add_row(['Currency Short Name', response.get('currencyShortName')])
table.add_row(['Prorated Initial Charge', response.get('proratedInitialCharge')])
table.add_row(['Prorated Order Total', response.get('proratedOrderTotal')])
table.add_row(['Hourly Pricing', response.get('useHourlyPricing')])
table_hardware = get_hardware_detail(response)
table.add_row(['Hardware', table_hardware])
table_prices = get_hardware_prices(response)
table.add_row(['Prices', table_prices])


def get_place_order_information(response):
"""Get the hardware server place order information."""
table_place_order = formatting.Table(['Id', 'Account Id', 'Status', 'Account CompanyName',
'UserRecord FirstName', 'UserRecord LastName', 'UserRecord Username'])
table_place_order.add_row([response.get('id'),
response.get('accountId'),
response.get('status'),
utils.lookup(response, 'account', 'companyName'),
utils.lookup(response, 'userRecord', 'firstName'),
utils.lookup(response, 'account', 'lastName'),
utils.lookup(response, 'account', 'username')])

return table_place_order


def get_hardware_detail(response):
"""Get the hardware server detail."""
table_hardware = formatting.Table(['Account Id', 'Hostname', 'Domain'])
for hardware in response['hardware']:
table_hardware.add_row([hardware.get('accountId'),
hardware.get('hostname'),
hardware.get('domain')])

return table_hardware


def get_hardware_prices(response):
"""Get the hardware server prices."""
table_prices = formatting.Table(['Id', 'HourlyRecurringFee', 'RecurringFee', 'Categories', 'Item Description',
'Item Units'])
for price in response['prices']:
categories = price.get('categories')[0]
table_prices.add_row([price.get('id'),
price.get('hourlyRecurringFee'),
price.get('recurringFee'),
categories.get('name'),
utils.lookup(price, 'item', 'description'),
utils.lookup(price, 'item', 'units')])

return table_prices


def get_order_detail(response):
"""Get the hardware server order detail."""
table_order_detail = formatting.Table(['Billing City', 'Billing Country Code', 'Billing Email',
'Billing Name First', 'Billing Name Last', 'Billing Postal Code',
'Billing State'])
table_order_detail.add_row([utils.lookup(response, 'orderDetails', 'billingInformation', 'billingCity'),
utils.lookup(response, 'orderDetails', 'billingInformation', 'billingCountryCode'),
utils.lookup(response, 'orderDetails', 'billingInformation', 'billingEmail'),
utils.lookup(response, 'orderDetails', 'billingInformation', 'billingNameFirst'),
utils.lookup(response, 'orderDetails', 'billingInformation', 'billingNameLast'),
utils.lookup(response, 'orderDetails', 'billingInformation', 'billingPostalCode'),
utils.lookup(response, 'orderDetails', 'billingInformation', 'billingState')])

return table_order_detail
148 changes: 148 additions & 0 deletions SoftLayer/fixtures/SoftLayer_Product_Order.py
Original file line number Diff line number Diff line change
@@ -63,6 +63,154 @@
'postTaxRecurring': '0.32',
}

hardware_verifyOrder = {
"currencyShortName": "USD",
"hardware": [
{
"accountId": 1111,
"domain": "testedit.com",
"hostname": "test",
"globalIdentifier": "81434794-af69-44d5-bb97-12312asdasdasd"
}
],
"location": "1441195",
"locationObject": {
"id": 1441195,
"longName": "Dallas 10",
"name": "dal10"
},
"packageId": 911,
"postTaxRecurring": "0",
"postTaxRecurringHourly": "0",
"postTaxRecurringMonthly": "0",
"preTaxRecurring": "0",
"preTaxRecurringHourly": "0",
"preTaxRecurringMonthly": "0",
"prices": [
{
"hourlyRecurringFee": "0",
"id": 209391,
"recurringFee": "0",
"categories": [
{
"categoryCode": "ram",
"id": 3,
"name": "RAM"
}
],
"item": {
"capacity": "32",
"description": "32 GB RAM",
"id": 11291,
"units": "GB"
}
}
],
"proratedInitialCharge": "0",
"proratedOrderTotal": "0",
"quantity": 1,
"sendQuoteEmailFlag": None,
"totalRecurringTax": "0",
"useHourlyPricing": False
}

hardware_placeOrder = {
"orderDate": "2021-05-07T07:41:41-06:00",
"orderDetails": {
"billingInformation": {
"billingAddressLine1": "4849 Alpha Rd",
"billingCity": "Dallas",
"billingCountryCode": "US",
"billingEmail": "test.ibm.com",
"billingNameCompany": "SoftLayer Internal - Development Community",
"billingNameFirst": "Test",
"billingNameLast": "Test",
"billingPhoneVoice": "1111111",
"billingPostalCode": "75244-1111",
"billingState": "TX",
},
"currencyShortName": "USD",
"hardware": [
{
"accountId": 1111111,
"bareMetalInstanceFlag": 0,
"domain": "testedit.com",
"fullyQualifiedDomainName": "test.testedit.com",
"hostname": "test",
"globalIdentifier": "81434794-af69-44d5-bb97-1111111"
}
],
"location": "1441195",
"locationObject": {
"id": 1441195,
"longName": "Dallas 10",
"name": "dal10"
},
"packageId": 911,
"paymentType": "ADD_TO_BALANCE",
"postTaxRecurring": "0",
"postTaxRecurringHourly": "0",
"postTaxRecurringMonthly": "0",
"postTaxSetup": "0",
"preTaxRecurring": "0",
"preTaxRecurringHourly": "0",
"preTaxRecurringMonthly": "0",
"preTaxSetup": "0",
"prices": [
{
"hourlyRecurringFee": "0",
"id": 209391,
"recurringFee": "0",
"categories": [
{
"categoryCode": "ram",
"id": 3,
"name": "RAM"
}
],
"item": {
"capacity": "32",
"description": "32 GB RAM",
"id": 11291,
"keyName": "RAM_32_GB_DDR4_2133_ECC_NON_REG",
"units": "GB",
}
}
],
"proratedInitialCharge": "0",
"proratedOrderTotal": "0",
"quantity": 1,
"totalRecurringTax": "0",
"useHourlyPricing": False
},
"orderId": 78332111,
"placedOrder": {
"accountId": 1111111,
"id": 1234,
"status": "PENDING_UPGRADE",
"account": {
"brandId": 2,
"companyName": "SoftLayer Internal - Development Community",
"id": 1234
},
"items": [
{
"categoryCode": "ram",
"description": "32 GB RAM",
"id": 824199364,
"recurringFee": "0"
}
],
"userRecord": {
"accountId": 1234,
"firstName": "test",
"id": 3333,
"lastName": "test",
"username": "sl1234-test"
}
}
}

rsc_placeOrder = {
'orderDate': '2013-08-01 15:23:45',
'orderId': 1234,
26 changes: 26 additions & 0 deletions SoftLayer/fixtures/SoftLayer_Provisioning_Maintenance_Window.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
getMaintenanceWindows = [
{
"beginDate": "2021-05-13T16:00:00-06:00",
"dayOfWeek": 4,
"endDate": "2021-05-13T19:00:00-06:00",
"id": 198351,
"locationId": 1441195,
"portalTzId": 114
},
{
"beginDat": "2021-05-14T00:00:00-06:00",
"dayOfWeek": 5,
"endDate": "2021-05-14T03:00:00-06:00",
"id": 189747,
"locationId": 1441195,
"portalTzId": 114
},
{
"beginDate": "2021-05-14T08:00:00-06:00",
"dayOfWeek": 5,
"endDate": "2021-05-14T11:00:00-06:00",
"id": 198355,
"locationId": 1441195,
"portalTzId": 114
}
]
51 changes: 42 additions & 9 deletions SoftLayer/managers/hardware.py
Original file line number Diff line number Diff line change
@@ -834,6 +834,8 @@ def upgrade(self, instance_id, memory=None,

:returns: bool
"""
result = None
maintenance_window_id = None
upgrade_prices = self._get_upgrade_prices(instance_id)
prices = []
data = {}
@@ -849,14 +851,26 @@ def upgrade(self, instance_id, memory=None,

server_response = self.get_instance(instance_id)
package_id = server_response['billingItem']['package']['id']
location_id = server_response['datacenter']['id']

maintenance_window = datetime.datetime.now(utils.UTC())
maintenance_window_detail = self.get_maintenance_windows_detail(location_id)
if maintenance_window_detail:
maintenance_window_id = maintenance_window_detail.get('id')

order = {
'complexType': 'SoftLayer_Container_Product_Order_Hardware_Server_Upgrade',
'properties': [{
'name': 'MAINTENANCE_WINDOW',
'value': maintenance_window.strftime("%Y-%m-%d %H:%M:%S%z")
}],
'properties': [
{
'name': 'MAINTENANCE_WINDOW',
'value': maintenance_window.strftime("%Y-%m-%d %H:%M:%S%z")
},
{
'name': 'MAINTENANCE_WINDOW_ID',
'value': str(maintenance_window_id)
}

],
'hardware': [{'id': int(instance_id)}],
'packageId': package_id
}
@@ -878,11 +892,30 @@ def upgrade(self, instance_id, memory=None,

if prices:
if test:
self.client['Product_Order'].verifyOrder(order)
result = self.client['Product_Order'].verifyOrder(order)
else:
self.client['Product_Order'].placeOrder(order)
return True
return False
result = self.client['Product_Order'].placeOrder(order)
return result

def get_maintenance_windows_detail(self, location_id):
"""Get the disks prices to be added or upgraded.

:param int location_id: Hardware Server location id.
:return int.
"""
result = None
begin_date_object = datetime.datetime.now()
begin_date = begin_date_object.strftime("%Y-%m-%dT00:00:00.0000-06:00")
end_date_object = datetime.date.today() + datetime.timedelta(days=30)
end_date = end_date_object.strftime("%Y-%m-%dT00:00:00.0000-06:00")

result_windows = self.client['SoftLayer_Provisioning_Maintenance_Window'].getMaintenanceWindows(begin_date,
end_date,
location_id)
if len(result_windows) > 0:
result = result_windows[0]

return result

@retry(logger=LOGGER)
def get_instance(self, instance_id):
@@ -893,7 +926,7 @@ def get_instance(self, instance_id):
the specified instance.
"""
mask = [
'billingItem[id,package[id,keyName],nextInvoiceChildren]'
'datacenter,billingItem[id,package[id,keyName],nextInvoiceChildren]'
]
mask = "mask[%s]" % ','.join(mask)

49 changes: 28 additions & 21 deletions tests/CLI/modules/server_tests.py
Original file line number Diff line number Diff line change
@@ -14,6 +14,7 @@
from unittest import mock as mock

from SoftLayer.CLI import exceptions
from SoftLayer.fixtures import SoftLayer_Product_Order
from SoftLayer import SoftLayerError
from SoftLayer import testing

@@ -691,19 +692,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'])

@@ -746,12 +747,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)
@@ -936,23 +937,27 @@ def test_upgrade_aborted(self, confirm_mock):
self.assertEqual(result.exit_code, 2)
self.assertIsInstance(result.exception, exceptions.CLIAbort)

@mock.patch('SoftLayer.CLI.formatting.confirm')
def test_upgrade_test(self, confirm_mock):
confirm_mock.return_value = True
def test_upgrade_test(self):
order_mock = self.set_mock('SoftLayer_Product_Order', 'verifyOrder')
order_mock.return_value = SoftLayer_Product_Order.hardware_verifyOrder
result = self.run_command(['hw', 'upgrade', '100', '--test', '--memory=32', '--public-bandwidth=500',
'--drive-controller=RAID', '--network=10000 Redundant'])
self.assert_no_fail(result)

@mock.patch('SoftLayer.CLI.formatting.confirm')
def test_upgrade_add_disk(self, confirm_mock):
confirm_mock.return_value = True
order_mock = self.set_mock('SoftLayer_Product_Order', 'placeOrder')
order_mock.return_value = SoftLayer_Product_Order.hardware_placeOrder
result = self.run_command(['hw', 'upgrade', '100', '--add-disk=1000', '2'])

self.assert_no_fail(result)

@mock.patch('SoftLayer.CLI.formatting.confirm')
def test_upgrade_resize_disk(self, confirm_mock):
confirm_mock.return_value = True
order_mock = self.set_mock('SoftLayer_Product_Order', 'placeOrder')
order_mock.return_value = SoftLayer_Product_Order.hardware_placeOrder
result = self.run_command(['hw', 'upgrade', '100', '--resize-disk=1000', '1'])

self.assert_no_fail(result)
@@ -981,6 +986,8 @@ def test_upgrade_disk_does_not_exist(self, confirm_mock):
@mock.patch('SoftLayer.CLI.formatting.confirm')
def test_upgrade(self, confirm_mock):
confirm_mock.return_value = True
order_mock = self.set_mock('SoftLayer_Product_Order', 'placeOrder')
order_mock.return_value = SoftLayer_Product_Order.hardware_placeOrder
result = self.run_command(['hw', 'upgrade', '100', '--memory=32', '--public-bandwidth=500',
'--drive-controller=RAID', '--network=10000 Redundant'])

10 changes: 5 additions & 5 deletions tests/managers/hardware_tests.py
Original file line number Diff line number Diff line change
@@ -879,7 +879,7 @@ def test_get_price_id_disk_capacity(self):
def test_upgrade(self):
result = self.hardware.upgrade(1, memory=32)

self.assertEqual(result, True)
self.assertEqual(result['orderId'], 1234)
self.assert_called_with('SoftLayer_Product_Order', 'placeOrder')
call = self.calls('SoftLayer_Product_Order', 'placeOrder')[0]
order_container = call.args[0]
@@ -891,7 +891,7 @@ def test_upgrade_add_disk(self):
disk_list.append(disks)
result = self.hardware.upgrade(1, disk=disk_list)

self.assertEqual(result, True)
self.assertEqual(result['orderId'], 1234)
self.assert_called_with('SoftLayer_Product_Order', 'placeOrder')
call = self.calls('SoftLayer_Product_Order', 'placeOrder')[0]
order_container = call.args[0]
@@ -903,7 +903,7 @@ def test_upgrade_resize_disk(self):
disk_list.append(disks)
result = self.hardware.upgrade(1, disk=disk_list)

self.assertEqual(result, True)
self.assertEqual(result['orderId'], 1234)
self.assert_called_with('SoftLayer_Product_Order', 'placeOrder')
call = self.calls('SoftLayer_Product_Order', 'placeOrder')[0]
order_container = call.args[0]
@@ -912,14 +912,14 @@ def test_upgrade_resize_disk(self):
def test_upgrade_blank(self):
result = self.hardware.upgrade(1)

self.assertEqual(result, False)
self.assertEqual(result, None)
self.assertEqual(self.calls('SoftLayer_Product_Order', 'placeOrder'), [])

def test_upgrade_full(self):
result = self.hardware.upgrade(1, memory=32, nic_speed="10000 Redundant", drive_controller="RAID",
public_bandwidth=500, test=False)

self.assertEqual(result, True)
self.assertEqual(result['orderId'], 1234)
self.assert_called_with('SoftLayer_Product_Order', 'placeOrder')
call = self.calls('SoftLayer_Product_Order', 'placeOrder')[0]
order_container = call.args[0]