Repository: softlayer/softlayer-python
Pull request #1998 (2023-06-20 20:18:43)

Added new command `slcli bandwidth pools-delete`
Issue link: #1995 
```
softlayer-python/ (issue1995) $ slcli bandwidth pools-delete 1292861
Bandwidth pool with ID 1292861 was programmed to will delete
```


Patch:
diff --git a/SoftLayer/CLI/bandwidth/pools_delete.py b/SoftLayer/CLI/bandwidth/pools_delete.py
new file mode 100644
index 00000000..6d1aadc4
--- /dev/null
+++ b/SoftLayer/CLI/bandwidth/pools_delete.py
@@ -0,0 +1,19 @@
+"""Delete bandwidth pool."""
+# :license: MIT, see LICENSE for more details.
+import click
+
+from SoftLayer import BandwidthManager
+from SoftLayer.CLI.command import SLCommand as SLCommand
+from SoftLayer.CLI import environment
+
+
+@click.command(cls=SLCommand)
+@click.argument('identifier')
+@environment.pass_env
+def cli(env, identifier):
+    """Delete bandwidth pool."""
+
+    manager = BandwidthManager(env.client)
+    bandwidth_pool = manager.delete_pool(identifier)
+
+    env.fout(f"Bandwidth pool {identifier} has been scheduled for deletion.")
diff --git a/SoftLayer/CLI/config/setup.py b/SoftLayer/CLI/config/setup.py
index db895fa3..7ba52ee9 100644
--- a/SoftLayer/CLI/config/setup.py
+++ b/SoftLayer/CLI/config/setup.py
@@ -76,7 +76,7 @@ def cli(env, auth):
 
     elif auth == 'cloud_key':
         username = 'apikey'
-        secret = env.getpass('Classic Infrastructure API Key', default=defaults['api_key'])
+        secret = env.getpass('Classic Infrastructue API Key', default=defaults['api_key'])
         new_client = SoftLayer.Client(username=username, api_key=secret, endpoint_url=endpoint_url, timeout=timeout)
         api_key = get_api_key(new_client, username, secret)
 
@@ -84,8 +84,8 @@ def cli(env, auth):
         username, api_key = sso_login(env)
 
     else:
-        username = env.input('Classic Infrastructure Username', default=defaults['username'])
-        secret = env.getpass('Classic Infrastructure API Key', default=defaults['api_key'])
+        username = env.input('Classic Infrastructue Username', default=defaults['username'])
+        secret = env.getpass('Classic Infrastructue API Key', default=defaults['api_key'])
         new_client = SoftLayer.Client(username=username, api_key=secret, endpoint_url=endpoint_url, timeout=timeout)
         api_key = get_api_key(new_client, username, secret)
 
diff --git a/SoftLayer/CLI/routes.py b/SoftLayer/CLI/routes.py
index c2e57f03..d51a4c3e 100644
--- a/SoftLayer/CLI/routes.py
+++ b/SoftLayer/CLI/routes.py
@@ -426,6 +426,7 @@
     ('bandwidth:pools-detail', 'SoftLayer.CLI.bandwidth.pools_detail:cli'),
     ('bandwidth:pools-create', 'SoftLayer.CLI.bandwidth.pools_create:cli'),
     ('bandwidth:pools-edit', 'SoftLayer.CLI.bandwidth.pools_edit:cli'),
+    ('bandwidth:pools-delete', 'SoftLayer.CLI.bandwidth.pools_delete:cli'),
 ]
 
 ALL_ALIASES = {
diff --git a/SoftLayer/fixtures/SoftLayer_Network_Bandwidth_Version1_Allotment.py b/SoftLayer/fixtures/SoftLayer_Network_Bandwidth_Version1_Allotment.py
index b0145963..10a4e450 100644
--- a/SoftLayer/fixtures/SoftLayer_Network_Bandwidth_Version1_Allotment.py
+++ b/SoftLayer/fixtures/SoftLayer_Network_Bandwidth_Version1_Allotment.py
@@ -158,3 +158,5 @@
 }
 
 editObject = True
+
+requestVdrCancellation = True
diff --git a/SoftLayer/managers/bandwidth.py b/SoftLayer/managers/bandwidth.py
index 8612f3ca..c9c78b3e 100644
--- a/SoftLayer/managers/bandwidth.py
+++ b/SoftLayer/managers/bandwidth.py
@@ -69,3 +69,10 @@ def edit_pool(self, identifier, new_name_pool):
         }
 
         return self.client.call('Network_Bandwidth_Version1_Allotment', 'editObject', template, id=identifier)
