We have a python application that loads a config.yml
with aumbry. For production purpose we need to encrypt this configuration with fernet, which aumbry can load seamlessly.
We want to be able to load both unencrypted and encrypted in a transparent way, for example load unencrypted if found, and if not (production) load encrypted. So far we have implemented this.
import cryptography.Fernet as fn
from os.path import split, splitext
def _encrypt_file(path, key):
with open(path, 'rb') as infile:
file_data = infile.read()
nc_data= fn(key).encrypt(file_data)
infile.close()
base_path, filename = split(path)
name, _ = splitext(filename)
nc_name = "{}.{}".format(name, 'nc')
with open(join(base_path, nc_name), 'wb') as outfile:
outfile.write(nc_data)
outfile.close()
from aumbry.errors import LoadError
def _get_configuration():
return aumbry.load(
aumbry.FILE,
AppConfig,
options={
'CONFIG_FILE_PATH': "config.yml"
}
)
def _get_encrypted_configuration():
return aumbry.load(
aumbry.FERNET,
AppConfig,
options={
'CONFIG_FILE_PATH': "config.nc",
'CONFIG_FILE_FERNET_KEY': 'bZhF6nN4A6fhVBPtru2dG1_6d7i0d_B2FxmsybjtE-g='
}
)
def load_config():
"""General method to load configuration"""
try:
return _get_configuration()
except LoadError:
try:
return _get_encrypted_configuration()
except LoadError:
return None
Depending on the framework on which your python application is built, there is usually some kind of global "mode" value that can be used.
Flask, for example, uses FLASK_ENV
environment variable that can be set to either development
or production
. Within the app, you can use
app.config['DEBUG'] # True if FLASK_ENV is "development"
to differentiate between the 2 modes.
In your case, the ambury loader can be refactored to do:
config_loader_cls = EncryptedConfigLoader if environment=='production' else PlainConfigLoader
I would go even further and have EncryptedConfigLoader
fail if the configuration is not encrypted for additional security.
There are a few solutions:
a) Encrypted files use different file names from its unencrypted counterparts. For example, an unencrypted file with the name "config.yml" may be renamed to "config_en.yml". This may not be your option.
b) I notice that "config.yml" normally has "version: 2" in its content. You just need to use Python to check if "version:
is in
the file, if so, it is unencrypted.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With