Chef为烹饪书提供了一个非常精细(可能太多)的方案来提供属性的默认值。我认为Puppet与类参数类似,默认情况下通常会进入params.pp
。有了盐,我见过:
grains.filter_by
合并默认属性值与用户提供的支柱数据(例如map.jinja中的apache-formula)file.managed
州时,将默认属性值指定为defaults
参数,将用户指定的支柱数据指定为context
。选项1似乎是最常见的,但缺点是模板文件变得非常难以阅读。它还需要在查找完成时重复默认值,这样就很容易出错。
选项2在精神上与Chef的方法感觉最接近,但似乎期望默认值基于某些过滤属性(例如,谷物中记录的操作系统类型)分解为案例字典。
选项3也不错,但是将属性默认值放入状态文件中,而不是像选项2那样将它们分成自己的文件。
Saltstack的best practices doc支持选项2,但它没有解决如何在不使用grains.filter_by
的情况下将默认值与用户指定的值合并的问题。有什么方法吗?
答案 0 :(得分:4)
注意:defaults.get的行为在版本2015.8中已更改,因此此处描述的方法不再有效。我将为旧版本的用户留下此答案,并将为当前版本发布类似的方法。
defaults.get
加上defaults.yaml
文件可以做你想要的。假设您的公式树看起来像这样:
my-formula/
files/
template.jinja
init.sls
defaults.yaml
# my-formula/init.sls
my-formula-conf-file:
file.managed:
- name: {{ salt['defaults.get']('conf_location') }}
- source: {{ salt['defaults.get']('conf_source') }}
... and so on.
# defaults.yaml
conf_location: /etc/my-formula.conf
conf_source: salt://my-formula/files/template.jinja
# pillar/my-formula.sls
my-formula:
conf_location: /etc/my-formula/something.conf
这将以/etc/my-formula/something.conf
(支柱值)的配置文件结束,使用salt://my-formula/files/template.jinja
作为源(默认情况下,没有提供支柱覆盖)。
注意支柱和默认文件的非直观结构; defaults.get
期望defaults.yaml
将其值保存在文件的根目录中,但希望支柱覆盖位于以公式命名的字典中,因为一致性适用于弱点。
defaults.get的documentation使用defaults.json
代替defaults.yaml
来举例说明。这有效,但我发现yaml更具可读性。可写。
有一个bug来自托管模板内部而不是状态文件中的defaults.get,据我所知,它仍然是打开的。它仍然可以工作;解决方法在链接后面。
答案 1 :(得分:1)
defaults.get的行为在2015.8中发生了变化,可能是由于某个错误。这个答案描述了在(至少)2015.8及更高版本中获得相同结果的兼容方法。
假设您的公式树如下所示:
something/
files/
template.jinja
init.sls
defaults.yaml
# defaults.yaml
conf_location: /etc/something.conf
conf_source: salt://something/files/template.jinja
# pillar/something.sls
something:
conf_location: /etc/something/something.conf
这个想法是公式默认值在defaults.yaml中,但可以在支柱中重写。柱子中未提供的任何内容都应使用默认值。您可以通过任何给定.sls顶部的几行来完成此任务:
# something/init.sls
{%- set pget = salt['pillar.get'] %} # Convenience alias
{%- import_yaml slspath + "/defaults.yaml" as defaults %}
{%- set something = pget('something', defaults, merge=True) %}
something-conf-file:
file.managed:
- name: {{ something.conf_location }}
- source: {{ something.conf_source }}
- template: jinja
- context:
slspath: {{ slspath }}
... and so on.
这是做什么的:defaults.yaml的内容作为嵌套字典加载。然后,嵌套字典与something
支柱键的内容合并,支柱赢得冲突。结果是一个包含默认值和任何柱子覆盖的嵌套字典,然后可以直接使用它而不用考虑特定值的来源。
slspath
并非严格要求工作;它是一个神奇的变量,包含当前运行的sls的目录路径。我喜欢使用它,因为它将公式与目录树中的任何特定位置分离。它通常不能从托管模板中获得,这就是我将其作为上面的显式上下文传递的原因。它在旧版本中可能无法正常工作,在这种情况下,您必须提供相对于salt树根的路径。
这种方法的缺点是,据我所知,你无法使用salt的基于冒号的嵌套键语法访问最终字典;你需要一次下降一级。我没有遇到过这方面的问题(点法语法更容易输入),但这是一个缺点。另一个缺点是需要使用该技术在任何.sls或模板顶部使用几行样板。
有一些上升空间。一个是你可以使用.items()
遍历最终字典或其子字典,并且会发生正确的事情,而defaults.get并非如此,这让我疯狂。另一个是,如果盐团队恢复defaults.get的旧功能,这里建议的默认/柱结构已经兼容,它们将并行工作。