diff --git a/CHANGELOG.md b/CHANGELOG.md index 2afa1d0f9..d8cdb623b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -28,6 +28,9 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) ### Fixed - Quota updates concerning volumes would silently fail ([#611](https://github.com/cyverse/atmosphere/pull/611)) +### Added +- Added dynamic settings feature ([#613](https://github.com/cyverse/atmosphere/pull/613)) + ## [v32-1](https://github.com/cyverse/atmosphere/compare/v32-0...v32-1) - 2018-04-17 ### Added - Support multiple hostnames for Atmosphere(1) server ([#602](https://github.com/cyverse/atmosphere/pull/602)) diff --git a/atmosphere/settings/__init__.py b/atmosphere/settings/__init__.py index c52928905..483e49fca 100644 --- a/atmosphere/settings/__init__.py +++ b/atmosphere/settings/__init__.py @@ -51,6 +51,8 @@ # Django uses this one.. MANAGERS = ADMINS +CONSTANCE_BACKEND = 'constance.backends.database.DatabaseBackend' +CONSTANCE_DATABASE_CACHE_BACKEND = 'default' DATABASES = { 'default': { @@ -92,6 +94,8 @@ 'cyverse_allocation', 'service', 'core', + 'constance', + 'constance.backends.database' ) SESSION_COOKIE_NAME = 'atmo_sessionid' diff --git a/atmosphere/settings/local.py.j2 b/atmosphere/settings/local.py.j2 index da5fd2c81..8544e98eb 100644 --- a/atmosphere/settings/local.py.j2 +++ b/atmosphere/settings/local.py.j2 @@ -4,6 +4,7 @@ Settings specific to the local deploy. import os import sys import logging +from collections import OrderedDict from datetime import timedelta from celery.schedules import crontab @@ -500,6 +501,11 @@ TACC_API_PASS = '' TACC_API_URL = '' {% endif %} +CONSTANCE_CONFIG = OrderedDict([ + ('ALLOCATION_OVERRIDES_NEVER_ENFORCE', ('', 'Never enforce on these allocation sources. Comma-separated strings.')), + ('ALLOCATION_OVERRIDES_ALWAYS_ENFORCE', ('', 'Stop all instances on these allocation sources (nuclear option)')), +]) + ###### # Atmosphere Plugin Settings ###### diff --git a/cyverse_allocation/plugins/allocation_source.py b/cyverse_allocation/plugins/allocation_source.py index eae4ddfad..56edde2b3 100644 --- a/cyverse_allocation/plugins/allocation_source.py +++ b/cyverse_allocation/plugins/allocation_source.py @@ -1,6 +1,7 @@ import uuid from django.conf import settings +from constance import config as constance_config from django.core.exceptions import ObjectDoesNotExist from threepio import logger @@ -49,9 +50,9 @@ def _get_enforcement_override(allocation_source): """ assert isinstance(allocation_source, AllocationSource) import core.plugins - if allocation_source.name in getattr(settings, 'ALLOCATION_OVERRIDES_NEVER_ENFORCE', []): + if allocation_source.name in getattr(constance_config, 'ALLOCATION_OVERRIDES_NEVER_ENFORCE', '').split(','): return core.plugins.EnforcementOverrideChoice.NEVER_ENFORCE - if allocation_source.name in getattr(settings, 'ALLOCATION_OVERRIDES_ALWAYS_ENFORCE', []): + if allocation_source.name in getattr(constance_config, 'ALLOCATION_OVERRIDES_ALWAYS_ENFORCE', '').split(','): return core.plugins.EnforcementOverrideChoice.ALWAYS_ENFORCE return core.plugins.EnforcementOverrideChoice.NO_OVERRIDE diff --git a/dev_requirements.txt b/dev_requirements.txt index 89d51b8e5..a4769404e 100644 --- a/dev_requirements.txt +++ b/dev_requirements.txt @@ -41,6 +41,7 @@ decorator==4.1.2 # via ipython, traitlets defusedxml==0.5.0 deprecation==1.0.1 django-celery-beat==1.0.1 +django-constance[database]==2.2.0 django-cors-headers==2.1.0 django-cyverse-auth==1.1.4 django-debug-toolbar==1.8 @@ -48,6 +49,7 @@ django-filter==1.0.4 django-jenkins==0.110.0 django-memoize==2.1.0 django-nose==1.4.4 +django-picklefield==1.0.0 django-redis-cache==1.7.1 django-sslserver==0.20 django==1.11.4 diff --git a/jetstream/plugins/allocation_source.py b/jetstream/plugins/allocation_source.py index 46df74ef5..2c64fd117 100644 --- a/jetstream/plugins/allocation_source.py +++ b/jetstream/plugins/allocation_source.py @@ -1,4 +1,4 @@ -from django.conf import settings +from constance import config as constance_config from core.models import AllocationSource @@ -44,9 +44,9 @@ def _get_enforcement_override(allocation_source): """ assert isinstance(allocation_source, AllocationSource) import core.plugins - if allocation_source.name in getattr(settings, 'ALLOCATION_OVERRIDES_NEVER_ENFORCE', []): + if allocation_source.name in getattr(constance_config, 'ALLOCATION_OVERRIDES_NEVER_ENFORCE', '').split(','): return core.plugins.EnforcementOverrideChoice.NEVER_ENFORCE - if allocation_source.name in getattr(settings, 'ALLOCATION_OVERRIDES_ALWAYS_ENFORCE', []): + if allocation_source.name in getattr(constance_config, 'ALLOCATION_OVERRIDES_ALWAYS_ENFORCE', '').split(','): return core.plugins.EnforcementOverrideChoice.ALWAYS_ENFORCE return core.plugins.EnforcementOverrideChoice.NO_OVERRIDE diff --git a/requirements.in b/requirements.in index 9075be11b..1ae8d5a99 100644 --- a/requirements.in +++ b/requirements.in @@ -41,6 +41,8 @@ psycopg2 python-ldap uWSGI +django-constance[database] + ## ours chromogenic django-cyverse-auth diff --git a/requirements.txt b/requirements.txt index e7a3a638e..8a5154791 100644 --- a/requirements.txt +++ b/requirements.txt @@ -31,10 +31,12 @@ debtcollector==1.17.0 # via oslo.config, oslo.context, oslo.log, oslo.utils, defusedxml==0.5.0 # via djangorestframework-xml deprecation==1.0.1 # via openstacksdk django-celery-beat==1.0.1 +django-constance[database]==2.2.0 django-cors-headers==2.1.0 django-cyverse-auth==1.1.4 django-filter==1.0.4 django-memoize==2.1.0 +django-picklefield==1.0.0 # via django-constance django-redis-cache==1.7.1 django-sslserver==0.20 django==1.11.4