Skip to content

Commit 25769c3

Browse files
Merge pull request #1032 from FernandoOjeda/fo_vs_upgrade_with_flavor
Fo vs upgrade with flavor
2 parents 301a488 + 5576b39 commit 25769c3

File tree

6 files changed

+106
-20
lines changed

6 files changed

+106
-20
lines changed

SoftLayer/CLI/virt/upgrade.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,15 +21,17 @@
2121
help="CPU core will be on a dedicated host server.")
2222
@click.option('--memory', type=virt.MEM_TYPE, help="Memory in megabytes")
2323
@click.option('--network', type=click.INT, help="Network port speed in Mbps")
24+
@click.option('--flavor', type=click.STRING, help="Flavor keyName\n"
25+
"Do not use --memory, --cpu or --private, if you are using flavors")
2426
@environment.pass_env
25-
def cli(env, identifier, cpu, private, memory, network):
27+
def cli(env, identifier, cpu, private, memory, network, flavor):
2628
"""Upgrade a virtual server."""
2729

2830
vsi = SoftLayer.VSManager(env.client)
2931

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

3436
if private and not cpu:
3537
raise exceptions.ArgumentError(
@@ -48,5 +50,6 @@ def cli(env, identifier, cpu, private, memory, network):
4850
cpus=cpu,
4951
memory=memory,
5052
nic_speed=network,
51-
public=not private):
53+
public=not private,
54+
preset=flavor):
5255
raise exceptions.CLIAbort('VS Upgrade Failed')

SoftLayer/fixtures/SoftLayer_Product_Package.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1340,3 +1340,32 @@
13401340
}]
13411341
}]
13421342
}]
1343+
1344+
getActivePresets = [
1345+
{
1346+
"description": "M1.64x512x25",
1347+
"id": 799,
1348+
"isActive": "1",
1349+
"keyName": "M1_64X512X25",
1350+
"name": "M1.64x512x25",
1351+
"packageId": 835
1352+
},
1353+
{
1354+
"description": "M1.56x448x100",
1355+
"id": 797,
1356+
"isActive": "1",
1357+
"keyName": "M1_56X448X100",
1358+
"name": "M1.56x448x100",
1359+
"packageId": 835
1360+
},
1361+
{
1362+
"description": "M1.64x512x100",
1363+
"id": 801,
1364+
"isActive": "1",
1365+
"keyName": "M1_64X512X100",
1366+
"name": "M1.64x512x100",
1367+
"packageId": 835
1368+
}
1369+
]
1370+
1371+
getAccountRestrictedActivePresets = []

