149 Commits

Author SHA1 Message Date
Tim Burke
7a1e192803 Use bulk-delete middleware when available
When issuing `delete` commands that would require three or more
individual deletes, check whether the cluster supports bulk deletes
and use that if it's available.

Additionally, a new option is added to the `delete` command:

  * --prefix <prefix>

    Delete all objects that start with <prefix>. This is similar to the
    --prefix option for the `list` command.

Example:

$ swift delete c --prefix obj_prefix/

    ...will delete from container "c" all objects whose name begins with
    "obj_prefix/", such as "obj_prefix/foo" and "obj_prefix/bar".

Change-Id: I6b9504848d6ef562cf4f570bbcd17db4e3da8264
2016-01-12 15:40:57 -08:00
Jenkins
6ed6c3343f Merge "Retry file uploads via SwiftService" 2016-01-12 13:00:17 +00:00
Tim Burke
d4157ce5b5 Retry file uploads via SwiftService
When we introduced LengthWrapper, we neglected to make it resettable. As
a result, upload failures result in errors like:

    put_object(...) failure and no ability to reset contents for reupload.

Now, LengthWrappers will be resettable if their _readable has seek/tell.

Related-Change: I6c8bc1366dfb591a26d934a30cd21c9e6b9a04ce
Change-Id: I21f43f06e8c78b24d1fc081efedf2687942e042f
2016-01-11 11:12:13 -08:00
Stuart McLaren
4af623bcf1 Retry download of object body
Currently the swift client retries establishing a connection to the server
(by default up to 5 times).  However, when downloading an object, once
the connection has been established and the inital headers have been
returned, no attempt is made to retry.

So, for example, if 99MB of a 100MB object have been downloaded and the
connection is then lost, the download will fail.  This patch changes the
behaviour to re-establish the connection and fetch the remaining bytes
using the 'Range' header to offset.

Data retry is not yet supported if the original request is for a subset
of the object data (ie uses the 'Range' header), or if resp_chunk_size
has not been set.

The object's etag is checked using If-Match to make sure the object data
hasn't changed since the start of the download.

Change-Id: Iab47f10081ff39f6d344dbc2479cbc3bfd1c5b29
2016-01-08 17:12:02 +00:00
Jenkins
81003b8d99 Merge "Wrap raw iterators to ensure we send entire contents to server" 2016-01-06 00:06:04 +00:00
Tim Burke
39b1a31d8a Wrap raw iterators to ensure we send entire contents to server
Currently, if you attempt to stream an upload from an iterator, as in

    def data():
        yield 'foo'
        yield ''
        yield 'bar'
    conn.put_object('c', 'o', data())

... requests will faithfully emit a zero-length chunk, ending the
transfer. Swift will then close the connection, possibly (if Connection:
keep-alive was set) after attempting to parse the next chunk as a new
request.

Now, Swift will receive all of the bytes from the iterable, and any
zero-byte chunks will be ignored.

This will be fixed in requests [1], but not until an eventual 3.0.0
release.

[1] https://github.com/kennethreitz/requests/pull/2631

Change-Id: I19579ed7a0181ac3f488433e7c1839f7f7a040b8
2015-12-30 11:56:36 -08:00
Tim Burke
62bfe10f58 Fix some typos
Change-Id: Iaf7f30a7ae0c2ac76fc5cdcee31ea74c08ce601e
2015-12-30 11:01:33 -08:00
hgangwx
ab65eef4ce Wrong usage of "an"
Wrong usage of "an" in the messages:
"the optional os_options paramater includes an non-empty"
"We are allowing to have an tenant_name argument"

Should be:
"the optional os_options paramater includes a non-empty"
"We are allowing to have a tenant_name argument"

Totally 2 occurrences in python-swiftclient base code.

Change-Id: I2f2f7e07432fedfee5ccb418d9505250b3fed597
2015-12-30 14:27:29 +08:00
Jenkins
5e13c3e845 Merge "Stop passing attr to keystoneclient when there's no filter_value" 2015-12-22 11:15:27 +00:00
Tim Burke
2345ae54f1 Stop passing attr to keystoneclient when there's no filter_value
It was dropping warnings like "UserWarning: Providing attr without
filter_value to get_urls() is deprecated as of the 1.7.0 release and may
be removed in the 2.0.0 release. Either both should be provided or
neither should be provided."

Change-Id: Iead0bcf36b4a46bf465a55a33a21fd7f14f0ac40
2015-12-07 10:42:15 -08:00
Joel Wright
a3a78be87b New API documentation for python-swiftclient
New documentation for python-swiftclient that introduces
the APIs available and gives some opinionated advice about
when to use the shell, the client API and the service API.

