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
11 changes: 7 additions & 4 deletions SoftLayer/CLI/virt/upgrade.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,17 @@
help="CPU core will be on a dedicated host server.")
@click.option('--memory', type=virt.MEM_TYPE, help="Memory in megabytes")
@click.option('--network', type=click.INT, help="Network port speed in Mbps")
@click.option('--flavor', type=click.STRING, help="Flavor keyName\n"
"Do not use --memory, --cpu or --private, if you are using flavors")
@environment.pass_env
def cli(env, identifier, cpu, private, memory, network):
def cli(env, identifier, cpu, private, memory, network, flavor):
"""Upgrade a virtual server."""

vsi = SoftLayer.VSManager(env.client)

if not any([cpu, memory, network]):
if not any([cpu, memory, network, flavor]):
raise exceptions.ArgumentError(
"Must provide [--cpu], [--memory], or [--network] to upgrade")
"Must provide [--cpu], [--memory], [--network], or [--flavor] to upgrade")

if private and not cpu:
raise exceptions.ArgumentError(
Expand All @@ -48,5 +50,6 @@ def cli(env, identifier, cpu, private, memory, network):
cpus=cpu,
memory=memory,
nic_speed=network,
public=not private):
public=not private,
preset=flavor):
raise exceptions.CLIAbort('VS Upgrade Failed')
29 changes: 29 additions & 0 deletions SoftLayer/fixtures/SoftLayer_Product_Package.py
Original file line number Diff line number Diff line change
Expand Up @@ -1340,3 +1340,32 @@
}]
}]
}]

getActivePresets = [
{
"description": "M1.64x512x25",
"id": 799,
"isActive": "1",
"keyName": "M1_64X512X25",
"name": "M1.64x512x25",
"packageId": 835
},
{
"description": "M1.56x448x100",
"id": 797,
"isActive": "1",
"keyName": "M1_56X448X100",
"name": "M1.56x448x100",
"packageId": 835
},
{
"description": "M1.64x512x100",
"id": 801,
"isActive": "1",
"keyName": "M1_64X512X100",
"name": "M1.64x512x100",
"packageId": 835
}
]

