diff --git a/openstackclient/network/common.py b/openstackclient/network/common.py index c539dd052f..cc343c3c13 100644 --- a/openstackclient/network/common.py +++ b/openstackclient/network/common.py @@ -60,3 +60,105 @@ class NetworkAndComputeCommand(command.Command): def take_action_compute(self, client, parsed_args): """Override to do something useful.""" pass + + +@six.add_metaclass(abc.ABCMeta) +class NetworkAndComputeLister(command.Lister): + """Network and Compute Lister + + Lister class for commands that support implementation via + the network or compute endpoint. Such commands have different + implementations for take_action() and may even have different + arguments. + """ + + def take_action(self, parsed_args): + if self.app.client_manager.is_network_endpoint_enabled(): + return self.take_action_network(self.app.client_manager.network, + parsed_args) + else: + return self.take_action_compute(self.app.client_manager.compute, + parsed_args) + + def get_parser(self, prog_name): + self.log.debug('get_parser(%s)', prog_name) + parser = super(NetworkAndComputeLister, self).get_parser(prog_name) + parser = self.update_parser_common(parser) + self.log.debug('common parser: %s', parser) + if self.app.client_manager.is_network_endpoint_enabled(): + return self.update_parser_network(parser) + else: + return self.update_parser_compute(parser) + + def update_parser_common(self, parser): + """Default is no updates to parser.""" + return parser + + def update_parser_network(self, parser): + """Default is no updates to parser.""" + return parser + + def update_parser_compute(self, parser): + """Default is no updates to parser.""" + return parser + + @abc.abstractmethod + def take_action_network(self, client, parsed_args): + """Override to do something useful.""" + pass + + @abc.abstractmethod + def take_action_compute(self, client, parsed_args): + """Override to do something useful.""" + pass + + +@six.add_metaclass(abc.ABCMeta) +class NetworkAndComputeShowOne(command.ShowOne): + """Network and Compute ShowOne + + ShowOne class for commands that support implementation via + the network or compute endpoint. Such commands have different + implementations for take_action() and may even have different + arguments. + """ + + def take_action(self, parsed_args): + if self.app.client_manager.is_network_endpoint_enabled(): + return self.take_action_network(self.app.client_manager.network, + parsed_args) + else: + return self.take_action_compute(self.app.client_manager.compute, + parsed_args) + + def get_parser(self, prog_name): + self.log.debug('get_parser(%s)', prog_name) + parser = super(NetworkAndComputeShowOne, self).get_parser(prog_name) + parser = self.update_parser_common(parser) + self.log.debug('common parser: %s', parser) + if self.app.client_manager.is_network_endpoint_enabled(): + return self.update_parser_network(parser) + else: + return self.update_parser_compute(parser) + + def update_parser_common(self, parser): + """Default is no updates to parser.""" + return parser + + def update_parser_network(self, parser): + """Default is no updates to parser.""" + return parser + + def update_parser_compute(self, parser): + """Default is no updates to parser.""" + return parser + + @abc.abstractmethod + def take_action_network(self, client, parsed_args): + """Override to do something useful.""" + pass + + @abc.abstractmethod + def take_action_compute(self, client, parsed_args): + """Override to do something useful.""" + pass diff --git a/openstackclient/tests/network/test_common.py b/openstackclient/tests/network/test_common.py index a3396b9da8..4700c66a9e 100644 --- a/openstackclient/tests/network/test_common.py +++ b/openstackclient/tests/network/test_common.py @@ -18,57 +18,103 @@ from openstackclient.network import common from openstackclient.tests import utils +def _add_common_argument(parser): + parser.add_argument( + 'common', + metavar='<common>', + help='Common argument', + ) + return parser + + +def _add_network_argument(parser): + parser.add_argument( + 'network', + metavar='<network>', + help='Network argument', + ) + return parser + + +def _add_compute_argument(parser): + parser.add_argument( + 'compute', + metavar='<compute>', + help='Compute argument', + ) + return parser + + class FakeNetworkAndComputeCommand(common.NetworkAndComputeCommand): def update_parser_common(self, parser): - parser.add_argument( - 'common', - metavar='<common>', - help='Common argument', - ) - return parser + return _add_common_argument(parser) def update_parser_network(self, parser): - parser.add_argument( - 'network', - metavar='<network>', - help='Network argument', - ) - return parser + return _add_network_argument(parser) def update_parser_compute(self, parser): - parser.add_argument( - 'compute', - metavar='<compute>', - help='Compute argument', - ) - return parser + return _add_compute_argument(parser) def take_action_network(self, client, parsed_args): - client.network_action(parsed_args) - return 'take_action_network' + return client.network_action(parsed_args) def take_action_compute(self, client, parsed_args): - client.compute_action(parsed_args) - return 'take_action_compute' + return client.compute_action(parsed_args) -class TestNetworkAndComputeCommand(utils.TestCommand): +class FakeNetworkAndComputeLister(common.NetworkAndComputeLister): + def update_parser_common(self, parser): + return _add_common_argument(parser) + + def update_parser_network(self, parser): + return _add_network_argument(parser) + + def update_parser_compute(self, parser): + return _add_compute_argument(parser) + + def take_action_network(self, client, parsed_args): + return client.network_action(parsed_args) + + def take_action_compute(self, client, parsed_args): + return client.compute_action(parsed_args) + + +class FakeNetworkAndComputeShowOne(common.NetworkAndComputeShowOne): + def update_parser_common(self, parser): + return _add_common_argument(parser) + + def update_parser_network(self, parser): + return _add_network_argument(parser) + + def update_parser_compute(self, parser): + return _add_compute_argument(parser) + + def take_action_network(self, client, parsed_args): + return client.network_action(parsed_args) + + def take_action_compute(self, client, parsed_args): + return client.compute_action(parsed_args) + + +class TestNetworkAndCompute(utils.TestCommand): def setUp(self): - super(TestNetworkAndComputeCommand, self).setUp() + super(TestNetworkAndCompute, self).setUp() self.namespace = argparse.Namespace() # Create network client mocks. self.app.client_manager.network = mock.Mock() self.network = self.app.client_manager.network - self.network.network_action = mock.Mock(return_value=None) + self.network.network_action = mock.Mock( + return_value='take_action_network') # Create compute client mocks. self.app.client_manager.compute = mock.Mock() self.compute = self.app.client_manager.compute - self.compute.compute_action = mock.Mock(return_value=None) + self.compute.compute_action = mock.Mock( + return_value='take_action_compute') - # Get the command object to test + # Subclasses can override the command object to test. self.cmd = FakeNetworkAndComputeCommand(self.app, self.namespace) def test_take_action_network(self): @@ -101,3 +147,21 @@ class TestNetworkAndComputeCommand(utils.TestCommand): result = self.cmd.take_action(parsed_args) self.compute.compute_action.assert_called_with(parsed_args) self.assertEqual('take_action_compute', result) + + +class TestNetworkAndComputeCommand(TestNetworkAndCompute): + def setUp(self): + super(TestNetworkAndComputeCommand, self).setUp() + self.cmd = FakeNetworkAndComputeCommand(self.app, self.namespace) + + +class TestNetworkAndComputeLister(TestNetworkAndCompute): + def setUp(self): + super(TestNetworkAndComputeLister, self).setUp() + self.cmd = FakeNetworkAndComputeLister(self.app, self.namespace) + + +class TestNetworkAndComputeShowOne(TestNetworkAndCompute): + def setUp(self): + super(TestNetworkAndComputeShowOne, self).setUp() + self.cmd = FakeNetworkAndComputeShowOne(self.app, self.namespace)