Change-Id: I19020f041fab2e72469979f712ffe3951c431d24
2015-11-25 15:15:09 +00:00
Jenkins
50978ddf63 Merge "Centralize header parsing" 2015-11-12 02:53:20 +00:00
Jenkins
ad5656020c Merge "Add tests and param definitions for headers parameter" 2015-11-04 01:11:37 +00:00
Jenkins
1c649cc0d8 Merge "enable autodocumentation for utils module; docstring fixes" 2015-10-29 06:09:46 +00:00
Lisak, Peter
df1f4f3e39 swiftclient content-type header
According to help `swift upload -h` you can add a customized request header 'Content-Type'.
But actually it is ignored (cleared and default is used) if subcommand is upload.

Subcommand post works as expected in help.

Bug fix: Use 'Content-Type' from the customized request headers also if
uploading.

Change-Id: If0d1354b6214b909527341078fe1769aa6587457
2015-10-22 08:54:13 +00:00
Tim Burke
9fed7ed5e1 Miscellaneous (mostly test) cleanup
* Always use testtools.TestCase, since we're relying on testtools
 * Always use mock (as opposed to unittest.mock) since we're relying on
   mock
 * Add note about when a missing logging handler was added
 * Stop %-formatting the giant usage string that doesn't actually need
   any formatting
 * Prefer assertIs, assertIn, assertIsInstance over assertTrue
 * Use else-self.fail instead of sentinel values
 * Check resp.get('error') is None before checking resp['success'] is
   True, so test failures actually tell you something useful
 * Tighten some isinstance assertions
 * Import MockHttpTest from correct location
 * Only populate clean_os_environ once
 * Use setUp for setup, not __init__
 * Replace assertIn(key, dict) and assertEqual(foo, dict[key]) with
   assertEqual(foo, dict.get(key)) when key is a literal and foo is not
   None
 * Use mock.patch.object instead of manually patching for tests
 * Use six.binary_type instead of type(''.encode('utf-8'))
 * Stop shadowing builtin bytes
 * Reclaim some margin
 * Stop checking the return-type of encode_utf8; we already know it's
   bytes

Change-Id: I2138ea553378ce88810b7353147c8645a8f8c90e
2015-10-07 22:33:42 -07:00
Alistair Coles
328d6a8d45 Add tests and param definitions for headers parameter
Cleanups for change I35c3b266b3c733f6b1629de4c683ea7d40128032

Add missing param definitions to client get_container
and head_object docstrings.

For consistency, add headers parameter to the Connection class
head_object and head_container wrapper methods.

Add tests to verify that the headers parameter of Connection
get_container, head_container and head_object methods is passed to the
module functions.

Change-Id: Ib40d5b626b2793840727c58cffbf725bea55651f
2015-09-23 12:21:45 +01:00
Mahati
7cb99d3157 Add headers parameter
Headers parameter is required when passing client key for encryption.
It is missing for get_container and head_object.

Change-Id: I35c3b266b3c733f6b1629de4c683ea7d40128032
2015-09-16 21:55:56 +05:30
Zack M. Davis
6b3638ecec enable autodocumentation for utils module; docstring fixes
This commit adds the utils module to those for which Sphinx
automatically generates documentation from docstrings. (Many of the
functions here may be of little interest to users, but
`generate_temp_url`, at least, definitely deserves to be in the
documentation; in this way, this commit can be seen as a spiritual
companion to ca70dd9e.)

Also, a few markup errors and perceived infelicities in existing
docstrings are amended.

Change-Id: I8c66a23cb359d7dd9302a16459fad9825fedb690
2015-09-10 15:19:26 -07:00
Zack M. Davis
5ae4b42392 make ClientException.http_status default to None rather than 0
The extant default of zero is a bit counterintuitive;
insufficiently-careful programmers using swiftclient in their
application might, without carefully reading the source or
documentation, write buggy code based on the assumption that the
`http_status` attribute is absent or defaults to None if ClientException
is raised for reasons other than to indicate an unsuccessful HTTP
request. (However improbable this scenario may seem, the present author
can sadly attest to it having actually happened at least once.)

Just changing the default would break some tests on Python 3, due to the
`500 <= err.http_status <= 599` comparison in Connection's _retry
method (NoneType and int are not orderable in the Python 3.x series);
thus, the case where http_status is None is explicitly folded into a
code branch that logs and reraises (whereas previously it would have
fallen through to an `else` branch where it would be logged and reraised
just the same).

