diff --git a/setup.cfg b/setup.cfg index 0c38157..97aed85 100644 --- a/setup.cfg +++ b/setup.cfg @@ -26,7 +26,7 @@ console_scripts = sushycli = sushycli.cmd.sushycli:main sushycli = - power_reset = sushycli.power_reset:PowerReset + power = sushycli.power:Power version = sushycli.version:Version [build_sphinx] diff --git a/sushycli/cmd/sushycli.py b/sushycli/cmd/sushycli.py index b8d1d73..d6bafad 100644 --- a/sushycli/cmd/sushycli.py +++ b/sushycli/cmd/sushycli.py @@ -24,11 +24,10 @@ class SushyCliApp(App): def __init__(self): super(SushyCliApp, self).__init__( - description='a Redfish CLI client for sushy library ', + description='Redfish CLI based on sushy library', version='0.1', - command_manager=CommandManager('sushy.cli'), - deferred_help=True, - ) + command_manager=CommandManager('sushycli'), + deferred_help=True) def initialize_app(self, argv): self.LOG.debug('initialize_app') diff --git a/sushycli/power.py b/sushycli/power.py new file mode 100644 index 0000000..3fc04eb --- /dev/null +++ b/sushycli/power.py @@ -0,0 +1,74 @@ +# -*- coding: utf-8 -*- + +# Copyright 2010-2020 OpenStack Foundation +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +import sushy + +from cliff import command + + +class Power(command.Command): + """Change machine power state""" + + def get_parser(self, prog_name): + """Power state command parser""" + parser = super(Power, self).get_parser(prog_name) + + parser.add_argument( + '--username', + help='Redfish BMC username') + + parser.add_argument( + '--password', + help='Redfish BMC user password') + + parser.add_argument( + '--service-endpoint', + required=True, + help='Redfish BMC service endpoint URL e.g. ' + 'http://localhost:8000') + + parser.add_argument( + '--system-id', + required=True, + help='The canonical path to the ComputerSystem ' + 'resource that the driver will interact with. ' + 'It should include the root service, version and ' + 'the unique resource path to a ComputerSystem. ' + 'For example: /redfish/v1/Systems/1') + + parser.add_argument( + 'state', + metavar='on|off', + type=lambda x: x.lower(), + choices=['on', 'off'], + help='Set machine power state') + + return parser + + def take_action(self, args): + """Power state command action""" + + root = sushy.Sushy( + args.service_endpoint, username=args.username, + password=args.password) + + sys_inst = root.get_system(args.system_id) + + sys_inst.reset_system( + sushy.RESET_TYPE_ON + if args.state == 'on' else sushy.RESET_TYPE_FORCE_OFF) + + return 0 diff --git a/sushycli/power_reset.py b/sushycli/power_reset.py deleted file mode 100644 index 83aece7..0000000 --- a/sushycli/power_reset.py +++ /dev/null @@ -1,69 +0,0 @@ -# -*- coding: utf-8 -*- - -# Copyright 2010-2020 OpenStack Foundation -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import sushy - -from cliff import command - - -class PowerReset(command.Command): - - def get_parser(self, prog_name): - """Command argument parsing.""" - parser = super(PowerReset, self).get_parser(prog_name) - - parser.add_argument( - '--user', - dest='user', - default='foo', - help='The user or login for authentication') - parser.add_argument( - '--password', - dest='password', - default='bar', - help='The password for authentication') - parser.add_argument( - '--rhost', - dest='rhost', - default='http://localhost:8000/redfish/v1/', - help='The address of the Redfish service; defaults' - 'to "http://localhost:8000/redfish/v1"') - parser.add_argument( - '--system', - dest='system', - default='437XR1138R2', - help='The ID of the system') - parser.add_argument( - '--type', - dest='power_mode', - default='on', - help='Specifying the type of action to perform' - '"reset/shutOff.."; default mode is ON') - - return parser - - def take_action(self, parsed_args): - """Command action""" - user = parsed_args.user - password = parsed_args.password - rhost = parsed_args.rhost - system = parsed_args.system - - s = sushy.Sushy(rhost, username=user, password=password) - - sys_inst = s.get_system('/redfish/v1/Systems/%s' % system) - - sys_inst.reset_system(parsed_args.power_mode) diff --git a/sushycli/tests/unit/cmd/test_sushycli.py b/sushycli/tests/unit/cmd/test_sushycli.py index 9d5f85c..3dfbcd1 100644 --- a/sushycli/tests/unit/cmd/test_sushycli.py +++ b/sushycli/tests/unit/cmd/test_sushycli.py @@ -15,10 +15,53 @@ # License for the specific language governing permissions and limitations # under the License. +import mock + +import sushy + +from sushycli.cmd.sushycli import main from sushycli.tests.unit import base +@mock.patch.object(sushy, 'Sushy', autospec=True) class SuchyCliTestCase(base.TestCase): - def test_main(self): - pass + def test_power_on(self, mock_sushy): + + main(['power', + '--username', 'jelly', '--password', 'fish', + '--service-endpoint', 'http://fish.me', + '--system-id', '/redfish/v1/Systems/1', + 'on']) + + mock_sushy.assert_called_once_with( + 'http://fish.me', password='fish', username='jelly') + + mock_root = mock_sushy.return_value + + mock_root.get_system.assert_called_once_with( + '/redfish/v1/Systems/1') + + mock_system = mock_root.get_system.return_value + + mock_system.reset_system.assert_called_once_with('on') + + def test_power_off(self, mock_sushy): + + main(['power', + '--username', 'jelly', '--password', 'fish', + '--service-endpoint', 'http://fish.me', + '--system-id', '/redfish/v1/Systems/1', + 'Off']) + + mock_sushy.assert_called_once_with( + 'http://fish.me', password='fish', username='jelly') + + mock_root = mock_sushy.return_value + + mock_root.get_system.assert_called_once_with( + '/redfish/v1/Systems/1') + + mock_system = mock_root.get_system.return_value + + mock_system.reset_system.assert_called_once_with('force off')