有没有办法让 puppet 创建用户的主文件夹(managehome)但在确保“不存在”时不删除?

Bel*_*dez 2 linux user-management puppet

我的第一个想法是做这样的事情:

define my_user( $name = $title, $ensure = present, $uid, $gid, $password, $groups, $comment, $shell ) {
    $managehome = $ensure ? {
        present => true,
        default => false,
    }
    user { $name:
        ensure     => $ensure,
        managehome => $managehome,
        uid        => $uid,
        gid        => $gid,
        password   => $password,
        groups     => $groups,
        comment    => $comment,
        shell      => $shell,
     }
}
Run Code Online (Sandbox Code Playgroud)

这有几个问题:

  • 如果我想使用另一个user类型属性,我需要my_user在两个地方进行更改。
  • 我需要更改所有user声明以使用my_user.
  • 我更愿意使用内置类型而不是定义的类型。

也许有:

  • 一种将所有参数捕获到已定义类型并将其作为属性传递给内置类型的方法。
  • 一种更优雅的方式来做到这一点,而不使用定义的类型。

有人有什么建议吗?

小智 5

有几种方法可以解决这个问题,您可以直接在用户声明中使用三元检查,如下所示:

user { $user:
  ensure     => $ensure,
  managehome => $ensure ? { present => true, default => false, },
  uid        => $uid,
  gid        => $gid,
  password   => $password,
  groups     => $groups,
  comment    => $comment,
  shell      => $shell,
}
Run Code Online (Sandbox Code Playgroud)

这是假设您在这里参数化您的值,我猜这不一定是这种情况。您仍然会遇到必须更新所有类型引用的问题,这可能有点痛苦。相反,您可以使用更强大的功能,即create_resources函数。考虑以下人偶文件的摘录:

class profile::base {
  $user_params = {
      'user1'     => { ensure     => absent,
                       managehome => false,
                       uid        => '1337',
                       gid        => dev,
                     },
      'user2'     => { uid        => '1338',
                       gid        => ops,
                       groups     => ['wheel', 'company'],
                     },
  }

  $user_defaults = {
      ensure        => present,
      managehome    => true,
      groups        => ['users', 'company'],
      comment       => 'Managed by puppet',
      shell         => '/bin/bash',
  }

  create_resources(user, $user_params, $user_defaults)

  ...
}
Run Code Online (Sandbox Code Playgroud)

所以最终在这里发生的是 create_resources 函数采用散列$user_params并使用提供的参数为每个条目动态创建一个资源。此外,$user_params未提供的任何参数使用$user_defaults散列中的值。上面的代码有效地评估了以下代码段。(如果您不熟悉 create_resources 函数,我强烈建议您在此处阅读相关内容)

class profile::base {

  user { 'user1':
    ensure     => absent,
    managehome => false,
    uid        => 1337,
    gid        => dev,
    groups     => ['users', 'company'],
    comment    => 'Managed by puppet',
    shell      => '/bin/bash',
  }

  user { 'user2':
    ensure     => present,
    managehome => true,
    uid        => 1338,
    gid        => ops,
    groups     => ['wheel', 'company'],
    comment    => 'Managed by puppet',
    shell      => '/bin/bash',
  }

  ...
}
Run Code Online (Sandbox Code Playgroud)

这使您可以快速添加/更改要管理的所有用户的属性,而无需查找每个参考。假设您想为您的公司切换到使用 ksh,您只需更改user_defaults散列中的值以反映这一点。也没有什么可以阻止您拥有不同的参数组和默认值(比如超级用户的 $root_params 和 $root_defaults)并有另一个 create_resources 函数调用。

将这个想法更进一步,您可以将此概念与来自Hiera 的数据配对,然后解决方案将如下所示:

class profile::base {
  $user_params = hiera("user-params")
  $user_defaults = hiera("user-defaults")

  create_resources(user, $user_params, $user_defaults)

  ...
}
Run Code Online (Sandbox Code Playgroud)

更干净,更容易阅读。相应的hieradata json 文件如下所示:

{
  "user-params": {
                  "user1": {
                            "ensure": "absent",
                            "managehome": "false",
                            "uid": "1337",
                            "gid": "dev"
                  },

                  "user2": {
                            "uid": "1338",
                            "gid": "ops",
                            "groups": ["wheel", "company"]
                  }
  },

  "user_defaults": {
                    "ensure": "present",
                    "managehome": "true",
                    "groups": ["users", "company"],
                    "comment": "Managed by puppet",
                    "shell": "/bin/bash"
  }
}
Run Code Online (Sandbox Code Playgroud)

我个人更喜欢 JSON 作为我的 hieradata 但 YAML 也是一个可行的选择(Hiera 数据源)Hiera 的好处是您可以根据您在 hiera.yaml 文件中决定和配置的任何标准使用不同的数据源(通常按环境,但可能是每个节点)

最后,您可能需要考虑编写一个自定义类型来包装用户类型,它将:

  • 如果确保 => 不存在,则存档用户的主目录
  • 如果确保 => 存在,则搜索并恢复存档目录
  • 使用 managehome => true 通常使用内置用户类型

如果你决定采取这条路线,你仍然会通过使用获得很大的好处create_resources功能和Hiera