diff options
-rw-r--r-- | Modulefile | 2 | ||||
-rw-r--r-- | README.md | 10 | ||||
-rw-r--r-- | manifests/init.pp | 73 | ||||
-rw-r--r-- | manifests/params.pp | 47 | ||||
-rw-r--r-- | spec/classes/tftp_spec.rb | 249 | ||||
-rw-r--r-- | spec/defines/tftp_file_spec.rb | 153 | ||||
-rw-r--r-- | spec/fixtures/manifests/site.pp | 0 |
7 files changed, 354 insertions, 180 deletions
@@ -8,4 +8,4 @@ description 'Manage tftp service and files for Debian/Ubuntu.' project_page 'https://github.com/puppetlabs/puppetlabs-tftp' ## Add dependencies, if any: -# dependency 'username/name', '>= 1.2.0' +dependency 'puppetlabs/xinetd', '>= 1.1.0' @@ -2,7 +2,7 @@ ## Overview -Install tftp-hpa package and configuration files for osfamily Debian. +Install tftp-hpa package and configuration files ## Usage @@ -10,15 +10,12 @@ Install tftp-hpa package and configuration files for osfamily Debian. Parameters: -* username: tftp daemon user, default tftp. +* username: tftp daemon user, default tftp(debian) or nobody(redhat). * directory: service directory, deafult see params class. * address: bind address, default 0.0.0.0. * port: bind port, default 69. * options: service option, default --secure. -* inetd: run service via inetd, default false. (Warning: this option when enabled to true is not compatible with custom service options). -* inetd_conf: inetd.conf file path, default /etc/inetd.conf. - -Enabling inetd requires [puppetlabs-inetd](https://github.com/puppetlabs/puppetlabs-inetd) module. +* inetd: run service via xinetd - default false. Example: @@ -90,3 +87,4 @@ The module have been tested on the following operating systems. Testing and patc * Debian Wheezy * Ubuntu Oneiric +* CentOS diff --git a/manifests/init.pp b/manifests/init.pp index 9dfab37..973049c 100644 --- a/manifests/init.pp +++ b/manifests/init.pp @@ -7,14 +7,13 @@ # [*address*]: tftp service bind address (default 0.0.0.0). # [*port*]: tftp service bind port (default 69). # [*options*]: tftp service bind port (default 69). -# [*inetd*]: tftp service bind port (default 69). -# [*inetd_conf*]: tftp service bind port (default 69). +# [*inetd*]: Run as an xinetd service instead of standalone daemon (false) # # Actions: # # Requires: # -# puppetlabs-inetd when inetd = true. +# Class['xinetd'] (if inetd set to true) # # Usage: # @@ -31,45 +30,44 @@ class tftp ( $port = $tftp::params::port, $options = $tftp::params::options, $inetd = false, - $inetd_conf = $tftp::params::inetd_conf + $package = $tftp::params::package, + $binary = $tftp::params::binary, + $defaults = $tftp::params::defaults ) inherits tftp::params { + package { 'tftpd-hpa': - ensure => present, + ensure => present, + name => $package, } - - file { '/etc/default/tftpd-hpa': - ensure => file, - owner => 'root', - group => 'root', - mode => '0644', - content => template('tftp/tftpd-hpa.erb'), - require => Package['tftpd-hpa'], + if $defaults { + file { '/etc/default/tftpd-hpa': + ensure => file, + owner => 'root', + group => 'root', + mode => '0644', + content => template('tftp/tftpd-hpa.erb'), + require => Package['tftpd-hpa'], + notify => Service['tftpd-hpa'], + } } if $inetd { - if $options != '--secure' { - fail('tftp class does not support custom options when inetd is enabled.') - } - - include 'inetd' - augeas { 'inetd_tftp': - changes => [ - "ins tftp after /files${inetd_conf}", - "set /files${inetd_conf}/tftp/socket dgram", - "set /files${inetd_conf}/tftp/protocol udp", - "set /files${inetd_conf}/tftp/wait wait", - "set /files${inetd_conf}/tftp/user ${username}", - "set /files${inetd_conf}/tftp/command /usr/libexec/tftpd", - "set /files${inetd_conf}/tftp/arguments/1 tftpd", - "set /files${inetd_conf}/tftp/arguments/2 --address", - "set /files${inetd_conf}/tftp/arguments/3 ${address}:${port}", - "set /files${inetd_conf}/tftp/arguments/4 --secure", - "set /files${inetd_conf}/tftp/arguments/5 ${directory}", - ], - require => Class['inetd'], - } + include 'xinetd' + xinetd::service { 'tftp': + port => $port, + protocol => 'udp', + server_args => "${options} ${directory}", + server => $binary, + user => $username, + bind => $address, + socket_type => 'dgram', + cps => '100 2', + flags => 'IPv4', + per_source => '11', + wait => 'yes', + } $svc_ensure = stopped $svc_enable = false } else { @@ -77,12 +75,17 @@ class tftp ( $svc_enable = true } + $start = $provider ? { + 'base' => "${binary} -l -a ${address}:${port} -u ${username} ${options} ${directory}", + default => undef + } + service { 'tftpd-hpa': ensure => $svc_ensure, enable => $svc_enable, provider => $tftp::params::provider, hasstatus => $tftp::params::hasstatus, pattern => '/usr/sbin/in.tftpd', - subscribe => File['/etc/default/tftpd-hpa'], + start => $start, } } diff --git a/manifests/params.pp b/manifests/params.pp index e658184..3520068 100644 --- a/manifests/params.pp +++ b/manifests/params.pp @@ -4,28 +4,43 @@ class tftp::params { $address = '0.0.0.0' $port = '69' - $username = 'tftp' $options = '--secure' - $inetd_conf = '/etc/inetd.conf' + $binary = '/usr/sbin/in.tftpd' - case $::operatingsystem { + case $::osfamily { 'debian': { - # hasstatus is to get around an issue where the service script appears to - # be broken. - $directory = '/srv/tftp' - $hasstatus = false - $provider = undef + $package = 'tftpd-hpa' + $defaults = true + $username = 'tftp' + case $::operatingsystem { + 'debian': { + $directory = '/srv/tftp' + $hasstatus = false + $provider = undef + } + 'ubuntu': { + $directory = '/var/lib/tftpboot' + $hasstatus = true + $provider = 'upstart' + } + } } - 'ubuntu': { - $directory = '/var/lib/tftpboot' - $hasstatus = true - $provider = 'upstart' + 'redhat': { + $package = 'tftp-server' + $username = 'nobody' + $defaults = false + $directory = '/var/lib/tftpboot' + $hasstatus = false + $provider = 'base' } default: { - warning("tftp:: not verified on operatingsystem ${::operatingsystem}.") - $directory = '/var/lib/tftpboot' - $hasstatus = true - $provider = undef + $package = 'tftpd' + $username = 'nobody' + $defaults = false + $hasstatus = false + $provider = undef + warning("tftp:: $::operatingsystem may not be supported") } } + } diff --git a/spec/classes/tftp_spec.rb b/spec/classes/tftp_spec.rb index 016130d..21e6f72 100644 --- a/spec/classes/tftp_spec.rb +++ b/spec/classes/tftp_spec.rb @@ -2,70 +2,205 @@ require 'spec_helper' describe 'tftp', :type => :class do describe 'when deploying on debian' do - let(:facts) { { :operatingsystem => 'Debian', - :path => '/usr/local/bin:/usr/bin:/bin', } } - - it { should contain_file('/etc/default/tftpd-hpa') } - it { should contain_package('tftpd-hpa') } - it { should contain_service('tftpd-hpa').with({ - 'ensure' => 'running', - 'enable' => true, - 'hasstatus' => false, - 'provider' => nil, - }) } + let(:facts) { { :operatingsystem => 'Debian', + :osfamily => 'Debian', + :path => '/usr/local/bin:/usr/bin:/bin', } } + + it { + should contain_file('/etc/default/tftpd-hpa') + should contain_package('tftpd-hpa') + should contain_service('tftpd-hpa').with({ + 'ensure' => 'running', + 'enable' => true, + 'hasstatus' => false, + 'provider' => nil, + }) + } end describe 'when deploying on ubuntu' do - let(:facts) { { :operatingsystem => 'Ubuntu', - :path => '/usr/local/bin:/usr/bin:/bin', } } - - it { should contain_package('tftpd-hpa') } - it { should contain_file('/etc/default/tftpd-hpa') } - it { should contain_service('tftpd-hpa').with({ - 'ensure' => 'running', - 'enable' => true, - 'hasstatus' => true, - 'provider' => 'upstart', - }) } + let(:facts) { { :operatingsystem => 'Ubuntu', + :osfamily => 'Debian', + :path => '/usr/local/bin:/usr/bin:/bin', } } + + it { + should contain_package('tftpd-hpa') + should contain_file('/etc/default/tftpd-hpa') + should contain_service('tftpd-hpa').with({ + 'ensure' => 'running', + 'enable' => true, + 'hasstatus' => true, + 'provider' => 'upstart', + }) + } + end + + describe 'when deploying on redhat family' do + let (:facts) { { :osfamily => 'RedHat', + :path => '/usr/local/bin:/usr/bin:/bin', } } + + it { + should contain_package('tftpd-hpa').with({ + 'name' => 'tftp-server', + }) + + should contain_service('tftpd-hpa').with({ + 'ensure' => 'running', + 'enable' => 'true', + 'hasstatus' => false, + 'provider' => 'base', + 'start' => '/usr/sbin/in.tftpd -l -a 0.0.0.0:69 -u nobody --secure /var/lib/tftpboot', + }) + } + end + + describe 'when deploying on redhat family with custom options' do + let (:facts) { { :osfamily => 'RedHat', + :path => '/usr/local/bin:/usr/bin:/bin', } } + let (:params) { { :address => '127.0.0.1', + :port => '1069', + :username => 'root', + :options => '--secure --timeout 50', + :directory => '/tftpboot', } } + + it { + should contain_package('tftpd-hpa').with({ + 'name' => 'tftp-server', + }) + + should contain_service('tftpd-hpa').with({ + 'ensure' => 'running', + 'enable' => 'true', + 'hasstatus' => false, + 'provider' => 'base', + 'start' => '/usr/sbin/in.tftpd -l -a 127.0.0.1:1069 -u root --secure --timeout 50 /tftpboot', + }) + } + end + + describe 'when deploying with xinetd on redhat family' do + let (:facts) { { :osfamily => 'Redhat', + :path => '/usr/local/bin:/usr/bin:/bin', } } + let (:params) { { :inetd => true, } } + it { + should include_class('xinetd') + should contain_service('tftpd-hpa').with({ + 'ensure' => 'stopped', + 'enable' => false, + }) + should contain_xinetd__service('tftp').with({ + 'port' => '69', + 'protocol' => 'udp', + 'server_args' => '--secure /var/lib/tftpboot', + 'server' => '/usr/sbin/in.tftpd', + 'user' => 'nobody', + 'socket_type' => 'dgram', + 'cps' => '100 2', + 'flags' => 'IPv4', + 'per_source' => '11', + 'wait' => 'yes', + }) + } end - describe 'when deploying with inetd' do - let(:facts) { { :operatingsystem => 'Debian', - :path => '/usr/local/bin:/usr/bin:/bin', } } - let(:params) { { :inetd => true, } } - - it { should contain_package('tftpd-hpa') } - it { should contain_file('/etc/default/tftpd-hpa') } - it { should contain_class('inetd') } - it { should contain_augeas('inetd_tftp').with({ - 'changes' => [ - "ins tftp after /files/etc/inetd.conf", - "set /files/etc/inetd.conf/tftp/socket dgram", - "set /files/etc/inetd.conf/tftp/protocol udp", - "set /files/etc/inetd.conf/tftp/wait wait", - "set /files/etc/inetd.conf/tftp/user tftp", - "set /files/etc/inetd.conf/tftp/command /usr/libexec/tftpd", - "set /files/etc/inetd.conf/tftp/arguments/1 tftpd", - "set /files/etc/inetd.conf/tftp/arguments/2 --address", - "set /files/etc/inetd.conf/tftp/arguments/3 0.0.0.0:69", - "set /files/etc/inetd.conf/tftp/arguments/4 --secure", - "set /files/etc/inetd.conf/tftp/arguments/5 /srv/tftp", - ], - }) } - it { should contain_service('tftpd-hpa').with({ - 'ensure' => 'stopped', - 'enable' => false, - 'hasstatus' => false, - 'provider' => nil, - }) } + describe 'when deploying with xinetd on ubuntu' do + let (:facts) { { :osfamily => 'Debian', + :operatingsystem => 'Ubuntu', + :path => '/usr/local/bin:/usr/bin:/bin', } } + let (:params) { { :inetd => true, } } + it { + should include_class('xinetd') + should contain_service('tftpd-hpa').with({ + 'ensure' => 'stopped', + 'enable' => false, + }) + should contain_xinetd__service('tftp').with({ + 'port' => '69', + 'protocol' => 'udp', + 'server_args' => '--secure /var/lib/tftpboot', + 'server' => '/usr/sbin/in.tftpd', + 'user' => 'tftp', + 'socket_type' => 'dgram', + 'cps' => '100 2', + 'flags' => 'IPv4', + 'per_source' => '11', + 'wait' => 'yes', + }) + } end - describe 'when deploying with inetd and custom options' do - let(:facts) { { :operatingsystem => 'Debian', - :path => '/usr/local/bin:/usr/bin:/bin', } } - let(:params) { { :inetd => true, - :options => '--timeout 5 --secure', } } + describe 'when deploying with xinetd on debian' do + let (:facts) { { :osfamily => 'Debian', + :operatingsystem => 'Debian', + :path => '/usr/local/bin:/usr/bin:/bin', } } + let (:params) { { :inetd => true, } } + it { + should include_class('xinetd') + should contain_xinetd__service('tftp').with({ + 'port' => '69', + 'protocol' => 'udp', + 'server_args' => '--secure /srv/tftp', + 'server' => '/usr/sbin/in.tftpd', + 'user' => 'tftp', + 'socket_type' => 'dgram', + 'cps' => '100 2', + 'flags' => 'IPv4', + 'per_source' => '11', + 'wait' => 'yes', + 'bind' => '0.0.0.0', + }) + } + end + + describe 'when deploying with xinetd with custom options' do + let (:facts) { { :osfamily => 'Debian', + :operatingsystem => 'Debian', + :path => '/usr/local/bin:/usr/bin:/bin', } } + let (:params) { { :inetd => true, + :options => '--secure --timeout 50', } } + it { + should include_class('xinetd') + should contain_xinetd__service('tftp').with({ + 'port' => '69', + 'protocol' => 'udp', + 'server_args' => '--secure --timeout 50 /srv/tftp', + 'server' => '/usr/sbin/in.tftpd', + 'user' => 'tftp', + 'socket_type' => 'dgram', + 'cps' => '100 2', + 'flags' => 'IPv4', + 'per_source' => '11', + 'wait' => 'yes', + 'bind' => '0.0.0.0', + }) + } + end - it { expect { should contain_class('tftp') }.to raise_error(Puppet::Error) } + describe 'when deploying with xinetd with custom settings' do + let (:facts) { { :osfamily => 'Debian', + :operatingsystem => 'Debian', + :path => '/usr/local/bin:/usr/bin:/bin', } } + let (:params) { { :inetd => true, + :port => 1069, + :address => '127.0.0.1', + :username => 'root', + :directory => '/tftpboot', } } + it { + should include_class('xinetd') + should contain_xinetd__service('tftp').with({ + 'port' => '1069', + 'protocol' => 'udp', + 'server_args' => '--secure /tftpboot', + 'server' => '/usr/sbin/in.tftpd', + 'user' => 'root', + 'socket_type' => 'dgram', + 'cps' => '100 2', + 'flags' => 'IPv4', + 'per_source' => '11', + 'wait' => 'yes', + 'bind' => '127.0.0.1', + }) + } end + end diff --git a/spec/defines/tftp_file_spec.rb b/spec/defines/tftp_file_spec.rb index 0de1b6f..e24f0f3 100644 --- a/spec/defines/tftp_file_spec.rb +++ b/spec/defines/tftp_file_spec.rb @@ -6,30 +6,36 @@ describe 'tftp::file' do describe 'when deploying on debian' do let(:facts) { { :operatingsystem => 'Debian', + :osfamily => 'Debian', :path => '/usr/local/bin:/usr/bin:/bin', } } - it { should include_class('tftp') } - it { should contain_file('/srv/tftp/sample').with({ - 'ensure' => 'file', - 'owner' => 'tftp', - 'group' => 'tftp', - 'mode' => '0644', - 'recurse' => false, - }) } + it { + should include_class('tftp') + should contain_file('/srv/tftp/sample').with({ + 'ensure' => 'file', + 'owner' => 'tftp', + 'group' => 'tftp', + 'mode' => '0644', + 'recurse' => false, + }) + } end describe 'when deploying on ubuntu' do let(:facts) { { :operatingsystem => 'ubuntu', + :osfamily => 'Debian', :path => '/usr/local/bin:/usr/bin:/bin', } } - it { should include_class('tftp') } - it { should contain_file('/var/lib/tftpboot/sample').with({ - 'ensure' => 'file', - 'owner' => 'tftp', - 'group' => 'tftp', - 'mode' => '0644', - 'recurse' => false, - }) } + it { + should include_class('tftp') + should contain_file('/var/lib/tftpboot/sample').with({ + 'ensure' => 'file', + 'owner' => 'tftp', + 'group' => 'tftp', + 'mode' => '0644', + 'recurse' => false, + }) + } end describe 'when deploying with parameters' do @@ -39,30 +45,36 @@ describe 'tftp::file' do :mode => '0755', :recurse => true }} let(:facts) { { :operatingsystem => 'Debian', + :osfamily => 'Debian', :path => '/usr/local/bin:/usr/bin:/bin', } } - it { should include_class('tftp') } - it { should contain_file('/srv/tftp/sample').with({ - 'ensure' => 'directory', - 'owner' => 'root', - 'group' => 'root', - 'mode' => '0755', - 'recurse' => true, - }) } + it { + should include_class('tftp') + should contain_file('/srv/tftp/sample').with({ + 'ensure' => 'directory', + 'owner' => 'root', + 'group' => 'root', + 'mode' => '0755', + 'recurse' => true, + }) + } end describe 'when deploying without recurse parameters' do let(:facts) { {:operatingsystem => 'Debian', + :osfamily => 'Debian', :path => '/usr/local/bin:/usr/bin:/bin', } } - it { should include_class('tftp') } - it { should contain_file('/srv/tftp/sample').with({ - 'ensure' => 'file', - 'recurse' => false, - 'purge' => nil, - 'replace' => nil, - 'recurselimit' => nil, - }) } + it { + should include_class('tftp') + should contain_file('/srv/tftp/sample').with({ + 'ensure' => 'file', + 'recurse' => false, + 'purge' => nil, + 'replace' => nil, + 'recurselimit' => nil, + }) + } end describe 'when deploying with recurse parameters' do @@ -73,49 +85,57 @@ describe 'tftp::file' do :purge => true, :replace => false }} let(:facts) { {:operatingsystem => 'Debian', + :osfamily => 'Debian', :path => '/usr/local/bin:/usr/bin:/bin', }} - it { should include_class('tftp') } - it { should contain_file('/srv/tftp/sample').with({ - 'ensure' => 'directory', - 'owner' => 'tftp', - 'group' => 'tftp', - 'mode' => '0755', - 'recurse' => true, - 'recurselimit' => 42, - 'purge' => true, - 'replace' => false, - }) } + it { + should include_class('tftp') + should contain_file('/srv/tftp/sample').with({ + 'ensure' => 'directory', + 'owner' => 'tftp', + 'group' => 'tftp', + 'mode' => '0755', + 'recurse' => true, + 'recurselimit' => 42, + 'purge' => true, + 'replace' => false, + }) + } end describe 'when deploying directory' do let(:params) { {:ensure => 'directory', :mode => '0755' }} let(:facts) { { :operatingsystem => 'Debian', + :osfamily => 'Debian', :caller_module_name => 'acme', :path => '/usr/local/bin:/usr/bin:/bin', } } - it { should include_class('tftp') } - it { should contain_file('/srv/tftp/sample').with({ - 'ensure' => 'directory', - 'mode' => '0755', - 'source' => nil, - }) } + it { + should include_class('tftp') + should contain_file('/srv/tftp/sample').with({ + 'ensure' => 'directory', + 'mode' => '0755', + 'source' => nil, + }) + } end - describe 'when deploying file from another module' do + describe 'when deploying file' do let(:params) { {:ensure => 'file', :mode => '0755' }} let(:facts) { { :operatingsystem => 'Debian', - :caller_module_name => 'acme', + :osfamily => 'Debian', :path => '/usr/local/bin:/usr/bin:/bin', } } - it { should include_class('tftp') } - it { should contain_file('/srv/tftp/sample').with({ - 'ensure' => 'file', - 'mode' => '0755', - 'source' => 'puppet:///modules/acme/sample' - }) } + it { + should include_class('tftp') + should contain_file('/srv/tftp/sample').with({ + 'ensure' => 'file', + 'mode' => '0755', + 'source' => 'puppet:///modules/tftp/sample' + }) + } end describe 'when deploying file with content' do @@ -123,15 +143,18 @@ describe 'tftp::file' do :content => 'hi', :mode => '0755' }} let(:facts) { { :operatingsystem => 'Debian', + :osfamily => 'Debian', :caller_module_name => 'acme', :path => '/usr/local/bin:/usr/bin:/bin', } } - - it { should include_class('tftp') } - it { should contain_file('/srv/tftp/sample').with({ - 'ensure' => 'file', - 'mode' => '0755', - 'content' => 'hi', - 'source' => nil, - }) } + it { + should include_class('tftp') + should contain_file('/srv/tftp/sample').with({ + 'ensure' => 'file', + 'mode' => '0755', + 'content' => 'hi', + 'source' => nil, + }) + } end + end diff --git a/spec/fixtures/manifests/site.pp b/spec/fixtures/manifests/site.pp deleted file mode 100644 index e69de29..0000000 --- a/spec/fixtures/manifests/site.pp +++ /dev/null |