getAccountRestrictedActivePresets = []
4 changes: 4 additions & 0 deletions SoftLayer/fixtures/SoftLayer_Virtual_Guest.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@
{'nextInvoiceTotalRecurringAmount': 1},
{'nextInvoiceTotalRecurringAmount': 1},
],
'package': {
"id": 835,
"keyName": "PUBLIC_CLOUD_SERVER"
},
'orderItem': {
'order': {
'userRecord': {
Expand Down
49 changes: 33 additions & 16 deletions SoftLayer/managers/vs.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ def __init__(self, client, ordering_manager=None):
self.client = client
self.account = client['Account']
self.guest = client['Virtual_Guest']
self.package_svc = client['Product_Package']
self.resolvers = [self._get_ids_from_ip, self._get_ids_from_hostname]
if ordering_manager is None:
self.ordering_manager = ordering.OrderingManager(client)
Expand Down Expand Up @@ -209,6 +210,7 @@ def get_instance(self, instance_id, **kwargs):
'maxMemory,'
'datacenter,'
'activeTransaction[id, transactionStatus[friendlyName,name]],'
'lastTransaction[transactionStatus],'
'lastOperatingSystemReload.id,'
'blockDevices,'
'blockDeviceTemplateGroup[id, name, globalIdentifier],'
Expand All @@ -225,6 +227,7 @@ def get_instance(self, instance_id, **kwargs):
'hourlyBillingFlag,'
'userData,'
'''billingItem[id,nextInvoiceTotalRecurringAmount,
package[id,keyName],
children[categoryCode,nextInvoiceTotalRecurringAmount],
orderItem[id,
order.userRecord[username],
Expand Down Expand Up @@ -803,7 +806,7 @@ def capture(self, instance_id, name, additional_disks=False, notes=None):
name, disks_to_capture, notes, id=instance_id)

def upgrade(self, instance_id, cpus=None, memory=None,
nic_speed=None, public=True):
nic_speed=None, public=True, preset=None):
"""Upgrades a VS instance.

Example::
Expand All @@ -817,6 +820,7 @@ def upgrade(self, instance_id, cpus=None, memory=None,
:param int instance_id: Instance id of the VS to be upgraded
:param int cpus: The number of virtual CPUs to upgrade to
of a VS instance.
:param string preset: preset assigned to the vsi
:param int memory: RAM of the VS to be upgraded to.
:param int nic_speed: The port speed to set
:param bool public: CPU will be in Private/Public Node.
Expand All @@ -826,9 +830,28 @@ def upgrade(self, instance_id, cpus=None, memory=None,
upgrade_prices = self._get_upgrade_prices(instance_id)
prices = []

for option, value in {'cpus': cpus,
'memory': memory,
'nic_speed': nic_speed}.items():
data = {'nic_speed': nic_speed}

if cpus is not None and preset is not None:
raise exceptions.SoftLayerError("Do not use cpu, private and memory if you are using flavors")
data['cpus'] = cpus

if memory is not None and preset is not None:
raise exceptions.SoftLayerError("Do not use memory, private or cpu if you are using flavors")
data['memory'] = memory

maintenance_window = datetime.datetime.now(utils.UTC())
order = {
'complexType': 'SoftLayer_Container_Product_Order_Virtual_Guest_'
'Upgrade',
'properties': [{
'name': 'MAINTENANCE_WINDOW',
'value': maintenance_window.strftime("%Y-%m-%d %H:%M:%S%z")
}],
'virtualGuests': [{'id': int(instance_id)}],
}

for option, value in data.items():
if not value:
continue
price_id = self._get_price_id_for_upgrade_option(upgrade_prices,
Expand All @@ -841,19 +864,13 @@ def upgrade(self, instance_id, cpus=None, memory=None,
"Unable to find %s option with value %s" % (option, value))

prices.append({'id': price_id})
order['prices'] = prices

maintenance_window = datetime.datetime.now(utils.UTC())
order = {
'complexType': 'SoftLayer_Container_Product_Order_Virtual_Guest_'
'Upgrade',
'prices': prices,
'properties': [{
'name': 'MAINTENANCE_WINDOW',
'value': maintenance_window.strftime("%Y-%m-%d %H:%M:%S%z")
}],
'virtualGuests': [{'id': int(instance_id)}],
}
if prices:
if preset is not None:
vs_object = self.get_instance(instance_id)['billingItem']['package']
order['presetId'] = self.ordering_manager.get_preset_by_key(vs_object['keyName'], preset)['id']

if prices or preset:
self.client['Product_Order'].placeOrder(order)
return True
return False
Expand Down
17 changes: 17 additions & 0 deletions tests/CLI/modules/vs_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -901,6 +901,23 @@ def test_upgrade(self, confirm_mock):
self.assertIn({'id': 1122}, order_container['prices'])
self.assertEqual(order_container['virtualGuests'], [{'id': 100}])

@mock.patch('SoftLayer.CLI.formatting.confirm')
def test_upgrade_with_flavor(self, confirm_mock):
confirm_mock.return_value = True
result = self.run_command(['vs', 'upgrade', '100', '--flavor=M1_64X512X100'])
self.assert_no_fail(result)
self.assert_called_with('SoftLayer_Product_Order', 'placeOrder')
call = self.calls('SoftLayer_Product_Order', 'placeOrder')[0]
order_container = call.args[0]
self.assertEqual(799, order_container['presetId'])
self.assertIn({'id': 100}, order_container['virtualGuests'])
self.assertEqual(order_container['virtualGuests'], [{'id': 100}])

def test_upgrade_with_cpu_memory_and_flavor(self):
result = self.run_command(['vs', 'upgrade', '100', '--cpu=4',
'--memory=1024', '--flavor=M1_64X512X100'])
self.assertEqual("Do not use cpu, private and memory if you are using flavors", str(result.exception))

def test_edit(self):
result = self.run_command(['vs', 'edit',
'--domain=example.com',
Expand Down
16 changes: 16 additions & 0 deletions tests/managers/vs_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -879,6 +879,22 @@ def test_upgrade_full(self):
self.assertIn({'id': 1122}, order_container['prices'])
self.assertEqual(order_container['virtualGuests'], [{'id': 1}])

def test_upgrade_with_flavor(self):
# Testing Upgrade with parameter preset
result = self.vs.upgrade(1,
preset="M1_64X512X100",
nic_speed=1000,
public=True)

self.assertEqual(result, True)
self.assert_called_with('SoftLayer_Product_Order', 'placeOrder')
call = self.calls('SoftLayer_Product_Order', 'placeOrder')[0]
order_container = call.args[0]
self.assertEqual(799, order_container['presetId'])
self.assertIn({'id': 1}, order_container['virtualGuests'])
self.assertIn({'id': 1122}, order_container['prices'])
self.assertEqual(order_container['virtualGuests'], [{'id': 1}])

def test_upgrade_dedicated_host_instance(self):
mock = self.set_mock('SoftLayer_Virtual_Guest', 'getUpgradeItemPrices')
mock.return_value = fixtures.SoftLayer_Virtual_Guest.DEDICATED_GET_UPGRADE_ITEM_PRICES
Expand Down