diff --git a/README.rst b/README.rst index ba73f88..f5b19cb 100644 --- a/README.rst +++ b/README.rst @@ -107,7 +107,11 @@ Retrieving introspection data * ``uuid`` - Ironic node UUID; * ``raw`` - whether to return raw data or parsed JSON data (the default). -This call is not exposed in CLI yet. +CLI:: + + $ openstack baremetal introspection data save [--file=file_name] UUID + +If file name is not provided, the data is dumped to stdout. .. note:: This feature requires Swift support to be enabled in **Ironic Inspector** diff --git a/ironic_inspector_client/shell.py b/ironic_inspector_client/shell.py index cca452d..00fb4c7 100644 --- a/ironic_inspector_client/shell.py +++ b/ironic_inspector_client/shell.py @@ -17,6 +17,7 @@ from __future__ import print_function import json import logging +import sys from cliff import command from cliff import lister @@ -165,3 +166,25 @@ class RulePurgeCommand(command.Command): def take_action(self, parsed_args): client = self.app.client_manager.baremetal_introspection client.rules.delete_all() + + +class DataSaveCommand(command.Command): + """Save or display raw introspection data.""" + + def get_parser(self, prog_name): + parser = super(DataSaveCommand, self).get_parser(prog_name) + parser.add_argument("--file", metavar="", + help="downloaded introspection data filename " + "(default: stdout)") + parser.add_argument('uuid', help='baremetal node UUID') + return parser + + def take_action(self, parsed_args): + client = self.app.client_manager.baremetal_introspection + data = client.get_data(parsed_args.uuid, + raw=bool(parsed_args.file)) + if parsed_args.file: + with open(parsed_args.file, 'wb') as fp: + fp.write(data) + else: + json.dump(data, sys.stdout) diff --git a/ironic_inspector_client/test/test_shell.py b/ironic_inspector_client/test/test_shell.py index f7fa1a4..ef9e7fa 100644 --- a/ironic_inspector_client/test/test_shell.py +++ b/ironic_inspector_client/test/test_shell.py @@ -11,8 +11,11 @@ # See the License for the specific language governing permissions and # limitations under the License. +import sys + import mock from openstackclient.tests import utils +import six import tempfile from ironic_inspector_client import shell @@ -183,3 +186,35 @@ class TestRules(BaseTest): cmd.take_action(parsed_args) self.rules_api.delete_all.assert_called_once_with() + + +class TestDataSave(BaseTest): + def test_stdout(self): + self.client.get_data.return_value = {'answer': 42} + buf = six.StringIO() + + arglist = ['uuid1'] + verifylist = [('uuid', 'uuid1')] + + cmd = shell.DataSaveCommand(self.app, None) + parsed_args = self.check_parser(cmd, arglist, verifylist) + with mock.patch.object(sys, 'stdout', buf): + cmd.take_action(parsed_args) + self.assertEqual('{"answer": 42}', buf.getvalue()) + self.client.get_data.assert_called_once_with('uuid1', raw=False) + + def test_file(self): + self.client.get_data.return_value = b'{"answer": 42}' + + with tempfile.NamedTemporaryFile() as fp: + arglist = ['--file', fp.name, 'uuid1'] + verifylist = [('uuid', 'uuid1'), ('file', fp.name)] + + cmd = shell.DataSaveCommand(self.app, None) + parsed_args = self.check_parser(cmd, arglist, verifylist) + cmd.take_action(parsed_args) + + content = fp.read() + + self.assertEqual(b'{"answer": 42}', content) + self.client.get_data.assert_called_once_with('uuid1', raw=True) diff --git a/releasenotes/notes/data-save-9d9d4b3ac7c9851f.yaml b/releasenotes/notes/data-save-9d9d4b3ac7c9851f.yaml new file mode 100644 index 0000000..f10555c --- /dev/null +++ b/releasenotes/notes/data-save-9d9d4b3ac7c9851f.yaml @@ -0,0 +1,4 @@ +--- +features: + - Added "introspection data save" command to retrieve stored introspection + data for the node. diff --git a/setup.cfg b/setup.cfg index d47997c..52b1459 100644 --- a/setup.cfg +++ b/setup.cfg @@ -23,6 +23,7 @@ openstack.cli.extension = openstack.baremetal_introspection.v1 = baremetal_introspection_start = ironic_inspector_client.shell:StartCommand baremetal_introspection_status = ironic_inspector_client.shell:StatusCommand + baremetal_introspection_data_save = ironic_inspector_client.shell:DataSaveCommand baremetal_introspection_rule_import = ironic_inspector_client.shell:RuleImportCommand baremetal_introspection_rule_list = ironic_inspector_client.shell:RuleListCommand baremetal_introspection_rule_show = ironic_inspector_client.shell:RuleShowCommand