While we're here, we might as well make ClientException's __init__ use
super() (although admittedly the kinds of multiple-inheritance scenarios
in which `super` truly shines seem unlikely to occur here).

Change-Id: I8c02bfb4a0ef059e781be5e08fcde13fb1be5b88
2015-09-04 16:24:54 -07:00
Tim Burke
ce569f4651 Centralize header parsing
All response headers are now exposed as unicode objects. Any
url-encoding is interpretted as UTF-8; if that causes decoding to fail,
the url-encoded form is returned.

As a result, deleting DLOs with unicode characters will no longer raise
UnicodeEncodeErrors under Python 2.

Related-Bug: #1431866
Change-Id: Idb111c5bf3ac1f5ccfa724b3f4ede8f37d5bfac4
2015-09-03 13:46:03 -07:00
Jenkins
ff073ab34a Merge "Increase httplib._MAXHEADERS to 256." 2015-09-03 08:37:00 +00:00
Charles Hsu
4b627327c9 Increase httplib._MAXHEADERS to 256.
By default Swift increase the number of max metadata count to 90
and extra header count to 32. That mean we can put 90 metadata to
Account/Container/Object by default, when user put 90 metadata to a
Account, the Account header count is close or more than 100. The
swift client unable to access Account and get an error likes,

('Connection aborted.', HTTPException('got more than 100 headers',))

So the default _MAXHEADERS(100) won't enough.

Change-Id: I5ffc4eb5d3e1ebc3dbdd7dc69376919ae3e1c5a8
2015-08-27 00:01:22 +08:00
Alistair Coles
4b310083df Stop Connection class modifying os_options parameter
When a caller passes an os_options dict to the Connection class
constructor, the constructor may modify the os_options dict,
which can surprise the caller if they re-use the os_options
dict. Specifically the os_options tenant_name and object_storage_url
may be modified, and the changed values would then leak through to a
subsequent Connection constructed using the same os_options dict.

This fix simply constructs a new dict from the supplied os_options.
The patch also adds a test that covers this and also verifies that
a preauth_url passed as a keyword arg to Connection() will take
precedence over any object_storage_url in an os_options parameter.

Closes-Bug: 1488070
Change-Id: Ic6b5cf3ac68c505de155619f2610be9529e15432
2015-08-25 09:47:09 +01:00
Stuart McLaren
1789c2654d Add minimal working service token support.
Add client changes to allow accessing alternative
reseller_prefixes via a service token.

ie client changes for this server side spec:
 https://review.openstack.org/#/c/105228

We assume that the service storage url has been passed in
as a preauthurl.

We rely on get_auth preserving this url.