+
+    def delete_pool(self, identifier):
+        """Delete bandwidth pool
+
+        :return: Boolean value
+        """
+        return self.client.call('Network_Bandwidth_Version1_Allotment', 'requestVdrCancellation', id=identifier)
diff --git a/SoftLayer/managers/ordering.py b/SoftLayer/managers/ordering.py
index 8e6a34d8..9bd25c90 100644
--- a/SoftLayer/managers/ordering.py
+++ b/SoftLayer/managers/ordering.py
@@ -10,8 +10,6 @@
 
 from SoftLayer import exceptions
 
-from SoftLayer import utils
-
 CATEGORY_MASK = '''id, isRequired, itemCategory[id, name, categoryCode]'''
 
 ITEM_MASK = '''id, keyName, description, itemCategory, categories, prices'''
@@ -34,8 +32,6 @@ def __init__(self, client):
         self.order_svc = client['Product_Order']
         self.billing_svc = client['Billing_Order']
         self.package_preset = client['Product_Package_Preset']
-        self.package_mask = 'id, description, capacity, itemCategory, keyName, prices[categories], ' \
-            'softwareDescription[id,referenceCode,longDescription]'
 
     def get_packages_of_type(self, package_types, mask=None):
         """Get packages that match a certain type.
@@ -374,8 +370,7 @@ def get_price_id_list(self, package_keyname, item_keynames, core=None):
                   keynames in the given package
 
         """
-        mask = 'id, description, capacity, itemCategory, keyName, prices[categories], ' \
-            'softwareDescription[id,referenceCode,longDescription]'
+        mask = 'id, description, capacity, itemCategory, keyName, prices[categories]'
         items = self.list_items(package_keyname, mask=mask)
         item_capacity = self.get_item_capacity(items, item_keynames)
 
@@ -383,18 +378,14 @@ def get_price_id_list(self, package_keyname, item_keynames, core=None):
         category_dict = {"gpu0": -1, "pcie_slot0": -1}
 
         for item_keyname in item_keynames:
-            matching_item = []
-            # Need to find the item in the package that has a matching
-            # keyName with the current item we are searching for
-            for i in items:
-                reference_code = utils.lookup(i, 'softwareDescription', 'referenceCode')
-                if i['keyName'] == item_keyname or reference_code == item_keyname:
-                    matching_item.append(i)
-
-            if len(matching_item) == 0:
+            try:
+                # Need to find the item in the package that has a matching
+                # keyName with the current item we are searching for
+                matching_item = [i for i in items
+                                 if i['keyName'] == item_keyname][0]
+            except IndexError as ex:
                 message = f"Item {item_keyname} does not exist for package {package_keyname}"
-                raise exceptions.SoftLayerError(message)
-            matching_item = matching_item[0]
+                raise exceptions.SoftLayerError(message) from ex
 
             # we want to get the price ID that has no location attached to it,
             # because that is the most generic price. verifyOrder/placeOrder
diff --git a/docs/cli/bandwidth.rst b/docs/cli/bandwidth.rst
index 772e5ac1..f194e2c8 100644
--- a/docs/cli/bandwidth.rst
+++ b/docs/cli/bandwidth.rst
@@ -23,3 +23,7 @@ bandwidth Commands
 .. click:: SoftLayer.CLI.bandwidth.pools_edit:cli
     :prog: bandwidth pools-edit
     :show-nested:
+
+.. click:: SoftLayer.CLI.bandwidth.pools_delete:cli
+    :prog: bandwidth pools-delete
+    :show-nested:


Test patch:
diff --git a/tests/CLI/modules/bandwidth_tests.py b/tests/CLI/modules/bandwidth_tests.py
index bc9d321f..596ff1e6 100644
--- a/tests/CLI/modules/bandwidth_tests.py
+++ b/tests/CLI/modules/bandwidth_tests.py
@@ -61,6 +61,13 @@ def test_edit_bandwidth(self):
         self.assertEqual('MexRegionEdited', json_output['Name Pool'])
         self.assertEqual('MEX', json_output['Region'])
 
