我的第一个想法是做这样的事情:
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,
}
}
存在以下几个问题:
- 如果我想使用另一种
user
类型属性,我需要my_user
在两个地方进行更改。 - 我需要改变所有
user
声明才能使用my_user
。 - 我宁愿使用内置类型而不是定义类型。
或许有以下两种情况:
- 一种将所有参数捕获到定义类型并将其作为属性传递给内置类型的方法。
- 一个更优雅的方法是不使用定义的类型来做到这一点。
有人有什么建议吗?
答案1
有几种方法可以解决这个问题,您可以直接在用户声明中使用三元检查,如下所示:
user { $user:
ensure => $ensure,
managehome => $ensure ? { present => true, default => false, },
uid => $uid,
gid => $gid,
password => $password,
groups => $groups,
comment => $comment,
shell => $shell,
}
这是假设你在这里参数化你的值,我猜情况不一定如此。你仍然会遇到必须更新所有类型引用的问题,这可能有点痛苦。相反,你可以使用更强大的东西,创建资源函数。请考虑以下来自 puppet 文件的摘录:
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)
...
}
所以最终发生的事情是,create_resources 函数获取哈希值用户参数并使用提供的参数为每个条目动态创建资源。此外,任何未提供的参数用户参数使用来自$用户默认值哈希。上面的代码有效地评估了以下代码片段。(如果您不熟悉 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',
}
...
}
这样您就可以快速添加/更改要管理的所有用户的属性,而无需查找每个引用。假设您想为公司切换到使用 ksh,您只需更改用户默认值hash 来反映这一点。同样,没有什么可以阻止您拥有不同的参数和默认值组(例如,对于超级用户,使用 $root_params 和 $root_defaults)并进行另一个 create_resources 函数调用。
进一步将这个想法与以下数据配对:希拉 解决方案如下:
class profile::base {
$user_params = hiera("user-params")
$user_defaults = hiera("user-defaults")
create_resources(user, $user_params, $user_defaults)
...
}
更加清晰,更易于阅读。相应的层次数据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"
}
}
我个人更喜欢 JSON 作为我的 hieradata,但 YAML 也是一个可行的选择(Hiera 数据源)Hiera 的优点在于,您可以根据自己决定并在 hiera.yaml 文件中配置的任何标准使用不同的数据源(通常按环境完成,但也可以按节点完成)
最后,您可能需要考虑编写一个自定义类型来包装用户类型,它将:
- 如果 Ensure => 不存在,则归档用户的主目录
- 如果存在 Ensure =>,则搜索并恢复存档目录
- 通常使用 managehome => true 的内置用户类型
如果你决定采用这种方式,你仍然可以通过使用创建资源功能和希拉
答案2
在这种情况下,可选参数的处理方法不太优雅。
my_user($ensure = 'present', $uid = undef) {
if $uid != undef { User { uid => $uid } }
user { $name: ensure => $ensure }
}
user
您只需在定义范围内分配资源默认值即可。您可以对任意数量的参数重复此模式。