diff --git a/ironicclient/osc/v1/baremetal_node.py b/ironicclient/osc/v1/baremetal_node.py index 1e558f0ea..990905fe3 100755 --- a/ironicclient/osc/v1/baremetal_node.py +++ b/ironicclient/osc/v1/baremetal_node.py @@ -802,31 +802,18 @@ class PassthruListBaremetalNode(command.Lister): class PowerBaremetalNode(command.Command): - """Set power state of baremetal node""" + """Base power state class, for setting the power of a node""" log = logging.getLogger(__name__ + ".PowerBaremetalNode") def get_parser(self, prog_name): parser = super(PowerBaremetalNode, self).get_parser(prog_name) - parser.add_argument( - 'power_state', - metavar='', - choices=['on', 'off'], - help=_("Power node on or off") - ) parser.add_argument( 'node', metavar='', help=_("Name or UUID of the node.") ) - parser.add_argument( - '--soft', - dest='soft', - action='store_true', - default=False, - help=_("Request graceful power-off.") - ) parser.add_argument( '--power-timeout', metavar='', @@ -842,11 +829,38 @@ class PowerBaremetalNode(command.Command): baremetal_client = self.app.client_manager.baremetal + soft = getattr(parsed_args, 'soft', False) + baremetal_client.node.set_power_state( - parsed_args.node, parsed_args.power_state, parsed_args.soft, + parsed_args.node, self.POWER_STATE, soft, timeout=parsed_args.power_timeout) +class PowerOffBaremetalNode(PowerBaremetalNode): + """Power off a node""" + + log = logging.getLogger(__name__ + ".PowerOffBaremetalNode") + POWER_STATE = 'off' + + def get_parser(self, prog_name): + parser = super(PowerOffBaremetalNode, self).get_parser(prog_name) + parser.add_argument( + '--soft', + dest='soft', + action='store_true', + default=False, + help=_("Request graceful power-off.") + ) + return parser + + +class PowerOnBaremetalNode(PowerBaremetalNode): + """Power on a node""" + + log = logging.getLogger(__name__ + ".PowerOnBaremetalNode") + POWER_STATE = 'on' + + class ProvideBaremetalNode(ProvisionStateWithWait): """Set provision state of baremetal node to 'provide'""" diff --git a/ironicclient/tests/unit/osc/v1/test_baremetal_node.py b/ironicclient/tests/unit/osc/v1/test_baremetal_node.py index a14f7ea85..ef6275671 100644 --- a/ironicclient/tests/unit/osc/v1/test_baremetal_node.py +++ b/ironicclient/tests/unit/osc/v1/test_baremetal_node.py @@ -1050,69 +1050,34 @@ class TestPassthruList(TestBaremetal): mock.assert_called_once_with('node_uuid') -class TestBaremetalPower(TestBaremetal): +class TestPower(TestBaremetal): def setUp(self): - super(TestBaremetalPower, self).setUp() + super(TestPower, self).setUp() # Get the command object to test self.cmd = baremetal_node.PowerBaremetalNode(self.app, None) - def test_baremetal_power_just_on(self): - arglist = ['on'] - verifylist = [('power_state', 'on')] - - self.assertRaises(oscutils.ParserException, - self.check_parser, - self.cmd, arglist, verifylist) - - def test_baremetal_power_just_off(self): - arglist = ['off'] - verifylist = [('power_state', 'off')] - - self.assertRaises(oscutils.ParserException, - self.check_parser, - self.cmd, arglist, verifylist) - - def test_baremetal_power_uuid_only(self): + def test_baremetal_power(self): arglist = ['node_uuid'] verifylist = [('node', 'node_uuid')] - self.assertRaises(oscutils.ParserException, - self.check_parser, - self.cmd, arglist, verifylist) - - def test_baremetal_power_on(self): - arglist = ['on', 'node_uuid'] - verifylist = [('power_state', 'on'), - ('node', 'node_uuid'), - ('soft', False), - ('power_timeout', None)] - parsed_args = self.check_parser(self.cmd, arglist, verifylist) - self.cmd.take_action(parsed_args) + self.assertRaisesRegex(AttributeError, + ".*no attribute 'POWER_STATE'", + self.cmd.take_action, parsed_args) - self.baremetal_mock.node.set_power_state.assert_called_once_with( - 'node_uuid', 'on', False, timeout=None) - def test_baremetal_power_on_timeout(self): - arglist = ['on', 'node_uuid', '--power-timeout', '2'] - verifylist = [('power_state', 'on'), - ('node', 'node_uuid'), - ('soft', False), - ('power_timeout', 2)] +class TestPowerOff(TestBaremetal): + def setUp(self): + super(TestPowerOff, self).setUp() - parsed_args = self.check_parser(self.cmd, arglist, verifylist) - - self.cmd.take_action(parsed_args) - - self.baremetal_mock.node.set_power_state.assert_called_once_with( - 'node_uuid', 'on', False, timeout=2) + # Get the command object to test + self.cmd = baremetal_node.PowerOffBaremetalNode(self.app, None) def test_baremetal_power_off(self): - arglist = ['off', 'node_uuid'] - verifylist = [('power_state', 'off'), - ('node', 'node_uuid'), + arglist = ['node_uuid'] + verifylist = [('node', 'node_uuid'), ('soft', False), ('power_timeout', None)] @@ -1124,9 +1089,8 @@ class TestBaremetalPower(TestBaremetal): 'node_uuid', 'off', False, timeout=None) def test_baremetal_power_off_timeout(self): - arglist = ['off', 'node_uuid', '--power-timeout', '2'] - verifylist = [('power_state', 'off'), - ('node', 'node_uuid'), + arglist = ['node_uuid', '--power-timeout', '2'] + verifylist = [('node', 'node_uuid'), ('soft', False), ('power_timeout', 2)] @@ -1138,9 +1102,8 @@ class TestBaremetalPower(TestBaremetal): 'node_uuid', 'off', False, timeout=2) def test_baremetal_soft_power_off(self): - arglist = ['off', 'node_uuid', '--soft'] - verifylist = [('power_state', 'off'), - ('node', 'node_uuid'), + arglist = ['node_uuid', '--soft'] + verifylist = [('node', 'node_uuid'), ('soft', True), ('power_timeout', None)] @@ -1152,9 +1115,8 @@ class TestBaremetalPower(TestBaremetal): 'node_uuid', 'off', True, timeout=None) def test_baremetal_soft_power_off_timeout(self): - arglist = ['off', 'node_uuid', '--soft', '--power-timeout', '2'] - verifylist = [('power_state', 'off'), - ('node', 'node_uuid'), + arglist = ['node_uuid', '--soft', '--power-timeout', '2'] + verifylist = [('node', 'node_uuid'), ('soft', True), ('power_timeout', 2)] @@ -1165,6 +1127,54 @@ class TestBaremetalPower(TestBaremetal): self.baremetal_mock.node.set_power_state.assert_called_once_with( 'node_uuid', 'off', True, timeout=2) + def test_baremetal_power_off_no_args(self): + arglist = [] + verifylist = [] + + self.assertRaises(oscutils.ParserException, + self.check_parser, + self.cmd, arglist, verifylist) + + +class TestPowerOn(TestBaremetal): + def setUp(self): + super(TestPowerOn, self).setUp() + + # Get the command object to test + self.cmd = baremetal_node.PowerOnBaremetalNode(self.app, None) + + def test_baremetal_power_on(self): + arglist = ['node_uuid'] + verifylist = [('node', 'node_uuid'), + ('power_timeout', None)] + + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + self.cmd.take_action(parsed_args) + + self.baremetal_mock.node.set_power_state.assert_called_once_with( + 'node_uuid', 'on', False, timeout=None) + + def test_baremetal_power_on_timeout(self): + arglist = ['node_uuid', '--power-timeout', '2'] + verifylist = [('node', 'node_uuid'), + ('power_timeout', 2)] + + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + self.cmd.take_action(parsed_args) + + self.baremetal_mock.node.set_power_state.assert_called_once_with( + 'node_uuid', 'on', False, timeout=2) + + def test_baremetal_power_on_no_args(self): + arglist = [] + verifylist = [] + + self.assertRaises(oscutils.ParserException, + self.check_parser, + self.cmd, arglist, verifylist) + class TestDeployBaremetalProvisionState(TestBaremetal): def setUp(self): diff --git a/releasenotes/notes/osc-node-power-on-off-c269980e3b9c79ca.yaml b/releasenotes/notes/osc-node-power-on-off-c269980e3b9c79ca.yaml new file mode 100644 index 000000000..f16a84510 --- /dev/null +++ b/releasenotes/notes/osc-node-power-on-off-c269980e3b9c79ca.yaml @@ -0,0 +1,13 @@ +--- +fixes: + - | + Replaces ``openstack baremetal node power `` with + the two commands: + + * ``openstack baremetal node power on`` and + * ``openstack baremetal node power off``. + + There is no change to the command the user enters (the actual + command line is the same). However, help (e.g. via + ``openstack -h baremetal``) will list the two power commands + (instead of the original one). diff --git a/setup.cfg b/setup.cfg index 3cd3c2261..31d6f577e 100644 --- a/setup.cfg +++ b/setup.cfg @@ -59,7 +59,8 @@ openstack.baremetal.v1 = baremetal_node_manage = ironicclient.osc.v1.baremetal_node:ManageBaremetalNode baremetal_node_passthru_call = ironicclient.osc.v1.baremetal_node:PassthruCallBaremetalNode baremetal_node_passthru_list = ironicclient.osc.v1.baremetal_node:PassthruListBaremetalNode - baremetal_node_power = ironicclient.osc.v1.baremetal_node:PowerBaremetalNode + baremetal_node_power_off = ironicclient.osc.v1.baremetal_node:PowerOffBaremetalNode + baremetal_node_power_on = ironicclient.osc.v1.baremetal_node:PowerOnBaremetalNode baremetal_node_provide = ironicclient.osc.v1.baremetal_node:ProvideBaremetalNode baremetal_node_reboot = ironicclient.osc.v1.baremetal_node:RebootBaremetalNode baremetal_node_rebuild = ironicclient.osc.v1.baremetal_node:RebuildBaremetalNode