2015-07-24 18:52:19 +00:00
|
|
|
import logging
|
2016-10-10 20:23:42 +00:00
|
|
|
import yaml
|
|
|
|
|
2016-10-18 22:47:51 +00:00
|
|
|
from util.license import LICENSE_FILENAME, LicenseDecodeError, decode_license
|
2015-07-24 18:52:19 +00:00
|
|
|
|
2015-10-30 19:48:29 +00:00
|
|
|
|
2015-07-24 18:52:19 +00:00
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
2016-10-10 20:23:42 +00:00
|
|
|
|
2015-07-24 18:52:19 +00:00
|
|
|
class CannotWriteConfigException(Exception):
|
|
|
|
""" Exception raised when the config cannot be written. """
|
|
|
|
pass
|
|
|
|
|
2016-10-10 20:23:42 +00:00
|
|
|
|
2015-10-30 19:48:29 +00:00
|
|
|
class SetupIncompleteException(Exception):
|
|
|
|
""" Exception raised when attempting to verify config that has not yet been setup. """
|
|
|
|
pass
|
|
|
|
|
2016-10-10 20:23:42 +00:00
|
|
|
|
2015-07-24 18:52:19 +00:00
|
|
|
def import_yaml(config_obj, config_file):
|
|
|
|
with open(config_file) as f:
|
|
|
|
c = yaml.safe_load(f)
|
|
|
|
if not c:
|
|
|
|
logger.debug('Empty YAML config file')
|
|
|
|
return
|
|
|
|
|
|
|
|
if isinstance(c, str):
|
|
|
|
raise Exception('Invalid YAML config file: ' + str(c))
|
|
|
|
|
|
|
|
for key in c.iterkeys():
|
|
|
|
if key.isupper():
|
|
|
|
config_obj[key] = c[key]
|
|
|
|
|
|
|
|
return config_obj
|
|
|
|
|
|
|
|
|
2015-07-27 15:17:44 +00:00
|
|
|
def get_yaml(config_obj):
|
|
|
|
return yaml.safe_dump(config_obj, encoding='utf-8', allow_unicode=True)
|
|
|
|
|
2016-10-10 20:23:42 +00:00
|
|
|
|
2015-07-24 18:52:19 +00:00
|
|
|
def export_yaml(config_obj, config_file):
|
|
|
|
try:
|
|
|
|
with open(config_file, 'w') as f:
|
2015-07-27 15:17:44 +00:00
|
|
|
f.write(get_yaml(config_obj))
|
2015-07-24 18:52:19 +00:00
|
|
|
except IOError as ioe:
|
|
|
|
raise CannotWriteConfigException(str(ioe))
|
|
|
|
|
|
|
|
|
|
|
|
class BaseProvider(object):
|
|
|
|
""" A configuration provider helps to load, save, and handle config override in the application.
|
|
|
|
"""
|
2015-10-30 19:48:29 +00:00
|
|
|
def __init__(self):
|
|
|
|
self.license = None
|
2015-07-24 18:52:19 +00:00
|
|
|
|
2015-07-27 15:17:44 +00:00
|
|
|
@property
|
|
|
|
def provider_id(self):
|
|
|
|
raise NotImplementedError
|
|
|
|
|
2015-07-24 18:52:19 +00:00
|
|
|
def update_app_config(self, app_config):
|
|
|
|
""" Updates the given application config object with the loaded override config. """
|
|
|
|
raise NotImplementedError
|
|
|
|
|
2015-07-27 15:17:44 +00:00
|
|
|
def get_config(self):
|
|
|
|
""" Returns the contents of the config override file, or None if none. """
|
2015-07-24 18:52:19 +00:00
|
|
|
raise NotImplementedError
|
|
|
|
|
2015-07-27 15:17:44 +00:00
|
|
|
def save_config(self, config_object):
|
|
|
|
""" Updates the contents of the config override file to those given. """
|
2015-07-24 18:52:19 +00:00
|
|
|
raise NotImplementedError
|
|
|
|
|
2015-07-27 15:17:44 +00:00
|
|
|
def config_exists(self):
|
|
|
|
""" Returns true if a config override file exists in the config volume. """
|
2015-07-24 18:52:19 +00:00
|
|
|
raise NotImplementedError
|
|
|
|
|
|
|
|
def volume_exists(self):
|
|
|
|
""" Returns whether the config override volume exists. """
|
|
|
|
raise NotImplementedError
|
|
|
|
|
|
|
|
def volume_file_exists(self, filename):
|
|
|
|
""" Returns whether the file with the given name exists under the config override volume. """
|
|
|
|
raise NotImplementedError
|
|
|
|
|
2016-10-13 18:53:50 +00:00
|
|
|
def get_volume_file(self, filename, mode='r'):
|
2015-12-08 20:00:50 +00:00
|
|
|
""" Returns a Python file referring to the given name under the config override volume. """
|
|
|
|
raise NotImplementedError
|
|
|
|
|
|
|
|
def write_volume_file(self, filename, contents):
|
|
|
|
""" Writes the given contents to the config override volumne, with the given filename. """
|
2015-07-24 18:52:19 +00:00
|
|
|
raise NotImplementedError
|
|
|
|
|
2016-12-09 22:37:26 +00:00
|
|
|
def remove_volume_file(self, filename):
|
|
|
|
""" Removes the config override volume file with the given filename. """
|
|
|
|
raise NotImplementedError
|
|
|
|
|
|
|
|
def list_volume_directory(self, path):
|
|
|
|
""" Returns a list of strings representing the names of the files found in the config override
|
|
|
|
directory under the given path. If the path doesn't exist, returns None.
|
|
|
|
"""
|
|
|
|
raise NotImplementedError
|
|
|
|
|
2015-07-24 18:52:19 +00:00
|
|
|
def save_volume_file(self, filename, flask_file):
|
|
|
|
""" Saves the given flask file to the config override volume, with the given
|
|
|
|
filename.
|
|
|
|
"""
|
|
|
|
raise NotImplementedError
|
|
|
|
|
|
|
|
def requires_restart(self, app_config):
|
|
|
|
""" If true, the configuration loaded into memory for the app does not match that on disk,
|
|
|
|
indicating that this container requires a restart.
|
|
|
|
"""
|
2015-10-30 19:48:29 +00:00
|
|
|
raise NotImplementedError
|
|
|
|
|
2015-12-08 20:00:50 +00:00
|
|
|
def _get_license_file(self):
|
|
|
|
""" Returns the contents of the license file. """
|
2016-10-11 19:16:28 +00:00
|
|
|
if not self.has_license_file():
|
|
|
|
msg = 'Could not find license file. Please make sure it is in your config volume.'
|
2016-10-18 22:47:51 +00:00
|
|
|
raise LicenseDecodeError(msg)
|
2016-10-11 19:16:28 +00:00
|
|
|
|
2015-12-08 20:00:50 +00:00
|
|
|
try:
|
2016-10-17 19:21:11 +00:00
|
|
|
return self.get_volume_file(LICENSE_FILENAME)
|
2015-12-08 20:00:50 +00:00
|
|
|
except IOError:
|
2016-10-17 19:21:11 +00:00
|
|
|
msg = 'Could not open license file. Please make sure it is in your config volume.'
|
2016-10-18 22:47:51 +00:00
|
|
|
raise LicenseDecodeError(msg)
|
2015-12-08 20:00:50 +00:00
|
|
|
|
2016-10-11 19:16:28 +00:00
|
|
|
def get_license(self):
|
|
|
|
""" Returns the decoded license, if any. """
|
2015-10-30 19:48:29 +00:00
|
|
|
with self._get_license_file() as f:
|
|
|
|
license_file_contents = f.read()
|
|
|
|
|
2016-10-11 19:16:28 +00:00
|
|
|
return decode_license(license_file_contents)
|
2015-10-30 19:48:29 +00:00
|
|
|
|
2015-12-08 20:00:50 +00:00
|
|
|
def save_license(self, license_file_contents):
|
|
|
|
""" Saves the given contents as the license file. """
|
|
|
|
self.write_volume_file(LICENSE_FILENAME, license_file_contents)
|
2015-10-30 19:48:29 +00:00
|
|
|
|
2015-12-08 20:00:50 +00:00
|
|
|
def has_license_file(self):
|
|
|
|
""" Returns true if a license file was found in the config directory. """
|
|
|
|
return self.volume_file_exists(LICENSE_FILENAME)
|