条件资源属性
Conditonal resource attributes
为了安装包,我将来自 Hiera 的数据输入到 for 循环中。一些包需要额外的参数。对于不需要参数的包,我将值设置为 undef
,但是,Chocolatey 读取 undef
并抱怨。
如何让 package
资源在 install_options
属性为空或 undef
时忽略它?
Hiera 片段:
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 例子:
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 条件示例,但我不知道这是否适合我。
T.I.A
这个 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,
}
}
为了安装包,我将来自 Hiera 的数据输入到 for 循环中。一些包需要额外的参数。对于不需要参数的包,我将值设置为 undef
,但是,Chocolatey 读取 undef
并抱怨。
如何让 package
资源在 install_options
属性为空或 undef
时忽略它?
Hiera 片段:
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 例子:
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 条件示例,但我不知道这是否适合我。
T.I.A
这个 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,
}
}