Change-Id: I1cfda178f0b6c8add46cfebd6bf38440caae2036
2015-08-24 10:54:15 +01:00
Zack M. Davis
3cd1faa7af make Connection.get_auth set url and token attributes on self
When a Connection is first __init__ialized (without providing a
preauthurl or preauthtoken), the url and token attributes are None; they
get set (to be reused on future requests) after one of the wrapper
methods internally using _retry (head_account, get_container,
put_object, and similar friends) is called. However, this had not been
the case for get_auth, much to the momentary confusion and
disappointment of programmers using swiftclient who expected to be able
to get the token or storage URL off the Connection object after calling
get_auth (perhaps in order to make an unusual kind of request that
swiftclient doesn't already have a function for). This commit makes
get_auth set the url and token attributes as one might expect.

Change-Id: I0d9593eb5b072c8e3fa84f7d5a4c948c0bc6037a
2015-07-24 10:57:29 -07:00
Jenkins
ec3e2ab3a0 Merge "Allow reading from object body on download" 2015-06-04 12:08:07 +00:00
Alistair Coles
f0cc3be2ac Make default get_auth timeout be None
Setting timeout to a default of False in get_auth()
results in a requests timeout of 0.0 in keystoneclient,
which causes a connection failure.

This bug will cause func tests to not run when using
keystoneauth.

Added unit tests to verify correct default timeout is set
in get_auth().

Drive-by: remove what seems like a stale TODO comment

Change-Id: I17c781ce160a682b1768d315422ade0cdd2df198
2015-06-03 12:03:30 +01:00
Jenkins
bcca25a2c8 Merge "Stop decoding object content" 2015-05-29 08:13:16 +00:00
Tim Burke
7d5c85ad10 Stop decoding object content
Previously, we had urllib3 (via requests) automatically decode all
responses with a Content-Encoding of deflate or gzip. This included
object downloads, which would in turn cause etag or content-length
mismatch errors. (See bug 1338464)

This was apparently added in response to a third-party proxy sitting
between the client and server which, having observed that the client
would accept gzip-encoded content while the server sent an unencoded
response, would perform the compression. (See bug 1282861)

Now, we'll no longer let requests send any default headers, nor do any
decoding.

Change-Id: I6cc30a5c12e37de06d7322533a3c36ad15397cc8
Closes-Bug: 1338464
Related-Bug: 1282861
2015-05-22 13:24:46 -07:00
Tim Burke
317df7e527 Remove simplejson dependency
In addition to removing an unnecessary dependency, this closes another
hole that was allowing raw bytes to appear in user-facing messages.

Change-Id: Ia0b76426a38e5a5c368c4c7e7ba2aef286758aca
2015-05-20 18:14:53 -07:00
Pete Zaitcev
e2f41a6635 Use a socket timeout in get_auth
A previous change added socket timeouts, but they weren't plumbed
through to the get_auth code path. Make sure we're passing them along
everywhere.

Original-Author: Monty Taylor <mordred@inaugust.com>
Change-Id: I398241898248e66d1f8c436c8ed2ec7a0e9387f6
Closes-bug: 1447847
2015-04-26 01:37:15 -06:00
Jenkins
ea6d2bf74d Merge "Add socket-level read timeout parameter" 2015-04-24 01:18:49 +00:00
Jenkins
3105cdc4f8 Merge "Include unsupported url scheme with ClientException" 2015-03-31 22:18:44 +00:00
Monty Taylor
f5a473edfc Add socket-level read timeout parameter
The underlying requests library supports a timeout input parameter. The
other python-*client libraries support passing it in, so while working
on shade, it seemed like a great idea to be able to pass in timeout to
swiftclient too. For reference, there's a change in shade:
I095c1240693abf024bda2315dd77f4400b24a45b that shows interaction with
the other libs, and a tentative patch that would consume this one.

Change-Id: I699ebb1e092aa010af678de7ba15712da6ed5315
2015-03-30 17:01:02 -04:00
Stuart McLaren
b6457e0f95 Allow reading from object body on download
Currently, get_object returns a generator. This allows access to the
object's data in multiples of 'resp_chunk_size'.

This patch adds a read function to also allow accessing the object data
using read(size).

This allows, for example, the consumer of an object (where no byte range
has been specified) to read up to certain boundaries while streaming to
a new Large Object with segments of a specified size.

Reading and chunking can be safely mixed.

Related-Bug: 1367925
Co-Authored-By: Clay Gerrard <clay.gerrard@gmail.com>
Change-Id: I1cfb67f45afc7015fd896f1a89bebae048871769
2015-03-24 10:45:33 +00:00
Ian Cordasco
8756591b0a Release connection after consuming the content
When using stream=True, we need to make sure we release a connection
back to the connection pool to avoid warnings clogging up the logs. We
can do this by releasing the connection once we've read all the content
from the response. In situations where stream=False, requests already
does this for us.

Related-bug: 1424732
Closes-bug: 1341777
Change-Id: Id1c72ad86135a49d4b985992d788736b65f7dbda
2015-02-25 11:00:56 +00:00
Alistair Coles
47f089fbca Include unsupported url scheme with ClientException
This was an attempt to reveal some more info about failing
jenkins jobs such as here [1] where glance_store is
receiving a swiftclient exception because of 'unsupported
scheme in url'. It seems worth merging the more helpful
exception message.

[1] http://logs.openstack.org/91/155291/7/check/gate-tempest-dsvm-neutron-src-python-swiftclient/4adac1e/

Change-Id: I0f3411efd42d045b07d6d1000f59a06865d8034b
2015-02-23 19:10:32 +00:00
Daniel Wakefield
f0300e3714 Verify MD5 of uploaded objects.
Changed existing code to calculate the MD5 of the object
during the upload stream. Checks this MD5 against the etag
returned in the response.
An exception is raised if they do not match.

Closes-Bug: 1379263

Change-Id: I6c8bc1366dfb591a26d934a30cd21c9e6b9a04ce
2015-02-19 11:21:32 +00:00
Charles Hsu
df2442166c Fix missing ca-certificate parameter to get_auth.
Missing cacert parameter in get_auth_1_0() and it makes requests_args['verify']
is True in default(likes "swift --os-cacert ssl.crti list").
The requests_args['verify'] should be a ca-certificate file name("ssl.crt").

Change-Id: Id3110f3818f55922ad19eeb1ead80fface824009
Closes-Bug: 1418473
2015-02-07 11:42:49 +08:00
Jenkins
9aeb2cfaf4 Merge "Suppress 'No handlers...' message from keystoneclient logger" 2015-01-02 19:07:11 +00:00
Clay Gerrard
fbe558885f Make preauth params work
If you specify a token and storage url when creating a Connection,
regardless of the auth api version the first request will be made
directly to swift.  You can either provide a preauthurl and preauthtoken
or fall back to os_options' object_storage_url and auth_token keys
(exposed as --os-storage-url and --os-auth-token on the command line or
OS_STORAGE_URL and OS_AUTH_TOKEN in the environment).

If a _retry wrapped request on a Connection fails because of invalid
authentication (401) the Connection's cached token and url will be
invalidated.  If the Connection's retries attribute is > 0 the
subsequent attempt will call get_auth to refresh the token, but the
pre-configured storage_url will always be re-used.  This is consistent
with current auth v2 behavior and less surprising for auth v1.

The pre-existing, but previously undocumented behavior/interface of
get_auth would override the storage_url returned by the auth service if
the 'os_storage_url' option was provided in the os_options dict.  To
ensure that this behavior is consistent across auth v1 and v2 from the
command line and when using the Connection class as a library - the
preauthurl is stashed in the os_options dict when provided.

Improved Connection.get_capabilities storage_url handling to better
support the consistent behavior of a preauthurl/object_storage_url on
the connection regardless of auth version.

Fixed up some test infrastructure to enable setting up and testing
multiple requests/responses.

Change-Id: I6950fb73f3e28fdddb62760cae9320e2f4336776
2014-12-17 05:53:56 -07:00
Jenkins
d59af8cc8b Merge "Show warning when auth_version >= 2 and keystoneclient is missing" 2014-12-15 19:07:23 +00:00
Christian Schwede
47546eb145 Show warning when auth_version >= 2 and keystoneclient is missing
Swiftclient hangs forever without any reasonable hint if someone
uses a recent version of swiftclient together with auth version
2 or later. The reason for this is the sys.exit() call in a thread
- the main thread never exists, and swift just waits forever.

Raising a ClientException instead of calling sys.exit() fixes this
and returns the desired information back to the user.

Change-Id: I1fdff85da2dd4b883d337d6098b1695e448d6f2b
2014-11-25 13:15:08 +01:00
Alistair Coles
e566f77a6e Suppress 'No handlers...' message from keystoneclient logger
keystoneclient isn't adding a NullHandler to its logger,
so we see 'No handlers could be found for logger...'
messages when using the swift cli with keystone auth.

Since keystoneclient follows the usual pattern of
naming loggers  from module name, we can add a
NullHandler to the 'keystoneclient' logger to handle
any logging from the library.

Note that this makes no change to keystoneclient
logging being emitted when using 'swift --debug'
or 'swift --info'.

No test because I am not sure how to usefully
test this without ending up just testing a mock
of keystoneclient.

Change-Id: Ic81cf8e5a590ae9224d35e3a5b1c5f2a8c33835a
2014-11-13 13:38:07 +00:00
Daniel Wakefield
0f2b0dc300 Add unit tests for _encode_meta_headers
Also move it to a module level function.
Change-Id: I2da64876815619a6db7ff208061df2191767806c
2014-11-13 11:25:45 +00:00
Jenkins
f99e71da0f Merge "Fix KeyError raised from client Connection" 2014-11-13 03:12:53 +00:00
Daniel Wakefield
025da14326 Replaces Stacktraces with useful error messages.
Changed the message shown when a user doesn't enter project/tenant
id/name to be more informative.

When attempting to stat a container without supplying project/tenant
name or id, an empty response was being returned instead of an error
being raised.

Changed the error raised in swiftclient.client when no tenant or project
is specified to be more specific.

Add tests for basic regression checking.

Closes-Bug: #1372589

Change-Id: I4eb6964d9f1702db119cc0294edc02841b1ecd5f
2014-10-21 08:23:26 +00:00
Alistair Coles
871a3e40f3 Fix KeyError raised from client Connection
Some client.Connection methods will raise a KeyError
if a response_dict argument is passed and an error
occurs during authentication or making the request.

The fix is straightforward: add a test for existence
of a response_dict before attempting to get it from
kwargs.

The bulk of this patch is adding unit tests for the
response_dict feature.

Closes-Bug: 1381304

Change-Id: Ic7e1b3dfae33909533931c52ac97355867a08a07
2014-10-20 12:00:54 +01:00
Pete Zaitcev
b27ca7c0c0 Fix the info command with --insecure
We forgot to propagate options into http_connection() for the info
aka capabilities command. Fix is to use the proper helper.

Fixes bug: 1381866

Change-Id: I9515203c969a1bba38dd909412355080383905f9
2014-10-17 13:38:01 -06:00