diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000000..8820ed6b99 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,3 @@ +# generated from manifests external_dependencies +boto3<=1.15.18 +vcrpy-unittest diff --git a/setup/storage_backend_s3/odoo/addons/storage_backend_s3 b/setup/storage_backend_s3/odoo/addons/storage_backend_s3 new file mode 120000 index 0000000000..ec8c7ff362 --- /dev/null +++ b/setup/storage_backend_s3/odoo/addons/storage_backend_s3 @@ -0,0 +1 @@ +../../../../storage_backend_s3 \ No newline at end of file diff --git a/setup/storage_backend_s3/setup.py b/setup/storage_backend_s3/setup.py new file mode 100644 index 0000000000..28c57bb640 --- /dev/null +++ b/setup/storage_backend_s3/setup.py @@ -0,0 +1,6 @@ +import setuptools + +setuptools.setup( + setup_requires=['setuptools-odoo'], + odoo_addon=True, +) diff --git a/storage_backend_s3/README.rst b/storage_backend_s3/README.rst new file mode 100644 index 0000000000..0288170990 --- /dev/null +++ b/storage_backend_s3/README.rst @@ -0,0 +1,80 @@ +================== +Storage Backend S3 +================== + +.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png + :target: https://odoo-community.org/page/development-status + :alt: Beta +.. |badge2| image:: https://img.shields.io/badge/licence-LGPL--3-blue.png + :target: http://www.gnu.org/licenses/lgpl-3.0-standalone.html + :alt: License: LGPL-3 +.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fstorage-lightgray.png?logo=github + :target: https://github.com/OCA/storage/tree/15.0/storage_backend_s3 + :alt: OCA/storage +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/storage-15-0/storage-15-0-storage_backend_s3 + :alt: Translate me on Weblate +.. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png + :target: https://runbot.odoo-community.org/runbot/275/15.0 + :alt: Try me on Runbot + +|badge1| |badge2| |badge3| |badge4| |badge5| + +Add the possibility to store and get data from amazon S3 for your storage backend + +**Table of contents** + +.. contents:: + :local: + +Known issues / Roadmap +====================== + +There is an issue with the latest version of `boto3` and `urllib3` +- boto3 needs to be `boto3<=1.15.18` related with https://github.com/OCA/storage/issues/67 + +Bug Tracker +=========== + +Bugs are tracked on `GitHub Issues `_. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us smashing it by providing a detailed and welcomed +`feedback `_. + +Do not contact contributors directly about support or help with technical issues. + +Credits +======= + +Authors +~~~~~~~ + +* Akretion + +Contributors +~~~~~~~~~~~~ + +* Sebastien Beau +* Raphaël Reverdy + +Maintainers +~~~~~~~~~~~ + +This module is maintained by the OCA. + +.. image:: https://odoo-community.org/logo.png + :alt: Odoo Community Association + :target: https://odoo-community.org + +OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use. + +This module is part of the `OCA/storage `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/storage_backend_s3/__init__.py b/storage_backend_s3/__init__.py new file mode 100644 index 0000000000..0f00a6730d --- /dev/null +++ b/storage_backend_s3/__init__.py @@ -0,0 +1,2 @@ +from . import models +from . import components diff --git a/storage_backend_s3/__manifest__.py b/storage_backend_s3/__manifest__.py new file mode 100644 index 0000000000..d58006e7cb --- /dev/null +++ b/storage_backend_s3/__manifest__.py @@ -0,0 +1,17 @@ +# Copyright 2017 Akretion (http://www.akretion.com). +# @author Sébastien BEAU +# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). + +{ + "name": "Storage Backend S3", + "summary": "Implement amazon S3 Storage", + "version": "16.0.1.0.0", + "category": "Storage", + "website": "https://github.com/OCA/storage", + "author": " Akretion, Odoo Community Association (OCA)", + "license": "LGPL-3", + "installable": True, + "external_dependencies": {"python": ["boto3<=1.15.18", "vcrpy-unittest"]}, + "depends": ["storage_backend"], + "data": ["views/backend_storage_view.xml"], +} diff --git a/storage_backend_s3/components/__init__.py b/storage_backend_s3/components/__init__.py new file mode 100644 index 0000000000..0d8ef55eeb --- /dev/null +++ b/storage_backend_s3/components/__init__.py @@ -0,0 +1 @@ +from . import s3_adapter diff --git a/storage_backend_s3/components/s3_adapter.py b/storage_backend_s3/components/s3_adapter.py new file mode 100644 index 0000000000..15d9d40528 --- /dev/null +++ b/storage_backend_s3/components/s3_adapter.py @@ -0,0 +1,121 @@ +# Copyright 2017 Akretion (http://www.akretion.com). +# @author Sébastien BEAU +# Copyright 2019 Camptocamp SA (http://www.camptocamp.com). +# @author Simone Orsi +# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). + +import io +import logging + +from odoo import _, exceptions + +from odoo.addons.component.core import Component + +_logger = logging.getLogger(__name__) + +try: + import boto3 + from botocore.exceptions import ClientError, EndpointConnectionError + +except ImportError as err: # pragma: no cover + _logger.debug(err) + + +class S3StorageAdapter(Component): + _name = "s3.adapter" + _inherit = "base.storage.adapter" + _usage = "amazon_s3" + + def _aws_bucket_params(self): + params = { + "aws_access_key_id": self.collection.aws_access_key_id, + "aws_secret_access_key": self.collection.aws_secret_access_key, + } + if self.collection.aws_host: + params["endpoint_url"] = self.collection.aws_host + + if self.collection.aws_region: + if self.collection.aws_region != "other": + params["region_name"] = self.collection.aws_region + elif self.collection.aws_other_region: + params["region_name"] = self.collection.aws_other_region + return params + + def _get_bucket(self): + params = self._aws_bucket_params() + s3 = boto3.resource("s3", **params) + bucket_name = self.collection.aws_bucket + bucket = s3.Bucket(bucket_name) + exists = True + try: + s3.meta.client.head_bucket(Bucket=bucket_name) + except ClientError as e: + # If a client error is thrown, then check that it was a 404 error. + # If it was a 404 error, then the bucket does not exist. + error_code = e.response["Error"]["Code"] + if error_code == "404": + exists = False + except EndpointConnectionError as error: + # log verbose error from s3, return short message for user + _logger.exception("Error during connection on S3") + raise exceptions.UserError(str(error)) from error + region_name = params.get("region_name") + if not exists: + if not region_name: + bucket = s3.create_bucket(Bucket=bucket_name) + else: + bucket = s3.create_bucket( + Bucket=bucket_name, + CreateBucketConfiguration={"LocationConstraint": region_name}, + ) + return bucket + + def _get_object(self, relative_path=None): + bucket = self._get_bucket() + path = None + if relative_path: + path = self._fullpath(relative_path) + return bucket.Object(key=path) + + def add(self, relative_path, bin_data, mimetype=None, **kwargs): + s3object = self._get_object(relative_path) + file_params = self._aws_upload_fileobj_params(mimetype=mimetype, **kwargs) + with io.BytesIO() as fileobj: + fileobj.write(bin_data) + fileobj.seek(0) + try: + s3object.upload_fileobj(fileobj, **file_params) + except ClientError as error: + # log verbose error from s3, return short message for user + _logger.exception("Error during storage of the file %s" % relative_path) + raise exceptions.UserError( + _("The file could not be stored: %s") % str(error) + ) from error + + def _aws_upload_fileobj_params(self, mimetype=None, **kw): + extra_args = {} + if mimetype: + extra_args["ContentType"] = mimetype + if self.collection.aws_cache_control: + extra_args["CacheControl"] = self.collection.aws_cache_control + if self.collection.aws_file_acl: + extra_args["ACL"] = self.collection.aws_file_acl + if extra_args: + return {"ExtraArgs": extra_args} + return {} + + def get(self, relative_path): + s3object = self._get_object(relative_path) + return s3object.get()["Body"].read() + + def list(self, relative_path): + bucket = self._get_bucket() + dir_path = self.collection.directory_path or "" + return [ + o.key.replace(dir_path, "").lstrip("/") + for o in bucket.objects.filter(Prefix=dir_path) + ] + + def delete(self, relative_path): + s3object = self._get_object(relative_path) + s3object.delete() diff --git a/storage_backend_s3/i18n/storage_backend_s3.pot b/storage_backend_s3/i18n/storage_backend_s3.pot new file mode 100644 index 0000000000..954bdea0fc --- /dev/null +++ b/storage_backend_s3/i18n/storage_backend_s3.pot @@ -0,0 +1,116 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * storage_backend_s3 +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 15.0\n" +"Report-Msgid-Bugs-To: \n" +"Last-Translator: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: storage_backend_s3 +#: model:ir.model.fields,field_description:storage_backend_s3.field_storage_backend__aws_host +msgid "AWS Host" +msgstr "" + +#. module: storage_backend_s3 +#: model:ir.model.fields,field_description:storage_backend_s3.field_storage_backend__aws_access_key_id +msgid "Access Key ID" +msgstr "" + +#. module: storage_backend_s3 +#: model:ir.model.fields.selection,name:storage_backend_s3.selection__storage_backend__backend_type__amazon_s3 +#: model_terms:ir.ui.view,arch_db:storage_backend_s3.storage_backend_view_form +msgid "Amazon S3" +msgstr "" + +#. module: storage_backend_s3 +#: model:ir.model.fields,field_description:storage_backend_s3.field_storage_backend__aws_cache_control +msgid "Aws Cache Control" +msgstr "" + +#. module: storage_backend_s3 +#: model:ir.model.fields,field_description:storage_backend_s3.field_storage_backend__aws_file_acl +msgid "Aws File Acl" +msgstr "" + +#. module: storage_backend_s3 +#: model:ir.model.fields,field_description:storage_backend_s3.field_storage_backend__backend_type +msgid "Backend Type" +msgstr "" + +#. module: storage_backend_s3 +#: model:ir.model.fields,field_description:storage_backend_s3.field_storage_backend__aws_bucket +msgid "Bucket" +msgstr "" + +#. module: storage_backend_s3 +#: model:ir.model.fields,help:storage_backend_s3.field_storage_backend__aws_host +msgid "If you are using a different host than standard AWS ones, eg: Exoscale" +msgstr "" + +#. module: storage_backend_s3 +#: model:ir.model.fields,field_description:storage_backend_s3.field_storage_backend__aws_other_region +msgid "Other region" +msgstr "" + +#. module: storage_backend_s3 +#: model:ir.model.fields,field_description:storage_backend_s3.field_storage_backend__aws_region +msgid "Region" +msgstr "" + +#. module: storage_backend_s3 +#: model:ir.model.fields,field_description:storage_backend_s3.field_storage_backend__aws_secret_access_key +msgid "Secret Access Key" +msgstr "" + +#. module: storage_backend_s3 +#: model:ir.model,name:storage_backend_s3.model_storage_backend +msgid "Storage Backend" +msgstr "" + +#. module: storage_backend_s3 +#: code:addons/storage_backend_s3/components/s3_adapter.py:0 +#, python-format +msgid "The file could not be stored: %s" +msgstr "" + +#. module: storage_backend_s3 +#: model:ir.model.fields.selection,name:storage_backend_s3.selection__storage_backend__aws_file_acl__authenticated-read +msgid "authenticated-read" +msgstr "" + +#. module: storage_backend_s3 +#: model:ir.model.fields.selection,name:storage_backend_s3.selection__storage_backend__aws_file_acl__aws-exec-read +msgid "aws-exec-read" +msgstr "" + +#. module: storage_backend_s3 +#: model:ir.model.fields.selection,name:storage_backend_s3.selection__storage_backend__aws_file_acl__bucket-owner-full-control +msgid "bucket-owner-full-control" +msgstr "" + +#. module: storage_backend_s3 +#: model:ir.model.fields.selection,name:storage_backend_s3.selection__storage_backend__aws_file_acl__bucket-owner-read +msgid "bucket-owner-read" +msgstr "" + +#. module: storage_backend_s3 +#: model:ir.model.fields.selection,name:storage_backend_s3.selection__storage_backend__aws_file_acl__private +msgid "private" +msgstr "" + +#. module: storage_backend_s3 +#: model:ir.model.fields.selection,name:storage_backend_s3.selection__storage_backend__aws_file_acl__public-read +msgid "public-read" +msgstr "" + +#. module: storage_backend_s3 +#: model:ir.model.fields.selection,name:storage_backend_s3.selection__storage_backend__aws_file_acl__public-read-write +msgid "public-read-write" +msgstr "" diff --git a/storage_backend_s3/models/__init__.py b/storage_backend_s3/models/__init__.py new file mode 100644 index 0000000000..f45f402268 --- /dev/null +++ b/storage_backend_s3/models/__init__.py @@ -0,0 +1 @@ +from . import storage_backend diff --git a/storage_backend_s3/models/storage_backend.py b/storage_backend_s3/models/storage_backend.py new file mode 100644 index 0000000000..6a0d04a706 --- /dev/null +++ b/storage_backend_s3/models/storage_backend.py @@ -0,0 +1,86 @@ +# Copyright 2017 Akretion (http://www.akretion.com). +# @author Sébastien BEAU +# Copyright 2019 Camptocamp SA (http://www.camptocamp.com). +# @author Simone Orsi +# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). + +import logging + +from odoo import fields, models + +_logger = logging.getLogger(__name__) + +try: + import boto3 +except ImportError as err: # pragma: no cover + _logger.debug(err) + + +def _load_aws_regions(): + _logger.info("Loading available AWS regions") + session = boto3.session.Session() + return [ + (region, region.replace("-", " ").capitalize()) + for region in session.get_available_regions("s3") + ] + + +# AWS regions won't change that often, fine to retrieve them at instance load. +# Also, this prevents to call AWS every time the selection list is accessed. +AWS_REGIONS = _load_aws_regions() + + +class StorageBackend(models.Model): + _inherit = "storage.backend" + + backend_type = fields.Selection( + selection_add=[("amazon_s3", "Amazon S3")], + ondelete={"amazon_s3": "set default"}, + ) + aws_host = fields.Char( + string="AWS Host", + help="If you are using a different host than standard AWS ones, " + "eg: Exoscale", + ) + aws_bucket = fields.Char(string="Bucket") + aws_access_key_id = fields.Char(string="Access Key ID") + aws_secret_access_key = fields.Char(string="Secret Access Key") + aws_region = fields.Selection(selection="_selection_aws_region", string="Region") + aws_cache_control = fields.Char(default="max-age=31536000, public") + aws_other_region = fields.Char(string="Other region") + aws_file_acl = fields.Selection( + selection=[ + ("", ""), + ("private", "private"), + ("public-read", "public-read"), + ("public-read-write", "public-read-write"), + ("aws-exec-read", "aws-exec-read"), + ("authenticated-read", "authenticated-read"), + ("bucket-owner-read", "bucket-owner-read"), + ("bucket-owner-full-control", "bucket-owner-full-control"), + ] + ) + + @property + def _server_env_fields(self): + env_fields = super()._server_env_fields + env_fields.update( + { + "aws_host": {}, + "aws_bucket": {}, + "aws_access_key_id": {}, + "aws_secret_access_key": {}, + "aws_region": {}, + "aws_other_region": {}, + "aws_cache_control": {}, + "aws_file_acl": {}, + } + ) + return env_fields + + def _selection_aws_region(self): + return ( + [("", "None")] + + AWS_REGIONS + + [("other", "Empty or Other (Manually specify below)")] + ) diff --git a/storage_backend_s3/readme/CONTRIBUTORS.rst b/storage_backend_s3/readme/CONTRIBUTORS.rst new file mode 100644 index 0000000000..3cd662081b --- /dev/null +++ b/storage_backend_s3/readme/CONTRIBUTORS.rst @@ -0,0 +1,2 @@ +* Sebastien Beau +* Raphaël Reverdy diff --git a/storage_backend_s3/readme/DESCRIPTION.rst b/storage_backend_s3/readme/DESCRIPTION.rst new file mode 100644 index 0000000000..8d9fd944e8 --- /dev/null +++ b/storage_backend_s3/readme/DESCRIPTION.rst @@ -0,0 +1 @@ +Add the possibility to store and get data from amazon S3 for your storage backend diff --git a/storage_backend_s3/readme/ROADMAP.rst b/storage_backend_s3/readme/ROADMAP.rst new file mode 100644 index 0000000000..898d925979 --- /dev/null +++ b/storage_backend_s3/readme/ROADMAP.rst @@ -0,0 +1,2 @@ +There is an issue with the latest version of `boto3` and `urllib3` +- boto3 needs to be `boto3<=1.15.18` related with https://github.com/OCA/storage/issues/67 diff --git a/storage_backend_s3/static/description/icon.png b/storage_backend_s3/static/description/icon.png new file mode 100644 index 0000000000..3a0328b516 Binary files /dev/null and b/storage_backend_s3/static/description/icon.png differ diff --git a/storage_backend_s3/static/description/index.html b/storage_backend_s3/static/description/index.html new file mode 100644 index 0000000000..53ef73c63e --- /dev/null +++ b/storage_backend_s3/static/description/index.html @@ -0,0 +1,426 @@ + + + + + + +Storage Backend S3 + + + +
+

