【问题标题】:How to update values dynamically for the individual match sections within sshd config file using puppet如何使用 puppet 为 sshd 配置文件中的各个匹配部分动态更新值
【发布时间】:2020-08-04 16:48:16
【问题描述】:

我可以通过传递索引来更新“用户 foo”和“主机 *.example.net”部分的值。如果我通过索引 1 或 2,则相应的值正在更新。

我的代码:

$sections = ['Host *.example.net', 'User foo']

$sections.each |String $section| {
  sshd_config_match { "${section}":
    ensure => present,
  }
}

$settings = [['User foo', 'X11Forwarding yes', 'banner none'],['Host *.example.net', 'X11Forwarding no', 'banner none']]
$settings.each |Array $setting| {
  $setting_array = split($setting[1],/ /)
  sshd_config { "${setting_array[0]} ${setting[0]}":
    ensure    => present,
    key       => "${setting_array[0]}",
    condition => "${setting[0]}",
    value     => "${setting_array[1]}",
  }
}

当前结果:

 Match Host *.example.net
      # Created by Puppet
      X11Forwarding no
     
    Match User foo
      # Created by Puppet
      X11Forwarding yes

预期结果:

Match Host *.example.net
  # Created by Puppet
  X11Forwarding no
  Banner none
Match User foo
  # Created by Puppet
  X11Forwarding yes
  Banner none

我只能更新索引中提到的一个值,但我正在寻找一种方法来更新列表中提到的更多或所有值。

【问题讨论】:

    标签: list arraylist indexing puppet


    【解决方案1】:

    不清楚是什么模块提供了sshd_config_matchsshd_config 资源类型,因此也不清楚它们的作用。然而,如果我们考虑这段代码......

    $settings = [['User foo', 'X11Forwarding yes', 'banner none'],['Host *.example.net', 'X11Forwarding no', 'banner none']]
    $settings.each |Array $setting| {
      $setting_array = split($setting[1],/ /)
      sshd_config { "${setting_array[0]} ${setting[0]}":
        ensure    => present,
        key       => "${setting_array[0]}",
        condition => "${setting[0]}",
        value     => "${setting_array[1]}",
      }
    }
    

    ...我们可以看到$settings 的每个元素都是一个三元素数组,其中each 调用仅访问索引为0 和1 的元素。这似乎与您看到的结果相匹配,它不包含与索引 2 处元素的数据相对应的任何内容。

    可以从索引 1 开始迭代内部 $setting 元素,而不是只考虑该元素,但我建议改为更自然地重组数据,并编写适合重组数据。您的数组中具有混合重要性的数据,并且您将键和值不必要地混杂在一起,因此您需要花费精力将它们分开。将数据构造为散列的散列而不是数组的数组可能是一个好的开始:

    $settings = {
      'User foo'           => { 'X11Forwarding' => 'yes', 'banner' => 'none'},
      'Host *.example.net' => { 'X11Forwarding' => 'no',  'banner' => 'none'},
    }
    

    这不仅大大增强了可读性(主要来自格式化),而且还提供了更好的可用性。也就是说,虽然我在这里猜测了一下,但您应该能够执行类似于以下的操作:

    $settings.each |String $condition, Hash $properties| {
      $properties.each |String $key, String $value| {
        sshd_config { "${condition} ${key}":
          ensure    => 'present',
          condition => $condition,
          key       => $key,
          value     => $value,
        }
      }
    }
    

    再一次,更好的可读性,这一次主要来自于一个有用的名称选择,并且随着它更清晰,这样的东西实际上是代码的正确结构(假设我已经正确推断出你所使用的类型)使用)。

    【讨论】:

    • 您的代码正在运行并且能够获得预期的结果,但我的输入将始终采用列表格式,正如我在上面的问题中提到的那样。是否可以根据列表格式更改代码?请帮忙。
    • @Docgyan,正如这个答案已经观察到的那样,“您可以从索引 1 开始迭代内部 $setting 元素,而不是仅考虑该元素”。这将采取在内部资源声明周围放置$setting[1,-1].each |...| { ... } 的一般形式。但是,我再次敦促您更好地构建数据。
    • 感谢您的回复,对于同一问题,我需要您的扩展帮助。目前正在寻找的是,如果部分不匹配,那么我只需要更新 'X11Forwarding' => 'yes' (key => value),如果部分匹配,那么我需要更新匹配部分内的值。希望得到答复。
    • 那将是一个单独的问题,@Docgyan。此外,尽管在我不知道您正在使用的资源类型的详细信息的情况下,这个答案是可能的,但您的后续行动似乎不太可能是这样。
    • 如前所述,考虑到您的上述 cmets,我发布了一个新问题,请提供帮助。新问题的链接:stackoverflow.com/questions/63271537/…
    猜你喜欢
    • 1970-01-01
    • 2012-06-05
    • 1970-01-01
    • 2018-10-31
    • 1970-01-01
    • 2014-05-21
    • 2016-12-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多