[IMP] attachment_azure: Add support for DB operations

This commit is contained in:
Hiren Pattani-SerpentCS
2021-08-12 11:10:52 -05:00
committed by Maxime Chambreuil
co-authored by Maxime Chambreuil
parent 4b61f43f85
commit 1c25f1c1a8
6 changed files with 120 additions and 13 deletions
+33 -9
View File
@@ -13,20 +13,44 @@ Activate Azure Blob storage:
* Create or set the system parameter with the key ``ir_attachment.location``
and the value in the form ``azure``.
Configure accesses with environment variables:
* Configure accesses with the following environment variables:
* ``AZURE_STORAGE_CONNECTION_STRING`` or
* ``AZURE_STORAGE_ACCOUNT_NAME``
* ``AZURE_STORAGE_ACCOUNT_URL``
* ``AZURE_STORAGE_ACCOUNT_KEY``
.. list-table::
:header-rows: 1
* - Name
- Description
- Values
* - ``AZURE_STORAGE_CONNECTION_STRING``
- Connection string.
- Required if using the connection string authentication method.
* - ``AZURE_STORAGE_ACCOUNT_NAME``
- Name of the storage account.
- Required if using the storage account authentication method.
* - ``AZURE_STORAGE_ACCOUNT_URL``
- URL of the storage account
-
* - ``AZURE_STORAGE_ACCOUNT_KEY``
- Key of the storage account
-
* - ``AZURE_STORAGE_NAME``
- Name of the container within the blob storage. 1 container per database will be
created.
- Optional. The strings ``{db}`` and ``{env}`` can be used inside that variable
and the values will be replaced respectively by the database name and environment
name.
* - ``AZURE_DUPLICATE``
- If set, the blob storage and all its objects will be copied when the database is
duplicated.
- True
* - ``AZURE_DELETE_ON_DBDROP``
- If set, the container and all its objects will be deleted when the database is
dropped.
- True
One container will be created per database using the `RUNNING_ENV` environment variable
and the name of the database. By default, `RUNNING_ENV` is set to `dev`.
The container name can be overridden with environment variable ``AZURE_STORAGE_NAME``.
The strings ``{db}`` and ``{env}`` can be used inside that variable and the values
will be replaced respectively by the database name and environment name.
This addon must be added in the server wide addons with (``--load`` option):
``--load=web,attachment_azure``
+16
View File
@@ -1,4 +1,20 @@
# Copyright 2016-2019 Camptocamp SA
# Copyright 2021 Open Source Integrators
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html)
import os
from . import models
from . import controllers
from odoo import api, SUPERUSER_ID
def _post_init_hook(cr, registry):
# create the S3 bucket after module installation
if os.environ.get("AZURE_STORAGE_CONNECTION_STRING", False):
env = api.Environment(cr, SUPERUSER_ID, {})
env["ir.attachment"]._get_azure_container()
env["ir.config_parameter"].create(
{"key": "ir_attachment.location", "value": "azure"}
)
env["ir.attachment"].force_storage()
+1
View File
@@ -18,5 +18,6 @@
"website": "https://github.com/camptocamp/odoo-cloud-platform",
"installable": True,
"development_status": "Beta",
"post_init_hook": "_post_init_hook",
"maintainers": ["max3903"],
}
+1
View File
@@ -0,0 +1 @@
from . import main
+66
View File
@@ -0,0 +1,66 @@
import logging
import os
from odoo.addons.web.controllers.main import Database
from odoo import http
from odoo import exceptions
from odoo.http import request
_logger = logging.getLogger(__name__)
class Database(Database):
@http.route()
def drop(self, master_pwd, name):
res = super().drop(master_pwd, name)
delete = os.environ.get("AZURE_DELETE_ON_DBDROP", False)
if delete:
attachment_obj = request.env["ir.attachment"]
try:
container_name = attachment_obj._get_container_name()
blob_service_client = attachment_obj._get_blob_service_client()
container_client = blob_service_client.get_container_client(
container_name
)
container_client.delete_container()
except exceptions.UserError:
_logger.exception("Error deleting attachments from object storage.")
return res
@http.route()
def duplicate(self, master_pwd, name, new_name):
res = super().duplicate(master_pwd, name, new_name)
duplicate = os.environ.get("AWS_DUPLICATE", False)
if duplicate:
attachment_obj = request.env["ir.attachment"]
try:
copy_from_container = attachment_obj._get_container_name()
copy_to_container = attachment_obj._get_container_name(new_name)
blob_service = attachment_obj._get_blob_service_client()
container_client = blob_service.get_container_client(
copy_from_container
)
blobs_list = container_client.list_blobs()
for blob in blobs_list:
blob_url = container_client.make_blob_url(
copy_from_container, blob.name
)
container_client.copy_blob(copy_to_container, blob.name, blob_url)
except exceptions.UserError:
_logger.exception("Error writing attachments to object storage.")
return res
@http.route()
def restore(self, master_pwd, backup_file, name, copy=False):
res = super().restore(master_pwd, backup_file, name, copy)
attachment_obj = request.env["ir.attachment"]
try:
attachment_obj._get_azure_container()
request.env["ir.config_parameter"].create(
{"key": "ir_attachment.location", "value": "azure"}
)
attachment_obj.force_storage()
except exceptions.UserError:
_logger.exception("Error writing attachments to object storage.")
return res
+3 -4
View File
@@ -111,16 +111,15 @@ class IrAttachment(models.Model):
return blob_service_client
@api.model
def _get_container_name(self):
def _get_container_name(self, db_name=None):
"""
Container naming rules:
https://docs.microsoft.com/en-us/rest/api/storageservices/naming-and-referencing-containers--blobs--and-metadata#container-names
"""
running_env = os.environ.get("RUNNING_ENV", "dev")
storage_name = os.environ.get('AZURE_STORAGE_NAME', r'{env}-{db}')
storage_name = os.environ.get("AZURE_STORAGE_NAME", r"{env}-{db}")
storage_name = storage_name.format(
env=running_env,
db=self.env.cr.dbname
env=running_env, db=db_name or self.env.cr.dbname
)
# replace invalid characters by _
storage_name = re.sub(r"[\W_]+", "-", storage_name)