python - 支持带有 aumbry 的加密和非加密配置
问题描述
我们有一个 python 应用程序,它加载config.yml
了aumbry。出于生产目的,我们需要使用 fernet 加密此配置,aumbry可以无缝加载。
我们希望能够以透明的方式加载未加密和加密的内容,例如,如果找到则加载未加密,如果没有(生产)加载加密。到目前为止,我们已经实现了这一点。
加密
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
- 有没有更优雅的方式来实现这种行为?
解决方案
根据构建 Python 应用程序的框架,通常可以使用某种全局“模式”值。
例如,Flask 使用FLASK_ENV
可以设置为development
或的环境变量production
。在应用程序中,您可以使用
app.config['DEBUG'] # True if FLASK_ENV is "development"
区分两种模式。
在您的情况下,可以将 ambury 加载程序重构为:
config_loader_cls = EncryptedConfigLoader if environment=='production' else PlainConfigLoader
EncryptedConfigLoader
如果配置未加密以提高安全性,我会走得更远并且失败。