Repository: softlayer/softlayer-python
Pull request #1804 (2022-12-06 21:55:45)

`slcli vs upgrade --resize-disk` is resizing another disk and not the selected one
Issue: https://github.com/softlayer/softlayer-python/issues/1802
Observations: The command was updated to resize disk using category id instead category code
```
slcli vs upgrade 134499384 --resize-disk 10 4
This action will incur charges on your account. Continue? [y/N]: y
```
![image](https://user-images.githubusercontent.com/78806346/206031529-f5d192f6-5946-474b-85e5-f5a2bd799502.png)



Patch:
diff --git a/SoftLayer/fixtures/SoftLayer_Product_Package.py b/SoftLayer/fixtures/SoftLayer_Product_Package.py
index 8ca1c408..9c2b02ec 100644
--- a/SoftLayer/fixtures/SoftLayer_Product_Package.py
+++ b/SoftLayer/fixtures/SoftLayer_Product_Package.py
@@ -2216,3 +2216,63 @@
         }
     ]
 }]
+
+getVSDiskItemPrices = [
+    {
+        "id": 2255,
+        "locationGroupId": None,
+        "categories": [
+            {
+                "categoryCode": "guest_disk1",
+                "id": 82,
+                "name": "Second Disk",
+                "quantityLimit": 0,
+                "sortOrder": None
+            },
+            {
+                "categoryCode": "guest_disk2",
+                "id": 92,
+                "name": "Third Disk",
+                "quantityLimit": 0,
+                "sortOrder": None
+            },
+            {
+                "categoryCode": "guest_disk3",
+                "id": 93,
+                "name": "Fourth Disk",
+                "quantityLimit": 0,
+                "sortOrder": None
+            },
+            {
+                "categoryCode": "guest_disk4",
+                "id": 116,
+                "name": "Fifth Disk",
+                "quantityLimit": 0,
+                "sortOrder": None
+            }
+        ],
+        "item": {
+            "capacity": "10",
+            "description": "10 GB (SAN)",
+            "keyName": "GUEST_DISK_10_GB_SAN"
+        }
+    },
+    {
+        "id": 1639,
+        "locationGroupId": None,
+        "categories": [
+            {
+                "categoryCode": "guest_disk0",
+                "id": 81,
+                "name": "First Disk",
+                "quantityLimit": 0,
+                "sortOrder": None
+            }
+        ],
+        "item": {
+            "capacity": "10",
+            "description": "10 GB (SAN)",
+            "keyName": "GUEST_DISK_10_GB_SAN"
+        }
+    }
+]
diff --git a/SoftLayer/managers/vs.py b/SoftLayer/managers/vs.py
index 92a37998..c749e96c 100644
--- a/SoftLayer/managers/vs.py
+++ b/SoftLayer/managers/vs.py
@@ -1068,8 +1068,11 @@ def upgrade(self, instance_id, cpus=None, memory=None, nic_speed=None, public=Tr
                                                        'Unable to find %s option with value %s' % (
                                                            ('disk', disk_guest.get('capacity'))))
 
+                category_id = self.get_disk_category_id_by_disk_number(disk_guest.get('capacity'), disk_number)
+                if category_id is None:
+                    raise exceptions.SoftLayerError('Invalid disk number to this disk capacity')
                 category = {'categories': [{
-                    'categoryCode': 'guest_disk' + str(disk_number),
+                    'id': category_id,
                     'complexType': "SoftLayer_Product_Item_Category"}],
                     'complexType': 'SoftLayer_Product_Item_Price',
                     'id': price_id}
@@ -1101,6 +1104,43 @@ def upgrade(self, instance_id, cpus=None, memory=None, nic_speed=None, public=Tr
             return True
         return False
 
+    def get_disk_category_id_by_disk_number(self, capacity, disk_number):
+        """Uses Product_Package::getItemPrices to get all disk items with its categories and
+
+        disk_key_names dictionary to convert disk numbers (int) to ordinal numbers (string)
+        """
+        disk_key_names = {
+            1: "First Disk",
+            2: "Second Disk",
+            3: "Third Disk",
+            4: "Fourth Disk",
+            5: "Fifth Disk",
+        }
+        category_to_request = disk_key_names.get(disk_number)
+        if category_to_request is None:
+            return None
+
+        key_name = "*= GUEST_DISK_"+str(capacity)+"_GB_SAN"
+        object_filter = {
+            "itemPrices": {
+                "locationGroupId": {"operation": "is null"},
+                "item": {
+                    "keyName": {"operation": key_name}
+                }
+            }
+        }
+        mask = "mask[id,locationGroupId,item[capacity,description,keyName],categories]"
+        disk_items = self.client.call(
+            'SoftLayer_Product_Package', 'getItemPrices', id=46, mask=mask, filter=object_filter
+        )
+        category_id = None
+        for disk_item in disk_items:
+            for category in disk_item.get('categories'):
+                if category.get('name') == category_to_request:
+                    category_id = category.get('id')
+                    break
+        return category_id
+
     def order_guest(self, guest_object, test=False):
         """Uses Product_Order::placeOrder to create a virtual guest.
 


Test patch:
diff --git a/tests/CLI/modules/vs/vs_tests.py b/tests/CLI/modules/vs/vs_tests.py
index 86d9c5ee..029fea99 100644
--- a/tests/CLI/modules/vs/vs_tests.py
+++ b/tests/CLI/modules/vs/vs_tests.py
@@ -10,6 +10,7 @@
 from unittest import mock as mock
 
 from SoftLayer.CLI import exceptions
+from SoftLayer.fixtures import SoftLayer_Product_Package
 from SoftLayer.fixtures import SoftLayer_Virtual_Guest as SoftLayer_Virtual_Guest
 from SoftLayer import SoftLayerAPIError
 from SoftLayer import SoftLayerError
@@ -565,6 +566,8 @@ def test_upgrade(self, confirm_mock):
     @mock.patch('SoftLayer.CLI.formatting.confirm')
     def test_upgrade_disk(self, confirm_mock):
         confirm_mock.return_value = True
+        mock = self.set_mock('SoftLayer_Product_Package', 'getItemPrices')
+        mock.return_value = SoftLayer_Product_Package.getVSDiskItemPrices
         result = self.run_command(['vs', 'upgrade', '100', '--flavor=M1_64X512X100',
                                    '--resize-disk=10', '1', '--resize-disk=10', '2'])
         self.assert_no_fail(result)
@@ -598,6 +601,8 @@ def test_upgrade_with_flavor(self, confirm_mock):
     @mock.patch('SoftLayer.CLI.formatting.confirm')
     def test_upgrade_with_add_disk(self, confirm_mock):
         confirm_mock.return_value = True
+        mock = self.set_mock('SoftLayer_Product_Package', 'getItemPrices')
+        mock.return_value = SoftLayer_Product_Package.getVSDiskItemPrices
         result = self.run_command(['vs', 'upgrade', '100', '--add-disk=10', '--add-disk=10'])
         self.assert_no_fail(result)
         self.assert_called_with('SoftLayer_Product_Order', 'placeOrder')