From a79a67ab7b8783094da538cd0ee1eb670da09672 Mon Sep 17 00:00:00 2001 From: Arzhel Younsi Date: Wed, 6 Dec 2023 11:35:39 +0100 Subject: [PATCH 1/6] Extend STORAGE_BACKEND config to support Swift Requires django-storage-swift >= 1.4.0 when used. Bug: T310717 Change-Id: I67cf439e9152608cbba3a3de4173d54ba5fbddc2 --- docs/configuration/system.md | 4 ++-- netbox/netbox/configuration_example.py | 11 +++++++++++ netbox/netbox/settings.py | 25 +++++++++++++++++++++---- 3 files changed, 34 insertions(+), 6 deletions(-) diff --git a/docs/configuration/system.md b/docs/configuration/system.md index a1e0ebb17f9..ed588ccf332 100644 --- a/docs/configuration/system.md +++ b/docs/configuration/system.md @@ -177,7 +177,7 @@ The dotted path to the desired search backend class. `CachedValueSearchBackend` Default: None (local storage) -The backend storage engine for handling uploaded files (e.g. image attachments). NetBox supports integration with the [`django-storages`](https://django-storages.readthedocs.io/en/stable/) package, which provides backends for several popular file storage services. If not configured, local filesystem storage will be used. +The backend storage engine for handling uploaded files (e.g. image attachments). NetBox supports integration with the [`django-storages`](https://django-storages.readthedocs.io/en/stable/) and [`django-storage-swift`](https://github.com/dennisv/django-storage-swift) packages, which provides backends for several popular file storage services. If not configured, local filesystem storage will be used. The configuration parameters for the specified storage backend are defined under the `STORAGE_CONFIG` setting. @@ -187,7 +187,7 @@ The configuration parameters for the specified storage backend are defined under Default: Empty -A dictionary of configuration parameters for the storage backend configured as `STORAGE_BACKEND`. The specific parameters to be used here are specific to each backend; see the [`django-storages` documentation](https://django-storages.readthedocs.io/en/stable/) for more detail. +A dictionary of configuration parameters for the storage backend configured as `STORAGE_BACKEND`. The specific parameters to be used here are specific to each backend; see the [`django-storages` documentation](https://django-storages.readthedocs.io/en/stable/) or [`django-storage-swift` documentation](https://github.com/dennisv/django-storage-swift) for more detail. If `STORAGE_BACKEND` is not defined, this setting will be ignored. diff --git a/netbox/netbox/configuration_example.py b/netbox/netbox/configuration_example.py index 84ead53390f..5e181593086 100644 --- a/netbox/netbox/configuration_example.py +++ b/netbox/netbox/configuration_example.py @@ -230,6 +230,17 @@ # 'AWS_STORAGE_BUCKET_NAME': 'netbox', # 'AWS_S3_REGION_NAME': 'eu-west-1', # } +# Swift is also supported as storage backend, for example: +# STORAGE_BACKEND = 'swift.storage.SwiftStorage' +# STORAGE_CONFIG = { +# 'SWIFT_AUTH_URL': 'https://swift.netbox.dev/auth/v1.0', +# 'SWIFT_USERNAME': 'netbox', +# 'SWIFT_PASSWORD': 'Secret', +# 'SWIFT_CONTAINER_NAME': 'netbox', +# 'SWIFT_USE_TEMP_URLS': True, +# 'SWIFT_TEMP_URL_KEY': 'Secret', +# 'SWIFT_BASE_URL': 'https://demo.netbox.dev/', +# } # Time zone (default: UTC) TIME_ZONE = 'UTC' diff --git a/netbox/netbox/settings.py b/netbox/netbox/settings.py index 3a8e51e056c..b99b43e6681 100644 --- a/netbox/netbox/settings.py +++ b/netbox/netbox/settings.py @@ -206,6 +206,11 @@ if STORAGE_BACKEND is not None: DEFAULT_FILE_STORAGE = STORAGE_BACKEND + def _setting(name, default=None): + if name in STORAGE_CONFIG: + return STORAGE_CONFIG[name] + return globals().get(name, default) + # django-storages if STORAGE_BACKEND.startswith('storages.'): try: @@ -219,12 +224,24 @@ raise e # Monkey-patch django-storages to fetch settings from STORAGE_CONFIG - def _setting(name, default=None): - if name in STORAGE_CONFIG: - return STORAGE_CONFIG[name] - return globals().get(name, default) storages.utils.setting = _setting + elif STORAGE_BACKEND == 'swift.storage.SwiftStorage': + + try: + import swift.utils # type: ignore + except ModuleNotFoundError as e: + if getattr(e, 'name') == 'swift': + raise ImproperlyConfigured( + f"STORAGE_BACKEND is set to {STORAGE_BACKEND} but django-storage-swift is not present. " + "It can be installed by running 'pip install django-storage-swift'." + ) + raise e + + # Monkey-patch django-storage-swift to fetch settings from STORAGE_CONFIG + swift.utils.setting = _setting + + if STORAGE_CONFIG and STORAGE_BACKEND is None: warnings.warn( "STORAGE_CONFIG has been set in configuration.py but STORAGE_BACKEND is not defined. STORAGE_CONFIG will be " From 4399a156228baa24b7cc96a08fb9a4afc7753897 Mon Sep 17 00:00:00 2001 From: Arzhel Younsi Date: Wed, 26 Jun 2024 15:22:00 +0200 Subject: [PATCH 2/6] Update system.md from suggestions Co-authored-by: Jeremy Stretch --- docs/configuration/system.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/configuration/system.md b/docs/configuration/system.md index ed588ccf332..bce0a43635a 100644 --- a/docs/configuration/system.md +++ b/docs/configuration/system.md @@ -187,7 +187,7 @@ The configuration parameters for the specified storage backend are defined under Default: Empty -A dictionary of configuration parameters for the storage backend configured as `STORAGE_BACKEND`. The specific parameters to be used here are specific to each backend; see the [`django-storages` documentation](https://django-storages.readthedocs.io/en/stable/) or [`django-storage-swift` documentation](https://github.com/dennisv/django-storage-swift) for more detail. +A dictionary of configuration parameters for the storage backend configured as `STORAGE_BACKEND`. The specific parameters to be used here are specific to each backend; see the documentation for your selected backend ([`django-storages`](https://django-storages.readthedocs.io/en/stable/) or [`django-storage-swift`](https://github.com/dennisv/django-storage-swift)) for more detail. If `STORAGE_BACKEND` is not defined, this setting will be ignored. From 21753b39197c7fcf5471263105a60f28a7f98d43 Mon Sep 17 00:00:00 2001 From: Arzhel Younsi Date: Wed, 26 Jun 2024 15:22:21 +0200 Subject: [PATCH 3/6] Update settings.py from suggestions Co-authored-by: Jeremy Stretch --- netbox/netbox/settings.py | 1 + 1 file changed, 1 insertion(+) diff --git a/netbox/netbox/settings.py b/netbox/netbox/settings.py index b99b43e6681..3c0d5c68027 100644 --- a/netbox/netbox/settings.py +++ b/netbox/netbox/settings.py @@ -226,6 +226,7 @@ def _setting(name, default=None): # Monkey-patch django-storages to fetch settings from STORAGE_CONFIG storages.utils.setting = _setting + # django-storage-swift elif STORAGE_BACKEND == 'swift.storage.SwiftStorage': try: From d56ab5a880d9f1faeaf417dc21718bd9ab7477e6 Mon Sep 17 00:00:00 2001 From: Arzhel Younsi Date: Wed, 26 Jun 2024 15:22:40 +0200 Subject: [PATCH 4/6] Update system.md from suggestions 2 Co-authored-by: Jeremy Stretch --- docs/configuration/system.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/configuration/system.md b/docs/configuration/system.md index bce0a43635a..f3c68db1b29 100644 --- a/docs/configuration/system.md +++ b/docs/configuration/system.md @@ -177,7 +177,7 @@ The dotted path to the desired search backend class. `CachedValueSearchBackend` Default: None (local storage) -The backend storage engine for handling uploaded files (e.g. image attachments). NetBox supports integration with the [`django-storages`](https://django-storages.readthedocs.io/en/stable/) and [`django-storage-swift`](https://github.com/dennisv/django-storage-swift) packages, which provides backends for several popular file storage services. If not configured, local filesystem storage will be used. +The backend storage engine for handling uploaded files (e.g. image attachments). NetBox supports integration with the [`django-storages`](https://django-storages.readthedocs.io/en/stable/) and [`django-storage-swift`](https://github.com/dennisv/django-storage-swift) packages, which provide backends for several popular file storage services. If not configured, local filesystem storage will be used. The configuration parameters for the specified storage backend are defined under the `STORAGE_CONFIG` setting. From ad40f433da9a46b44ac368175d7f3452a0d0aff9 Mon Sep 17 00:00:00 2001 From: Arzhel Younsi Date: Wed, 26 Jun 2024 13:27:04 +0000 Subject: [PATCH 5/6] Remove SWIFT storage from configuration_example.py --- netbox/netbox/configuration_example.py | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/netbox/netbox/configuration_example.py b/netbox/netbox/configuration_example.py index 5e181593086..84ead53390f 100644 --- a/netbox/netbox/configuration_example.py +++ b/netbox/netbox/configuration_example.py @@ -230,17 +230,6 @@ # 'AWS_STORAGE_BUCKET_NAME': 'netbox', # 'AWS_S3_REGION_NAME': 'eu-west-1', # } -# Swift is also supported as storage backend, for example: -# STORAGE_BACKEND = 'swift.storage.SwiftStorage' -# STORAGE_CONFIG = { -# 'SWIFT_AUTH_URL': 'https://swift.netbox.dev/auth/v1.0', -# 'SWIFT_USERNAME': 'netbox', -# 'SWIFT_PASSWORD': 'Secret', -# 'SWIFT_CONTAINER_NAME': 'netbox', -# 'SWIFT_USE_TEMP_URLS': True, -# 'SWIFT_TEMP_URL_KEY': 'Secret', -# 'SWIFT_BASE_URL': 'https://demo.netbox.dev/', -# } # Time zone (default: UTC) TIME_ZONE = 'UTC' From 8256fefc93eae93594d51cbfe9c009fc2977948c Mon Sep 17 00:00:00 2001 From: Arzhel Younsi Date: Wed, 26 Jun 2024 15:58:40 +0000 Subject: [PATCH 6/6] Load swift config as global instead of monkey path --- netbox/netbox/settings.py | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/netbox/netbox/settings.py b/netbox/netbox/settings.py index 3c0d5c68027..7a248c8757f 100644 --- a/netbox/netbox/settings.py +++ b/netbox/netbox/settings.py @@ -206,11 +206,6 @@ if STORAGE_BACKEND is not None: DEFAULT_FILE_STORAGE = STORAGE_BACKEND - def _setting(name, default=None): - if name in STORAGE_CONFIG: - return STORAGE_CONFIG[name] - return globals().get(name, default) - # django-storages if STORAGE_BACKEND.startswith('storages.'): try: @@ -224,11 +219,14 @@ def _setting(name, default=None): raise e # Monkey-patch django-storages to fetch settings from STORAGE_CONFIG + def _setting(name, default=None): + if name in STORAGE_CONFIG: + return STORAGE_CONFIG[name] + return globals().get(name, default) storages.utils.setting = _setting # django-storage-swift elif STORAGE_BACKEND == 'swift.storage.SwiftStorage': - try: import swift.utils # type: ignore except ModuleNotFoundError as e: @@ -239,9 +237,10 @@ def _setting(name, default=None): ) raise e - # Monkey-patch django-storage-swift to fetch settings from STORAGE_CONFIG - swift.utils.setting = _setting - + # Load all SWIFT_* settings from the user configuration + for param, value in STORAGE_CONFIG.items(): + if param.startswith('SWIFT_'): + globals()[param] = value if STORAGE_CONFIG and STORAGE_BACKEND is None: warnings.warn(