首页 > 解决方案 > 在 Puppet 中,如何在 if 子句中使用定义的节点变量

问题描述

在木偶类中,我应该如何测试节点中是否设置了变量?我使用用户可以访问该页面的 VM 名称(如 server1)和域名(如 example.org)。“example.org”不会通过事实传达,所以我需要通过类参数传递它。我想出了这种方法来在节点块中定义变量并在我的测试类中使用它来进行设置。

node "VM1" {
  class { 'test':
    domainname => "example.org",
  }

[...]

class test ($domainname) {
  ini_setting {
    'set_property':
      ensure  => present,
      path    => '/tmp/test.ini',
      section => 'main',
      setting => 'url',
      value   => "https://$domainname";
  }

[...]

但是现在我想添加一个条件,如果$domainname没有设置,那么$hostname应该使用事实来代替它。

ini_setting {
    'set_property':
    ensure  => present,
    path    => '/tmp/test.ini',
    section => 'main',
    setting => 'url',
    if $domainname !~ $hostname {
      value   => "https://$domainname";
    } else {
      value   => "https://$hostname";
    }

但现在我每次都会收到这样的错误:

错误:无法从远程服务器检索目录:服务器上的错误 500:服务器错误:“域名”处的语法错误

我应该怎么做?

标签: variablesif-statementpuppetfacter

解决方案


错误消息向您解释if语句不能出现在资源声明中。但是,有一种不同的条件形式,称为“选择器”,可以出现在资源声明中。?:它是 Puppet 对出现在多种语言中的三元运算符的模拟。

但是,从风格上讲,保持资源声明尽可能简单通常是更好的形式。为此,您可能应该有条件地在资源声明之外设置一个变量,然后在内部使用它的值。使用您自己的条件,可能如下所示:

  if $domainname !~ $hostname {
    $url_value = "https://$domainname";
  } else {
    $url_value = "https://$hostname";
  }

  ini_setting {
    'set_property':
      ensure  => present,
      path    => '/tmp/test.ini',
      section => 'main',
      setting => 'url',
      value   => $url_value;
  }

但是,此外,我注意到您在上面重复的特定情况非常值得怀疑。在最近的 Puppet(版本 4 及更高版本)中,您应该使用 Puppet 数据类型来声明您的类参数并检查它们。特别是,如果允许在不提供$domainname参数的情况下声明类 test,那么您可以像这样声明该类:

# Using the Puppet v4+ type system
class test(
  Optional[String] $domainname = undef
) {
  # ...

,并会测试是否提供了一个值,$domainname如下所示:

  if $domainname =~ Undef {
    # ...
  }

你不能在早期的 Puppet 中使用类型系统,但是当你插入它们时,你可以依赖未定义的变量来扩展它们:

# Using the Puppet v3- behavior
class test(
  $domainname = undef
) {
  # ...

  if "$domainname" == "" {
    # ...
  }

  # ...
}

推荐阅读