公式提供属性默认值的最佳方式是什么? [英] What's the best way for a formula to provide attribute defaults?

查看:36
本文介绍了公式提供属性默认值的最佳方式是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Chef 有一个非常详尽的(也许太多了)的食谱方案来提供属性的默认值.我认为 Puppet 对类参数做了一些类似的事情,其中​​默认值通常进入 params.pp.使用 Salt,我见过:

Chef has a very elaborate (maybe too much so) scheme for cookbooks to provide default values of attributes. I think Puppet does something similar with class parameters where defaults usually go into params.pp. With Salt, I've seen:

  1. 在字典/支柱查找中指定默认值.
  2. grains.filter_by 将默认属性值与用户提供的支柱数据(例如,map.jinja阿帕奇公式)
  3. 在调用 file.managed 状态时,将默认属性值指定为 defaults 参数,将用户指定的支柱数据指定为 context.
  1. specifying default value in dictionary/pillar lookups.
  2. the grains.filter_by merging of default attribute values with user-provided pillar data (e.g., map.jinja in apache-formula)
  3. in a call to file.managed state, specifying default attribute values as the defaults parameter and user-specified pillar data as context.

选项 1 似乎是最常见的,但其缺点是模板文件变得非常难以阅读.它还需要在查找完成时重复默认值,很容易出错.

Option 1 seems to be the most common, but has the drawback that the template file becomes very hard to read. It also requires repeating the default value whenever the lookup is done, making it very easy to make a mistake.

选项 2 在精神上与 Chef 的方法最接近,但似乎希望将默认值分解为基于某些过滤属性(例如,记录在谷物中的操作系统类型)的案例字典.

Option 2 feels closest in spirit to Chef's approach, but seems to expect the defaults broken down into a dictionary of cases based on some filtering attribute (e.g., the OS type recorded in grains).

选项 3 还不错,但将属性默认值放入状态文件中,而不是像选项 2 那样将它们分离到自己的文件中.

Option 3 is not bad, but puts attribute defaults into the state file, instead of separating them into their own file as they are with option 2.

Saltstack 的 最佳实践文档 支持选项 2,只是它不支持没有解决如何在不必使用 grains.filter_by 的情况下将默认值与用户指定的值合并.有什么办法可以解决吗?

Saltstack's best practices doc endorses Option 2, except that it doesn't address how to merge defaults with user-specified values without having to use grains.filter_by. Is there any way around it?

推荐答案

defaults.get 的行为在 2015.8 中发生了变化,可能是由于一个错误.此答案描述了一种在(至少)2015.8 及更高版本中获得相同结果的兼容方法.

假设您的公式树如下所示:

Suppose your formula tree looks like this:

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 中,但可以在 pillar 中覆盖.支柱中未提供的任何内容都应使用默认值.您可以通过在任何给定 .sls 的顶部添加几行来完成此操作:

The idea is that formula defaults are in defaults.yaml, but can be overridden in pillar. Anything not provided in pillar should use the value in defaults. You can accomplish this with a few lines at the top of any given .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 支柱键的内容合并,支柱赢得冲突.结果是一个包含默认值和任何支柱覆盖的嵌套字典,然后可以直接使用它而无需关心特定值的来源.

What this does: The contents of defaults.yaml are loaded in as a nested dictionary. That nested dictionary is then merged with the contents of the something pillar key, with the pillar winning conflicts. The result is a nested dictionary containing both the defaults and any pillar overrides, which can then be used directly without concern to where a particular value came from.

slspath 不是严格要求的;它是一个魔法变量,包含当前运行的 sls 的目录路径.我喜欢使用它,因为它将公式与目录树中的任何特定位置分离.它通常不能从托管模板中获得,这就是我将它作为上面的显式上下文传递的原因.在旧版本中它可能无法按预期工作,在这种情况下,您必须提供相对于盐树根的路径.

slspath is not strictly required for this to work; it's a magic variable that contains the directory path to the currently-running sls. I like to use it because it decouples the formula from any particular location in the directory tree. It is not normally available from managed templates, which is why I pass it on as explicit context above. It may not work as expected in older versions, in which case you'll have to provide a path relative to the root of the salt tree.

这种方法的缺点是,据我所知,您无法使用 salt 的基于冒号的嵌套键语法访问最终字典;你需要一次下降一层.我没有遇到任何问题(无论如何,点语法更容易输入),但这是一个缺点.另一个缺点是使用该技术的任何 .sls 或模板顶部都需要几行样板.

The downside to this method is that, so far as I know, you can't access the final dictionary with salt's colon-based nested-keys syntax; you need to descend through it one level at a time. I have not had problems with that (dot syntax is easier to type anyway), but it is a downside. Another downside is the need for a few lines of boilerplate at the top of any .sls or template using the technique.

有一些好处.一是您可以使用 .items() 循环遍历最终字典或其子字典,然后就会发生正确的事情,而 defaults.get 并非如此,这让我发疯.另一个是,如果当 salt 团队恢复 defaults.get 的旧功能时,这里建议的 defaults/pillar 结构已经兼容,并且它们将一起正常工作.

There are a few upsides. One is that you can loop over the final dictionary or its sub-dicts with .items() and the Right Thing will happen, which was not the case with defaults.get and which drove me insane. Another is that, if and when the salt team restores defaults.get's old functionality, the defaults/pillar structure suggested here is already compatible and they'll work fine side by side.

这篇关于公式提供属性默认值的最佳方式是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