72 Commits

Author SHA1 Message Date
Jenkins
f9d0657e70 Merge "Support client certificate/key" 2016-05-19 22:20:17 +00:00
Jenkins
3a6c14981d Merge "Check responses when retrying bodies" 2016-05-11 07:52:47 +00:00
Tim Burke
fd5579a154 Check responses when retrying bodies
Previously, if a Range request came back 200 OK (rather than 206 Partial
Content), we would mangle the response body. This could happen if there
was a middleware that would silently drop Range headers, for example.

Now, if the response does not include a Content-Range header, we will
log a warning and seek to our previous position in the stream. If the
Content-Range header has an unexpected value, we will raise an exception.

Change-Id: I94d4536cc1489968d45a2b6ba7edd70c85800275
2016-05-04 15:21:26 -07:00
Cedric Brandily
450f505c35 Support client certificate/key
This change enables to specify a client certificate/key with:
 * usual CLI options (--os-cert/--os-key)
 * usual environment variables ($OS_CERT/$OS_KEY)

Closes-Bug: #1565112
Change-Id: I12e151adcb6084d801c6dfed21d82232a3259aea
2016-04-10 23:20:49 +02:00
Tim Burke
9b8ab67a78 Include response headers in ClientExceptions
Now, client applications can get to things like transaction IDs for
failures without needing to turn on all of logging.

While we're at it, add a from_response factory method for
ClientException.

Co-Authored-By: Alexander Corwin <ancorwin@gmail.com>
Change-Id: Ib46d5f8fc7f36f651f5908bb9d900316fdaebce3
2016-03-03 17:16:33 +00:00
Jenkins
cd3a4dbf0a Merge "Drop testtools from test-requirements.txt" 2016-03-01 17:51:32 +00:00
Jenkins
b040ce4e1a Merge "Fix wrong args for get_container with full listing" 2016-02-29 16:26:58 +00:00
Jenkins
ba2ff4a6ea Merge "Force header keys/values to bytes/unicode before coercing to unicode" 2016-02-27 01:44:38 +00:00
Tim Burke
aa0edd0096 Force header keys/values to bytes/unicode before coercing to unicode
Previously, parse_header_string was only called with data coming out of
requests, which would be either bytes or unicode. Now that we're sending
it request headers as well (see related change), we need to be more
defensive.

If the value given is neither bytes nor unicode, convert it to a native
string. This will allow developers using the client API to continue
sending header dicts like

  {'X-Delete-After': 2}

...as in Swift's test/probe/test_object_expirer.py

Change-Id: Ie57a93274507b184af5cad4260f244359a585f09
Related-Change: I43dd7254f7281d4db59b286aa2145643c64e1705
2016-02-26 11:25:10 -08:00
Joel Wright
46d8178280 Fix test for redacting sensitive data in client.http_log()
The test should have included utf8 encoded unicode data to
test that encoded unicode data stored in headers was parsed
correctly.

Also fixes the docstring for swiftclient.safe_value()

Change-Id: Id0def0b3af7a364f1257cc22f67b71c0cc5d8479
2016-02-26 11:36:45 +00:00
Tim Burke
c3f0641704 Follow-up to patch 282363
* Improve some formatting
* Be more explicit about how much will be revealed when
* Rename redact_sensitive_tokens to redact_sensitive_headers, as it
  affects more than tokens.

Change-Id: I02b375d914e9f0a210d038ecb31188d09a8ffce3
2016-02-25 10:06:48 -08:00
Joel Wright
4d44dcf360 Do not reveal auth token in swiftclient log messages by default
Currently the swiftclient logs sensitive info in headers when logging
HTTP requests. This patch hides sensitive info in headers such as
'X-Auth-Token' in a similar way to swift itself (we add a
'reveal_sensitive_prefix' configuration to the client).

With this patch, tokens are truncated by removing the specified number
of characters, after which '...' is appended to the logged token to
indicate that it has been redacted.

Co-Authored-By: Li Cheng <shcli@cn.ibm.com>
Co-Authored-By: Zack M. Davis <zdavis@swiftstack.com>
Change-Id: I43dd7254f7281d4db59b286aa2145643c64e1705
Closes-bug: #1516692
2016-02-22 17:55:51 +00:00
Alistair Coles
67f5468ee4 Fix wrong args for get_container with full listing
In client get_container(), when full_listing is true,
the calls back to get_container() pass service_token
as a positional arg which maps its value to the
full_listing arg. It should use a keyword.

Change-Id: Iac2af45df124ff33fcb7fbaf1ba959ef06c96378
Closes-Bug: #1496093
2016-02-22 15:22:44 +00:00
Jenkins
da0aa24f28 Merge "_RetryBody doesn't need to take explicit etag/content-length" 2016-02-18 23:40:51 +00:00
Tim Burke
bed6bbd5ef Drop testtools from test-requirements.txt
My understanding is that it was mainly being used so we could have sane
testing on py26.  With py26 support being dropped, we no longer need it.

