我想保持development.ini
和production.ini
版本控制之下,但出于安全原因,不想让sqlalchemy.url
存储连接字符串,因为这将包含用于数据库连接的用户名和密码。
什么是规范的方法,在金字塔,从一个额外的外部文件采购此设置的?
编辑除了使用环境变量的解决方案,我想出了这个解决方案要求各地于#pyramid后:
def main(global_config, **settings):
""" This function returns a Pyramid WSGI application.
"""
# Read db password from config file outside of version control
secret_cfg = ConfigParser()
secret_cfg.read(settings['secrets'])
dbpass = secret_cfg.get("secrets", "dbpass")
settings['sqlalchemy.url'] = settings['connstr'] % (dbpass,)
我看着这个了很多,有很多不同的方法发挥。 然而,金字塔是如此灵活,和.ini
配置解析器是它做什么对你那么微乎其微,这似乎没有成为一个事实上的答案。
在我的方案,我想有production.example.ini
首先在版本控制那跟填写细节在生产服务器上复制,但这个有毛,像更新的例子没有得到转化为副本,所以副本必须重新创建一个变化的任何时间。 此外,我开始使用Heroku上,所以文件中没有版本控制从未进入部署。
然后,是加密的配置方法。 其中,我不喜欢的范例。 想象一下,一个系统管理员负责维护生产环境,但他或她无法更改数据库或特定环境设定的位置,但不运行它放回通过版本控制。 这真是不错的环境和代码之间的距离尽可能地使这些变化可以在没有版本控制修订飞行进行。
我最终的解决办法是有一个看起来像这样的一些值:
[app:main]
sqlalchemy.url = ${SQLALCHEMY_URL}
然后,在生产服务器上,我将设置环境变量SQLALCHEMY_URL
指向数据库。 这甚至让我使用临时和生产相同的配置文件,这是很好的。
在我的金字塔的init,我只是扩大使用环境变量值os.path.expandvars
:
sqlalchemy_url = os.path.expandvars(settings.get('sqlalchemy.url'))
engine = create_engine(sqlalchemy_url)
而且,如果你想获得幻想与它会自动替换设置字典中的所有环境变量,我做我的项目,这个小帮手方法:
def expandvars_dict(settings):
"""Expands all environment variables in a settings dictionary."""
return dict((key, os.path.expandvars(value)) for
key, value in settings.iteritems())
使用它像这样在你的main
应用程序的入口点:
settings = expandvars_dict(settings)
在金字塔单独的INI文件的全部要点是,你不必版本控制所有的人,他们可以包含不同的场景(开发/生产/测试)不同的设置。 你production.ini几乎总是不应该在同一个VCS的源代码。
我发现这种方式对于装载秘密从一个额外的配置,从ENV。
from pyramid.config import Configurator
from paste.deploy import appconfig
from os import path
__all__ = [ "main" ]
def _load_secrets(global_config, settings):
""" Helper to load secrets from a secrets config and
from env (in that order).
"""
if "drawstack.secrets" in settings:
secrets_config = appconfig('config:' + settings["drawstack.secrets"],
relative_to=path.dirname(global_config['__file__']))
for k, v in secrets_config.items():
if k == "here" or k == "__file__":
continue
settings[k] = v
if "ENV_DB_URL" in global_config:
settings["sqlalchemy.url"] = global_config["ENV_DB_URL"]
def main(global_config, **settings):
""" This function returns a Pyramid WSGI application.
"""
_load_secrets(global_config, settings)
config = Configurator(settings=settings)
config.include('pyramid_jinja2')
config.include('.models')
config.include('.routes')
config.scan()
return config.make_wsgi_app()
上面的代码,将从配置密钥的值加载任何变量drawstack.secrets
并且它试图加载后DB_URL
从enviornment。
drawstack.secrets
可以相对于原来的配置文件或绝对。
文章来源: In the Pyramid web framework, how do I source sensitive settings into development.ini / production.ini from an external file?