Repository: softlayer/softlayer-python

Issue:
`slcli vs create` should only display "closing soon" on closing datacenters
```
(good)
$ slcli --really vs create --billing hourly -H delete -D cgallo.com  --flavor B1_2X8X100 -o DEBIAN_LATEST -d mex01
Warning: Closed soon: mex01.pod01

(bad)
$ slcli --really vs create --billing hourly -H delete -D cgallo.com  --flavor B1_2X8X100 -o DEBIAN_LATEST
Datacenter: dal13
Warning: Closed soon:
```

Discussion:

Patch:
diff --git a/SoftLayer/CLI/hardware/create.py b/SoftLayer/CLI/hardware/create.py
index 52ebfa5c..682c07be 100644
--- a/SoftLayer/CLI/hardware/create.py
+++ b/SoftLayer/CLI/hardware/create.py
@@ -44,7 +44,6 @@ def cli(env, **args):
     network = SoftLayer.NetworkManager(env.client)
 
     pods = network.get_closed_pods()
-    closure = []
 
     # Get the SSH keys
     ssh_keys = []
@@ -104,9 +103,8 @@ def cli(env, **args):
 
     if do_create:
         for pod in pods:
-            if args.get('datacenter') in str(pod['name']):
-                closure.append(pod['name'])
-        click.secho(click.style('Warning: Closed soon: %s' % (', '.join(closure)), fg='yellow'))
+            if args.get('datacenter') in pod['name']:
+                click.secho('Warning: Closed soon: {}'.format(pod['name']), fg='yellow')
         if not (env.skip_confirmations or formatting.confirm(
                 "This action will incur charges on your account. Continue?")):
             raise exceptions.CLIAbort('Aborting dedicated server order.')
diff --git a/SoftLayer/CLI/order/place.py b/SoftLayer/CLI/order/place.py
index eeb9ad2e..351b9678 100644
--- a/SoftLayer/CLI/order/place.py
+++ b/SoftLayer/CLI/order/place.py
@@ -12,9 +12,8 @@
 from SoftLayer.managers import NetworkManager
 from SoftLayer.managers import ordering
 
-COLUMNS = ['keyName',
-           'description',
-           'cost', ]
+
+COLUMNS = ['keyName', 'description', 'cost']
 
 
 @click.command(cls=SLCommand)
@@ -22,17 +21,11 @@
 @click.argument('location')
 @click.option('--preset',
               help="The order preset (if required by the package)")
