基于条件消除 Puppet 参数

Elide Puppet parameters based on conditional

我在 Puppet define 中声明了以下资源。有一些以 auth_* 开头的参数控制身份验证。我希望能够根据布尔变量的值传递或不传递该参数块,即 $use_authentication.

似乎 if 语句在这里不起作用,而且我认为 "selector" 也不会起作用。 Felix Frank 在非常相关的问题“conditional within define in puppet”中有一个非常有用的答案,但我认为该策略在这里不起作用,因为需要省略的参数嵌套了两层深。

apache::vhost { "$name-non-ssl":
    servername => $vhost_name,
    docroot => $document_root,
    port => 80,

    access_log_file => 'access.log',
    access_log_format => 'vhost_common',
    error_log_file => 'error.log',

    directories => [
         {path => $document_root,
          auth_type => 'Basic',
          auth_name => "$name",
          auth_user_file => '/somefile.pwd',
          auth_require => 'valid-user',
          rewrites => [
              {
                  comment => "rule1",
                  rewrite_base => "/",
                  rewrite_rule => ['^index\.html$ - [L]']
              },
              {
                  comment => "rule2",
                  rewrite_cond => ['%{REQUEST_FILENAME} !-f', '%{REQUEST_FILENAME} !-d'],
                  rewrite_rule => ['. /index.html [L]']
              }
          ]}
    ],
}

下面给出语法错误:Syntax error at 'if'; expected '}'

apache::vhost { "$name-non-ssl":
    ... same as previous ...
    directories => [
         {path => $document_root,

          if $use_authentication {
              auth_type => 'Basic',
              auth_name => "$name",
              auth_user_file => '/somefile.pwd',
              auth_require => 'valid-user',
          }

          rewrites => [
              ...same as before...
          ]}
    ],
}

这很难处理,因为您想动态地填充散列中的一些 key/value 对,散列是作为参数值的数组的元素。

选项 1:在资源声明之外构建哈希

$auth_settings = {
     auth_type => 'Basic',
     auth_name => "$name",
     auth_user_file => '/somefile.pwd',
     auth_require => 'valid-user',
}
$base_dir1 = {path => $document_root,
      rewrites => [
          {
              comment => "rule1",
              rewrite_base => "/",
              rewrite_rule => ['^index\.html$ - [L]']
          },
          {
              comment => "rule2",
              rewrite_cond => ['%{REQUEST_FILENAME} !-f', '%{REQUEST_FILENAME} !-d'],
              rewrite_rule => ['. /index.html [L]']
          }
      ]
}
if $use_authentication {
    $real_dir1 = merge($base_dir1, $auth_settings)
}
else {
    $real_dir1 = $base_dir1
}

apache::vhost { "$name-non-ssl":
    servername => $vhost_name,
    docroot => $document_root,
    port => 80,
    access_log_file => 'access.log',
    access_log_format => 'vhost_common',
    error_log_file => 'error.log',
    directories => [ $real_dir1 ],
}

当然,变量有点乱。

选项 2:创建自定义函数

编写一个函数,接受上面的 $base_dir1$use_authentication 的布尔值,如果合适的话 returns 合并的散列。

apache::vhost { "$name-non-ssl":
    servername => $vhost_name,
    docroot => $document_root,
    port => 80,

    access_log_file => 'access.log',
    access_log_format => 'vhost_common',
    error_log_file => 'error.log',

    directories => [ add_auth($use_authentication, { ... }) ],
}

选项 3:内联

你可以在资源声明中漫不经心地进行合并。使用选择器来决定要合并的内容。这个的可读性超出了 window。

apache::vhost { "$name-non-ssl":
    servername => $vhost_name,
    docroot => $document_root,
    port => 80,

    access_log_file => 'access.log',
    access_log_format => 'vhost_common',
    error_log_file => 'error.log',

    directories => [ merge({path => $document_root,
      rewrites => [
          {
              comment => "rule1",
              rewrite_base => "/",
              rewrite_rule => ['^index\.html$ - [L]']
          },
          {
              comment => "rule2",
              rewrite_cond => ['%{REQUEST_FILENAME} !-f', '%{REQUEST_FILENAME} !-d'],
              rewrite_rule => ['. /index.html [L]']
          }
      ]
    }, $use_authentication ? {
         true => {
             auth_type => 'Basic',
             auth_name => "$name",
             auth_user_file => '/somefile.pwd',
             auth_require => 'valid-user',
         },
         default => {}
       }
     )
   ],
}

我没有费心测试这个怪物。甚至不确定牙套是否对齐。

您可能会在 (1) 和 (3) 之间做出妥协,但请倾向于前者。