Repository: softlayer/softlayer-python
Pull request #1286 (2020-06-19 22:46:08)

Subnet Editing (tagging) #1283


Patch:
diff --git a/SoftLayer/CLI/routes.py b/SoftLayer/CLI/routes.py
index 92f52b68..48b0af83 100644
--- a/SoftLayer/CLI/routes.py
+++ b/SoftLayer/CLI/routes.py
@@ -286,6 +286,7 @@
     ('subnet', 'SoftLayer.CLI.subnet'),
     ('subnet:cancel', 'SoftLayer.CLI.subnet.cancel:cli'),
     ('subnet:create', 'SoftLayer.CLI.subnet.create:cli'),
+    ('subnet:edit', 'SoftLayer.CLI.subnet.edit:cli'),
     ('subnet:detail', 'SoftLayer.CLI.subnet.detail:cli'),
     ('subnet:list', 'SoftLayer.CLI.subnet.list:cli'),
     ('subnet:lookup', 'SoftLayer.CLI.subnet.lookup:cli'),
diff --git a/SoftLayer/CLI/subnet/detail.py b/SoftLayer/CLI/subnet/detail.py
index da4b3626..7eb93443 100644
--- a/SoftLayer/CLI/subnet/detail.py
+++ b/SoftLayer/CLI/subnet/detail.py
@@ -47,6 +47,10 @@ def cli(env, identifier, no_vs, no_hardware):
     table.add_row(['datacenter', subnet['datacenter']['name']])
     table.add_row(['usable ips',
                    subnet.get('usableIpAddressCount', formatting.blank())])
+    table.add_row(['note',
+                   subnet.get('note', formatting.blank())])
+    table.add_row(['tags',
+                   formatting.tags(subnet.get('tagReferences'))])
 
     ip_address = subnet.get('ipAddresses')
 
@@ -66,7 +70,7 @@ def cli(env, identifier, no_vs, no_hardware):
                                   vsi.get('primaryBackendIpAddress')])
             table.add_row(['vs', vs_table])
         else:
-            table.add_row(['vs', 'none'])
+            table.add_row(['vs', formatting.blank()])
 
     if not no_hardware:
         if subnet['hardware']:
@@ -78,6 +82,6 @@ def cli(env, identifier, no_vs, no_hardware):
                                   hardware.get('primaryBackendIpAddress')])
             table.add_row(['hardware', hw_table])
         else:
-            table.add_row(['hardware', 'none'])
+            table.add_row(['hardware', formatting.blank()])
 
     env.fout(table)
diff --git a/SoftLayer/CLI/subnet/edit.py b/SoftLayer/CLI/subnet/edit.py
new file mode 100644
index 00000000..9a62692b
--- /dev/null
+++ b/SoftLayer/CLI/subnet/edit.py
@@ -0,0 +1,39 @@
+"""Edit a subnet."""
+# :license: MIT, see LICENSE for more details.
+
+import click
+
+import SoftLayer
+from SoftLayer.CLI import environment
+from SoftLayer.CLI import helpers
+
+
+@click.command(short_help="Edit note and tags of a subnet")
+@click.argument('identifier')
+@click.option('--tags', '-t', type=click.STRING,
+              help='Comma separated list of tags, enclosed in quotes. "tag1, tag2"')
+@click.option('--note', '-n', type=click.STRING,
+              help="The note")
+@environment.pass_env
+def cli(env, identifier, tags, note):
+    """Edit note and tags of a subnet."""
+
+    mgr = SoftLayer.NetworkManager(env.client)
+    subnet_id = helpers.resolve_id(mgr.resolve_subnet_ids, identifier,
+                                   name='subnet')
+
+    if tags:
+        result = mgr.set_tags_subnet(subnet_id, tags)
+        print_result(result, "Set tags")
+
+    if note:
+        result = mgr.edit_note_subnet(subnet_id, note)
+        print_result(result, "Edit note")
+
+
+def print_result(result, detail):
+    """Prints a successfully or Failed message."""
+    if result:
+        click.secho("{} successfully".format(detail), fg='green')
+    else:
+        click.secho("Failed to {}".format(detail.lower()), fg='red')
diff --git a/SoftLayer/fixtures/SoftLayer_Network_Subnet.py b/SoftLayer/fixtures/SoftLayer_Network_Subnet.py
index c6658165..24683da1 100644
--- a/SoftLayer/fixtures/SoftLayer_Network_Subnet.py
+++ b/SoftLayer/fixtures/SoftLayer_Network_Subnet.py
@@ -26,9 +26,20 @@
     ],
     'hardware': [],
     'usableIpAddressCount': 22,