Also drop discover from test-requirements.txt, as we don't seem to
actually use it.

Change-Id: Iee04c42890596d3b483c1473169480a3ae19aac8
Related-Change: I37116731db11449d0c374a6a83a3a43789a19d5f
2016-02-12 09:57:58 -08:00
Jenkins
84d110c63e Merge "Accept token and tenant_id for authenticating against KS" 2016-02-10 19:39:53 +00:00
Pratik Mallya
a175689418 Accept token and tenant_id for authenticating against KS
Allow swiftclient to authenticate against keystone using tenant
name/id and token only. Without this patch, the password is
required, which may not always be available. Authentication
against keystone is required to get the service catalog,
which includes the endpoints for swift.

Change-Id: I4477af445474c5fa97ff864c4942f1330b59e5d6
Closes-Bug: #1476002
2016-01-18 10:47:05 -08:00
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
5050027610 _RetryBody doesn't need to take explicit etag/content-length
Also, don't try to do int(None) for chunk-encoded responses (like DLOs
that are longer than a single container listing).

Change-Id: Ibacd75d5ee46135d62388786903c895fda8ed3ba
2016-01-11 15:36:37 -08: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
d1e3109588 Merge "Replace assertEqual(arg, None) with assertIsNone(arg)" 2016-01-06 09:19:43 +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
SaiKiran
6da38adb8d Replace assertEqual(arg, None) with assertIsNone(arg)
In python-swiftclient some test cases using asserEqual(arg, None)
instead of assertIsNone(arg).assertIsNone method provides clear error message.

Change-Id: I4d673ede0965408344325c9c234c5c4b1ae4146a
Closes-Bug: #1527556
2015-12-30 17:25:30 +05:30
Stuart McLaren
0103465fcb Test 'string' behaviour of get_object
Add a unit test to test the 'string' like behaviour of
get_object when it is called without resp_chunk_size set.

Co-Authored-By: Clay Gerrard <clay.gerrard@gmail.com>
Change-Id: I496032a76036141d027c30b076c810b34bc6bef0
2015-12-15 17:15:27 +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
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
Alistair Coles
43b2c6bfe5 Make more assertions in client unit tests
Some tests rely on the fake connection checking expected request
parameters, but that assumes that the fake ocnnection is even called,
which is not being checked. Add more explicit assertions that requests
are in fact made.

Change-Id: Id1c48235d7d97fd1b0feec6c19ed59a87bebdf89
2015-09-23 09:55:10 +01:00
Tim Burke
305cd6253f Actually make assertions when testing get_account and get_container
Change-Id: Ibb1301b00d1bc99ec089ead02f944aa94972120a
2015-09-22 12:14:18 -07: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
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
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
Jenkins
b4b9254bc3 Merge "Add minimal working service token support." 2015-08-25 02:02:51 +00: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
Hiroshi Miura
38a82e9035 flake8 ignores same hacks as swift
- blacklisted flake8 hacking
- fix against E122 continuation line missing
  indentation or outdented

Closes-bug: #1475516

Change-Id: I708d0a3466a1f85c84e478873e142821ce0774cb
Signed-off-by: Hiroshi Miura <miurahr@nttdata.co.jp>
2015-08-18 19:19:22 -07:00
Jenkins
e9147ca0e0 Merge "change deprecated assertEquals to assertEqual" 2015-08-11 15:19:07 +00:00
Hiroshi Miura
be0f1aad8a change deprecated assertEquals to assertEqual
fix against H234: assertEquals() logs a DeprecationWarning
in Python3.x. use assertEqual() instead.

Closes-bug: #1480776

Change-Id: Iffda6bb5f2616d4af4567eeea37bb26531e34371
Signed-off-by: Hiroshi Miura <miurahr@nttdata.co.jp>
2015-08-06 18:50:33 +09: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
Christian Schwede
7f2ee7322b Add connection release test
This patch adds a small test to ensure a connection
is released after all chunks have been consumed.

It's a follow up to commit 8756591b and added to ensure
there will be no regression in the future (this test
fails also with that patch not applied).

Change-Id: I6a6fcd26879eb2070f418c8770a395ff6c30aa51
2015-06-05 07:17:31 +00: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
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
Alistair Coles
a39e18ff5a Add test for timeout being passed to keystone client
Extends existing unit test for timeout being passed to get_auth
to cover v2.0 auth when keystone client should get the timeout
kwarg.

Related-Bug: 1447847
Change-Id: Ie9cfc86fa2156b94b45d290ac12e3f71b20d6c4f
2015-04-28 16:58:23 +01: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