diff --git a/moganclient/osc/v1/server.py b/moganclient/osc/v1/server.py index ffeab34..f7b115a 100644 --- a/moganclient/osc/v1/server.py +++ b/moganclient/osc/v1/server.py @@ -657,6 +657,71 @@ class RemoveFloatingIP(command.Command): parsed_args.ip_address) +class AddInterface(command.Command): + _description = _("Add interface to server") + + def get_parser(self, prog_name): + parser = super(AddInterface, self).get_parser(prog_name) + excluded_group = parser.add_mutually_exclusive_group(required=True) + excluded_group.add_argument( + "--net-id", + metavar="", + help=_("Network to link to server"), + ) + excluded_group.add_argument( + "--port-id", + metavar="", + help=_("Port to link to server"), + ) + parser.add_argument( + "server", + metavar="", + help=_("Server to attach interface for"), + ) + return parser + + def take_action(self, parsed_args): + bc_client = self.app.client_manager.baremetal_compute + server = utils.find_resource( + bc_client.server, + parsed_args.server, + ) + + bc_client.server.add_interface(server.uuid, + parsed_args.net_id, + parsed_args.port_id) + + +class RemoveInterface(command.Command): + _description = _("Remove interface from server") + + def get_parser(self, prog_name): + parser = super(RemoveInterface, self).get_parser(prog_name) + parser.add_argument( + "port_id", + metavar="", + help=_("Interface to remove from server"), + ) + parser.add_argument( + "server", + metavar="", + help=_( + "Server to remove the interface from" + ), + ) + return parser + + def take_action(self, parsed_args): + bc_client = self.app.client_manager.baremetal_compute + server = utils.find_resource( + bc_client.server, + parsed_args.server, + ) + + bc_client.server.remove_interface(server.uuid, + parsed_args.port_id) + + class ShowConsoleURL(command.ShowOne): _description = _("Show server's remote console URL") diff --git a/moganclient/tests/unit/osc/v1/test_server.py b/moganclient/tests/unit/osc/v1/test_server.py index ee5b639..1e06e1a 100644 --- a/moganclient/tests/unit/osc/v1/test_server.py +++ b/moganclient/tests/unit/osc/v1/test_server.py @@ -665,3 +665,69 @@ class TestServerShowNetInfo(TestServer): self.cmd.take_action(parsed_args) mock_get.assert_called_once_with(self.fake_server.uuid) mock_netinfo.assert_called_once_with(self.fake_server.uuid) + + +@mock.patch.object(utils, 'find_resource') +@mock.patch.object(server_mgr.ServerManager, '_create') +class TestServerAddInterface(TestServer): + def setUp(self): + super(TestServerAddInterface, self).setUp() + self.cmd = server.AddInterface(self.app, None) + + def test_add_interface_with_net_id(self, mock_create, mock_find): + fake_server = fakes.FakeServer.create_one_server() + mock_find.return_value = fake_server + net_id = uuidutils.generate_uuid() + server = fake_server.uuid + args = ['--net-id', net_id, server] + verify_args = [ + ('net_id', net_id), + ('server', server) + ] + parsed_args = self.check_parser(self.cmd, args, verify_args) + self.cmd.take_action(parsed_args) + expected_url = '/servers/%s/networks/interfaces' % server + expected_data = {'net_id': net_id} + mock_create.assert_called_once_with(expected_url, + data=expected_data) + + def test_add_interface_with_port_id(self, mock_create, mock_find): + fake_server = fakes.FakeServer.create_one_server() + mock_find.return_value = fake_server + port_id = uuidutils.generate_uuid() + server = fake_server.uuid + args = ['--port-id', port_id, server] + verify_args = [ + ('port_id', port_id), + ('server', server) + ] + parsed_args = self.check_parser(self.cmd, args, verify_args) + self.cmd.take_action(parsed_args) + expected_url = '/servers/%s/networks/interfaces' % server + expected_data = {'port_id': port_id} + mock_create.assert_called_once_with(expected_url, + data=expected_data) + + +@mock.patch.object(utils, 'find_resource') +@mock.patch.object(server_mgr.ServerManager, '_delete') +class TestServerRemoveInterface(TestServer): + def setUp(self): + super(TestServerRemoveInterface, self).setUp() + self.cmd = server.RemoveInterface(self.app, None) + + def test_remove_interface(self, mock_delete, mock_find): + fake_server = fakes.FakeServer.create_one_server() + mock_find.return_value = fake_server + port_id = uuidutils.generate_uuid() + server = fake_server.uuid + args = [port_id, server] + verify_args = [ + ('port_id', port_id), + ('server', server) + ] + parsed_args = self.check_parser(self.cmd, args, verify_args) + self.cmd.take_action(parsed_args) + expected_url = '/servers/%(server)s/networks/interfaces/%(port_id)s' % \ + {'server': server, 'port_id': port_id} + mock_delete.assert_called_once_with(expected_url) diff --git a/moganclient/v1/server.py b/moganclient/v1/server.py index 2bdef26..ae86eb1 100644 --- a/moganclient/v1/server.py +++ b/moganclient/v1/server.py @@ -140,6 +140,19 @@ class ServerManager(base.ManagerWithFind): 'server': base.getid(server_id), 'ip': ip_address} return self._delete(url) + def add_interface(self, server_id, net_id=None, port_id=None): + url = '/servers/%s/networks/interfaces' % base.getid(server_id) + if net_id: + data = {'net_id': net_id} + else: + data = {'port_id': port_id} + return self._create(url, data=data) + + def remove_interface(self, server_id, port_id): + url = '/servers/%(server)s/networks/interfaces/%(port_id)s' % { + 'server': base.getid(server_id), 'port_id': port_id} + return self._delete(url) + def get_serial_console(self, server_id): url = '/servers/%(server)s/serial_console' % { 'server': base.getid(server_id)} diff --git a/setup.cfg b/setup.cfg index 49aaf67..bbe127d 100644 --- a/setup.cfg +++ b/setup.cfg @@ -51,6 +51,8 @@ openstack.baremetal_compute.v1 = baremetalcompute_server_netinfo = moganclient.osc.v1.server:ShowServerNetworkInfo baremetalcompute_server_add_floating_ip = moganclient.osc.v1.server:AddFloatingIP baremetalcompute_server_remove_floating_ip = moganclient.osc.v1.server:RemoveFloatingIP + baremetalcompute_server_add_interface = moganclient.osc.v1.server:AddInterface + baremetalcompute_server_remove_interface = moganclient.osc.v1.server:RemoveInterface baremetalcompute_console_url_show = moganclient.osc.v1.server:ShowConsoleURL baremetalcompute_availability_zone_list = moganclient.osc.v1.availability_zone:ListAvailabilityZone baremetalcompute_keypair_create = moganclient.osc.v1.keypair:CreateKeyPair