diff --git a/README.md b/README.md index 59c1a0b..98a87dd 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,26 @@ line: #include /etc/sudoers.d +The following OSs are also supported, even though they store the sudoers.d in +a different location: + + * FreeBSD + +If your OS is not supported, you can add support by adding your OS specific +settings to the `manifests/os_specific.pp` file. + +Alternatively, you can also override all os specific settings as follows: + +```puppet +class { 'sudo' :: + ... + os_specific_override => { + sudoers_file_path => '/etc/sandwichmakers', + sudoers_directory => '/etc/sandwichmakers.d' + } +} +``` + ## Parameters for class sudo ### sudoers diff --git a/manifests/init.pp b/manifests/init.pp index d3fc892..801bd49 100644 --- a/manifests/init.pp +++ b/manifests/init.pp @@ -46,23 +46,28 @@ # Copyright 2015 Arnoud de Jonge # class sudo ( - $sudoers = {}, - $manage_sudoersd = false, - $manage_package = true, - $package_ensure = 'installed', - $sudoers_file = '', + $sudoers = {}, + $manage_sudoersd = false, + $manage_package = true, + $package_ensure = 'installed', + $sudoers_file = '', + $os_specific_override = {} ) { + if ! defined(Class['::sudo::os_specific']) { + ensure_resource('class', '::sudo::os_specific', $os_specific_override) + } + create_resources('sudo::sudoers', $sudoers) if $manage_package { ensure_packages (['sudo'], {'ensure' => $package_ensure}) } - file { '/etc/sudoers.d': + file { $sudo::os_specific::sudoers_directory: ensure => directory, - owner => 'root', - group => 'root', + owner => $sudo::os_specific::root_user, + group => $sudo::os_specific::root_group, mode => '0750', purge => $manage_sudoersd, recurse => $manage_sudoersd, @@ -70,10 +75,10 @@ } if $sudoers_file =~ /^puppet:\/\// { - file { '/etc/sudoers': + file { $sudo::os_specific::sudoers_file_path: ensure => file, - owner => 'root', - group => 'root', + owner => $sudo::os_specific::root_user, + group => $sudo::os_specific::root_group, mode => '0440', source => $sudoers_file, } diff --git a/manifests/os_specific.pp b/manifests/os_specific.pp new file mode 100644 index 0000000..7db8405 --- /dev/null +++ b/manifests/os_specific.pp @@ -0,0 +1,21 @@ +class sudo::os_specific( + $root_user = $::osfamily ? { + default => 'root' + }, + $root_group = $::osfamily ? { + 'FreeBSD' => 'wheel', + default => 'root' + }, + $sudoers_directory = $::osfamily ? { + 'FreeBSD' => '/usr/local/etc/sudoers.d', + default => '/etc/sudoers.d' + }, + $sudoers_file_path = $::osfamily ? { + 'FreeBSD' => '/usr/local/etc/sudoers', + default => '/etc/sudoers' + }, + $visudo_path = $::osfamily ? { + 'FreeBSD' => '/usr/local/sbin/visudo', + default => '/usr/sbin/visudo' + }, +) { } diff --git a/manifests/sudoers.pp b/manifests/sudoers.pp index d410b6b..9f5578a 100644 --- a/manifests/sudoers.pp +++ b/manifests/sudoers.pp @@ -64,19 +64,25 @@ # # Copyright 2015 Arnoud de Jonge # + define sudo::sudoers ( - $ensure = 'present', - $users = undef, - $group = undef, - $hosts = 'ALL', - $cmnds = 'ALL', - $comment = undef, - $runas = ['root'], - $tags = [], - $defaults = [], - $priority = 50, + $ensure = 'present', + $users = undef, + $group = undef, + $hosts = 'ALL', + $cmnds = 'ALL', + $comment = undef, + $runas = ['root'], + $tags = [], + $defaults = [], + $priority = 50, + $os_specific_override = {}, ) { + if ! defined(Class['::sudo::os_specific']) { + ensure_resource('class', '::sudo::os_specific', $os_specific_override) + } + # Priority, since the order of multiple matching rules matters (the # last one found is used), optional and with '_' separator added if $priority != '' { @@ -93,7 +99,7 @@ # contain dots. # As having dots in a username is legit, let's fudge $sane_name = regsubst($name, '\.', '_', 'G') - $sudoers_user_file = "/etc/sudoers.d/${sane_priority}${sane_name}" + $sudoers_user_file = "${sudo::os_specific::sudoers_directory}/${sane_priority}${sane_name}" if $sane_name !~ /^[A-Za-z][A-Za-z0-9_]*$/ { fail "Will not create sudoers file \"${sudoers_user_file}\" (for \"${name}\") should consist of letters numbers or underscores." @@ -102,21 +108,21 @@ if $users != undef and $group != undef { fail 'You cannot define both a list of users and a group. Choose one.' } - + validate_string($group) if $ensure == 'present' { file { $sudoers_user_file: content => template('sudo/sudoers.erb'), - owner => 'root', - group => 'root', + owner => $sudo::os_specific::root_user, + group => $sudo::os_specific::root_group, mode => '0440', } if versioncmp("${::puppetversion}", '3.5') >= 0 { - File[$sudoers_user_file] { validate_cmd => '/usr/sbin/visudo -c -f %' } + File[$sudoers_user_file] { validate_cmd => "${sudo::os_specific::visudo_path} -c -f %" } } else { - validate_cmd(template('sudo/sudoers.erb'), '/usr/sbin/visudo -c -f', 'Visudo failed to validate sudoers content') + validate_cmd(template('sudo/sudoers.erb'), "${sudo::os_specific::visudo_path} -c -f", 'Visudo failed to validate sudoers content') } } else { diff --git a/spec/classes/sudo_init_spec.rb b/spec/classes/sudo_init_spec.rb index 659db87..cc0b03b 100644 --- a/spec/classes/sudo_init_spec.rb +++ b/spec/classes/sudo_init_spec.rb @@ -1,7 +1,7 @@ require 'spec_helper' describe 'sudo', :type => :class do - let(:facts) { {:puppetversion => '3.8.5' } } + let(:facts) { {:puppetversion => '3.8.5', :osfamily => 'Debian' } } $testdata = { 'world.domination' => { 'ensure' => 'present', @@ -22,6 +22,23 @@ ) } end + context 'no params on freebsd' do + let(:facts) { {:osfamily => 'FreeBSD' } } + it { should contain_file('/usr/local/etc/sudoers.d/').with( + 'owner' => 'root', + 'group' => 'wheel' + ) } + end + + context 'override os specific parameters' do + let(:facts) { {:osfamily => 'FreeBSD' } } + let(:params) { { :os_specific_override => { 'sudoers_directory' => '/tmp/sudoers.d'} } } + it { should contain_file('/tmp/sudoers.d/').with( + 'owner' => 'root', + 'group' => 'wheel' + ) } + end + context 'create_resources' do let(:params) { { :sudoers => $testdata } } diff --git a/spec/defines/sudo_sudoers_spec.rb b/spec/defines/sudo_sudoers_spec.rb index 2b23418..c127f04 100644 --- a/spec/defines/sudo_sudoers_spec.rb +++ b/spec/defines/sudo_sudoers_spec.rb @@ -1,7 +1,7 @@ require 'spec_helper' describe 'sudo::sudoers', :type => :define do - let(:facts) { {:puppetversion => '3.8.5' } } + let(:facts) { {:puppetversion => '3.8.5', :osfamily => 'Debian' } } let(:title) { 'world.domination' } context 'minimum params' do @@ -93,14 +93,14 @@ if (Puppet.version >= '3.5.0') context "validating content with puppet #{Puppet.version}" do let(:params) { { :users => ['joe'] } } - let(:facts) {{ :puppetversion => Puppet.version }} + let(:facts) {{ :puppetversion => Puppet.version, :osfamily => 'Debian' }} it { should contain_file('/etc/sudoers.d/50-world_domination').with_validate_cmd('/usr/sbin/visudo -c -f %') } end else context "validating content with puppet #{Puppet.version}" do let(:params) { { :users => ['joe'] } } - let(:facts) {{ :puppetversion => Puppet.version }} + let(:facts) {{ :puppetversion => Puppet.version, :osfamily => 'Debian' }} it { should contain_file('/etc/sudoers.d/50-world_domination').with_validate_cmd(nil) } end