|
5 | 5 |
|
6 | 6 | :license: MIT, see LICENSE for more details. |
7 | 7 | """ |
| 8 | +import datetime |
8 | 9 | import logging |
9 | 10 | import socket |
10 | 11 | import time |
11 | 12 |
|
12 | 13 | from SoftLayer.decoration import retry |
| 14 | +from SoftLayer import exceptions |
13 | 15 | from SoftLayer.exceptions import SoftLayerError |
14 | 16 | from SoftLayer.managers import ordering |
15 | 17 | from SoftLayer.managers.ticket import TicketManager |
|
18 | 20 | LOGGER = logging.getLogger(__name__) |
19 | 21 |
|
20 | 22 | # Invalid names are ignored due to long method names and short argument names |
21 | | -# pylint: disable=invalid-name, no-self-use |
| 23 | +# pylint: disable=invalid-name, no-self-use, too-many-lines |
22 | 24 |
|
23 | 25 | EXTRA_CATEGORIES = ['pri_ipv6_addresses', |
24 | 26 | 'static_ipv6_addresses', |
@@ -786,6 +788,146 @@ def get_hardware_item_prices(self, location): |
786 | 788 | return self.client.call('SoftLayer_Product_Package', 'getItemPrices', mask=object_mask, filter=object_filter, |
787 | 789 | id=package['id']) |
788 | 790 |
|
| 791 | + def upgrade(self, instance_id, memory=None, |
| 792 | + nic_speed=None, drive_controller=None, |
| 793 | + public_bandwidth=None, test=False): |
| 794 | + """Upgrades a hardware server instance. |
| 795 | +
|
| 796 | + :param int instance_id: Instance id of the hardware server to be upgraded. |
| 797 | + :param int memory: Memory size. |
| 798 | + :param string nic_speed: Network Port Speed data. |
| 799 | + :param string drive_controller: Drive Controller data. |
| 800 | + :param int public_bandwidth: Public keyName data. |
| 801 | + :param bool test: Test option to verify the request. |
| 802 | +
|
| 803 | + :returns: bool |
| 804 | + """ |
| 805 | + upgrade_prices = self._get_upgrade_prices(instance_id) |
| 806 | + prices = [] |
| 807 | + data = {} |
| 808 | + |
| 809 | + if memory: |
| 810 | + data['memory'] = memory |
| 811 | + if nic_speed: |
| 812 | + data['nic_speed'] = nic_speed |
| 813 | + if drive_controller: |
| 814 | + data['disk_controller'] = drive_controller |
| 815 | + if public_bandwidth: |
| 816 | + data['bandwidth'] = public_bandwidth |
| 817 | + |
| 818 | + server_response = self.get_instance(instance_id) |
| 819 | + package_id = server_response['billingItem']['package']['id'] |
| 820 | + |
| 821 | + maintenance_window = datetime.datetime.now(utils.UTC()) |
| 822 | + order = { |
| 823 | + 'complexType': 'SoftLayer_Container_Product_Order_Hardware_Server_Upgrade', |
| 824 | + 'properties': [{ |
| 825 | + 'name': 'MAINTENANCE_WINDOW', |
| 826 | + 'value': maintenance_window.strftime("%Y-%m-%d %H:%M:%S%z") |
| 827 | + }], |
| 828 | + 'hardware': [{'id': int(instance_id)}], |
| 829 | + 'packageId': package_id |
| 830 | + } |
| 831 | + |
| 832 | + for option, value in data.items(): |
| 833 | + price_id = self._get_prices_for_upgrade_option(upgrade_prices, option, value) |
| 834 | + if not price_id: |
| 835 | + # Every option provided is expected to have a price |
| 836 | + raise exceptions.SoftLayerError( |
| 837 | + "Unable to find %s option with value %s" % (option, value)) |
| 838 | + |
| 839 | + prices.append({'id': price_id}) |
| 840 | + |
| 841 | + order['prices'] = prices |
| 842 | + |
| 843 | + if prices: |
| 844 | + if test: |
| 845 | + self.client['Product_Order'].verifyOrder(order) |
| 846 | + else: |
| 847 | + self.client['Product_Order'].placeOrder(order) |
| 848 | + return True |
| 849 | + return False |
| 850 | + |
| 851 | + @retry(logger=LOGGER) |
| 852 | + def get_instance(self, instance_id): |
| 853 | + """Get details about a hardware server instance. |
| 854 | +
|
| 855 | + :param int instance_id: the instance ID |
| 856 | + :returns: A dictionary containing a large amount of information about |
| 857 | + the specified instance. |
| 858 | + """ |
| 859 | + mask = [ |
| 860 | + 'billingItem[id,package[id,keyName]]' |
| 861 | + ] |
| 862 | + mask = "mask[%s]" % ','.join(mask) |
| 863 | + |
| 864 | + return self.hardware.getObject(id=instance_id, mask=mask) |
| 865 | + |
| 866 | + def _get_upgrade_prices(self, instance_id, include_downgrade_options=True): |
| 867 | + """Following Method gets all the price ids related to upgrading a Hardware Server. |
| 868 | +
|
| 869 | + :param int instance_id: Instance id of the Hardware Server to be upgraded. |
| 870 | +
|
| 871 | + :returns: list |
| 872 | + """ |
| 873 | + mask = [ |
| 874 | + 'id', |
| 875 | + 'locationGroupId', |
| 876 | + 'categories[name,id,categoryCode]', |
| 877 | + 'item[keyName,description,capacity,units]' |
| 878 | + ] |
| 879 | + mask = "mask[%s]" % ','.join(mask) |
| 880 | + return self.hardware.getUpgradeItemPrices(include_downgrade_options, id=instance_id, mask=mask) |
| 881 | + |
| 882 | + @staticmethod |
| 883 | + def _get_prices_for_upgrade_option(upgrade_prices, option, value): |
| 884 | + """Find the price id for the option and value to upgrade. This |
| 885 | +
|
| 886 | + :param list upgrade_prices: Contains all the prices related to a |
| 887 | + hardware server upgrade. |
| 888 | + :param string option: Describes type of parameter to be upgraded |
| 889 | +
|
| 890 | + :return: int. |
| 891 | + """ |
| 892 | + price_id = None |
| 893 | + option_category = { |
| 894 | + 'memory': 'ram', |
| 895 | + 'nic_speed': 'port_speed', |
| 896 | + 'disk_controller': 'disk_controller', |
| 897 | + 'bandwidth': 'bandwidth' |
| 898 | + } |
| 899 | + category_code = option_category.get(option) |
| 900 | + |
| 901 | + for price in upgrade_prices: |
| 902 | + if price.get('categories') is None or price.get('item') is None: |
| 903 | + continue |
| 904 | + |
| 905 | + product = price.get('item') |
| 906 | + for category in price.get('categories'): |
| 907 | + if not category.get('categoryCode') == category_code: |
| 908 | + continue |
| 909 | + |
| 910 | + if option == 'disk_controller': |
| 911 | + if value == product.get('description'): |
| 912 | + price_id = price.get('id') |
| 913 | + elif option == 'nic_speed': |
| 914 | + if value.isdigit(): |
| 915 | + if str(product.get('capacity')) == str(value): |
| 916 | + price_id = price.get('id') |
| 917 | + else: |
| 918 | + split_nic_speed = value.split(" ") |
| 919 | + if str(product.get('capacity')) == str(split_nic_speed[0]) and \ |
| 920 | + split_nic_speed[1] in product.get("description"): |
| 921 | + price_id = price.get('id') |
| 922 | + elif option == 'bandwidth': |
| 923 | + if str(product.get('capacity')) == str(value): |
| 924 | + price_id = price.get('id') |
| 925 | + else: |
| 926 | + if str(product.get('capacity')) == str(value): |
| 927 | + price_id = price.get('id') |
| 928 | + |
| 929 | + return price_id |
| 930 | + |
789 | 931 |
|
790 | 932 | def _get_bandwidth_key(items, hourly=True, no_public=False, location=None): |
791 | 933 | """Picks a valid Bandwidth Item, returns the KeyName""" |
|
0 commit comments