+    'note': 'test note',
+    'tagReferences': [
+        {'id': 1000123,
+         'resourceTableId': 1234,
+         'tag': {'id': 100123,
+                 'name': 'subnet: test tag'},
+         }
+    ],
     'ipAddresses': [
         {'id': 123456,
          'ipAddress': '16.26.26.25'},
         {'id': 123457,
          'ipAddress': '16.26.26.26'}]
 }
+
+editNote = True
+setTags = True
diff --git a/SoftLayer/managers/network.py b/SoftLayer/managers/network.py
index e421bd0f..f9c5f4af 100644
--- a/SoftLayer/managers/network.py
+++ b/SoftLayer/managers/network.py
@@ -24,6 +24,15 @@
                                 'datacenter',
                                 'ipAddressCount',
                                 'virtualGuests',
+                                'id',
+                                'networkIdentifier',
+                                'cidr',
+                                'subnetType',
+                                'gateway',
+                                'broadcastAddress',
+                                'usableIpAddressCount',
+                                'note',
+                                'tagReferences[tag]',
                                 'networkVlan[id,networkSpace]'])
 DEFAULT_VLAN_MASK = ','.join([
     'firewallInterfaces',
@@ -233,6 +242,22 @@ def cancel_subnet(self, subnet_id):
         billing_id = subnet['billingItem']['id']
         return self.client['Billing_Item'].cancelService(id=billing_id)
 
+    def set_tags_subnet(self, subnet_id, tags):
+        """Tag a subnet by passing in one or more tags separated by a comma.
+
+        :param int subnet_id: The ID of the subnet.
+        :param string tags:	Comma separated list of tags.
+        """
+        return self.subnet.setTags(tags, id=subnet_id)
+
+    def edit_note_subnet(self, subnet_id, note):
+        """Edit the note for this subnet.
+
+        :param int subnet_id: The ID of the subnet.
+        :param string note:	The note.
+        """
+        return self.subnet.editNote(note, id=subnet_id)
+
     def create_securitygroup(self, name=None, description=None):
         """Creates a security group.
 
diff --git a/docs/cli/subnet.rst b/docs/cli/subnet.rst
index 124f36cd..38bda428 100644
--- a/docs/cli/subnet.rst
+++ b/docs/cli/subnet.rst
@@ -15,6 +15,10 @@ Subnets
     :prog: subnet detail
     :show-nested:
 
+.. click:: SoftLayer.CLI.subnet.edit:cli
+    :prog: subnet edit
+    :show-nested:
+
 .. click:: SoftLayer.CLI.subnet.list:cli
     :prog: subnet list
     :show-nested:


Test patch:
diff --git a/tests/CLI/modules/subnet_tests.py b/tests/CLI/modules/subnet_tests.py
index 48d3b0a9..52de2cd2 100644
--- a/tests/CLI/modules/subnet_tests.py
+++ b/tests/CLI/modules/subnet_tests.py
@@ -17,32 +17,10 @@ class SubnetTests(testing.TestCase):
 
     def test_detail(self):
         result = self.run_command(['subnet', 'detail', '1234'])
-
+        subnet = json.loads(result.output)
         self.assert_no_fail(result)
-        self.assertEqual(
-            {
-                'id': 1234,
-                'identifier': '1.2.3.4/26',
-                'subnet type': 'ADDITIONAL_PRIMARY',
-                'network space': 'PUBLIC',
-                'gateway': '1.2.3.254',
-                'broadcast': '1.2.3.255',
-                'datacenter': 'dal10',
-                'vs': [
-                    {
-                        'hostname': 'hostname0',
-                        'domain': 'sl.test',
-                        'public_ip': '1.2.3.10',
-                        'private_ip': '10.0.1.2'
-                    }
-                ],
-                'ipAddresses': {
-                    '123456': '16.26.26.25',
-                    '123457': '16.26.26.26'},
-                'hardware': 'none',
-                'usable ips': 22
-            },
-            json.loads(result.output))
+        self.assertEqual(subnet.get('id'), 1234)
+        self.assertEqual(subnet.get('identifier'), '1.2.3.4/26')
 
     def test_list(self):
         result = self.run_command(['subnet', 'list'])
@@ -138,6 +116,38 @@ def test_create_subnet_static_ipv6(self, confirm_mock):
 
         self.assertEqual(output, json.loads(result.output))
 
+    @mock.patch('SoftLayer.CLI.subnet.edit.click')
+    def test_subnet_set_tags(self, click):
+        result = self.run_command(['subnet', 'edit', '1234', '--tags=tag1,tag2'])
+        click.secho.assert_called_with('Set tags successfully', fg='green')
+        self.assert_no_fail(result)
+        self.assert_called_with('SoftLayer_Network_Subnet', 'setTags', identifier=1234, args=("tag1,tag2",))
+
+    @mock.patch('SoftLayer.CLI.subnet.edit.click')
+    def test_subnet_edit_note(self, click):
+        result = self.run_command(['subnet', 'edit', '1234', '--note=test'])
+        click.secho.assert_called_with('Edit note successfully', fg='green')
+        self.assert_no_fail(result)
+        self.assert_called_with('SoftLayer_Network_Subnet', 'editNote', identifier=1234, args=("test",))
+
+    @mock.patch('SoftLayer.CLI.subnet.edit.click')
+    def test_subnet_set_tags_failure(self, click):
+        mock = self.set_mock('SoftLayer_Network_Subnet', 'setTags')
+        mock.return_value = False
+        result = self.run_command(['subnet', 'edit', '1234', '--tags=tag1,tag2'])
+        click.secho.assert_called_with('Failed to set tags', fg='red')
+        self.assert_no_fail(result)
+        self.assert_called_with('SoftLayer_Network_Subnet', 'setTags', identifier=1234, args=("tag1,tag2",))
+
+    @mock.patch('SoftLayer.CLI.subnet.edit.click')
+    def test_edit_note_failure(self, click):
+        mock = self.set_mock('SoftLayer_Network_Subnet', 'editNote')
+        mock.return_value = False
+        result = self.run_command(['subnet', 'edit', '1234', '--note=test'])
+        click.secho.assert_called_with('Failed to edit note', fg='red')
+        self.assert_no_fail(result)
+        self.assert_called_with('SoftLayer_Network_Subnet', 'editNote', identifier=1234, args=("test",))
+
     def test_editrou_Ip(self):
         result = self.run_command(['subnet', 'edit-ip', '16.26.26.26', '--note=test'])
         self.assert_no_fail(result)
diff --git a/tests/managers/network_tests.py b/tests/managers/network_tests.py
index 165d04b7..57106ece 100644
--- a/tests/managers/network_tests.py
+++ b/tests/managers/network_tests.py
@@ -158,6 +158,26 @@ def test_cancel_subnet(self):
         self.assert_called_with('SoftLayer_Billing_Item', 'cancelService',
                                 identifier=1056)
 
+    def test_set_tags_subnet(self):
+        subnet_id = 1234
+        tags = 'tags1,tag2'
+        result = self.network.set_tags_subnet(subnet_id, tags)
+
+        self.assertEqual(result, True)
+        self.assert_called_with('SoftLayer_Network_Subnet', 'setTags',
+                                identifier=subnet_id,
+                                args=(tags,))
+
+    def test_edit_note_subnet(self):
+        subnet_id = 1234
+        note = 'test note'
+        result = self.network.edit_note_subnet(subnet_id, note)
+
+        self.assertEqual(result, True)
+        self.assert_called_with('SoftLayer_Network_Subnet', 'editNote',
+                                identifier=subnet_id,
+                                args=(note,))
+
     def test_create_securitygroup(self):
         result = self.network.create_securitygroup(name='foo',
                                                    description='bar')