conditional-statements - 条件资源属性
问题描述
为了安装软件包,我将来自 Hiera 的数据输入到 for 循环中。一些包需要额外的参数。对于不需要参数的包,我将值设置为undef
,但是,Chocolatey 读取undef
并抱怨。
当它为空白或时,如何让package
资源忽略该属性?install_options
undef
希拉片段:
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
解决方案
这个 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,
}
}
推荐阅读
- python - 我不知道如何在我的程序中添加过滤功能来删除相同的元素,尤其是 '(', ')' 和相同的词
- reactjs - eslint 缩进规则没有被禁用
- java - Mac、Windows 和 Linux 上的 Java 桌面应用程序安装程序
- crystal-lang - 为什么 Crystal .should 会产生虚假错误
- python-3.x - Python中置换树上深度优先搜索的实现
- dump - 转储中的虚拟地址
- shell - 当目标服务器在网关后面时如何在jenkins中执行远程命令
- react-admin -
保存时将时间转换为 UTC - spring - 我们如何在 springframework.scheduling.quartz.CronTriggerFactoryBean 中添加 startTime?
- java - 多个实例而不是接口的副本