iSt0ne's Notes

Puppet: sudo模块

本文介绍puppet sudo模块,用来管理Linux (RedHat)上的/etc/sudoers文件。模块实现批量添加、删除用户sudo权限。

github地址:https://github.com/ist0ne/puppet-sudo

##1、描述

本模块依赖puppetlabs-stdlib,实现用户批量sudo权限的添加。

##2、用法

添加用户和组:

1
sudo { ['user1', 'user2']: }

/etc/sudoers会添加如下行:

1
2
user1 FILESERVERS=(ALL) NOPASSWD: ALL
user2 FILESERVERS=(ALL) NOPASSWD: ALL

删除用户和组:

1
sudo {['user1', 'user2']: ensure => absent}

使用别名添加ADMINS组:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
sudo { 'ADMINS':
ensure => present,
alias_hash => {
'ADMINS' => {
ensure => present,
alias_type => 'User_Alias',
alias_name => 'ADMINS',
alias_content => 'jsmith, mikem, jobs',
},
'FILESERVERS' => {
ensure => present,
alias_type => 'Host_Alias',
alias_name => 'FILESERVERS',
alias_content => 'fs1, fs2',
},
},
machine => 'FILESERVERS',
}

上面命令会添加如下行:

1
2
3
ADMINS FILESERVERS=(ALL) NOPASSWD: ALL
User_Alias ADMINS = jsmith, mikem, jobs
Host_Alias FILESERVERS = fs1, fs2

删除以上建立的别名只需将ensure都改为absent:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
sudo { 'ADMINS':
ensure => absent,
alias_hash => {
'ADMINS' => {
ensure => absent,
alias_type => 'User_Alias',
alias_name => 'ADMINS',
alias_content => 'jsmith, mikem, jobs',
},
'FILESERVERS' => {
ensure => absent,
alias_type => 'Host_Alias',
alias_name => 'FILESERVERS',
alias_content => 'fs1, fs2',
},
},
machine => 'FILESERVERS',
}

##3、模块代码解析
sudo的定义用到了create_resources函数,这个函数使用一个hash结构创建资源。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
define sudo (
$ensure = present,
$alias_hash = 'unset',
$machine = 'ALL',
$commands = '(ALL)',
$nopasswd = true,
$nopasswd_commands = 'ALL',
$sudo_file = 'sudoers',
$sudo_file_path = '/etc'
) {
validate_re($ensure, [present, absent])
validate_string($machine)
validate_string($commands)
validate_bool($nopasswd)
validate_string($nopasswd_commands)
validate_string($sudo_file)
validate_absolute_path($sudo_file_path)
if ($alias_hash != 'unset') {
create_resources('sudo::alias', $alias_hash)
}
if $nopasswd == true {
$nopwd = 'NOPASSWD'
$line = "$name $machine=$commands ${nopwd}: $nopasswd_commands"
} else {
$line = "$name $machine=$commands $commands"
}
exec { "test_user_exist_$name":
command => "sed -i '/^$name[[:space:]]/d' ${sudo_file_path}/${sudo_file}",
onlyif => "grep \'^$name[[:space:]]\' ${sudo_file_path}/${sudo_file} >/dev/null && cat ${sudo_file_path}/${sudo_file} |grep \'^$name[[:space:]]\' |grep -v \'^$line\$\' >/dev/null",
}
file_line { "$name":
ensure => $ensure,
line => $line,
path => "${sudo_file_path}/${sudo_file}",
}
Exec["test_user_exist_$name"] -> File_line["$name"]
}

sudo::alias定义如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
define sudo::alias (
$ensure = present,
$alias_type = undef,
$alias_name = undef,
$alias_content = undef,
$sudo_file = 'sudoers',
$sudo_file_path = '/etc'
) {
validate_re($ensure, [present, absent])
validate_re($alias_type, ['Host_Alias', 'User_Alias', 'Cmnd_Alias'])
validate_string($alias_name)
validate_string($alias_content)
validate_string($sudo_file)
validate_absolute_path($sudo_file_path)
if ! ($ensure in [present, absent]) {
fail('ensure parameter must be present or absent')
}
if ! ($alias_type in ['Host_Alias', 'User_Alias', 'Cmnd_Alias']) {
fail('alias_type parameter must be "Host_Alias" or "User_Alias" or "Cmnd_Alias"')
}
if ($alias_type != undef and $alias_name != undef and $alias_content != undef) {
$alias_line = "$alias_type $alias_name = $alias_content"
}
if ($alias_line != undef) {
exec { "test_alias_exist_$name":
command => "sed -i '/^$alias_type $alias_name[[:space:]]/d' ${sudo_file_path}/${sudo_file}",
onlyif => "grep \'^$alias_type[[:space:]]$alias_name[[:space:]]\' ${sudo_file_path}/${sudo_file} >/dev/null && cat ${sudo_file_path}/${sudo_file} |grep \'^$alias_type[[:space:]]$alias_name[[:space:]]\' |grep -v \'^$alias_line\$\' >/dev/null",
}
file_line { "alias_$name":
ensure => $ensure,
line => $alias_line,
path => "${sudo_file_path}/${sudo_file}",
}
Exec["test_alias_exist_$name"] -> File_line["alias_$name"]
}
}