-@click.option('--verify',
-              is_flag=True,
+@click.option('--verify', is_flag=True,
               help="Flag denoting whether or not to only verify the order, not place it")
-@click.option('--quantity',
-              type=int,
-              default=1,
+@click.option('--quantity', type=int, default=1,
               help="The quantity of the item being ordered")
-@click.option('--billing',
-              type=click.Choice(['hourly', 'monthly']),
-              default='hourly',
-              show_default=True,
+@click.option('--billing', type=click.Choice(['hourly', 'monthly']), default='hourly', show_default=True,
               help="Billing rate")
 @click.option('--complex-type',
               help=("The complex type of the order. Starts with 'SoftLayer_Container_Product_Order'."))
@@ -68,8 +61,12 @@ def cli(env, package_keyname, location, preset, verify, billing, complex_type,
     manager = ordering.OrderingManager(env.client)
     network = NetworkManager(env.client)
 
+    # Check if this location is going to be shutdown soon.
     pods = network.get_closed_pods()
-    closure = []
+    location_dc = network.get_datacenter_by_keyname(location)
+    for pod in pods:
+        if location_dc.get('name') in pod.get('name'):
+            click.secho('Warning: Closed soon: {}'.format(pod.get('name')), fg='yellow')
 
     if extras:
         try:
@@ -96,9 +93,6 @@ def cli(env, package_keyname, location, preset, verify, billing, complex_type,
             ])
 
     else:
-        for pod in pods:
-            closure.append(pod['name'])
-        click.secho(click.style('Warning: Closed soon: %s' % (', '.join(closure)), fg='yellow'))
         if not (env.skip_confirmations or formatting.confirm(
                 "This action will incur charges on your account. Continue?")):
             raise exceptions.CLIAbort("Aborting order.")
diff --git a/SoftLayer/CLI/virt/create.py b/SoftLayer/CLI/virt/create.py
index 8f6a8f64..3a581a5b 100644
--- a/SoftLayer/CLI/virt/create.py
+++ b/SoftLayer/CLI/virt/create.py
@@ -221,13 +221,11 @@ def cli(env, **args):
     network = SoftLayer.NetworkManager(env.client)
 
     pods = network.get_closed_pods()
-    closure = []
 
     if do_create:
         for pod in pods:
             if args.get('datacenter') in str(pod['name']):
-                closure.append(pod['name'])
-        click.secho(click.style('Warning: Closed soon: %s' % (', '.join(closure)), fg='yellow'))
+                click.secho('Warning: Closed soon: {}'.format(pod['name']), fg='yellow')
         if not (env.skip_confirmations or formatting.confirm(
                 "This action will incur charges on your account. Continue?")):
             raise exceptions.CLIAbort('Aborting virtual server order.')
diff --git a/SoftLayer/managers/network.py b/SoftLayer/managers/network.py
index 2480974a..ae4cc829 100644
--- a/SoftLayer/managers/network.py
+++ b/SoftLayer/managers/network.py
@@ -851,3 +851,18 @@ def get_datacenter(self, _filter=None, datacenter=None):
             _filter = {"name": {"operation": datacenter}}
 
         return self.client.call('SoftLayer_Location', 'getDatacenters', filter=_filter, limit=1)
+
+    def get_datacenter_by_keyname(self, keyname=None):
+        """Calls SoftLayer_Location::getDatacenters()
+
+        returns datacenter list.
+        """
+        mask = "mask[id,longName,name,regions[keyname,description]]"
+        _filter = {}
+        if keyname:
+            _filter = {"regions": {"keyname": {"operation": keyname}}}
+
+        result = self.client.call('SoftLayer_Location', 'getDatacenters', filter=_filter, limit=1, mask=mask)
+        if len(result) >= 1:
+            return result[0]
+        return {}


Test patch:
diff --git a/tests/CLI/modules/order_tests.py b/tests/CLI/modules/order_tests.py
index c1541594..246aa920 100644
--- a/tests/CLI/modules/order_tests.py
+++ b/tests/CLI/modules/order_tests.py
@@ -7,6 +7,8 @@
 import sys
 import tempfile
 
+from unittest import mock as mock
+
 from SoftLayer.CLI import exceptions
 from SoftLayer import testing
 
@@ -141,10 +143,12 @@ def test_place(self):
 
         self.assert_no_fail(result)
         self.assert_called_with('SoftLayer_Product_Order', 'placeOrder')
-        self.assertIn('Warning: Closed soon: ams01.pod01, wdc07.pod01, TEST00.pod2', result.output)
+        self.assertNotIn('Warning: Closed soon: dal13', result.output)
         self.assertIn('"status": "APPROVED"', result.output)
 
-    def test_place_with_quantity(self):
+    @mock.patch('SoftLayer.managers.network.NetworkManager.get_datacenter_by_keyname')
+    def test_place_with_quantity(self, keyname_mock):
+        keyname_mock.return_value = {"name": "ams01"}
         order_date = '2017-04-04 07:39:20'
         order = {'orderId': 1234, 'orderDate': order_date, 'placedOrder': {'status': 'APPROVED'}}
         verify_mock = self.set_mock('SoftLayer_Product_Order', 'verifyOrder')
@@ -155,12 +159,12 @@ def test_place_with_quantity(self):
         place_mock.return_value = order
         items_mock.return_value = self._get_order_items()
 
-        result = self.run_command(['-y', 'order', 'place', '--quantity=2', 'package', 'DALLAS13', 'ITEM1',
+        result = self.run_command(['-y', 'order', 'place', '--quantity=2', 'package', 'AMSTERDAM', 'ITEM1',
                                    '--complex-type', 'SoftLayer_Container_Product_Order_Thing'])
 
         self.assert_no_fail(result)
         self.assert_called_with('SoftLayer_Product_Order', 'placeOrder')
-        self.assertIn('Warning: Closed soon: ams01.pod01, wdc07.pod01, TEST00.pod2', result.output)
+        self.assertIn('Warning: Closed soon: ams01.pod01', result.output)
         self.assertIn('"status": "APPROVED"', result.output)
 
     def test_place_extras_parameter_fail(self):
diff --git a/tests/CLI/modules/server_tests.py b/tests/CLI/modules/server_tests.py
index 9f8653c0..cc30c70e 100644
--- a/tests/CLI/modules/server_tests.py
+++ b/tests/CLI/modules/server_tests.py
@@ -401,6 +401,17 @@ def test_create_server(self, order_mock):
         self.assertIn('Warning: Closed soon: TEST00.pod2', result.output)
         self.assertIn('"id": 98765', result.output)
 
+        result = self.run_command(['--really', 'server', 'create',
+                                   '--size=S1270_8GB_2X1TBSATA_NORAID',
+                                   '--hostname=test',
+                                   '--domain=example.com',
+                                   '--datacenter=mex01',
+                                   '--os=OS_UBUNTU_14_04_LTS_TRUSTY_TAHR_64_BIT',
+                                   ])
+
+        self.assert_no_fail(result)
+        self.assertNotIn('Warning: Closed soon: mex01', result.output)
+
     @mock.patch('SoftLayer.CLI.template.export_to_template')
     def test_create_server_with_export(self, export_mock):
 
@@ -1015,3 +1026,15 @@ def test_sensor_discrete(self):
     def test_monitoring(self):
         result = self.run_command(['hardware', 'monitoring', '100'])
         self.assert_no_fail(result)
+
+    @mock.patch('SoftLayer.CLI.formatting.confirm')
+    def test_check_for_closing(self, confirm_mock):
+        confirm_mock.return_value = True
+        result = self.run_command(['vs', 'create', '--hostname', 'TEST', '--domain', 'TESTING',
+                                   '--flavor', 'B1_2X8X25', '--datacenter', 'ams01', '--os', 'UBUNTU_LATEST'])
+        self.assert_no_fail(result)
+        self.assertIn('Warning: Closed soon: ams01', result.output)
+        result = self.run_command(['vs', 'create', '--hostname', 'TEST', '--domain', 'TESTING',
+                                   '--flavor', 'B1_2X8X25', '--datacenter', 'mex01', '--os', 'UBUNTU_LATEST'])
+        self.assert_no_fail(result)
+        self.assertNotIn('Warning: Closed soon: mex01', result.output)
diff --git a/tests/CLI/modules/vs/vs_create_tests.py b/tests/CLI/modules/vs/vs_create_tests.py
index efcb8cbc..468bc533 100644
--- a/tests/CLI/modules/vs/vs_create_tests.py
+++ b/tests/CLI/modules/vs/vs_create_tests.py
@@ -722,3 +722,15 @@ def test_create_with_userdata(self, confirm_mock):
         api_call = self.calls('SoftLayer_Product_Order', 'placeOrder')
         # Doing this because the placeOrder args are huge and mostly not needed to test
         self.assertEqual(api_call[0].args[0]['virtualGuests'], expected_guest)
+
+    @mock.patch('SoftLayer.CLI.formatting.confirm')
+    def test_check_for_closing(self, confirm_mock):
+        confirm_mock.return_value = True
+        result = self.run_command(['vs', 'create', '--hostname', 'TEST', '--domain', 'TESTING',
+                                   '--flavor', 'B1_2X8X25', '--datacenter', 'ams01', '--os', 'UBUNTU_LATEST'])
+        self.assert_no_fail(result)
+        self.assertIn('Warning: Closed soon: ams01', result.output)
+        result = self.run_command(['vs', 'create', '--hostname', 'TEST', '--domain', 'TESTING',
+                                   '--flavor', 'B1_2X8X25', '--datacenter', 'mex01', '--os', 'UBUNTU_LATEST'])
+        self.assert_no_fail(result)
+        self.assertNotIn('Warning: Closed soon: mex01', result.output)
diff --git a/tests/managers/network_tests.py b/tests/managers/network_tests.py
index 81a91faf..04c2d8d6 100644
--- a/tests/managers/network_tests.py
+++ b/tests/managers/network_tests.py
@@ -637,3 +637,19 @@ def test_route(self):
     def test_get_all_datacenter(self):
         self.network.get_datacenter()
         self.assert_called_with('SoftLayer_Location', 'getDatacenters')
+        self.network.get_datacenter(datacenter="dal11")
+        expected_filter = {"name": {"operation": "dal11"}}
+        self.assert_called_with('SoftLayer_Location', 'getDatacenters', filter=expected_filter)
+
+    def test_get_datacenter_by_keyname(self):
+        # normal operation
+        result = self.network.get_datacenter_by_keyname("TEST01")
+        expected_filter = {"regions": {"keyname": {"operation": "TEST01"}}}
+        self.assert_called_with('SoftLayer_Location', 'getDatacenters', filter=expected_filter)
+        self.assertEqual(result.get('name'), 'dal13')
+
+        # an "empty" result
+        SoftLayer_Location = self.set_mock('SoftLayer_Location', 'getDatacenters')
+        SoftLayer_Location.return_value = []
+        result = self.network.get_datacenter_by_keyname("TEST01")
+        self.assertEqual(result, {})