首页 > 解决方案 > 条件资源属性

问题描述

为了安装软件包,我将来自 Hiera 的数据输入到 for 循环中。一些包需要额外的参数。对于不需要参数的包,我将值设置为undef,但是,Chocolatey 读取undef并抱怨。

当它为空白或时,如何让package资源忽略该属性?install_optionsundef

希拉片段:

profile::business::packages:
  office365business:
    version: latest
    provider: chocolatey
    arguments: ['/productid:O365BusinessRetail']
  xmind:
    version: latest
    provider: chocolatey
    arguments: undef
  slack:
    version: latest
    provider: chocolatey
    arguments: undef

类示例:

class profile::business(
  Hash $packages,
){
  if $::kernel == 'windows' {
    $packages.each | $key, $value | {
      package { "install_${key}" :
        name            => $key,
        ensure          => $value['version'],
        provider        => $value['provider'],
        install_options => $value['arguments'],
        notify          => Reboot['after_profile_business'],
      }
    }
    reboot { 'after_profile_business' :
      apply   => finished,
      message => 'Reboot: Business profile applied.'
    }
  }
}

我能想到的最好方法是使用 if 子句来应用package资源的不同实例,有或没有install_options,具体取决于 的值arguments

$packages.each | $key, $value | {
  if $value['arguments'] != 'undef' {
    package { "install_${key}" :
      name            => $key,
      ensure          => $value['version'],
      provider        => $value['provider'],
      install_options => $value['arguments'],
      notify          => Reboot['after_profile_admin'],
    }
  } else {
    package { "install_${key}" :
      name     => $key,
      ensure   => $value['version'],
      provider => $value['provider'],
      notify   => Reboot['after_profile_admin'],
    }
  }
}

但是,这似乎很笨拙,我希望有人可以向我展示更好的方法?

我看过Puppet Selector条件示例,但我不知道这是否适合我。

TIA

标签: conditional-statementspuppetpuppet-enterprise

解决方案


这个 YAML 片段...

    arguments: undef

... 将'arguments'键的值设置为字符串 'undef'。这并不意味着在 Puppet 方面与 Puppet 字面量相同undef

有解决方案。所有最好的,IMO,都围绕着通过真正的数据缺失来表示数据缺失。这避免了对特殊保留字的任何需要。因此,假设您的数据看起来像这样:

profile::business::packages:
  office365business:
    version: latest
    provider: chocolatey
    arguments: ['/productid:O365BusinessRetail']
  xmind:
    version: latest
    provider: chocolatey
  slack:
    version: latest
    provider: chocolatey

请注意,arguments实际上没有要指定的参数的地方没有带有键的条目。如果您在定义数据类型方面一直严格而彻底,那么您可能需要调整这些数据的数据类型以适应这种情况,但这样会更好,因为这样可以更好地描述实际的数据语义。该数据修改可能会自行解决您的问题,因为查找不存在于确实存在的哈希中的键应该会产生undef(并且dig()如果未定义可能发生在深层数据结构的更高级别)。

然而,还要考虑一下,Puppet 有一个快捷方式来声明资源属性值是从哈希中提取的。这不太适合您当前的数据,因为您的键与所需的属性名称不同,但您可以更改数据中的键或在 Puppet 级别映射它们。后者可能如下所示:

# Defining the key / property name mappings here makes them clear, and is easy to
# change if you need to update the mappings
$mappings = { 'version' => 'ensure', 'arguments' => 'install_options' }

$packages.each |$package, $properties| {

  # map the keys appearing in the data to Puppet property names, based on
  # the hash defined above
  $filtered_props = $properties.reduce({}) |$memo, $pair| {
      $mapped_key = $pair[0] in $mappings ? { true => $mappings[$pair[0]], default => $pair[0] }
      $memo + { $mapped_key => $pair[1] }
  }

  # one declaration covering all cases
  package { "install_${package}" :
    name     => $package,
    provider => $value['provider'],
    notify   => Reboot['after_profile_admin'],
    *        => $filtered_props,
  }
}

推荐阅读