diff --git a/SoftLayer/CLI/routes.py b/SoftLayer/CLI/routes.py index 92f52b682..48b0af834 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 da4b36264..7eb934431 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 000000000..9a62692b1 --- /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 c6658165a..24683da15 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 e421bd0f6..f9c5f4af0 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 124f36cde..38bda428d 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: diff --git a/tests/CLI/modules/subnet_tests.py b/tests/CLI/modules/subnet_tests.py index 48d3b0a9c..52de2cd27 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 165d04b71..57106ecee 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')