-
Notifications
You must be signed in to change notification settings - Fork 1
Cciupgrade #2
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
base: master
Are you sure you want to change the base?
Cciupgrade #2
Changes from all commits
a28821c
ddd2c8c
2e10441
b390d41
2d8bc54
ebd63a4
e4da339
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -21,6 +21,7 @@ | |
| reboot Reboots a running CCI | ||
| reload Reload the OS on a CCI based on its current configuration | ||
| resume Resumes a paused CCI | ||
| upgrade Upgrades parameters of a CCI | ||
|
|
||
| For several commands, <identifier> will be asked for. This can be the id, | ||
| hostname or the ip address for a CCI. | ||
|
|
@@ -1016,3 +1017,96 @@ def execute(self, args): | |
| t.add_row(['transaction_id', capture['id']]) | ||
| t.add_row(['all_disks', additional_disks]) | ||
| return t | ||
|
|
||
|
|
||
| class UpgradeCCI(CLIRunnable): | ||
| """ | ||
| usage: sl cci upgrade <identifier> [options] | ||
|
|
||
| Upgrade parameters of an CCI | ||
|
|
||
| Options: | ||
| --cpu=CPU Number of CPU cores | ||
| --memory=MEMORY Memory in megabytes | ||
| --network=MBPS Network port speed in Mbps | ||
| --disk=SIZE... Disks. Can be specified multiple times | ||
| --san Use SAN storage instead of local disk. Applies to | ||
| all disks specified with --disk. | ||
| --reboot Soft Reboot of CCI | ||
| """ | ||
|
|
||
| action = 'upgrade' | ||
| options = ['confirm'] | ||
|
|
||
| def execute(self, args): | ||
| cci = CCIManager(self.client) | ||
| data = {} | ||
| data['cpus'] = args.get('--cpu') | ||
| data['memory'] = args.get('--memory') | ||
| data['nic_speed'] = args.get('--network') | ||
| instance_id = args.get('<identifier>') | ||
| if not instance_id: | ||
| raise ArgumentError('CCI ID must be provided') | ||
| reboot = False | ||
| if args['--reboot']: | ||
| reboot = True | ||
| data['local_disk'] = True | ||
| data['disk'] = "" | ||
| # Disks will be a comma-separated list. Let's make it a real list. | ||
| if isinstance(args.get('--disk'), str): | ||
| args['--disk'] = args.get('--disk').split(',') | ||
| data['disk'] = args['--disk'] | ||
| if args['--san']: | ||
| data['local_disk'] = False | ||
| if data['local_disk']: | ||
| if len(data['disk']) > 2: | ||
| raise ArgumentError( \ | ||
| 'Maximum 2 Disks are Allowed for Local') | ||
| elif len(data['disk']) > 5: | ||
| raise ArgumentError('Maximum 5 Disks are Allowed for SAN') | ||
| if data['memory']: | ||
| data['memory'] = int(data['memory']) / 1024 | ||
| if data['disk']: | ||
| raise NotImplementedError('Disk Upgrade yet to implement') | ||
| if args['--really'] or confirm( | ||
| "This action will incur charges on your account. " | ||
| "Continue?"): | ||
| item_id = [] | ||
| try: | ||
| package_items = cci.get_package_items_for_virtual_guest() | ||
| if data['cpus']: | ||
| item_id.append({'id': self.get_item_id_for_upgrade( | ||
| package_items, 'cpus', data['cpus'])}) | ||
| if data['memory']: | ||
| item_id.append({'id': self.get_item_id_for_upgrade( | ||
| package_items, 'memory', data['memory'])}) | ||
| if data['nic_speed']: | ||
| item_id.append({'id': self.get_item_id_for_upgrade( | ||
| package_items, 'nic_speed', | ||
| data['nic_speed'])}) | ||
| cci.upgrade(instance_id, item_id) | ||
| except: | ||
| raise CLIAbort('CCI Upgrade Failed') | ||
|
|
||
| def get_item_id_for_upgrade(self, package_items, option, value): | ||
| """ | ||
| Find the item ids for the parameters you want to upgrade to. | ||
| :param list package_items: Contains all the items related to an CCI | ||
| :param string option: Describes type of paramter to be upgraded | ||
| :param int value: The value of the parameter to be upgraded | ||
| """ | ||
| id = {'memory': 3, 'cpus': 80, 'nic_speed': 26, | ||
| 'First Disk': 81, 'Second Disk': 82, 'Third Disk': 92, | ||
| 'Fourth Disk': 93, 'Fifth Disk': 116} | ||
| f = 0 | ||
| for item in package_items: | ||
| if len(filter(lambda x: x.get('id') == id[option], \ | ||
| item['categories'])) \ | ||
| and item.get('capacity') == str(value): | ||
| if option == 'cpus' or option =='nic_speed': | ||
| if f == 1: | ||
|
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. what is this |
||
| return item['prices'][0]['id'] | ||
| else: | ||
| f = f + 1 | ||
| else: | ||
| return item['prices'][0]['id'] | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -8,7 +8,7 @@ | |
| import socket | ||
| from time import sleep | ||
| from itertools import repeat | ||
|
|
||
| import datetime | ||
| from SoftLayer.utils import NestedDict, query_filter, IdentifierMixin, lookup | ||
|
|
||
|
|
||
|
|
@@ -484,3 +484,35 @@ def capture(self, instance_id, name, additional_disks=False, notes=None): | |
|
|
||
| return self.guest.createArchiveTransaction( | ||
| name, disks, notes, id=instance_id) | ||
|
|
||
| def upgrade(self, instance_id, item_id, reboot = False): | ||
|
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. CCIManager is an abstract interface to manage CCIs. To remain abstract it has to hide details like |
||
| """ | ||
| Upgrades a CCI instane | ||
| :param int instance_id: Instane id of te CCI to be upgraded | ||
| :param int cpus: The number of virtual CPUs to upgrade to | ||
| of a CCI instance. | ||
| :param int memory: RAM of the CCI to be upgraded to. | ||
| :param bool local_disk: Flag to indicate if this should be a local disk | ||
| (default) or a SAN disk. | ||
| :param list disks: A list of disk capacities for this server | ||
| :param bool reboot: Flag to indicate weather to reboot or | ||
| not upon upgrade | ||
| :param int nic_speed: The port speed to set | ||
| """ | ||
| orderClient = self.client['Product_Order'] | ||
| orderContainer = {} | ||
| orderContainer['complexType'] = \ | ||
| 'SoftLayer_Container_Product_Order_Virtual_Guest_Upgrade' | ||
| orderContainer['virtualGuests'] = [{'id': int(instance_id)}] | ||
| orderContainer['prices'] = item_id | ||
| orderContainer['properties'] = [{'name': 'MAINTENANCE_WINDOW', | ||
| 'value': str(datetime.datetime.now())}] | ||
| orderClient.verifyOrder(orderContainer) | ||
| orderClient.placeOrder(orderContainer) | ||
| if reboot: | ||
| self.guest.rebootSoft(id=int(instance_id)) | ||
|
|
||
| def get_package_items_for_virtual_guest(self): | ||
| mask = "mask[capacity,prices.id,categories[name,id]]" | ||
| package = self.client['Product_Package'] | ||
| return package.getItems(id=46, mask=mask) | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -532,6 +532,42 @@ def test_captures(self): | |
| archive.called_once_with('a', [{"device": 0, "uuid": 1}, | ||
| {"device": 2, "uuid": 2}], "", id=1) | ||
|
|
||
| def test_upgrade(self): | ||
| # Testing Upgrade | ||
| orderClient = self.client['Product_Order'] | ||
|
|
||
| # test single upgrade | ||
| item_ids = [{'id': 1024}] | ||
| self.cci.upgrade(1, item_ids) | ||
|
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What are we testing here? Nothing seems to be getting asserted after this. |
||
|
|
||
| # test single upgrade with rebot | ||
| item_ids = [{'id': 1024}] | ||
| self.cci.upgrade(1, item_ids, reboot = True) | ||
|
|
||
| # Now test a blank upgrade | ||
| self.assertTrue(self.cci.upgrade, 1) | ||
|
|
||
| # Finally, test a full Upgrade | ||
| item_ids = [{'id': 1}, {'id': 2}, {'id': 3}] | ||
| self.cci.upgrade(1, item_ids) | ||
| order = self.test_ordercontainer_options() | ||
| orderClient.verifyOrder.called_once_with(order) | ||
| orderClient.placeOrder.called_once_with(order) | ||
|
|
||
| def test_package_ids_for_virtual_guest(self): | ||
| result = self.cci.get_package_items_for_virtual_guest()[0] | ||
| self.assertEqual(4444, result['prices'][0]['id']) | ||
|
|
||
| def test_ordercontainer_options(self): | ||
| orderContainer = {} | ||
| orderContainer['complexType'] = \ | ||
| 'SoftLayer_Container_Product_Order_Virtual_Guest_Upgrade' | ||
| orderContainer['virtualGuests'] = [{'id': 1}] | ||
| orderContainer['prices'] = [{'id': 1645}] | ||
| orderContainer['properties'] = [{'name': 'MAINTENANCE_WINDOW', | ||
| 'value': '2014-03-21 03:12:47.942307'}] | ||
| return orderContainer | ||
|
|
||
|
|
||
| class CCIWaitReadyGoTests(unittest.TestCase): | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do not use
idas object or function name. It's might confuse with built-in pythonidfunction. Can you use pluralids?