SoftLayer/fixtures/SoftLayer_Virtual_Guest.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@
1414
{'nextInvoiceTotalRecurringAmount': 1},
1515
{'nextInvoiceTotalRecurringAmount': 1},
1616
],
17+
'package': {
18+
"id": 835,
19+
"keyName": "PUBLIC_CLOUD_SERVER"
20+
},
1721
'orderItem': {
1822
'order': {
1923
'userRecord': {

SoftLayer/managers/vs.py

Lines changed: 33 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ def __init__(self, client, ordering_manager=None):
5151
self.client = client
5252
self.account = client['Account']
5353
self.guest = client['Virtual_Guest']
54+
self.package_svc = client['Product_Package']
5455
self.resolvers = [self._get_ids_from_ip, self._get_ids_from_hostname]
5556
if ordering_manager is None:
5657
self.ordering_manager = ordering.OrderingManager(client)
@@ -209,6 +210,7 @@ def get_instance(self, instance_id, **kwargs):
209210
'maxMemory,'
210211
'datacenter,'
211212
'activeTransaction[id, transactionStatus[friendlyName,name]],'
213+
'lastTransaction[transactionStatus],'
212214
'lastOperatingSystemReload.id,'
213215
'blockDevices,'
214216
'blockDeviceTemplateGroup[id, name, globalIdentifier],'
@@ -225,6 +227,7 @@ def get_instance(self, instance_id, **kwargs):
225227
'hourlyBillingFlag,'
226228
'userData,'
227229
'''billingItem[id,nextInvoiceTotalRecurringAmount,
230+
package[id,keyName],
228231
children[categoryCode,nextInvoiceTotalRecurringAmount],
229232
orderItem[id,
230233
order.userRecord[username],
@@ -803,7 +806,7 @@ def capture(self, instance_id, name, additional_disks=False, notes=None):
803806
name, disks_to_capture, notes, id=instance_id)
804807

805808
def upgrade(self, instance_id, cpus=None, memory=None,
806-
nic_speed=None, public=True):
809+
nic_speed=None, public=True, preset=None):
807810
"""Upgrades a VS instance.
808811
809812
Example::
@@ -817,6 +820,7 @@ def upgrade(self, instance_id, cpus=None, memory=None,
817820
:param int instance_id: Instance id of the VS to be upgraded
818821
:param int cpus: The number of virtual CPUs to upgrade to
819822
of a VS instance.
823+
:param string preset: preset assigned to the vsi
820824
:param int memory: RAM of the VS to be upgraded to.
821825
:param int nic_speed: The port speed to set
822826
:param bool public: CPU will be in Private/Public Node.
@@ -826,9 +830,28 @@ def upgrade(self, instance_id, cpus=None, memory=None,
826830
upgrade_prices = self._get_upgrade_prices(instance_id)
827831
prices = []
828832

829-
for option, value in {'cpus': cpus,
830-
'memory': memory,
831-
'nic_speed': nic_speed}.items():
833+
data = {'nic_speed': nic_speed}
834+
835+
if cpus is not None and preset is not None:
836+
raise exceptions.SoftLayerError("Do not use cpu, private and memory if you are using flavors")
837+
data['cpus'] = cpus
838+
839+
if memory is not None and preset is not None:
840+
raise exceptions.SoftLayerError("Do not use memory, private or cpu if you are using flavors")
841+
data['memory'] = memory
842+
843+
maintenance_window = datetime.datetime.now(utils.UTC())
844+
order = {
845+
'complexType': 'SoftLayer_Container_Product_Order_Virtual_Guest_'
846+
'Upgrade',
847+
'properties': [{
848+
'name': 'MAINTENANCE_WINDOW',
849+
'value': maintenance_window.strftime("%Y-%m-%d %H:%M:%S%z")
850+
}],
851+
'virtualGuests': [{'id': int(instance_id)}],
852+
}
853+
854+
for option, value in data.items():
832855
if not value:
833856
continue
834857
price_id = self._get_price_id_for_upgrade_option(upgrade_prices,
@@ -841,19 +864,13 @@ def upgrade(self, instance_id, cpus=None, memory=None,
841864
"Unable to find %s option with value %s" % (option, value))
842865

843866
prices.append({'id': price_id})
867+
order['prices'] = prices
844868

845-
maintenance_window = datetime.datetime.now(utils.UTC())
846-
order = {
847-
'complexType': 'SoftLayer_Container_Product_Order_Virtual_Guest_'
848-
'Upgrade',
849-
'prices': prices,
850-
'properties': [{
851-
'name': 'MAINTENANCE_WINDOW',
852-
'value': maintenance_window.strftime("%Y-%m-%d %H:%M:%S%z")
853-
}],
854-
'virtualGuests': [{'id': int(instance_id)}],
855-
}
856-
if prices:
869+
if preset is not None:
870+
vs_object = self.get_instance(instance_id)['billingItem']['package']
871+
order['presetId'] = self.ordering_manager.get_preset_by_key(vs_object['keyName'], preset)['id']
872+
873+
if prices or preset:
857874
self.client['Product_Order'].placeOrder(order)
858875
return True
859876
return False

tests/CLI/modules/vs_tests.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -901,6 +901,23 @@ def test_upgrade(self, confirm_mock):
901901
self.assertIn({'id': 1122}, order_container['prices'])
902902
self.assertEqual(order_container['virtualGuests'], [{'id': 100}])
903903

904+
@mock.patch('SoftLayer.CLI.formatting.confirm')
905+
def test_upgrade_with_flavor(self, confirm_mock):
906+
confirm_mock.return_value = True
907+
result = self.run_command(['vs', 'upgrade', '100', '--flavor=M1_64X512X100'])
908+
self.assert_no_fail(result)
909+
self.assert_called_with('SoftLayer_Product_Order', 'placeOrder')
910+
call = self.calls('SoftLayer_Product_Order', 'placeOrder')[0]
911+
order_container = call.args[0]
912+
self.assertEqual(799, order_container['presetId'])
913+
self.assertIn({'id': 100}, order_container['virtualGuests'])
914+
self.assertEqual(order_container['virtualGuests'], [{'id': 100}])
915+
916+
def test_upgrade_with_cpu_memory_and_flavor(self):
917+
result = self.run_command(['vs', 'upgrade', '100', '--cpu=4',
918+
'--memory=1024', '--flavor=M1_64X512X100'])
919+
self.assertEqual("Do not use cpu, private and memory if you are using flavors", str(result.exception))
920+
904921
def test_edit(self):
905922
result = self.run_command(['vs', 'edit',
906923
'--domain=example.com',

tests/managers/vs_tests.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -879,6 +879,22 @@ def test_upgrade_full(self):
879879
self.assertIn({'id': 1122}, order_container['prices'])
880880
self.assertEqual(order_container['virtualGuests'], [{'id': 1}])
881881

882+
def test_upgrade_with_flavor(self):
883+
# Testing Upgrade with parameter preset
884+
result = self.vs.upgrade(1,
885+
preset="M1_64X512X100",
886+
nic_speed=1000,
887+
public=True)
888+
889+
self.assertEqual(result, True)
890+
self.assert_called_with('SoftLayer_Product_Order', 'placeOrder')
891+
call = self.calls('SoftLayer_Product_Order', 'placeOrder')[0]
892+
order_container = call.args[0]
893+
self.assertEqual(799, order_container['presetId'])
894+
self.assertIn({'id': 1}, order_container['virtualGuests'])
895+
self.assertIn({'id': 1122}, order_container['prices'])
896+
self.assertEqual(order_container['virtualGuests'], [{'id': 1}])
897+
882898
def test_upgrade_dedicated_host_instance(self):
883899
mock = self.set_mock('SoftLayer_Virtual_Guest', 'getUpgradeItemPrices')
884900
mock.return_value = fixtures.SoftLayer_Virtual_Guest.DEDICATED_GET_UPGRADE_ITEM_PRICES

0 commit comments

Comments
 (0)