+    def test_delete_bandwidth(self):
+        result = self.run_command(['bandwidth', 'pools-delete', '123456'])
+        self.assert_no_fail(result)
+        self.assert_called_with('SoftLayer_Network_Bandwidth_Version1_Allotment', 'requestVdrCancellation')
+        json_output = json.loads(result.output)
+        self.assertEqual("Bandwidth pool 123456  has been scheduled for deletion.", json_output)
+
 
 def _bandwidth_advanced_search():
     result = [
diff --git a/tests/managers/ordering_tests.py b/tests/managers/ordering_tests.py
index 7d86c005..9bf11a04 100644
--- a/tests/managers/ordering_tests.py
+++ b/tests/managers/ordering_tests.py
@@ -316,7 +316,8 @@ def test_get_price_id_list(self):
 
             prices = self.ordering.get_price_id_list('PACKAGE_KEYNAME', ['ITEM1', 'ITEM2'], "8")
 
-        list_mock.assert_called_once_with('PACKAGE_KEYNAME', mask=self.ordering.package_mask)
+        list_mock.assert_called_once_with('PACKAGE_KEYNAME', mask='id, description, capacity, itemCategory, keyName, '
+                                                                  'prices[categories]')
         self.assertEqual([price1['id'], price2['id']], prices)
 
     def test_get_price_id_list_no_core(self):
@@ -334,24 +335,22 @@ def test_get_price_id_list_no_core(self):
             prices = self.ordering.get_price_id_list('PACKAGE_KEYNAME', ['ITEM1', 'ITEM2'], None)
 
         list_mock.assert_called_once_with('PACKAGE_KEYNAME', mask='id, description, capacity, itemCategory, keyName, '
-                                          'prices[categories], softwareDescription[id,referenceCode,longDescription]')
+                                                                  'prices[categories]')
         self.assertEqual([price1['id'], price2['id']], prices)
 
     def test_get_price_id_list_item_not_found(self):
         category1 = {'categoryCode': 'cat1'}
         price1 = {'id': 1234, 'locationGroupId': '', 'categories': [category1]}
-        softwareDescription1 = {'id': 1234, 'longDescription': 'ABCD 1.2-34', 'referenceCode': 'ABCD_9_32'}
-        item1 = {'id': 1111, 'keyName': 'ITEM1', 'itemCategory': category1,
-                 'prices': [price1], 'softwareDescription': softwareDescription1, }
+        item1 = {'id': 1111, 'keyName': 'ITEM1', 'itemCategory': category1, 'prices': [price1]}
 
         with mock.patch.object(self.ordering, 'list_items') as list_mock:
             list_mock.return_value = [item1]
 
             exc = self.assertRaises(exceptions.SoftLayerError,
                                     self.ordering.get_price_id_list,
-                                    'PACKAGE_KEYNAME', ['ITEM2'], "12")
+                                    'PACKAGE_KEYNAME', ['ITEM2'], "8")
         list_mock.assert_called_once_with('PACKAGE_KEYNAME', mask='id, description, capacity, itemCategory, keyName, '
-                                          'prices[categories], softwareDescription[id,referenceCode,longDescription]')
+                                                                  'prices[categories]')
         self.assertEqual("Item ITEM2 does not exist for package PACKAGE_KEYNAME", str(exc))
 
     def test_get_price_id_list_gpu_items_with_two_categories(self):
@@ -366,8 +365,7 @@ def test_get_price_id_list_gpu_items_with_two_categories(self):
             prices = self.ordering.get_price_id_list('PACKAGE_KEYNAME', ['ITEM1', 'ITEM1'], "8")
 
             list_mock.assert_called_once_with('PACKAGE_KEYNAME', mask='id, description, capacity, itemCategory, '
-                                              'keyName, prices[categories], '
-                                              'softwareDescription[id,referenceCode,longDescription]')
+                                                                      'keyName, ' 'prices[categories]')
             self.assertEqual([price2['id'], price1['id']], prices)
 
     def test_generate_no_complex_type(self):
@@ -622,7 +620,7 @@ def test_location_group_id_none(self):
             prices = self.ordering.get_price_id_list('PACKAGE_KEYNAME', ['ITEM1', 'ITEM2'], "8")
 
         list_mock.assert_called_once_with('PACKAGE_KEYNAME', mask='id, description, capacity, itemCategory, keyName, '
-                                          'prices[categories], softwareDescription[id,referenceCode,longDescription]')
+                                                                  'prices[categories]')
         self.assertEqual([price1['id'], price2['id']], prices)
 
     def test_location_groud_id_empty(self):
@@ -639,9 +637,8 @@ def test_location_groud_id_empty(self):
 
             prices = self.ordering.get_price_id_list('PACKAGE_KEYNAME', ['ITEM1', 'ITEM2'], "8")
 
-        list_mock.assert_called_once_with('PACKAGE_KEYNAME', mask='id, description, capacity, itemCategory, '
-                                          'keyName, prices[categories], '
-                                          'softwareDescription[id,referenceCode,longDescription]')
+        list_mock.assert_called_once_with('PACKAGE_KEYNAME', mask='id, description, capacity, itemCategory, keyName, '
+                                                                  'prices[categories]')
         self.assertEqual([price1['id'], price2['id']], prices)
 
     def test_get_item_price_id_without_capacity_restriction(self):