使用 aumbry 支持加密和非加密配置
Support both encrypted and non encrypted configuration with aumbry
我们有一个 python 应用程序,它使用 aumbry. For production purpose we need to encrypt this configuration with fernet 加载 config.yml
,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()
Aumbry 配置
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 应用程序的框架,通常可以使用某种全局 "mode" 值。
例如,Flask 使用可以设置为 development
或 production
的 FLASK_ENV
环境变量。在应用程序中,您可以使用
app.config['DEBUG'] # True if FLASK_ENV is "development"
区分这两种模式。
对于您的情况,ambury 加载程序可以重构为:
config_loader_cls = EncryptedConfigLoader if environment=='production' else PlainConfigLoader
如果配置未加密以提高安全性,我会更进一步让EncryptedConfigLoader
失败。
有几个解决方案:
a) 加密文件使用与未加密文件不同的文件名。例如,名称为 "config.yml" 的未加密文件可能会重命名为 "config_en.yml"。这可能不是您的选择。
b) 我注意到 "config.yml" 的内容通常包含 "version: 2"。您只需要使用 Python 来检查 "version:
是否是 in
文件,如果是,则它是未加密的。
我们有一个 python 应用程序,它使用 aumbry. For production purpose we need to encrypt this configuration with fernet 加载 config.yml
,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()
Aumbry 配置
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 应用程序的框架,通常可以使用某种全局 "mode" 值。
例如,Flask 使用可以设置为 development
或 production
的 FLASK_ENV
环境变量。在应用程序中,您可以使用
app.config['DEBUG'] # True if FLASK_ENV is "development"
区分这两种模式。
对于您的情况,ambury 加载程序可以重构为:
config_loader_cls = EncryptedConfigLoader if environment=='production' else PlainConfigLoader
如果配置未加密以提高安全性,我会更进一步让EncryptedConfigLoader
失败。
有几个解决方案:
a) 加密文件使用与未加密文件不同的文件名。例如,名称为 "config.yml" 的未加密文件可能会重命名为 "config_en.yml"。这可能不是您的选择。
b) 我注意到 "config.yml" 的内容通常包含 "version: 2"。您只需要使用 Python 来检查 "version:
是否是 in
文件,如果是,则它是未加密的。