Hello community,
here is the log from the commit of package python-apache-libcloud for
openSUSE:Factory checked in at 2020-03-08 22:22:34
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-apache-libcloud (Old)
and /work/SRC/openSUSE:Factory/.python-apache-libcloud.new.26092 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-apache-libcloud"
Sun Mar 8 22:22:34 2020 rev:30 rq:782015 version:2.8.1
Changes:
--------
---
/work/SRC/openSUSE:Factory/python-apache-libcloud/python-apache-libcloud.changes
2020-02-25 16:01:10.723913857 +0100
+++
/work/SRC/openSUSE:Factory/.python-apache-libcloud.new.26092/python-apache-libcloud.changes
2020-03-08 22:22:40.556023355 +0100
@@ -1,0 +2,7 @@
+Thu Mar 5 18:45:41 UTC 2020 - Niels Abspoel <[email protected]>
+
+- update to 2.8.1
+ for the changelog see:
+
https://libcloud.readthedocs.io/en/stable/changelog.html#changes-in-apache-libcloud-v2-8-1
+
+-------------------------------------------------------------------
@@ -5,0 +13,5 @@
+
+-------------------------------------------------------------------
+Thu Feb 20 18:19:46 UTC 2020 - James Fehlig <[email protected]>
+
+- Stop building for python2
Old:
----
apache-libcloud-2.8.0.tar.gz
New:
----
apache-libcloud-2.8.1.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-apache-libcloud.spec ++++++
--- /var/tmp/diff_new_pack.og3aAF/_old 2020-03-08 22:22:41.192023747 +0100
+++ /var/tmp/diff_new_pack.og3aAF/_new 2020-03-08 22:22:41.196023750 +0100
@@ -16,9 +16,12 @@
#
+# No longer build for python2
+%define skip_python2 1
+
%{?!python_module:%define python_module() python-%{**} python3-%{**}}
Name: python-apache-libcloud
-Version: 2.8.0
+Version: 2.8.1
Release: 0
Summary: Abstraction over multiple cloud provider APIs
License: Apache-2.0
@@ -41,7 +44,9 @@
BuildRequires: fdupes
BuildRequires: python-backports.ssl_match_hostname
BuildRequires: python-rpm-macros
+%if ! 0%{?skip_python2}
BuildRequires: python2
+%endif
Requires: python-lxml
Requires: python-requests
Requires: python-typing
@@ -78,8 +83,10 @@
%check
# Skip ShellOutSSHClientTests tests which attempt to ssh to localhost
+%if ! 0%{?skip_python2}
python2 -m pytest -k 'not ShellOutSSHClientTests and \
not ElasticContainerDriverTestCase'
+%endif
# Note these two extra py3 failures are undesirable and should be fixed
python3 -m pytest -k \
'not test_consume_stderr_chunk_contains_part_of_multi_byte_utf8_character
and \
++++++ apache-libcloud-2.8.0.tar.gz -> apache-libcloud-2.8.1.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/apache-libcloud-2.8.0/CHANGES.rst
new/apache-libcloud-2.8.1/CHANGES.rst
--- old/apache-libcloud-2.8.0/CHANGES.rst 2019-12-23 14:59:47.000000000
+0100
+++ new/apache-libcloud-2.8.1/CHANGES.rst 2020-02-29 22:24:53.000000000
+0100
@@ -1,6 +1,105 @@
Changelog
=========
+Changes in Apache Libcloud v2.8.1
+---------------------------------
+
+Common
+~~~~~~~
+
+- Fix ``LIBCLOUD_DEBUG_PRETTY_PRINT_RESPONSE`` functionality and make sure it
+ works correctly under Python 3 when ``response.read()`` function returns
+ unicode and not bytes.
+
+ (GITHUB-1430)
+ [Tomaz Muraus]
+
+Compute
+~~~~~~~
+
+- [GCE] Fix ``list_nodes()`` method so it correctly handles pagination
+ and returns all the nodes if there are more than 500 nodes available
+ in total.
+
+ Previously, only first 500 nodes were returned.
+
+ Reported by @TheSushiChef.
+ (GITHUB-1409, GITHUB-1360)
+ [Tomaz Muraus]
+
+- Fix some incorrect type annotations in the base compute API.
+
+ Reported by @dpeschman.
+ (GITHUB-1413)
+ [Tomaz Muraus]
+
+- [OpenStack] Fix error with getting node id in ``_to_floating_ip`` method
+ when region is not called ``nova``.
+ (GITHUB-1411, GITHUB-1412)
+ [Miguel Caballer - @micafer]
+
+- [EC2] Fix ``ex_userdata`` keyword argument in the ``create_node()`` method
+ being ignored / not working correctly.
+
+ NOTE: This regression has been inadvertently introduced in v2.8.0.
+ (GITHUB-1426)
+ [Dan Chaffelson - @Chaffelson]
+
+- [EC2] Update ``create_volume`` method to automatically select first available
+ availability zone if one is not explicitly provided via ``location``
argument.
+ [Tomaz Muraus]
+
+Storage
+~~~~~~~
+
+- [AWS S3] Fix upload object code so uploaded data MD5 checksum check is not
+ performed at the end of the upload when AWS KMS server side encryption is
+ used.
+
+ If AWS KMS server side object encryption is used, ETag header value in the
+ response doesn't contain data MD5 digest so we can't perform a checksum
+ check.
+
+ Reported by Jonathan Harden - @jfharden.
+ (GITHUB-1401, GITHUB-1406)
+ [Tomaz Muraus - @Kami]
+
+- [Google Storage] Fix a bug when uploading an object would fail and result
+ in 401 "invalid signature" error when object mime type contained mixed
+ casing and when S3 Interoperability authentication method was used.
+
+ Reported by Will Abson - wabson.
+ (GITHUB-1417, GITHUB-1418)
+ [Tomaz Muraus]
+
+- Fix ``upload_object_via_stream`` method so "Illegal seek" errors which
+ can arise when calculating iterator content hash are ignored. Those errors
+ likely indicate that the underlying file handle / iterator is a pipe which
+ doesn't support seek and that the error is not fatal and we should still
+ proceed.
+
+ Reported by Per Buer - @perbu.
+
+ (GITHUB-1424, GITHUB-1427)
+ [Tomaz Muraus]
+
+DNS
+~~~
+
+- [Gandi Live] Update the driver and make sure it matches the latest service /
+ API updates.
+ (GITHUB-1416)
+ [Ryan Lee - @zepheiryan]
+
+- [CloudFlare] Fix ``export_zone_to_bind_format`` method.
+
+ Previously it threw an exception, because ``record.extra`` dictionary
+ didn't contain ``priority`` key.
+
+ Reported by James Montgomery - @gh-jamesmontgomery.
+ (GITHUB-1428, GITHUB-1429)
+ [Tomaz Muraus]
+
Changes in Apache Libcloud v2.8.0
---------------------------------
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/apache-libcloud-2.8.0/PKG-INFO
new/apache-libcloud-2.8.1/PKG-INFO
--- old/apache-libcloud-2.8.0/PKG-INFO 2019-12-23 21:46:12.000000000 +0100
+++ new/apache-libcloud-2.8.1/PKG-INFO 2020-02-29 23:10:06.000000000 +0100
@@ -1,6 +1,6 @@
Metadata-Version: 1.2
Name: apache-libcloud
-Version: 2.8.0
+Version: 2.8.1
Summary: A standard Python library that abstracts away differences among
multiple cloud provider APIs. For more information and documentation, please
see http://libcloud.apache.org
Home-page: http://libcloud.apache.org/
Author: Apache Software Foundation
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/apache-libcloud-2.8.0/apache_libcloud.egg-info/PKG-INFO
new/apache-libcloud-2.8.1/apache_libcloud.egg-info/PKG-INFO
--- old/apache-libcloud-2.8.0/apache_libcloud.egg-info/PKG-INFO 2019-12-23
21:46:12.000000000 +0100
+++ new/apache-libcloud-2.8.1/apache_libcloud.egg-info/PKG-INFO 2020-02-29
23:10:05.000000000 +0100
@@ -1,6 +1,6 @@
Metadata-Version: 1.2
Name: apache-libcloud
-Version: 2.8.0
+Version: 2.8.1
Summary: A standard Python library that abstracts away differences among
multiple cloud provider APIs. For more information and documentation, please
see http://libcloud.apache.org
Home-page: http://libcloud.apache.org/
Author: Apache Software Foundation
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/apache-libcloud-2.8.0/apache_libcloud.egg-info/SOURCES.txt
new/apache-libcloud-2.8.1/apache_libcloud.egg-info/SOURCES.txt
--- old/apache-libcloud-2.8.0/apache_libcloud.egg-info/SOURCES.txt
2019-12-23 21:46:12.000000000 +0100
+++ new/apache-libcloud-2.8.1/apache_libcloud.egg-info/SOURCES.txt
2020-02-29 23:10:05.000000000 +0100
@@ -5,6 +5,7 @@
NOTICE
README.rst
example_compute.py
+example_container.py
example_dns.py
example_loadbalancer.py
example_storage.py
@@ -2163,8 +2164,6 @@
libcloud/test/dns/fixtures/gandi_live/create_existing_record.json
libcloud/test/dns/fixtures/gandi_live/create_record.json
libcloud/test/dns/fixtures/gandi_live/create_zone.json
-libcloud/test/dns/fixtures/gandi_live/delete_gandi_zone.json
-libcloud/test/dns/fixtures/gandi_live/delete_record.json
libcloud/test/dns/fixtures/gandi_live/get_bad_zone.json
libcloud/test/dns/fixtures/gandi_live/get_mx_record.json
libcloud/test/dns/fixtures/gandi_live/get_nonexistent_record.json
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/apache-libcloud-2.8.0/example_compute.py
new/apache-libcloud-2.8.1/example_compute.py
--- old/apache-libcloud-2.8.0/example_compute.py 2019-12-18
22:26:03.000000000 +0100
+++ new/apache-libcloud-2.8.1/example_compute.py 2020-02-28
23:54:12.000000000 +0100
@@ -21,28 +21,13 @@
from typing import Type, cast
-ec2_cls = get_driver(Provider.EC2)
-rackspace_cls = get_driver(Provider.RACKSPACE)
+cls = get_driver(Provider.KUBEVIRT)
-# NOTE: If you are using driver methods which are not part of the standard API,
-# you need to explicitly cast the driver class reference to the correct class
-# for type checking to work correctly
-EC2 = cast(Type[EC2NodeDriver], ec2_cls)
-Rackspace = cast(Type[RackspaceNodeDriver], rackspace_cls)
+conn = cls(host='192.168.99.103',
+ port=8443,
+ secure=True,
+ key_file='/home/kami/.minikube/client.key',
+ cert_file='/home/kami/.minikube/client.crt',
+ ca_cert='/home/kami/.minikube/ca.crt')
+print(conn.list_nodes())
-drivers = [EC2('access key id', 'secret key', region='us-east-1'),
- Rackspace('username', 'api key', region='iad')]
-
-nodes = []
-for driver in drivers:
- nodes.extend(driver.list_nodes())
-
-print(nodes)
-# [ <Node: provider=Amazon, status=RUNNING, name=bob, ip=1.2.3.4.5>,
-# <Node: provider=Rackspace, status=REBOOT, name=korine, ip=6.7.8.9.10>, ... ]
-
-# grab the node named "test"
-node = [n for n in nodes if n.name == 'test'][0]
-
-# reboot "test"
-node.reboot()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/apache-libcloud-2.8.0/example_container.py
new/apache-libcloud-2.8.1/example_container.py
--- old/apache-libcloud-2.8.0/example_container.py 1970-01-01
01:00:00.000000000 +0100
+++ new/apache-libcloud-2.8.1/example_container.py 2020-02-29
19:13:54.000000000 +0100
@@ -0,0 +1,30 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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.
+
+from libcloud.container.types import Provider
+from libcloud.container.providers import get_driver
+
+cls = get_driver(Provider.GKE)
+
+# You can retrieve cluster ip by running "minikube ip" command
+conn = cls('[email protected]',
+ '/home/kami/Downloads/api-project-767966281678-b44d02952d31.json',
+ project='767966281678')
+
+for cluster in conn.list_clusters():
+ print(cluster.name)
+
+for container in conn.list_containers():
+ print(container.name)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/apache-libcloud-2.8.0/example_dns.py
new/apache-libcloud-2.8.1/example_dns.py
--- old/apache-libcloud-2.8.0/example_dns.py 2019-09-09 18:10:00.000000000
+0200
+++ new/apache-libcloud-2.8.1/example_dns.py 2020-02-28 23:54:12.000000000
+0100
@@ -18,12 +18,14 @@
from libcloud.dns.types import Provider
from libcloud.dns.providers import get_driver
-Zerigo = get_driver(Provider.ZERIGO)
+Zerigo = get_driver(Provider.CLOUDFLARE)
-driver = Zerigo('email', 'key')
+driver = Zerigo('[email protected]', 'bae540b356fbf88ddb364875c9bb3ef4ab303')
zones = driver.list_zones()
pprint(zones)
records = zones[0].list_records()
pprint(records)
+
+print(zones[0].export_to_bind_format())
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/apache-libcloud-2.8.0/example_storage.py
new/apache-libcloud-2.8.1/example_storage.py
--- old/apache-libcloud-2.8.0/example_storage.py 2019-11-20
13:52:50.000000000 +0100
+++ new/apache-libcloud-2.8.1/example_storage.py 2020-02-29
18:01:17.000000000 +0100
@@ -13,17 +13,61 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+from io import BytesIO
from pprint import pprint
+import sys
from libcloud.storage.types import Provider
from libcloud.storage.providers import get_driver
-CloudFiles = get_driver(Provider.CLOUDFILES)
-driver = CloudFiles('access key id', 'secret key', region='ord')
+Driver = get_driver(Provider.GOOGLE_STORAGE)
+driver =
Driver('[email protected]',
+
'/home/kami/Downloads/api-project-767966281678-b44d02952d31.json',
+ project='api-project-767966281678')
+
+Driver = get_driver(Provider.AZURE_BLOBS)
+driver = Driver('libclouddevblobs',
+
'CWNVu69mq/9HUX7+hLNEWPulX4/45KLYN306CpW0BBccV4Ot6JyPxXsHRxK+wGENCYMf97NqPYUEA0nUtnDnqg==')
+
+
+Driver = get_driver(Provider.CLOUDFILES)
+driver = Driver('kamislo',
+ 'ad514c7eb8a55dfefecc6a1a1770aa47',
+ region='ord')
+
+
+#driver = Driver('GOOGC7RCLUYGL3IUBRNW',
'kjZ0t1VCFIz2zOCJXEv532mG4mlTZIg2NWd4Mrat')
containers = driver.list_containers()
+container = containers[0]
container_objects = driver.list_container_objects(containers[0])
-pprint(containers)
-pprint(container_objects)
+iterator = BytesIO(b'0123456789')
+
+
+obj = driver.upload_object_via_stream(iterator=BytesIO(b'0123456789'),
container=container, object_name='test1.xlsm')
+# extra={'content_type':
'application/vnd.ms-excel.sheet.macroenabled.12'})
+
+print(driver.download_object_range(obj=obj, destination_path='1.obj',
start_bytes=5, end_bytes=None, overwrite_existing=True))
+print(next(driver.download_object_range_as_stream(obj=obj, start_bytes=0,
end_bytes=1)))
+print(next(driver.download_object_range_as_stream(obj=obj, start_bytes=0,
end_bytes=2)))
+print(next(driver.download_object_range_as_stream(obj=obj, start_bytes=0,
end_bytes=3)))
+print(next(driver.download_object_range_as_stream(obj=obj, start_bytes=5,
end_bytes=8)))
+print(next(driver.download_object_range_as_stream(obj=obj, start_bytes=5)))
+
+print('====')
+sys.exit(1)
+
+driver = get_driver(Provider.LOCAL)('.')
+
+containers = driver.list_containers()
+container = containers[0]
+obj = driver.upload_object_via_stream(iterator=iterator, container=container,
object_name='test1.xlsm')
+print(driver.download_object_range(obj=obj, destination_path='3.obj',
start_bytes=0, end_bytes=6, overwrite_existing=True))
+sys.exit(1)
+print(next(driver.download_object_range_as_stream(obj=obj, start_bytes=0,
end_bytes=1)))
+print(next(driver.download_object_range_as_stream(obj=obj, start_bytes=0,
end_bytes=2)))
+print(next(driver.download_object_range_as_stream(obj=obj, start_bytes=5,
end_bytes=8)))
+print(next(driver.download_object_range_as_stream(obj=obj, start_bytes=5)))
+
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/apache-libcloud-2.8.0/libcloud/__init__.py
new/apache-libcloud-2.8.1/libcloud/__init__.py
--- old/apache-libcloud-2.8.0/libcloud/__init__.py 2019-12-23
18:51:49.000000000 +0100
+++ new/apache-libcloud-2.8.1/libcloud/__init__.py 2020-02-29
22:38:45.000000000 +0100
@@ -46,7 +46,7 @@
'enable_debug'
]
-__version__ = '2.8.0'
+__version__ = '2.8.1'
def enable_debug(fo):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/apache-libcloud-2.8.0/libcloud/common/gandi_live.py
new/apache-libcloud-2.8.1/libcloud/common/gandi_live.py
--- old/apache-libcloud-2.8.0/libcloud/common/gandi_live.py 2019-11-29
22:46:05.000000000 +0100
+++ new/apache-libcloud-2.8.1/libcloud/common/gandi_live.py 2020-02-29
22:24:24.000000000 +0100
@@ -139,13 +139,20 @@
valid_http_codes = [
httplib.OK,
httplib.CREATED,
- httplib.NO_CONTENT
]
if self.status in valid_http_codes:
if json_error:
raise JsonParseError(body, self.status)
else:
return body
+ elif self.status == httplib.NO_CONTENT:
+ # Parse error for empty body is acceptable, but a non-empty body
+ # is not.
+ if len(body) > 0:
+ msg = '"No Content" response contained content'
+ raise GandiLiveBaseError(msg, self.status)
+ else:
+ return {}
elif self.status == httplib.NOT_FOUND:
message = self._get_error(body, json_error)
raise ResourceNotFoundError(message, self.status)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/apache-libcloud-2.8.0/libcloud/compute/base.py
new/apache-libcloud-2.8.1/libcloud/compute/base.py
--- old/apache-libcloud-2.8.0/libcloud/compute/base.py 2019-12-21
22:34:46.000000000 +0100
+++ new/apache-libcloud-2.8.1/libcloud/compute/base.py 2020-02-29
21:56:39.000000000 +0100
@@ -350,7 +350,7 @@
disk, # type: int
bandwidth, # type: Optional[int]
price, # type: float
- driver, # type: Type[NodeDriver]
+ driver, # type: NodeDriver
extra=None # type: Optional[dict]
):
"""
@@ -421,7 +421,7 @@
def __init__(self,
id, # type: str
name, # type: str
- driver, # type: Type[NodeDriver]
+ driver, # type: NodeDriver
extra=None # type: Optional[dict]
):
"""
@@ -467,7 +467,7 @@
id, # type: str
image_id, # type: str
state, # type: NodeImageMemberState
- driver, # type: Type[NodeDriver]
+ driver, # type: NodeDriver
created=None, # type: datetime.datetime
extra=None # type: Optional[dict]
):
@@ -522,7 +522,7 @@
id, # type: str
name, # type: str
country, # type: str
- driver, # type: Type[NodeDriver]
+ driver, # type: NodeDriver
extra=None # type: Optional[dict]
):
"""
@@ -822,7 +822,7 @@
name = None # type: str
api_name = None # type: str
website = None # type: str
- type = None # type: Provider
+ type = None # type: Union[Provider,str]
port = None # type: int
features = {'create_node': []} # type: Dict[str, List[str]]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/apache-libcloud-2.8.0/libcloud/compute/drivers/ec2.py
new/apache-libcloud-2.8.1/libcloud/compute/drivers/ec2.py
--- old/apache-libcloud-2.8.0/libcloud/compute/drivers/ec2.py 2019-12-21
22:34:46.000000000 +0100
+++ new/apache-libcloud-2.8.1/libcloud/compute/drivers/ec2.py 2020-02-29
23:01:07.000000000 +0100
@@ -1954,7 +1954,7 @@
params['KeyName'] = ex_keyname
if ex_userdata:
- params['UserData'] = base64.b64encode(b('ex_userdata'))\
+ params['UserData'] = base64.b64encode(b(ex_userdata))\
.decode('utf-8')
if ex_clienttoken:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/apache-libcloud-2.8.0/libcloud/compute/drivers/gce.py
new/apache-libcloud-2.8.1/libcloud/compute/drivers/gce.py
--- old/apache-libcloud-2.8.0/libcloud/compute/drivers/gce.py 2019-12-21
22:34:46.000000000 +0100
+++ new/apache-libcloud-2.8.1/libcloud/compute/drivers/gce.py 2020-02-29
21:57:57.000000000 +0100
@@ -21,6 +21,7 @@
import datetime
import time
+import itertools
import sys
from libcloud.common.base import LazyObject
@@ -133,7 +134,7 @@
return response
- def request_aggregated_items(self, api_name):
+ def request_aggregated_items(self, api_name, zone=None):
"""
Perform request(s) to obtain all results from 'api_name'.
@@ -145,12 +146,19 @@
for valid names.
:type api_name: ``str``
+ :param zone: Optional zone to use.
+ :type zone: :class:`GCEZone`
+
:return: dict in the format of the API response.
format: { 'items': {'key': {api_name: []}} }
ex: { 'items': {'zones/us-central1-a': {disks: []}} }
:rtype: ``dict``
"""
- request_path = "/aggregated/%s" % api_name
+ if zone:
+ request_path = "/zones/%s/%s" % (zone.name, api_name)
+ else:
+ request_path = "/aggregated/%s" % (api_name)
+
api_responses = []
params = {'maxResults': 500}
@@ -159,6 +167,15 @@
self.gce_params = params
response = self.request(request_path, method='GET').object
if 'items' in response:
+ if zone:
+ # Special case when we are handling pagination for a
+ # specific zone
+ items = response['items']
+ response['items'] = {
+ 'zones/%s' % (zone): {
+ api_name: items
+ }
+ }
api_responses.append(response)
more_results = 'pageToken' in params
return self._merge_response_items(api_name, api_responses)
@@ -2569,50 +2586,39 @@
:return: List of Node objects
:rtype: ``list`` of :class:`Node`
"""
- list_nodes = []
zone = self._set_zone(ex_zone)
- if zone is None:
- request = '/aggregated/instances'
- else:
- request = '/zones/%s/instances' % (zone.name)
- response = self.connection.request(request, method='GET').object
+ response = self.connection.request_aggregated_items('instances',
+ zone=zone)
+
+ if not response.get('items', []):
+ return []
+
+ list_nodes = []
+
+ # The aggregated response returns a dict for each zone
+ # Create volume cache now for fast lookups of disk info.
+ self._ex_populate_volume_dict()
+
+ items = response['items'].values()
+ instances = [item.get('instances', []) for item in items]
+ instances = itertools.chain(*instances)
+
+ for instance in instances:
+ try:
+ node = self._to_node(instance,
+ use_disk_cache=ex_use_disk_cache)
+ except ResourceNotFoundError:
+ # If a GCE node has been deleted between
+ # - is was listed by `request('.../instances', 'GET')
+ # - it is converted by `self._to_node(i)`
+ # `_to_node()` will raise a ResourceNotFoundError.
+ #
+ # Just ignore that node and return the list of the
+ # other nodes.
+ continue
+
+ list_nodes.append(node)
- if 'items' in response:
- # The aggregated response returns a dict for each zone
- if zone is None:
- # Create volume cache now for fast lookups of disk info.
- self._ex_populate_volume_dict()
- for v in response['items'].values():
- for i in v.get('instances', []):
- try:
- list_nodes.append(
- self._to_node(i,
- use_disk_cache=ex_use_disk_cache)
- )
- # If a GCE node has been deleted between
- # - is was listed by `request('.../instances', 'GET')
- # - it is converted by `self._to_node(i)`
- # `_to_node()` will raise a ResourceNotFoundError.
- #
- # Just ignore that node and return the list of the
- # other nodes.
- except ResourceNotFoundError:
- pass
- else:
- for i in response['items']:
- try:
- list_nodes.append(
- self._to_node(i, use_disk_cache=ex_use_disk_cache)
- )
- # If a GCE node has been deleted between
- # - is was listed by `request('.../instances', 'GET')
- # - it is converted by `self._to_node(i)`
- # `_to_node()` will raise a ResourceNotFoundError.
- #
- # Just ignore that node and return the list of the
- # other nodes.
- except ResourceNotFoundError:
- pass
# Clear the volume cache as lookups are complete.
self._ex_volume_dict = {}
return list_nodes
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/apache-libcloud-2.8.0/libcloud/compute/drivers/openstack.py
new/apache-libcloud-2.8.1/libcloud/compute/drivers/openstack.py
--- old/apache-libcloud-2.8.0/libcloud/compute/drivers/openstack.py
2019-12-21 22:34:46.000000000 +0100
+++ new/apache-libcloud-2.8.1/libcloud/compute/drivers/openstack.py
2020-02-29 21:56:42.000000000 +0100
@@ -3927,8 +3927,8 @@
port.extra["mac_address"]}
if 'port_details' in obj and obj['port_details']:
- if obj['port_details']['device_owner'] in ['compute:nova',
- 'compute:None']:
+ dev_owner = obj['port_details']['device_owner']
+ if dev_owner and dev_owner.startswith("compute:"):
instance_id = obj['port_details']['device_id']
ip_address = obj['floating_ip_address']
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/apache-libcloud-2.8.0/libcloud/dns/drivers/cloudflare.py
new/apache-libcloud-2.8.1/libcloud/dns/drivers/cloudflare.py
--- old/apache-libcloud-2.8.0/libcloud/dns/drivers/cloudflare.py
2019-11-29 22:46:05.000000000 +0100
+++ new/apache-libcloud-2.8.1/libcloud/dns/drivers/cloudflare.py
2020-02-29 21:53:25.000000000 +0100
@@ -74,6 +74,7 @@
'created_on',
'modified_on',
'data',
+ 'priority'
}
RECORD_CREATE_ATTRIBUTES = {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/apache-libcloud-2.8.0/libcloud/storage/base.py
new/apache-libcloud-2.8.1/libcloud/storage/base.py
--- old/apache-libcloud-2.8.0/libcloud/storage/base.py 2019-12-18
22:26:03.000000000 +0100
+++ new/apache-libcloud-2.8.1/libcloud/storage/base.py 2020-02-29
21:52:41.000000000 +0100
@@ -24,6 +24,7 @@
import os.path # pylint: disable-msg=W0404
import hashlib
+import errno
from os.path import join as pjoin
from libcloud.utils.py3 import httplib
@@ -653,7 +654,20 @@
# Ensure we start from the begining of a stream in case stream is
# not at the beginning
if hasattr(stream, 'seek'):
- stream.seek(0)
+ try:
+ stream.seek(0)
+ except OSError as e:
+ if e.errno != errno.ESPIPE:
+ # This represents "OSError: [Errno 29] Illegal seek"
+ # error. This could either mean that the underlying
+ # handle doesn't support seek operation (e.g. pipe) or
+ # that the invalid seek position is provided. Sadly
+ # there is no good robust way to distinghuish that so
+ # we simply ignore all the "Illeal seek" errors so
+ # this function works correctly with pipes.
+ # See https://github.com/apache/libcloud/pull/1427 for
+ # details
+ raise e
for chunk in libcloud.utils.files.read_in_chunks(iterator=stream):
hasher.update(b(chunk))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/apache-libcloud-2.8.0/libcloud/storage/drivers/google_storage.py
new/apache-libcloud-2.8.1/libcloud/storage/drivers/google_storage.py
--- old/apache-libcloud-2.8.0/libcloud/storage/drivers/google_storage.py
2019-09-09 18:10:00.000000000 +0200
+++ new/apache-libcloud-2.8.1/libcloud/storage/drivers/google_storage.py
2020-02-29 21:50:42.000000000 +0100
@@ -119,7 +119,9 @@
# Lowercase all headers except 'date' and Google header values
for k, v in headers.items():
k_lower = k.lower()
- if (k_lower == 'date' or k_lower.startswith(
+ # NOTE: It's important that the value of Content-Type header is
+ # left as is and not lowercased
+ if (k_lower in ['date', 'content-type'] or k_lower.startswith(
GoogleStorageDriver.http_vendor_prefix) or
not isinstance(v, str)):
headers_copy[k_lower] = v
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/apache-libcloud-2.8.0/libcloud/storage/drivers/s3.py
new/apache-libcloud-2.8.1/libcloud/storage/drivers/s3.py
--- old/apache-libcloud-2.8.0/libcloud/storage/drivers/s3.py 2019-12-21
22:34:46.000000000 +0100
+++ new/apache-libcloud-2.8.1/libcloud/storage/drivers/s3.py 2020-02-29
21:58:56.000000000 +0100
@@ -846,8 +846,18 @@
headers = response.headers
response = response
server_hash = headers.get('etag', '').replace('"', '')
+ server_side_encryption = headers.get('x-amz-server-side-encryption',
+ None)
+ aws_kms_encryption = (server_side_encryption == 'aws:kms')
+ hash_matches = (result_dict['data_hash'] == server_hash)
- if (verify_hash and result_dict['data_hash'] != server_hash):
+ # NOTE: If AWS KMS server side encryption is enabled, ETag won't
+ # contain object MD5 digest so we skip the checksum check
+ # See https://docs.aws.amazon.com/AmazonS3/latest/API
+ # /RESTCommonResponseHeaders.html
+ # and https://github.com/apache/libcloud/issues/1401
+ # for details
+ if verify_hash and not aws_kms_encryption and not hash_matches:
raise ObjectHashMismatchError(
value='MD5 hash {0} checksum does not match {1}'.format(
server_hash, result_dict['data_hash']),
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/apache-libcloud-2.8.0/libcloud/test/compute/fixtures/openstack_v1.1/_v2_0__floatingips.json
new/apache-libcloud-2.8.1/libcloud/test/compute/fixtures/openstack_v1.1/_v2_0__floatingips.json
---
old/apache-libcloud-2.8.0/libcloud/test/compute/fixtures/openstack_v1.1/_v2_0__floatingips.json
2019-11-29 22:46:05.000000000 +0100
+++
new/apache-libcloud-2.8.1/libcloud/test/compute/fixtures/openstack_v1.1/_v2_0__floatingips.json
2020-02-29 21:56:42.000000000 +0100
@@ -75,6 +75,34 @@
},
"tags": ["tag3"],
"port_forwardings": []
+ },
+ {
+ "router_id": "d23abc8d-2991-4a55-ba98-2aaea84cc72f",
+ "description": "for test",
+ "dns_domain": "my-domain.org.",
+ "dns_name": "myfip",
+ "created_at": "2016-12-21T10:55:50Z",
+ "updated_at": "2016-12-21T10:55:53Z",
+ "revision_number": 1,
+ "project_id": "4969c491a3c74ee4af974e6d800c62de",
+ "tenant_id": "4969c491a3c74ee4af974e6d800c62de",
+ "floating_network_id": "376da547-b977-4cfe-9cba-275c80debf57",
+ "fixed_ip_address": "10.0.0.4",
+ "floating_ip_address": "10.3.1.3",
+ "port_id": "ce705c24-c1ef-408a-bda3-7bbd946164ab",
+ "id": "123c5336a-0629-4694-ba30-04b0bdfa88a4",
+ "status": "ACTIVE",
+ "port_details": {
+ "status": "ACTIVE",
+ "name": "",
+ "admin_state_up": true,
+ "network_id": "02dd8479-ef26-4398-a102-d19d0a7b3a1f",
+ "device_owner": "compute:region",
+ "mac_address": "fa:16:3e:b1:3b:30",
+ "device_id": "cb4fba64-19e2-40fd-8497-f29da1b21143"
+ },
+ "tags": ["tag3"],
+ "port_forwardings": []
}
]
}
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/apache-libcloud-2.8.0/libcloud/test/compute/test_ec2.py
new/apache-libcloud-2.8.1/libcloud/test/compute/test_ec2.py
--- old/apache-libcloud-2.8.0/libcloud/test/compute/test_ec2.py 2019-12-21
22:34:46.000000000 +0100
+++ new/apache-libcloud-2.8.1/libcloud/test/compute/test_ec2.py 2020-02-29
23:01:36.000000000 +0100
@@ -19,10 +19,13 @@
import os
import sys
+import base64
from datetime import datetime
from libcloud.utils.iso8601 import UTC
from libcloud.utils.py3 import httplib
+from libcloud.utils.py3 import parse_qs
+from libcloud.utils.py3 import b
from libcloud.compute.drivers.ec2 import EC2NodeDriver
from libcloud.compute.drivers.ec2 import EC2PlacementGroup
@@ -1359,7 +1362,7 @@
region = 'sa-east-1'
-class EC2MockHttp(MockHttp):
+class EC2MockHttp(MockHttp, unittest.TestCase):
fixtures = ComputeFileFixtures('ec2')
def _DescribeInstances(self, method, url, body, headers):
@@ -1426,6 +1429,17 @@
body = self.fixtures.load('run_instances.xml')
return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+ def _ex_user_data_RunInstances(self, method, url, body, headers):
+ # test_create_node_with_ex_userdata
+ params = parse_qs(url.replace('/?', ''))
+
+ self.assertTrue('UserData' in params)
+ user_data = base64.b64decode(b(params['UserData'][0])).decode('utf-8')
+ self.assertEqual(user_data, 'foo\nbar\foo')
+
+ body = self.fixtures.load('run_instances.xml')
+ return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
def _create_ex_assign_public_ip_RunInstances(self, method, url, body,
headers):
self.assertUrlContainsQueryParams(url, {
'NetworkInterface.1.AssociatePublicIpAddress': "true",
@@ -2004,6 +2018,19 @@
image=image, size=size,
ex_iamprofile='foo')
+ def test_create_node_with_ex_userdata(self):
+ EC2MockHttp.type = 'ex_user_data'
+
+ image = NodeImage(id='ami-be3adfd7',
+ name=self.image_name,
+ driver=self.driver)
+ size = NodeSize('m1.small', 'Small Instance', None, None, None, None,
+ driver=self.driver)
+
+ result = self.driver.create_node(name='foo', image=image, size=size,
+ ex_userdata='foo\nbar\foo')
+ self.assertTrue(result)
+
class FCUMockHttp(EC2MockHttp):
fixtures = ComputeFileFixtures('fcu')
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/apache-libcloud-2.8.0/libcloud/test/compute/test_gce.py
new/apache-libcloud-2.8.1/libcloud/test/compute/test_gce.py
--- old/apache-libcloud-2.8.0/libcloud/test/compute/test_gce.py 2019-12-21
22:34:46.000000000 +0100
+++ new/apache-libcloud-2.8.1/libcloud/test/compute/test_gce.py 2020-02-29
21:57:57.000000000 +0100
@@ -635,9 +635,11 @@
nodes = self.driver.list_nodes()
nodes_all = self.driver.list_nodes(ex_zone='all')
nodes_uc1a = self.driver.list_nodes(ex_zone='us-central1-a')
+ nodes_uc1b = self.driver.list_nodes(ex_zone='us-central1-b')
self.assertEqual(len(nodes), 1)
self.assertEqual(len(nodes_all), 8)
self.assertEqual(len(nodes_uc1a), 1)
+ self.assertEqual(len(nodes_uc1b), 0)
self.assertEqual(nodes[0].name, 'node-name')
self.assertEqual(nodes_uc1a[0].name, 'node-name')
self.assertEqual(nodes_uc1a[0].extra['cpuPlatform'], 'Intel Skylake')
@@ -3502,6 +3504,11 @@
body = self.fixtures.load('zones_europe-west1-a_instances.json')
return (httplib.OK, body, self.json_hdr, httplib.responses[httplib.OK])
+ def _zones_us_central1_b_instances(self, method, url, body, headers):
+ if method == 'GET':
+ body = '{}'
+ return (httplib.OK, body, self.json_hdr, httplib.responses[httplib.OK])
+
def _zones_europe_west1_a_diskTypes_pd_standard(self, method, url, body,
headers):
body = self.fixtures.load(
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/apache-libcloud-2.8.0/libcloud/test/compute/test_openstack.py
new/apache-libcloud-2.8.1/libcloud/test/compute/test_openstack.py
--- old/apache-libcloud-2.8.0/libcloud/test/compute/test_openstack.py
2019-12-21 22:34:46.000000000 +0100
+++ new/apache-libcloud-2.8.1/libcloud/test/compute/test_openstack.py
2020-02-29 21:56:42.000000000 +0100
@@ -1442,6 +1442,11 @@
self.assertEqual(ret[2].ip_address, '10.3.1.2')
self.assertEqual(
ret[2].node_id, 'cb4fba64-19e2-40fd-8497-f29da1b21143')
+ self.assertEqual(ret[3].id, '123c5336a-0629-4694-ba30-04b0bdfa88a4')
+ self.assertEqual(ret[3].pool, pool)
+ self.assertEqual(ret[3].ip_address, '10.3.1.3')
+ self.assertEqual(
+ ret[3].node_id, 'cb4fba64-19e2-40fd-8497-f29da1b21143')
def test_OpenStack_2_FloatingIpPool_get_floating_ip(self):
pool = OpenStack_2_FloatingIpPool(1, 'foo', self.driver.connection)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/apache-libcloud-2.8.0/libcloud/test/dns/fixtures/cloudflare/records_GET_1.json
new/apache-libcloud-2.8.1/libcloud/test/dns/fixtures/cloudflare/records_GET_1.json
---
old/apache-libcloud-2.8.0/libcloud/test/dns/fixtures/cloudflare/records_GET_1.json
2019-11-29 22:46:05.000000000 +0100
+++
new/apache-libcloud-2.8.1/libcloud/test/dns/fixtures/cloudflare/records_GET_1.json
2020-02-29 21:53:25.000000000 +0100
@@ -94,6 +94,26 @@
"managed_by_apps": false,
"managed_by_argo_tunnel": false
}
+ },
+ {
+ "content": "aspmx3.googlemail.com",
+ "created_on": "2015-09-04T23:06:50.625895Z",
+ "id": "78526",
+ "locked": false,
+ "meta": {
+ "auto_added": true,
+ "managed_by_apps": false,
+ "managed_by_argo_tunnel": false
+ },
+ "modified_on": "2015-09-04T23:06:50.625895Z",
+ "name": "foo.bar",
+ "priority": 30,
+ "proxiable": false,
+ "proxied": false,
+ "ttl": 1,
+ "type": "MX",
+ "zone_id": "1234",
+ "zone_name": "foo.bar"
}
],
"result_info": {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/apache-libcloud-2.8.0/libcloud/test/dns/fixtures/gandi_live/delete_gandi_zone.json
new/apache-libcloud-2.8.1/libcloud/test/dns/fixtures/gandi_live/delete_gandi_zone.json
---
old/apache-libcloud-2.8.0/libcloud/test/dns/fixtures/gandi_live/delete_gandi_zone.json
2019-11-29 22:46:05.000000000 +0100
+++
new/apache-libcloud-2.8.1/libcloud/test/dns/fixtures/gandi_live/delete_gandi_zone.json
1970-01-01 01:00:00.000000000 +0100
@@ -1,3 +0,0 @@
-{
- "message": "Zone deleted"
-}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/apache-libcloud-2.8.0/libcloud/test/dns/fixtures/gandi_live/delete_record.json
new/apache-libcloud-2.8.1/libcloud/test/dns/fixtures/gandi_live/delete_record.json
---
old/apache-libcloud-2.8.0/libcloud/test/dns/fixtures/gandi_live/delete_record.json
2019-11-29 22:46:05.000000000 +0100
+++
new/apache-libcloud-2.8.1/libcloud/test/dns/fixtures/gandi_live/delete_record.json
1970-01-01 01:00:00.000000000 +0100
@@ -1,3 +0,0 @@
-{
- "message": "Zone Record Deleted"
-}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/apache-libcloud-2.8.0/libcloud/test/dns/test_cloudflare.py
new/apache-libcloud-2.8.1/libcloud/test/dns/test_cloudflare.py
--- old/apache-libcloud-2.8.0/libcloud/test/dns/test_cloudflare.py
2019-11-29 22:46:05.000000000 +0100
+++ new/apache-libcloud-2.8.1/libcloud/test/dns/test_cloudflare.py
2020-02-29 21:53:25.000000000 +0100
@@ -76,13 +76,14 @@
def test_list_records(self):
zone = self.driver.list_zones()[0]
records = self.driver.list_records(zone=zone)
- self.assertEqual(len(records), 9)
+ self.assertEqual(len(records), 10)
record = records[0]
self.assertEqual(record.id, '364797364')
self.assertIsNone(record.name)
self.assertEqual(record.type, 'A')
self.assertEqual(record.data, '192.30.252.153')
+ self.assertEqual(record.extra['priority'], None)
for attribute_name in RECORD_EXTRA_ATTRIBUTES:
self.assertTrue(attribute_name in record.extra)
@@ -96,6 +97,13 @@
for attribute_name in RECORD_EXTRA_ATTRIBUTES:
self.assertTrue(attribute_name in record.extra)
+ record = [r for r in records if r.type == 'MX'][0]
+ self.assertEqual(record.id, '78526')
+ self.assertIsNone(record.name)
+ self.assertEqual(record.type, 'MX')
+ self.assertEqual(record.data, 'aspmx3.googlemail.com')
+ self.assertEqual(record.extra['priority'], 30)
+
def test_get_zone(self):
zone = self.driver.get_zone(zone_id='1234')
self.assertEqual(zone.id, '1234')
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/apache-libcloud-2.8.0/libcloud/test/dns/test_gandi_live.py
new/apache-libcloud-2.8.1/libcloud/test/dns/test_gandi_live.py
--- old/apache-libcloud-2.8.0/libcloud/test/dns/test_gandi_live.py
2019-11-29 22:46:05.000000000 +0100
+++ new/apache-libcloud-2.8.1/libcloud/test/dns/test_gandi_live.py
2020-02-29 22:24:24.000000000 +0100
@@ -269,8 +269,7 @@
return (httplib.OK, body, {}, httplib.responses[httplib.OK])
def _json_api_v5_zones_111111_delete(self, method, url, body, headers):
- body = self.fixtures.load('delete_gandi_zone.json')
- return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+ return (httplib.NO_CONTENT, '', {}, httplib.responses[httplib.OK])
def _json_api_v5_domains_example_org_patch(self, method, url, body,
headers):
@@ -347,8 +346,7 @@
def _json_api_v5_domains_example_com_records_bob_A_delete(self, method,
url, body,
headers):
- body = self.fixtures.load('delete_record.json')
- return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+ return (httplib.NO_CONTENT, '', {}, httplib.responses[httplib.OK])
if __name__ == '__main__':
sys.exit(unittest.main())
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/apache-libcloud-2.8.0/libcloud/test/storage/test_base.py
new/apache-libcloud-2.8.1/libcloud/test/storage/test_base.py
--- old/apache-libcloud-2.8.0/libcloud/test/storage/test_base.py
2019-12-18 22:26:03.000000000 +0100
+++ new/apache-libcloud-2.8.1/libcloud/test/storage/test_base.py
2020-02-29 22:48:43.000000000 +0100
@@ -14,6 +14,7 @@
# limitations under the License.
import sys
+import errno
import hashlib
from libcloud.utils.py3 import httplib
@@ -96,7 +97,6 @@
response_streamed = mock_response.request.stream
assert response_streamed is False
-
def test__get_hash_function(self):
self.driver1.hash_type = 'md5'
func = self.driver1._get_hash_function()
@@ -152,7 +152,8 @@
def test_upload_object_hash_calculation_is_efficient(self,
mock_read_in_chunks,
mock_exhaust_iterator):
# Verify that we don't buffer whole file in memory when calculating
- # object has when iterator has __next__ method, but instead read and
calculate hash in chunks
+ # object has when iterator has __next__ method, but instead read and
+ # calculate hash in chunks
size = 100
self.driver1.connection = Mock()
@@ -228,6 +229,47 @@
self.assertEqual(mock_read_in_chunks.call_count, 2)
self.assertEqual(mock_exhaust_iterator.call_count, 0)
+ def test_upload_object_via_stream_illegal_seek_errors_are_ignored(self):
+ # Illegal seek errors should be ignored
+ size = 100
+
+ self.driver1.connection = Mock()
+
+ seek_error = OSError('Illegal seek')
+ seek_error.errno = 29
+ assert errno.ESPIPE == 29
+
+ iterator = BodyStream('a' * size)
+ iterator.seek = mock.Mock(side_effect=seek_error)
+
+ result = self.driver1._upload_object(object_name='test1',
+ content_type=None,
+ request_path='/',
+ stream=iterator)
+
+ hasher = hashlib.md5()
+ hasher.update(b('a') * size)
+ expected_hash = hasher.hexdigest()
+
+ self.assertEqual(result['data_hash'], expected_hash)
+ self.assertEqual(result['bytes_transferred'], size)
+
+ # But others shouldn't
+ self.driver1.connection = Mock()
+
+ seek_error = OSError('Other error')
+ seek_error.errno = 21
+
+ iterator = BodyStream('b' * size)
+ iterator.seek = mock.Mock(side_effect=seek_error)
+
+ assertRaisesRegex(self, OSError, 'Other error',
+ self.driver1._upload_object,
+ object_name='test1',
+ content_type=None,
+ request_path='/',
+ stream=iterator)
+
if __name__ == '__main__':
sys.exit(unittest.main())
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/apache-libcloud-2.8.0/libcloud/test/storage/test_google_storage.py
new/apache-libcloud-2.8.1/libcloud/test/storage/test_google_storage.py
--- old/apache-libcloud-2.8.0/libcloud/test/storage/test_google_storage.py
2019-09-09 18:10:00.000000000 +0200
+++ new/apache-libcloud-2.8.1/libcloud/test/storage/test_google_storage.py
2020-02-29 21:50:42.000000000 +0100
@@ -235,10 +235,12 @@
'Date': TODAY,
'x-goog-foo': 'X-GOOG: MAINTAIN UPPERCASE!',
'x-Goog-bar': 'Header key should be lowered',
+ 'Content-Type': 'application/mIXED casING MAINTAINED',
'Other': 'LOWER THIS!'
}
modified_headers = {
'date': TODAY,
+ 'content-type': 'application/mIXED casING MAINTAINED',
'x-goog-foo': 'X-GOOG: MAINTAIN UPPERCASE!',
'x-goog-bar': 'Header key should be lowered',
'other': 'lower this!'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/apache-libcloud-2.8.0/libcloud/test/storage/test_s3.py
new/apache-libcloud-2.8.1/libcloud/test/storage/test_s3.py
--- old/apache-libcloud-2.8.0/libcloud/test/storage/test_s3.py 2019-12-21
22:34:46.000000000 +0100
+++ new/apache-libcloud-2.8.1/libcloud/test/storage/test_s3.py 2020-02-29
21:58:56.000000000 +0100
@@ -335,27 +335,6 @@
headers,
httplib.responses[httplib.OK])
- def _foo_bar_container_foo_test_upload_INVALID_HASH1(self, method, url,
- body, headers):
- body = ''
- headers = {}
- headers['etag'] = '"foobar"'
- # test_upload_object_invalid_hash1
- return (httplib.OK,
- body,
- headers,
- httplib.responses[httplib.OK])
-
- def _foo_bar_container_foo_test_upload_INVALID_HASH2(self, method, url,
- body, headers):
- # test_upload_object_invalid_hash2
- body = ''
- headers = {'etag': '"hash343hhash89h932439jsaa89"'}
- return (httplib.OK,
- body,
- headers,
- httplib.responses[httplib.OK])
-
def _foo_bar_container_foo_test_upload(self, method, url, body, headers):
# test_upload_object_success
body = ''
@@ -772,12 +751,11 @@
def upload_file(self, object_name=None, content_type=None,
request_path=None, request_method=None,
headers=None, file_path=None, stream=None):
- return {'response': make_response(200),
+ headers = {'etag': '"foobar"'}
+ return {'response': make_response(200, headers=headers),
'bytes_transferred': 1000,
'data_hash': 'hash343hhash89h932439jsaa89'}
- self.mock_response_klass.type = 'INVALID_HASH1'
-
old_func = self.driver_type._upload_object
self.driver_type._upload_object = upload_file
file_path = os.path.abspath(__file__)
@@ -802,12 +780,11 @@
def upload_file(self, object_name=None, content_type=None,
request_path=None, request_method=None,
headers=None, file_path=None, stream=None):
- return {'response': make_response(200, headers={'etag':
'woopwoopwoop'}),
+ headers = {'etag': '"hash343hhash89h932439jsaa89"'}
+ return {'response': make_response(200, headers=headers),
'bytes_transferred': 1000,
'data_hash': '0cc175b9c0f1b6a831c399e269772661'}
- self.mock_response_klass.type = 'INVALID_HASH2'
-
old_func = self.driver_type._upload_object
self.driver_type._upload_object = upload_file
@@ -827,6 +804,31 @@
finally:
self.driver_type._upload_object = old_func
+ def test_upload_object_invalid_hash_kms_encryption(self):
+ # Hash check should be skipped when AWS KMS server side encryption is
+ # used
+ def upload_file(self, object_name=None, content_type=None,
+ request_path=None, request_method=None,
+ headers=None, file_path=None, stream=None):
+ headers = {'etag': 'blahblah', 'x-amz-server-side-encryption':
'aws:kms'}
+ return {'response': make_response(200, headers=headers),
+ 'bytes_transferred': 1000,
+ 'data_hash': 'hash343hhash89h932439jsaa81'}
+
+ old_func = self.driver_type._upload_object
+ self.driver_type._upload_object = upload_file
+ file_path = os.path.abspath(__file__)
+ container = Container(name='foo_bar_container', extra={},
+ driver=self.driver)
+ object_name = 'foo_test_upload'
+ try:
+ self.driver.upload_object(file_path=file_path, container=container,
+ object_name=object_name,
+ verify_hash=True)
+ finally:
+ self.driver_type._upload_object = old_func
+
+
def test_upload_object_success(self):
def upload_file(self, object_name=None, content_type=None,
request_path=None, request_method=None,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/apache-libcloud-2.8.0/libcloud/test/test_logging_connection.py
new/apache-libcloud-2.8.1/libcloud/test/test_logging_connection.py
--- old/apache-libcloud-2.8.0/libcloud/test/test_logging_connection.py
2019-09-09 18:10:00.000000000 +0200
+++ new/apache-libcloud-2.8.1/libcloud/test/test_logging_connection.py
2020-02-29 22:33:43.000000000 +0100
@@ -13,20 +13,69 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+import os
import sys
from io import StringIO
import zlib
import requests_mock
+import mock
+
import libcloud
+from libcloud.utils.py3 import PY3
from libcloud.test import unittest
from libcloud.common.base import Connection
from libcloud.http import LibcloudConnection
from libcloud.utils.loggingconnection import LoggingConnection
+EXPECTED_DATA_JSON = """
+HTTP/1.1 200 OK
+Content-Type: application/json
+
+{"foo": "bar!"}
+""".strip()
+
+EXPECTED_DATA_JSON_PRETTY = """
+HTTP/1.1 200 OK
+Content-Type: application/json
+
+{
+ "foo": "bar!"
+}
+""".strip()
+
+EXPECTED_DATA_XML = """
+HTTP/1.1 200 OK
+Content-Type: text/xml
+
+<foo><bar /></foo>
+""".strip()
+
+EXPECTED_DATA_XML_PRETTY_1 = """
+HTTP/1.1 200 OK
+Content-Type: application/xml
+
+<foo><bar /></foo>
+""".strip()
+
+EXPECTED_DATA_XML_PRETTY_2 = """
+HTTP/1.1 200 OK
+Content-Type: application/xml
+
+<?xml version="1.0" ?>
+<foo>
+ <bar/>
+</foo>
+""".strip()
+
class TestLoggingConnection(unittest.TestCase):
+ def setUp(self):
+ super(TestLoggingConnection, self).setUp()
+ self._reset_environ()
+
def tearDown(self):
+ super(TestLoggingConnection, self).tearDown()
Connection.conn_class = LibcloudConnection
def test_debug_method_uses_log_class(self):
@@ -65,5 +114,67 @@
self.assertTrue(isinstance(conn.connection, LoggingConnection))
self.assertIn('-i -X GET', log)
+ def test_log_response_json_content_type(self):
+ conn = LoggingConnection(host='example.com', port=80)
+
+ r = self._get_mock_response('application/json', '{"foo": "bar!"}')
+ result = conn._log_response(r).replace('\r', '')
+ self.assertTrue(EXPECTED_DATA_JSON in result)
+
+ def test_log_response_xml_content_type(self):
+ conn = LoggingConnection(host='example.com', port=80)
+
+ r = self._get_mock_response('text/xml', '<foo><bar /></foo>')
+ result = conn._log_response(r).replace('\r', '')
+ self.assertTrue(EXPECTED_DATA_XML in result)
+
+ def test_log_response_with_pretty_print_json_content_type(self):
+ os.environ['LIBCLOUD_DEBUG_PRETTY_PRINT_RESPONSE'] = '1'
+
+ conn = LoggingConnection(host='example.com', port=80)
+
+ # body type is unicode
+ r = self._get_mock_response('application/json', u'{"foo": "bar!"}')
+ result = conn._log_response(r).replace('\r', '')
+ self.assertTrue(EXPECTED_DATA_JSON_PRETTY in result)
+
+ # body type is bytes
+ if PY3:
+ data = bytes('{"foo": "bar!"}', 'utf-8')
+ else:
+ data = bytes('{"foo": "bar!"}')
+ r = self._get_mock_response('application/json', data)
+ result = conn._log_response(r).replace('\r', '')
+ self.assertTrue(EXPECTED_DATA_JSON_PRETTY in result)
+
+ def test_log_response_with_pretty_print_xml_content_type(self):
+ os.environ['LIBCLOUD_DEBUG_PRETTY_PRINT_RESPONSE'] = '1'
+
+ conn = LoggingConnection(host='example.com', port=80)
+
+ r = self._get_mock_response('application/xml', '<foo><bar /></foo>')
+ result = conn._log_response(r).replace('\r', '')
+ self.assertTrue(EXPECTED_DATA_XML_PRETTY_1 in result or
+ EXPECTED_DATA_XML_PRETTY_2 in result)
+
+ def _reset_environ(self):
+ if 'LIBCLOUD_DEBUG_PRETTY_PRINT_RESPONSE' in os.environ:
+ del os.environ['LIBCLOUD_DEBUG_PRETTY_PRINT_RESPONSE']
+
+ def _get_mock_response(self, content_type, body):
+ header = mock.Mock()
+ header.title.return_value = 'Content-Type'
+ header.lower.return_value = 'content-type'
+
+ r = mock.Mock()
+ r.version = 11
+ r.status = '200'
+ r.reason = 'OK'
+ r.getheaders.return_value = [(header, content_type)]
+ r.read.return_value = body
+
+ return r
+
+
if __name__ == '__main__':
sys.exit(unittest.main())
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/apache-libcloud-2.8.0/libcloud/utils/loggingconnection.py
new/apache-libcloud-2.8.1/libcloud/utils/loggingconnection.py
--- old/apache-libcloud-2.8.0/libcloud/utils/loggingconnection.py
2019-12-18 22:26:03.000000000 +0100
+++ new/apache-libcloud-2.8.1/libcloud/utils/loggingconnection.py
2020-02-29 22:35:26.000000000 +0100
@@ -28,6 +28,7 @@
from libcloud.common.base import (LibcloudConnection,
HttpLibResponseProxy)
from libcloud.utils.py3 import _real_unicode as u
+from libcloud.utils.py3 import ensure_text
from libcloud.utils.misc import lowercase_keys
@@ -68,12 +69,12 @@
if pretty_print and content_type == 'application/json':
try:
- body = json.loads(body.decode('utf-8'))
+ body = json.loads(ensure_text(body))
body = json.dumps(body, sort_keys=True, indent=4)
except Exception:
# Invalid JSON or server is lying about content-type
pass
- elif pretty_print and content_type == 'text/xml':
+ elif pretty_print and content_type in ['text/xml', 'application/xml']:
try:
elem = parseString(body.decode('utf-8'))
body = elem.toprettyxml()
@@ -81,7 +82,7 @@
# Invalid XML
pass
- ht += u(body)
+ ht += ensure_text(body)
rv += ht
rv += ("\n# -------- end %d:%d response ----------\n"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/apache-libcloud-2.8.0/libcloud/utils/py3.py
new/apache-libcloud-2.8.1/libcloud/utils/py3.py
--- old/apache-libcloud-2.8.0/libcloud/utils/py3.py 2019-12-23
14:59:18.000000000 +0100
+++ new/apache-libcloud-2.8.1/libcloud/utils/py3.py 2020-02-29
22:35:52.000000000 +0100
@@ -112,6 +112,8 @@
else:
raise TypeError("Invalid argument %r for ensure_string()" % (s,))
+ ensure_text = ensure_string
+
def byte(n):
# assume n is a Latin-1 string of length 1
return ord(n)
@@ -187,6 +189,14 @@
b = bytes = ensure_string = str
+ def ensure_text(s):
+ if isinstance(s, _real_unicode):
+ return s
+ elif isinstance(s, (str, bytes)):
+ return s.decode('utf-8')
+ else:
+ raise TypeError("Invalid argument %r for ensure_text()" % (s,))
+
def byte(n):
return n
++++++ ec2_create_node.patch ++++++
--- /var/tmp/diff_new_pack.og3aAF/_old 2020-03-08 22:22:41.924024199 +0100
+++ /var/tmp/diff_new_pack.og3aAF/_new 2020-03-08 22:22:41.924024199 +0100
@@ -1,7 +1,7 @@
-Index: apache-libcloud-2.8.0/libcloud/compute/drivers/ec2.py
+Index: apache-libcloud-2.8.1/libcloud/compute/drivers/ec2.py
===================================================================
---- apache-libcloud-2.8.0.orig/libcloud/compute/drivers/ec2.py
-+++ apache-libcloud-2.8.0/libcloud/compute/drivers/ec2.py
+--- apache-libcloud-2.8.1.orig/libcloud/compute/drivers/ec2.py
++++ apache-libcloud-2.8.1/libcloud/compute/drivers/ec2.py
@@ -1892,12 +1892,18 @@ class BaseEC2NodeDriver(NodeDriver):
for system shutdown.
:type ex_terminate_on_shutdown: ``bool``
++++++ gce_image_projects.patch ++++++
--- /var/tmp/diff_new_pack.og3aAF/_old 2020-03-08 22:22:41.932024204 +0100
+++ /var/tmp/diff_new_pack.og3aAF/_new 2020-03-08 22:22:41.932024204 +0100
@@ -1,7 +1,7 @@
-Index: apache-libcloud-2.8.0/libcloud/compute/drivers/gce.py
+Index: apache-libcloud-2.8.1/libcloud/compute/drivers/gce.py
===================================================================
---- apache-libcloud-2.8.0.orig/libcloud/compute/drivers/gce.py
-+++ apache-libcloud-2.8.0/libcloud/compute/drivers/gce.py
+--- apache-libcloud-2.8.1.orig/libcloud/compute/drivers/gce.py
++++ apache-libcloud-2.8.1/libcloud/compute/drivers/gce.py
@@ -1803,20 +1803,35 @@ class GCENodeDriver(NodeDriver):
"rhel-8",
],