summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJenkins <jenkins@review.openstack.org>2017-07-06 15:24:31 +0000
committerGerrit Code Review <review@openstack.org>2017-07-06 15:24:31 +0000
commit91cc7311877c74adf2618bcb87f86f484e8d7aae (patch)
treef7e28d40224762d4f531eaa13a7882e20d7cf44b
parenteb19c167ead44a5df7a3ac072af8c4a0a895f36e (diff)
parentae35a29169ab460cdd5d6b8c26d376c000a5c10e (diff)
downloadpython-openstackclient-91cc7311877c74adf2618bcb87f86f484e8d7aae.tar.gz
Merge "Allow objects to be streamed to stdout"
-rw-r--r--doc/source/cli/command-objects/object.rst3
-rw-r--r--openstackclient/api/object_store_v1.py15
-rw-r--r--openstackclient/object/v1/object.py3
-rw-r--r--openstackclient/tests/functional/object/v1/test_object.py4
-rw-r--r--openstackclient/tests/unit/object/v1/fakes.py4
-rw-r--r--openstackclient/tests/unit/object/v1/test_object_all.py43
-rw-r--r--releasenotes/notes/object-stdout-db76cc500948b0e8.yaml5
7 files changed, 70 insertions, 7 deletions
diff --git a/doc/source/cli/command-objects/object.rst b/doc/source/cli/command-objects/object.rst
index 6323c4ed..4cba38ee 100644
--- a/doc/source/cli/command-objects/object.rst
+++ b/doc/source/cli/command-objects/object.rst
@@ -114,7 +114,8 @@ Save object locally
.. option:: --file <filename>
- Destination filename (defaults to object name)
+ Destination filename (defaults to object name);
+ using - as the filename will print the file to stdout
.. describe:: <container>
diff --git a/openstackclient/api/object_store_v1.py b/openstackclient/api/object_store_v1.py
index 74c4a46f..31033525 100644
--- a/openstackclient/api/object_store_v1.py
+++ b/openstackclient/api/object_store_v1.py
@@ -16,6 +16,7 @@
import io
import logging
import os
+import sys
from osc_lib import utils
import six
@@ -376,12 +377,16 @@ class APIv1(api.BaseAPI):
stream=True,
)
if response.status_code == 200:
- if not os.path.exists(os.path.dirname(file)):
- if len(os.path.dirname(file)) > 0:
- os.makedirs(os.path.dirname(file))
- with open(file, 'wb') as f:
+ if file == '-':
for chunk in response.iter_content(64 * 1024):
- f.write(chunk)
+ sys.stdout.write(chunk)
+ else:
+ if not os.path.exists(os.path.dirname(file)):
+ if len(os.path.dirname(file)) > 0:
+ os.makedirs(os.path.dirname(file))
+ with open(file, 'wb') as f:
+ for chunk in response.iter_content(64 * 1024):
+ f.write(chunk)
def object_set(
self,
diff --git a/openstackclient/object/v1/object.py b/openstackclient/object/v1/object.py
index e79cea48..aeb02536 100644
--- a/openstackclient/object/v1/object.py
+++ b/openstackclient/object/v1/object.py
@@ -204,7 +204,8 @@ class SaveObject(command.Command):
parser.add_argument(
"--file",
metavar="<filename>",
- help=_("Destination filename (defaults to object name)"),
+ help=_("Destination filename (defaults to object name); using '-'"
+ " as the filename will print the file to stdout"),
)
parser.add_argument(
'container',
diff --git a/openstackclient/tests/functional/object/v1/test_object.py b/openstackclient/tests/functional/object/v1/test_object.py
index 776cf47c..0927d706 100644
--- a/openstackclient/tests/functional/object/v1/test_object.py
+++ b/openstackclient/tests/functional/object/v1/test_object.py
@@ -66,6 +66,10 @@ class ObjectTests(base.TestCase):
+ ' ' + object_file + ' --file ' + tmp_file)
# TODO(stevemar): Assert returned fields
+ raw_output = self.openstack('object save ' + self.CONTAINER_NAME
+ + ' ' + object_file + ' --file -')
+ self.assertEqual(raw_output, 'test content')
+
self.openstack('object show ' + self.CONTAINER_NAME
+ ' ' + object_file)
# TODO(stevemar): Assert returned fields
diff --git a/openstackclient/tests/unit/object/v1/fakes.py b/openstackclient/tests/unit/object/v1/fakes.py
index 72646d25..5d65d106 100644
--- a/openstackclient/tests/unit/object/v1/fakes.py
+++ b/openstackclient/tests/unit/object/v1/fakes.py
@@ -13,6 +13,8 @@
# under the License.
#
+import six
+
from keystoneauth1 import session
from openstackclient.api import object_store_v1 as object_store
@@ -67,6 +69,8 @@ OBJECT = {
'last_modified': object_modified_1,
}
+object_1_content = six.b('object 1 content')
+
OBJECT_2 = {
'name': object_name_2,
'bytes': object_bytes_2,
diff --git a/openstackclient/tests/unit/object/v1/test_object_all.py b/openstackclient/tests/unit/object/v1/test_object_all.py
index f215836e..363f2ea2 100644
--- a/openstackclient/tests/unit/object/v1/test_object_all.py
+++ b/openstackclient/tests/unit/object/v1/test_object_all.py
@@ -13,8 +13,10 @@
import copy
+import mock
from osc_lib import exceptions
from requests_mock.contrib import fixture
+import six
from openstackclient.object.v1 import object as object_cmds
from openstackclient.tests.unit.object.v1 import fakes as object_fakes
@@ -202,3 +204,44 @@ class TestObjectShow(TestObjectAll):
'manifest',
)
self.assertEqual(datalist, data)
+
+
+class TestObjectSave(TestObjectAll):
+
+ def setUp(self):
+ super(TestObjectSave, self).setUp()
+
+ # Get the command object to test
+ self.cmd = object_cmds.SaveObject(self.app, None)
+
+ def test_save_to_stdout(self):
+ self.requests_mock.register_uri(
+ 'GET',
+ object_fakes.ENDPOINT +
+ '/' +
+ object_fakes.container_name +
+ '/' +
+ object_fakes.object_name_1,
+ status_code=200,
+ content=object_fakes.object_1_content
+ )
+
+ arglist = [
+ object_fakes.container_name,
+ object_fakes.object_name_1,
+ '--file',
+ '-'
+ ]
+
+ verifylist = [
+ ('container', object_fakes.container_name),
+ ('object', object_fakes.object_name_1),
+ ('file', '-'),
+ ]
+
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ with mock.patch('sys.stdout', new=six.BytesIO()) as fake_stdout:
+ self.cmd.take_action(parsed_args)
+
+ self.assertEqual(fake_stdout.getvalue(), object_fakes.object_1_content)
diff --git a/releasenotes/notes/object-stdout-db76cc500948b0e8.yaml b/releasenotes/notes/object-stdout-db76cc500948b0e8.yaml
new file mode 100644
index 00000000..29b21131
--- /dev/null
+++ b/releasenotes/notes/object-stdout-db76cc500948b0e8.yaml
@@ -0,0 +1,5 @@
+---
+features:
+ - |
+ Add support for streaming Swift objects to stdout when using the ``object
+ save`` command, by specifying ``--filename -``.