Storage Backend S3

+ + +

Beta License: LGPL-3 OCA/storage Translate me on Weblate Try me on Runbot

+

Add the possibility to store and get data from amazon S3 for your storage backend

+

Table of contents

+ +
+

Known issues / Roadmap

+

There is an issue with the latest version of boto3 and urllib3 +- boto3 needs to be boto3<=1.15.18 related with https://github.com/OCA/storage/issues/67

+
+
+

Bug Tracker

+

Bugs are tracked on GitHub Issues. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us smashing it by providing a detailed and welcomed +feedback.

+

Do not contact contributors directly about support or help with technical issues.

+
+
+

Credits

+
+

Authors

+
    +
  • Akretion
  • +
+
+
+

Contributors

+ +
+
+

Maintainers

+

This module is maintained by the OCA.

+Odoo Community Association +

OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use.

+

This module is part of the OCA/storage project on GitHub.

+

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

+
+
+
+ + diff --git a/storage_backend_s3/tests/__init__.py b/storage_backend_s3/tests/__init__.py new file mode 100644 index 0000000000..1282cd2ce0 --- /dev/null +++ b/storage_backend_s3/tests/__init__.py @@ -0,0 +1 @@ +from . import test_amazon_s3 diff --git a/storage_backend_s3/tests/cassettes/AmazonS3Case.test_setting_and_getting_data_from_dir.yaml b/storage_backend_s3/tests/cassettes/AmazonS3Case.test_setting_and_getting_data_from_dir.yaml new file mode 100644 index 0000000000..310c838b1d --- /dev/null +++ b/storage_backend_s3/tests/cassettes/AmazonS3Case.test_setting_and_getting_data_from_dir.yaml @@ -0,0 +1,510 @@ +interactions: + - request: + body: null + headers: + User-Agent: + - !!binary | + Qm90bzMvMS45LjEwMiBQeXRob24vMy41LjMgTGludXgvNC4xNS4wLTU0LWdlbmVyaWMgQm90b2Nv + cmUvMS4xMi4yNTMgUmVzb3VyY2U= + X-Amz-Content-SHA256: + - !!binary | + ZTNiMGM0NDI5OGZjMWMxNDlhZmJmNGM4OTk2ZmI5MjQyN2FlNDFlNDY0OWI5MzRjYTQ5NTk5MWI3 + ODUyYjg1NQ== + X-Amz-Date: + - !!binary | + MjAxOTExMDJUMTQ0MjQ1Wg== + method: HEAD + uri: https://sos-ch-dk-2.exo.io/test-storage-backend + response: + body: + string: "" + headers: + Connection: + - keep-alive + Content-Length: + - "0" + Date: + - Sat, 02 Nov 2019 14:42:45 GMT + Server: + - nginx + x-amz-bucket-region: + - ch-dk-2 + x-amz-id-2: + - a85cafab-77af-4f67-8e06-37a3ab1b637b + x-amz-request-id: + - a85cafab-77af-4f67-8e06-37a3ab1b637b + x-amz-requestid: + - a85cafab-77af-4f67-8e06-37a3ab1b637b + status: + code: 200 + message: OK + - request: + body: null + headers: + User-Agent: + - !!binary | + Qm90bzMvMS45LjEwMiBQeXRob24vMy41LjMgTGludXgvNC4xNS4wLTU0LWdlbmVyaWMgQm90b2Nv + cmUvMS4xMi4yNTMgUmVzb3VyY2U= + X-Amz-Content-SHA256: + - !!binary | + ZTNiMGM0NDI5OGZjMWMxNDlhZmJmNGM4OTk2ZmI5MjQyN2FlNDFlNDY0OWI5MzRjYTQ5NTk5MWI3 + ODUyYjg1NQ== + X-Amz-Date: + - !!binary | + MjAxOTExMDJUMTQ0MjQ1Wg== + method: GET + uri: https://sos-ch-dk-2.exo.io/test-storage-backend?encoding-type=url&prefix=subdirectory%2Fhere + response: + body: + string: + test-storage-backendsubdirectory/here1000urlfalse + headers: + Connection: + - keep-alive + Content-Length: + - "300" + Content-Type: + - application/xml + Date: + - Sat, 02 Nov 2019 14:42:45 GMT + Server: + - nginx + x-amz-bucket-region: + - ch-dk-2 + x-amz-id-2: + - 97757b05-7d88-480f-be75-98786a9492e8 + x-amz-request-id: + - 97757b05-7d88-480f-be75-98786a9492e8 + x-amzn-requestid: + - 97757b05-7d88-480f-be75-98786a9492e8 + status: + code: 200 + message: OK + - request: + body: null + headers: + User-Agent: + - !!binary | + Qm90bzMvMS45LjEwMiBQeXRob24vMy41LjMgTGludXgvNC4xNS4wLTU0LWdlbmVyaWMgQm90b2Nv + cmUvMS4xMi4yNTMgUmVzb3VyY2U= + X-Amz-Content-SHA256: + - !!binary | + ZTNiMGM0NDI5OGZjMWMxNDlhZmJmNGM4OTk2ZmI5MjQyN2FlNDFlNDY0OWI5MzRjYTQ5NTk5MWI3 + ODUyYjg1NQ== + X-Amz-Date: + - !!binary | + MjAxOTExMDJUMTQ0MjQ1Wg== + method: HEAD + uri: https://sos-ch-dk-2.exo.io/test-storage-backend + response: + body: + string: "" + headers: + Connection: + - keep-alive + Content-Length: + - "0" + Date: + - Sat, 02 Nov 2019 14:42:45 GMT + Server: + - nginx + x-amz-bucket-region: + - ch-dk-2 + x-amz-id-2: + - 69932919-580b-4d66-bf3d-1916710b4543 + x-amz-request-id: + - 69932919-580b-4d66-bf3d-1916710b4543 + x-amz-requestid: + - 69932919-580b-4d66-bf3d-1916710b4543 + status: + code: 200 + message: OK + - request: + body: !!python/object/new:_io.BytesIO + state: !!python/tuple + - !!binary | + VGhpcyBpcyBhIHNpbXBsZSBmaWxl + - 0 + - null + headers: + Cache-Control: + - !!binary | + bWF4LWFnZT0zMTUzNjAwMCwgcHVibGlj + Content-Length: + - "21" + Content-MD5: + - !!binary | + R1FxakVYc1JxclB5eGZUbDk5bmtBZz09 + Content-Type: + - !!binary | + dGV4dC9wbGFpbg== + Expect: + - !!binary | + MTAwLWNvbnRpbnVl + User-Agent: + - !!binary | + Qm90bzMvMS45LjEwMiBQeXRob24vMy41LjMgTGludXgvNC4xNS4wLTU0LWdlbmVyaWMgQm90b2Nv + cmUvMS4xMi4yNTMgUmVzb3VyY2U= + X-Amz-Content-SHA256: + - !!binary | + VU5TSUdORUQtUEFZTE9BRA== + X-Amz-Date: + - !!binary | + MjAxOTExMDJUMTQ0MjQ1Wg== + method: PUT + uri: https://sos-ch-dk-2.exo.io/test-storage-backend/subdirectory/here/test_file.txt + response: + body: + string: "" + headers: + Connection: + - keep-alive + Content-Length: + - "0" + Date: + - Sat, 02 Nov 2019 14:42:45 GMT + Server: + - nginx + etag: + - '"190aa3117b11aab3f2c5f4e5f7d9e402"' + x-amz-bucket-region: + - ch-dk-2 + x-amz-id-2: + - a10aa8d7-4b08-4a01-89fd-66ea990783e4 + x-amz-request-id: + - a10aa8d7-4b08-4a01-89fd-66ea990783e4 + x-amz-requestid: + - a10aa8d7-4b08-4a01-89fd-66ea990783e4 + status: + code: 200 + message: OK + - request: + body: null + headers: + User-Agent: + - !!binary | + Qm90bzMvMS45LjEwMiBQeXRob24vMy41LjMgTGludXgvNC4xNS4wLTU0LWdlbmVyaWMgQm90b2Nv + cmUvMS4xMi4yNTMgUmVzb3VyY2U= + X-Amz-Content-SHA256: + - !!binary | + ZTNiMGM0NDI5OGZjMWMxNDlhZmJmNGM4OTk2ZmI5MjQyN2FlNDFlNDY0OWI5MzRjYTQ5NTk5MWI3 + ODUyYjg1NQ== + X-Amz-Date: + - !!binary | + MjAxOTExMDJUMTQ0MjQ1Wg== + method: HEAD + uri: https://sos-ch-dk-2.exo.io/test-storage-backend + response: + body: + string: "" + headers: + Connection: + - keep-alive + Content-Length: + - "0" + Date: + - Sat, 02 Nov 2019 14:42:46 GMT + Server: + - nginx + x-amz-bucket-region: + - ch-dk-2 + x-amz-id-2: + - 0245bcda-d484-468c-98f4-5dc16e7f6aa5 + x-amz-request-id: + - 0245bcda-d484-468c-98f4-5dc16e7f6aa5 + x-amz-requestid: + - 0245bcda-d484-468c-98f4-5dc16e7f6aa5 + status: + code: 200 + message: OK + - request: + body: null + headers: + User-Agent: + - !!binary | + Qm90bzMvMS45LjEwMiBQeXRob24vMy41LjMgTGludXgvNC4xNS4wLTU0LWdlbmVyaWMgQm90b2Nv + cmUvMS4xMi4yNTMgUmVzb3VyY2U= + X-Amz-Content-SHA256: + - !!binary | + ZTNiMGM0NDI5OGZjMWMxNDlhZmJmNGM4OTk2ZmI5MjQyN2FlNDFlNDY0OWI5MzRjYTQ5NTk5MWI3 + ODUyYjg1NQ== + X-Amz-Date: + - !!binary | + MjAxOTExMDJUMTQ0MjQ2Wg== + method: GET + uri: https://sos-ch-dk-2.exo.io/test-storage-backend?encoding-type=url&prefix=subdirectory%2Fhere + response: + body: + string: + test-storage-backendsubdirectory/here1000urlfalsesubdirectory/here/test_file.txt2019-11-02T14:42:45.855Z"190aa3117b11aab3f2c5f4e5f7d9e402"21odoo-plateformeodoo-plateformeStandard + headers: + Connection: + - keep-alive + Content-Length: + - "596" + Content-Type: + - application/xml + Date: + - Sat, 02 Nov 2019 14:42:46 GMT + Server: + - nginx + x-amz-bucket-region: + - ch-dk-2 + x-amz-id-2: + - 5db74b47-e834-41c2-8b9c-d1575542f4f1 + x-amz-request-id: + - 5db74b47-e834-41c2-8b9c-d1575542f4f1 + x-amzn-requestid: + - 5db74b47-e834-41c2-8b9c-d1575542f4f1 + status: + code: 200 + message: OK + - request: + body: null + headers: + User-Agent: + - !!binary | + Qm90bzMvMS45LjEwMiBQeXRob24vMy41LjMgTGludXgvNC4xNS4wLTU0LWdlbmVyaWMgQm90b2Nv + cmUvMS4xMi4yNTMgUmVzb3VyY2U= + X-Amz-Content-SHA256: + - !!binary | + ZTNiMGM0NDI5OGZjMWMxNDlhZmJmNGM4OTk2ZmI5MjQyN2FlNDFlNDY0OWI5MzRjYTQ5NTk5MWI3 + ODUyYjg1NQ== + X-Amz-Date: + - !!binary | + MjAxOTExMDJUMTQ0MjQ2Wg== + method: HEAD + uri: https://sos-ch-dk-2.exo.io/test-storage-backend + response: + body: + string: "" + headers: + Connection: + - keep-alive + Content-Length: + - "0" + Date: + - Sat, 02 Nov 2019 14:42:46 GMT + Server: + - nginx + x-amz-bucket-region: + - ch-dk-2 + x-amz-id-2: + - 3393f9c7-9201-41c6-b8dd-a2ca873cca62 + x-amz-request-id: + - 3393f9c7-9201-41c6-b8dd-a2ca873cca62 + x-amz-requestid: + - 3393f9c7-9201-41c6-b8dd-a2ca873cca62 + status: + code: 200 + message: OK + - request: + body: null + headers: + User-Agent: + - !!binary | + Qm90bzMvMS45LjEwMiBQeXRob24vMy41LjMgTGludXgvNC4xNS4wLTU0LWdlbmVyaWMgQm90b2Nv + cmUvMS4xMi4yNTMgUmVzb3VyY2U= + X-Amz-Content-SHA256: + - !!binary | + ZTNiMGM0NDI5OGZjMWMxNDlhZmJmNGM4OTk2ZmI5MjQyN2FlNDFlNDY0OWI5MzRjYTQ5NTk5MWI3 + ODUyYjg1NQ== + X-Amz-Date: + - !!binary | + MjAxOTExMDJUMTQ0MjQ2Wg== + method: GET + uri: https://sos-ch-dk-2.exo.io/test-storage-backend/subdirectory/here/test_file.txt + response: + body: + string: This is a simple file + headers: + Connection: + - keep-alive + Content-Length: + - "21" + Content-Type: + - text/plain + Date: + - Sat, 02 Nov 2019 14:42:46 GMT + Server: + - nginx + cache-control: + - max-age=31536000, public + etag: + - '"190aa3117b11aab3f2c5f4e5f7d9e402"' + last-modified: + - Sat, 02 Nov 2019 14:42:45 GMT + x-amz-bucket-region: + - ch-dk-2 + x-amz-id-2: + - 04ac2feb-ccb9-4b10-a7ca-0630a87bf65e + x-amz-request-id: + - 04ac2feb-ccb9-4b10-a7ca-0630a87bf65e + x-amzn-requestid: + - 04ac2feb-ccb9-4b10-a7ca-0630a87bf65e + status: + code: 200 + message: OK + - request: + body: null + headers: + User-Agent: + - !!binary | + Qm90bzMvMS45LjEwMiBQeXRob24vMy41LjMgTGludXgvNC4xNS4wLTU0LWdlbmVyaWMgQm90b2Nv + cmUvMS4xMi4yNTMgUmVzb3VyY2U= + X-Amz-Content-SHA256: + - !!binary | + ZTNiMGM0NDI5OGZjMWMxNDlhZmJmNGM4OTk2ZmI5MjQyN2FlNDFlNDY0OWI5MzRjYTQ5NTk5MWI3 + ODUyYjg1NQ== + X-Amz-Date: + - !!binary | + MjAxOTExMDJUMTQ0MjQ2Wg== + method: HEAD + uri: https://sos-ch-dk-2.exo.io/test-storage-backend + response: + body: + string: "" + headers: + Connection: + - keep-alive + Content-Length: + - "0" + Date: + - Sat, 02 Nov 2019 14:42:46 GMT + Server: + - nginx + x-amz-bucket-region: + - ch-dk-2 + x-amz-id-2: + - d6dac54b-96a1-4336-90ab-ee6784f1a4f7 + x-amz-request-id: + - d6dac54b-96a1-4336-90ab-ee6784f1a4f7 + x-amz-requestid: + - d6dac54b-96a1-4336-90ab-ee6784f1a4f7 + status: + code: 200 + message: OK + - request: + body: null + headers: + Content-Length: + - "0" + User-Agent: + - !!binary | + Qm90bzMvMS45LjEwMiBQeXRob24vMy41LjMgTGludXgvNC4xNS4wLTU0LWdlbmVyaWMgQm90b2Nv + cmUvMS4xMi4yNTMgUmVzb3VyY2U= + X-Amz-Content-SHA256: + - !!binary | + ZTNiMGM0NDI5OGZjMWMxNDlhZmJmNGM4OTk2ZmI5MjQyN2FlNDFlNDY0OWI5MzRjYTQ5NTk5MWI3 + ODUyYjg1NQ== + X-Amz-Date: + - !!binary | + MjAxOTExMDJUMTQ0MjQ2Wg== + method: DELETE + uri: https://sos-ch-dk-2.exo.io/test-storage-backend/subdirectory/here/test_file.txt + response: + body: + string: "" + headers: + Connection: + - keep-alive + Date: + - Sat, 02 Nov 2019 14:42:46 GMT + Server: + - nginx + x-amz-bucket-region: + - ch-dk-2 + x-amz-id-2: + - 647fc062-5a74-4435-ab61-810d31aefde7 + x-amz-request-id: + - 647fc062-5a74-4435-ab61-810d31aefde7 + x-amz-requestid: + - 647fc062-5a74-4435-ab61-810d31aefde7 + status: + code: 204 + message: No Content + - request: + body: null + headers: + User-Agent: + - !!binary | + Qm90bzMvMS45LjEwMiBQeXRob24vMy41LjMgTGludXgvNC4xNS4wLTU0LWdlbmVyaWMgQm90b2Nv + cmUvMS4xMi4yNTMgUmVzb3VyY2U= + X-Amz-Content-SHA256: + - !!binary | + ZTNiMGM0NDI5OGZjMWMxNDlhZmJmNGM4OTk2ZmI5MjQyN2FlNDFlNDY0OWI5MzRjYTQ5NTk5MWI3 + ODUyYjg1NQ== + X-Amz-Date: + - !!binary | + MjAxOTExMDJUMTQ0MjQ2Wg== + method: HEAD + uri: https://sos-ch-dk-2.exo.io/test-storage-backend + response: + body: + string: "" + headers: + Connection: + - keep-alive + Content-Length: + - "0" + Date: + - Sat, 02 Nov 2019 14:42:47 GMT + Server: + - nginx + x-amz-bucket-region: + - ch-dk-2 + x-amz-id-2: + - f7261bc7-8d44-40ea-bbbf-030073cf1e51 + x-amz-request-id: + - f7261bc7-8d44-40ea-bbbf-030073cf1e51 + x-amz-requestid: + - f7261bc7-8d44-40ea-bbbf-030073cf1e51 + status: + code: 200 + message: OK + - request: + body: null + headers: + User-Agent: + - !!binary | + Qm90bzMvMS45LjEwMiBQeXRob24vMy41LjMgTGludXgvNC4xNS4wLTU0LWdlbmVyaWMgQm90b2Nv + cmUvMS4xMi4yNTMgUmVzb3VyY2U= + X-Amz-Content-SHA256: + - !!binary | + ZTNiMGM0NDI5OGZjMWMxNDlhZmJmNGM4OTk2ZmI5MjQyN2FlNDFlNDY0OWI5MzRjYTQ5NTk5MWI3 + ODUyYjg1NQ== + X-Amz-Date: + - !!binary | + MjAxOTExMDJUMTQ0MjQ3Wg== + method: GET + uri: https://sos-ch-dk-2.exo.io/test-storage-backend?encoding-type=url&prefix=subdirectory%2Fhere + response: + body: + string: + test-storage-backendsubdirectory/here1000urlfalse + headers: + Connection: + - keep-alive + Content-Length: + - "300" + Content-Type: + - application/xml + Date: + - Sat, 02 Nov 2019 14:42:47 GMT + Server: + - nginx + x-amz-bucket-region: + - ch-dk-2 + x-amz-id-2: + - 1cf7a3a2-cd2c-4f59-be26-85a2eb947e35 + x-amz-request-id: + - 1cf7a3a2-cd2c-4f59-be26-85a2eb947e35 + x-amzn-requestid: + - 1cf7a3a2-cd2c-4f59-be26-85a2eb947e35 + status: + code: 200 + message: OK +version: 1 diff --git a/storage_backend_s3/tests/cassettes/AmazonS3Case.test_setting_and_getting_data_from_root.yaml b/storage_backend_s3/tests/cassettes/AmazonS3Case.test_setting_and_getting_data_from_root.yaml new file mode 100644 index 0000000000..ea8af73967 --- /dev/null +++ b/storage_backend_s3/tests/cassettes/AmazonS3Case.test_setting_and_getting_data_from_root.yaml @@ -0,0 +1,510 @@ +interactions: + - request: + body: null + headers: + User-Agent: + - !!binary | + Qm90bzMvMS45LjEwMiBQeXRob24vMy41LjMgTGludXgvNC4xNS4wLTU0LWdlbmVyaWMgQm90b2Nv + cmUvMS4xMi4yNTMgUmVzb3VyY2U= + X-Amz-Content-SHA256: + - !!binary | + ZTNiMGM0NDI5OGZjMWMxNDlhZmJmNGM4OTk2ZmI5MjQyN2FlNDFlNDY0OWI5MzRjYTQ5NTk5MWI3 + ODUyYjg1NQ== + X-Amz-Date: + - !!binary | + MjAxOTExMDJUMTQ0MjQ3Wg== + method: HEAD + uri: https://sos-ch-dk-2.exo.io/test-storage-backend + response: + body: + string: "" + headers: + Connection: + - keep-alive + Content-Length: + - "0" + Date: + - Sat, 02 Nov 2019 14:42:47 GMT + Server: + - nginx + x-amz-bucket-region: + - ch-dk-2 + x-amz-id-2: + - 29a34678-f089-4df0-82be-6ea48fa074fc + x-amz-request-id: + - 29a34678-f089-4df0-82be-6ea48fa074fc + x-amz-requestid: + - 29a34678-f089-4df0-82be-6ea48fa074fc + status: + code: 200 + message: OK + - request: + body: null + headers: + User-Agent: + - !!binary | + Qm90bzMvMS45LjEwMiBQeXRob24vMy41LjMgTGludXgvNC4xNS4wLTU0LWdlbmVyaWMgQm90b2Nv + cmUvMS4xMi4yNTMgUmVzb3VyY2U= + X-Amz-Content-SHA256: + - !!binary | + ZTNiMGM0NDI5OGZjMWMxNDlhZmJmNGM4OTk2ZmI5MjQyN2FlNDFlNDY0OWI5MzRjYTQ5NTk5MWI3 + ODUyYjg1NQ== + X-Amz-Date: + - !!binary | + MjAxOTExMDJUMTQ0MjQ3Wg== + method: GET + uri: https://sos-ch-dk-2.exo.io/test-storage-backend?encoding-type=url&prefix= + response: + body: + string: + test-storage-backend1000urlfalse + headers: + Connection: + - keep-alive + Content-Length: + - "283" + Content-Type: + - application/xml + Date: + - Sat, 02 Nov 2019 14:42:47 GMT + Server: + - nginx + x-amz-bucket-region: + - ch-dk-2 + x-amz-id-2: + - 1dab5d2a-721c-44bb-b98b-c4bee9abd720 + x-amz-request-id: + - 1dab5d2a-721c-44bb-b98b-c4bee9abd720 + x-amzn-requestid: + - 1dab5d2a-721c-44bb-b98b-c4bee9abd720 + status: + code: 200 + message: OK + - request: + body: null + headers: + User-Agent: + - !!binary | + Qm90bzMvMS45LjEwMiBQeXRob24vMy41LjMgTGludXgvNC4xNS4wLTU0LWdlbmVyaWMgQm90b2Nv + cmUvMS4xMi4yNTMgUmVzb3VyY2U= + X-Amz-Content-SHA256: + - !!binary | + ZTNiMGM0NDI5OGZjMWMxNDlhZmJmNGM4OTk2ZmI5MjQyN2FlNDFlNDY0OWI5MzRjYTQ5NTk5MWI3 + ODUyYjg1NQ== + X-Amz-Date: + - !!binary | + MjAxOTExMDJUMTQ0MjQ3Wg== + method: HEAD + uri: https://sos-ch-dk-2.exo.io/test-storage-backend + response: + body: + string: "" + headers: + Connection: + - keep-alive + Content-Length: + - "0" + Date: + - Sat, 02 Nov 2019 14:42:47 GMT + Server: + - nginx + x-amz-bucket-region: + - ch-dk-2 + x-amz-id-2: + - 4be173e4-123b-497c-9a9c-c4acf4d0dcfd + x-amz-request-id: + - 4be173e4-123b-497c-9a9c-c4acf4d0dcfd + x-amz-requestid: + - 4be173e4-123b-497c-9a9c-c4acf4d0dcfd + status: + code: 200 + message: OK + - request: + body: !!python/object/new:_io.BytesIO + state: !!python/tuple + - !!binary | + VGhpcyBpcyBhIHNpbXBsZSBmaWxl + - 0 + - null + headers: + Cache-Control: + - !!binary | + bWF4LWFnZT0zMTUzNjAwMCwgcHVibGlj + Content-Length: + - "21" + Content-MD5: + - !!binary | + R1FxakVYc1JxclB5eGZUbDk5bmtBZz09 + Content-Type: + - !!binary | + dGV4dC9wbGFpbg== + Expect: + - !!binary | + MTAwLWNvbnRpbnVl + User-Agent: + - !!binary | + Qm90bzMvMS45LjEwMiBQeXRob24vMy41LjMgTGludXgvNC4xNS4wLTU0LWdlbmVyaWMgQm90b2Nv + cmUvMS4xMi4yNTMgUmVzb3VyY2U= + X-Amz-Content-SHA256: + - !!binary | + VU5TSUdORUQtUEFZTE9BRA== + X-Amz-Date: + - !!binary | + MjAxOTExMDJUMTQ0MjQ3Wg== + method: PUT + uri: https://sos-ch-dk-2.exo.io/test-storage-backend/test_file.txt + response: + body: + string: "" + headers: + Connection: + - keep-alive + Content-Length: + - "0" + Date: + - Sat, 02 Nov 2019 14:42:48 GMT + Server: + - nginx + etag: + - '"190aa3117b11aab3f2c5f4e5f7d9e402"' + x-amz-bucket-region: + - ch-dk-2 + x-amz-id-2: + - 6b3a20b8-79de-4146-89e3-6014ac70a811 + x-amz-request-id: + - 6b3a20b8-79de-4146-89e3-6014ac70a811 + x-amz-requestid: + - 6b3a20b8-79de-4146-89e3-6014ac70a811 + status: + code: 200 + message: OK + - request: + body: null + headers: + User-Agent: + - !!binary | + Qm90bzMvMS45LjEwMiBQeXRob24vMy41LjMgTGludXgvNC4xNS4wLTU0LWdlbmVyaWMgQm90b2Nv + cmUvMS4xMi4yNTMgUmVzb3VyY2U= + X-Amz-Content-SHA256: + - !!binary | + ZTNiMGM0NDI5OGZjMWMxNDlhZmJmNGM4OTk2ZmI5MjQyN2FlNDFlNDY0OWI5MzRjYTQ5NTk5MWI3 + ODUyYjg1NQ== + X-Amz-Date: + - !!binary | + MjAxOTExMDJUMTQ0MjQ4Wg== + method: HEAD + uri: https://sos-ch-dk-2.exo.io/test-storage-backend + response: + body: + string: "" + headers: + Connection: + - keep-alive + Content-Length: + - "0" + Date: + - Sat, 02 Nov 2019 14:42:48 GMT + Server: + - nginx + x-amz-bucket-region: + - ch-dk-2 + x-amz-id-2: + - efeeb2fc-f22c-4afe-80c4-ac5b4fa2aa33 + x-amz-request-id: + - efeeb2fc-f22c-4afe-80c4-ac5b4fa2aa33 + x-amz-requestid: + - efeeb2fc-f22c-4afe-80c4-ac5b4fa2aa33 + status: + code: 200 + message: OK + - request: + body: null + headers: + User-Agent: + - !!binary | + Qm90bzMvMS45LjEwMiBQeXRob24vMy41LjMgTGludXgvNC4xNS4wLTU0LWdlbmVyaWMgQm90b2Nv + cmUvMS4xMi4yNTMgUmVzb3VyY2U= + X-Amz-Content-SHA256: + - !!binary | + ZTNiMGM0NDI5OGZjMWMxNDlhZmJmNGM4OTk2ZmI5MjQyN2FlNDFlNDY0OWI5MzRjYTQ5NTk5MWI3 + ODUyYjg1NQ== + X-Amz-Date: + - !!binary | + MjAxOTExMDJUMTQ0MjQ4Wg== + method: GET + uri: https://sos-ch-dk-2.exo.io/test-storage-backend?encoding-type=url&prefix= + response: + body: + string: + test-storage-backend1000urlfalsetest_file.txt2019-11-02T14:42:48.041Z"190aa3117b11aab3f2c5f4e5f7d9e402"21odoo-plateformeodoo-plateformeStandard + headers: + Connection: + - keep-alive + Content-Length: + - "561" + Content-Type: + - application/xml + Date: + - Sat, 02 Nov 2019 14:42:48 GMT + Server: + - nginx + x-amz-bucket-region: + - ch-dk-2 + x-amz-id-2: + - 313f3b01-a1d5-40ae-8ae8-87eaf491b38e + x-amz-request-id: + - 313f3b01-a1d5-40ae-8ae8-87eaf491b38e + x-amzn-requestid: + - 313f3b01-a1d5-40ae-8ae8-87eaf491b38e + status: + code: 200 + message: OK + - request: + body: null + headers: + User-Agent: + - !!binary | + Qm90bzMvMS45LjEwMiBQeXRob24vMy41LjMgTGludXgvNC4xNS4wLTU0LWdlbmVyaWMgQm90b2Nv + cmUvMS4xMi4yNTMgUmVzb3VyY2U= + X-Amz-Content-SHA256: + - !!binary | + ZTNiMGM0NDI5OGZjMWMxNDlhZmJmNGM4OTk2ZmI5MjQyN2FlNDFlNDY0OWI5MzRjYTQ5NTk5MWI3 + ODUyYjg1NQ== + X-Amz-Date: + - !!binary | + MjAxOTExMDJUMTQ0MjQ4Wg== + method: HEAD + uri: https://sos-ch-dk-2.exo.io/test-storage-backend + response: + body: + string: "" + headers: + Connection: + - keep-alive + Content-Length: + - "0" + Date: + - Sat, 02 Nov 2019 14:42:48 GMT + Server: + - nginx + x-amz-bucket-region: + - ch-dk-2 + x-amz-id-2: + - a095635b-ac42-489e-bf67-f87c30ce4dfd + x-amz-request-id: + - a095635b-ac42-489e-bf67-f87c30ce4dfd + x-amz-requestid: + - a095635b-ac42-489e-bf67-f87c30ce4dfd + status: + code: 200 + message: OK + - request: + body: null + headers: + User-Agent: + - !!binary | + Qm90bzMvMS45LjEwMiBQeXRob24vMy41LjMgTGludXgvNC4xNS4wLTU0LWdlbmVyaWMgQm90b2Nv + cmUvMS4xMi4yNTMgUmVzb3VyY2U= + X-Amz-Content-SHA256: + - !!binary | + ZTNiMGM0NDI5OGZjMWMxNDlhZmJmNGM4OTk2ZmI5MjQyN2FlNDFlNDY0OWI5MzRjYTQ5NTk5MWI3 + ODUyYjg1NQ== + X-Amz-Date: + - !!binary | + MjAxOTExMDJUMTQ0MjQ4Wg== + method: GET + uri: https://sos-ch-dk-2.exo.io/test-storage-backend/test_file.txt + response: + body: + string: This is a simple file + headers: + Connection: + - keep-alive + Content-Length: + - "21" + Content-Type: + - text/plain + Date: + - Sat, 02 Nov 2019 14:42:48 GMT + Server: + - nginx + cache-control: + - max-age=31536000, public + etag: + - '"190aa3117b11aab3f2c5f4e5f7d9e402"' + last-modified: + - Sat, 02 Nov 2019 14:42:48 GMT + x-amz-bucket-region: + - ch-dk-2 + x-amz-id-2: + - 9d6ba5a1-90d6-4106-81f4-40ba427cb124 + x-amz-request-id: + - 9d6ba5a1-90d6-4106-81f4-40ba427cb124 + x-amzn-requestid: + - 9d6ba5a1-90d6-4106-81f4-40ba427cb124 + status: + code: 200 + message: OK + - request: + body: null + headers: + User-Agent: + - !!binary | + Qm90bzMvMS45LjEwMiBQeXRob24vMy41LjMgTGludXgvNC4xNS4wLTU0LWdlbmVyaWMgQm90b2Nv + cmUvMS4xMi4yNTMgUmVzb3VyY2U= + X-Amz-Content-SHA256: + - !!binary | + ZTNiMGM0NDI5OGZjMWMxNDlhZmJmNGM4OTk2ZmI5MjQyN2FlNDFlNDY0OWI5MzRjYTQ5NTk5MWI3 + ODUyYjg1NQ== + X-Amz-Date: + - !!binary | + MjAxOTExMDJUMTQ0MjQ4Wg== + method: HEAD + uri: https://sos-ch-dk-2.exo.io/test-storage-backend + response: + body: + string: "" + headers: + Connection: + - keep-alive + Content-Length: + - "0" + Date: + - Sat, 02 Nov 2019 14:42:48 GMT + Server: + - nginx + x-amz-bucket-region: + - ch-dk-2 + x-amz-id-2: + - b5f09cc0-4e00-4ce4-826e-72295237ab45 + x-amz-request-id: + - b5f09cc0-4e00-4ce4-826e-72295237ab45 + x-amz-requestid: + - b5f09cc0-4e00-4ce4-826e-72295237ab45 + status: + code: 200 + message: OK + - request: + body: null + headers: + Content-Length: + - "0" + User-Agent: + - !!binary | + Qm90bzMvMS45LjEwMiBQeXRob24vMy41LjMgTGludXgvNC4xNS4wLTU0LWdlbmVyaWMgQm90b2Nv + cmUvMS4xMi4yNTMgUmVzb3VyY2U= + X-Amz-Content-SHA256: + - !!binary | + ZTNiMGM0NDI5OGZjMWMxNDlhZmJmNGM4OTk2ZmI5MjQyN2FlNDFlNDY0OWI5MzRjYTQ5NTk5MWI3 + ODUyYjg1NQ== + X-Amz-Date: + - !!binary | + MjAxOTExMDJUMTQ0MjQ4Wg== + method: DELETE + uri: https://sos-ch-dk-2.exo.io/test-storage-backend/test_file.txt + response: + body: + string: "" + headers: + Connection: + - keep-alive + Date: + - Sat, 02 Nov 2019 14:42:48 GMT + Server: + - nginx + x-amz-bucket-region: + - ch-dk-2 + x-amz-id-2: + - bc2092e4-173a-465f-b87b-64a63fc18d17 + x-amz-request-id: + - bc2092e4-173a-465f-b87b-64a63fc18d17 + x-amz-requestid: + - bc2092e4-173a-465f-b87b-64a63fc18d17 + status: + code: 204 + message: No Content + - request: + body: null + headers: + User-Agent: + - !!binary | + Qm90bzMvMS45LjEwMiBQeXRob24vMy41LjMgTGludXgvNC4xNS4wLTU0LWdlbmVyaWMgQm90b2Nv + cmUvMS4xMi4yNTMgUmVzb3VyY2U= + X-Amz-Content-SHA256: + - !!binary | + ZTNiMGM0NDI5OGZjMWMxNDlhZmJmNGM4OTk2ZmI5MjQyN2FlNDFlNDY0OWI5MzRjYTQ5NTk5MWI3 + ODUyYjg1NQ== + X-Amz-Date: + - !!binary | + MjAxOTExMDJUMTQ0MjQ4Wg== + method: HEAD + uri: https://sos-ch-dk-2.exo.io/test-storage-backend + response: + body: + string: "" + headers: + Connection: + - keep-alive + Content-Length: + - "0" + Date: + - Sat, 02 Nov 2019 14:42:49 GMT + Server: + - nginx + x-amz-bucket-region: + - ch-dk-2 + x-amz-id-2: + - 70d48c9e-b13b-4b16-abd2-4c853ca55855 + x-amz-request-id: + - 70d48c9e-b13b-4b16-abd2-4c853ca55855 + x-amz-requestid: + - 70d48c9e-b13b-4b16-abd2-4c853ca55855 + status: + code: 200 + message: OK + - request: + body: null + headers: + User-Agent: + - !!binary | + Qm90bzMvMS45LjEwMiBQeXRob24vMy41LjMgTGludXgvNC4xNS4wLTU0LWdlbmVyaWMgQm90b2Nv + cmUvMS4xMi4yNTMgUmVzb3VyY2U= + X-Amz-Content-SHA256: + - !!binary | + ZTNiMGM0NDI5OGZjMWMxNDlhZmJmNGM4OTk2ZmI5MjQyN2FlNDFlNDY0OWI5MzRjYTQ5NTk5MWI3 + ODUyYjg1NQ== + X-Amz-Date: + - !!binary | + MjAxOTExMDJUMTQ0MjQ5Wg== + method: GET + uri: https://sos-ch-dk-2.exo.io/test-storage-backend?encoding-type=url&prefix= + response: + body: + string: + test-storage-backend1000urlfalse + headers: + Connection: + - keep-alive + Content-Length: + - "283" + Content-Type: + - application/xml + Date: + - Sat, 02 Nov 2019 14:42:49 GMT + Server: + - nginx + x-amz-bucket-region: + - ch-dk-2 + x-amz-id-2: + - f6a89089-3bda-45da-ad7b-9645679252c2 + x-amz-request-id: + - f6a89089-3bda-45da-ad7b-9645679252c2 + x-amzn-requestid: + - f6a89089-3bda-45da-ad7b-9645679252c2 + status: + code: 200 + message: OK +version: 1 diff --git a/storage_backend_s3/tests/test_amazon_s3.py b/storage_backend_s3/tests/test_amazon_s3.py new file mode 100644 index 0000000000..1256126aee --- /dev/null +++ b/storage_backend_s3/tests/test_amazon_s3.py @@ -0,0 +1,76 @@ +# Copyright 2017 Akretion (http://www.akretion.com). +# @author Sébastien BEAU +# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). + +# pylint: disable=missing-manifest-dependency +# disable warning on 'vcr' missing in manifest: this is only a dependency for +# dev/tests + +import logging +import os + +from vcr_unittest import VCRMixin + +from odoo.addons.storage_backend.tests.common import BackendStorageTestMixin, CommonCase + +_logger = logging.getLogger(__name__) + + +class AmazonS3Case(VCRMixin, CommonCase, BackendStorageTestMixin): + @classmethod + def setUpClass(cls): + super(AmazonS3Case, cls).setUpClass() + cls.backend = cls.env.ref("storage_backend.default_storage_backend") + cls.backend.write( + { + "backend_type": "amazon_s3", + "aws_bucket": os.environ.get("AWS_BUCKET", "test-storage-backend"), + "aws_access_key_id": os.environ.get( + "AWS_ACCESS_KEY_ID", "test-access-key" + ), + "aws_secret_access_key": os.environ.get( + "AWS_SECRET_ACCESS_KEY", "test-secret-access-key" + ), + "aws_host": os.environ.get("AWS_HOST", "https://sos-ch-dk-2.exo.io"), + } + ) + + def _get_vcr_kwargs(self, **kwargs): + return { + "record_mode": "once", + "match_on": ["method", "path", "query", "body"], + "filter_headers": ["Authorization"], + "decode_compressed_response": True, + } + + def test_setting_and_getting_data_from_root(self): + self._test_setting_and_getting_data_from_root() + + def test_setting_and_getting_data_from_dir(self): + self._test_setting_and_getting_data_from_dir() + + def test_params(self): + adapter = self.backend._get_adapter() + self.backend.aws_host = "" + params = adapter._aws_bucket_params() + self.assertNotIn("endpoint_url", params) + self.backend.aws_host = "another.s3.endpoint.com" + params = adapter._aws_bucket_params() + self.assertEqual(params["endpoint_url"], "another.s3.endpoint.com") + + def test_aws_other_region_filled(self): + adapter = self.backend._get_adapter() + self.assertFalse(self.backend.aws_region) + self.backend.aws_other_region = "fr-par" + params = adapter._aws_bucket_params() + # no region as "aws_region" is empty + self.assertNotIn("region_name", params) + self.backend.aws_region = "other" + params = adapter._aws_bucket_params() + self.assertEqual(params["region_name"], "fr-par") + + def test_aws_other_region_empty(self): + self.backend.aws_other_region = "" + adapter = self.backend._get_adapter() + params = adapter._aws_bucket_params() + self.assertNotIn("region_name", params) diff --git a/storage_backend_s3/views/backend_storage_view.xml b/storage_backend_s3/views/backend_storage_view.xml new file mode 100644 index 0000000000..80a0df38d2 --- /dev/null +++ b/storage_backend_s3/views/backend_storage_view.xml @@ -0,0 +1,45 @@ + + + + storage.backend + + + + + + + + + + + + + + + + + + + + +