diff options
37 files changed, 869 insertions, 343 deletions
diff --git a/.fixtures.yml b/.fixtures.yml new file mode 100644 index 0000000..112077f --- /dev/null +++ b/.fixtures.yml @@ -0,0 +1,4 @@ +fixtures: + repositories: + symlinks: + samba: "#{source_dir}" @@ -1,2 +1,5 @@ .DS_Store -pkg/
\ No newline at end of file +pkg/ +log/ +Gemfile.lock +spec/fixtures/ diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..625faa3 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,42 @@ +--- +language: ruby +bundler_args: --without development --jobs=3 --retry=3 + +sudo: false + +rvm: + - 1.8.7 + - 1.9.3 + - 2.0.0 + - 2.1 + +env: + - PUPPET_VERSION="~> 2.7.0" + - PUPPET_VERSION="~> 3.1.0" + - PUPPET_VERSION="~> 3.2.0" + - PUPPET_VERSION="~> 3.3.0" + - PUPPET_VERSION="~> 3.4.0" + - PUPPET_VERSION="~> 3.5.0" + +before_install: rm Gemfile.lock || true + +script: bundle exec rake test + +matrix: + exclude: + - rvm: 1.9.3 + env: PUPPET_VERSION="~> 2.7.0" + - rvm: 2.0.0 + env: PUPPET_VERSION="~> 2.7.0" + - rvm: 2.0.0 + env: PUPPET_VERSION="~> 3.1.0" + - rvm: 2.1 + env: PUPPET_VERSION="~> 2.7.0" + - rvm: 2.1 + env: PUPPET_VERSION="~> 3.1.0" + - rvm: 2.1 + env: PUPPET_VERSION="~> 3.2.0" + - rvm: 2.1 + env: PUPPET_VERSION="~> 3.3.0" + - rvm: 2.1 + env: PUPPET_VERSION="~> 3.4.0" @@ -1,5 +1,26 @@ -source "http://rubygems.org" +source "https://rubygems.org" -gem "rake" -gem "puppet-lint" -gem "puppet"
\ No newline at end of file +group :development do + gem "beaker", "> 2.0.0" + gem "beaker-rspec", ">= 5.1.0" + gem "pry" + gem "puppet-blacksmith" + gem "serverspec" + gem "vagrant-wrapper" + gem "metadata-json-lint" +end + +group :test do + gem "rake", '< 11.0' + gem "puppet", ENV['PUPPET_VERSION'] || '~> 3.7.0' + gem "puppet-lint", :github => 'rodjek/puppet-lint', + :ref => '2546fed6be894bbcff15c3f48d4b6f6bc15d94d1' + + # Pin for 1.8.7 compatibility for now + gem "rspec", '< 3.2.0' + gem "rspec-core", "3.1.7" + gem "rspec-puppet", "~> 2.1" + + gem "puppet-syntax" + gem "puppetlabs_spec_helper" +end diff --git a/Gemfile.lock b/Gemfile.lock deleted file mode 100644 index 6b9032d..0000000 --- a/Gemfile.lock +++ /dev/null @@ -1,18 +0,0 @@ -GEM - remote: http://rubygems.org/ - specs: - facter (1.6.13) - hiera (1.0.0) - puppet (3.0.1) - facter (~> 1.6.11) - hiera (~> 1.0.0) - puppet-lint (0.3.2) - rake (0.9.2.2) - -PLATFORMS - ruby - -DEPENDENCIES - puppet - puppet-lint - rake diff --git a/Modulefile b/Modulefile deleted file mode 100644 index 235cb3f..0000000 --- a/Modulefile +++ /dev/null @@ -1,6 +0,0 @@ -name 'ajjahn-samba' -version '0.1.2' -summary "Module for provisioning Samba" -description "Module for provisioning Samba" -author 'Adam Jahn' -project_page 'https://github.com/ajjahn/puppet-samba'
\ No newline at end of file @@ -1,8 +1,16 @@ # Puppet Samba Module +[![Build Status](https://travis-ci.org/ajjahn/puppet-samba.png?branch=master)](https://travis-ci.org/ajjahn/puppet-samba) + Module for provisioning Samba -Tested on Ubuntu 12.04, CentOS 6.3, patches to support other operating systems are welcome. +Supports: + +* Ubuntu: 14.04, 12.04 +* Debian: 8.x, 7.x +* CentOS: 7.x, 6.x + +Patches to support other operating systems are welcome. ## Installation @@ -18,58 +26,62 @@ or Tweak and add the following to your site manifest: - node 'server.example.com' { - class {'samba::server': - workgroup => 'example', - server_string => "Example Samba Server", - interfaces => "eth0 lo", - security => 'share' - } - - samba::server::share {'example-share': - comment => 'Example Share', - path => '/path/to/share', - guest_only => true, - guest_ok => true, - guest_account => "guest", - browsable => false, - create_mask => 0777, - force_create_mask => 0777, - directory_mask => 0777, - force_directory_mask => 0777, - force_group => 'group', - force_user => 'user', - copy => 'some-other-share', - } - } - -If you want join Samba server to Active Directory. Tested on Ubuntu 12.04. - - node 'server.example.com' { - class {'samba::server': - workgroup => 'example', - server_string => "Example Samba Server", - interfaces => "eth0 lo", - security => 'ads' - } - - samba::server::share {'ri-storage': - comment => 'RBTH User Storage', - path => "$smb_share", - browsable => true, - writable => true, - create_mask => 0770, - directory_mask => 0770, - } - - class { 'samba::server::ads': - winbind_acct => $::domain_admin, - winbind_pass => $::admin_password, - realm => 'EXAMPLE.COM', - nsswitch => true, - target_ou => "Nix_Mashine" - } - } +```puppet +node 'server.example.com' { + class {'samba::server': + workgroup => 'example', + server_string => "Example Samba Server", + interfaces => "eth0 lo", + security => 'share' + } + + samba::server::share {'example-share': + comment => 'Example Share', + path => '/path/to/share', + guest_only => true, + guest_ok => true, + guest_account => "guest", + browsable => false, + create_mask => 0777, + force_create_mask => 0777, + directory_mask => 0777, + force_directory_mask => 0777, + force_group => 'group', + force_user => 'user', + copy => 'some-other-share', + } +} +``` + +If you want join Samba server to Active Directory. + +```puppet +node 'server.example.com' { + class {'samba::server': + workgroup => 'example', + server_string => "Example Samba Server", + interfaces => "eth0 lo", + security => 'ads' + } + + samba::server::share {'ri-storage': + comment => 'RBTH User Storage', + path => "$smb_share", + browsable => true, + writable => true, + create_mask => 0770, + directory_mask => 0770, + } + + class { 'samba::server::ads': + winbind_acct => $::domain_admin, + winbind_pass => $::admin_password, + realm => 'EXAMPLE.COM', + nsswitch => true, + target_ou => "Nix_Mashine" + } +} +``` Most configuration options are optional. @@ -1,16 +1,42 @@ -require 'puppet' -require 'rake' +require 'puppetlabs_spec_helper/rake_tasks' require 'puppet-lint/tasks/puppet-lint' +require 'puppet-syntax/tasks/puppet-syntax' -# Leave this in until we're ready to write documentation -PuppetLint.configuration.send("disable_documentation") +# These two gems aren't always present, for instance +# on Travis with --without development +begin + require 'puppetlabs_spec_helper/rake_tasks' + require 'puppet_blacksmith/rake_tasks' +rescue LoadError +end -# Ruby's version of true does not equate to puppet's version of true -PuppetLint.configuration.send("disable_quoted_booleans") -PuppetLint.configuration.send("disable_selector_inside_resource") -PuppetLint.configuration.send("disable_autoloader_layout") PuppetLint.configuration.send("disable_80chars") PuppetLint.configuration.log_format = "%{path}:%{linenumber}:%{check}:%{KIND}:%{message}" -desc "Run puppet-lint" -task :default => [:lint] +# Forsake support for Puppet 2.6.2 for the benefit of cleaner code. +# http://puppet-lint.com/checks/class_parameter_defaults/ +PuppetLint.configuration.send('disable_80chars') +PuppetLint.configuration.send('disable_class_parameter_defaults') +# http://puppet-lint.com/checks/class_inherits_from_params_class/ +PuppetLint.configuration.send('disable_class_inherits_from_params_class') + +exclude_paths = [ + "pkg/**/*", + "vendor/**/*", + "spec/**/*", +] +PuppetLint.configuration.ignore_paths = exclude_paths +PuppetSyntax.exclude_paths = exclude_paths + +ENV['BEAKER_set'] ||= 'ubuntu-server-1204-x86' +desc "Run acceptance tests" +RSpec::Core::RakeTask.new(:acceptance) do |t| + t.pattern = 'spec/acceptance' +end + +desc "Run syntax, lint, and spec tests." +task :test => [ + :syntax, + :lint, + :spec, +] diff --git a/manifests/init.pp b/manifests/init.pp index 8a914a4..4fbac9a 100644 --- a/manifests/init.pp +++ b/manifests/init.pp @@ -1,7 +1,9 @@ +# == Class samba +# class samba { include samba::server if samba::server::security == 'ads' { include samba::server::ads } -}
\ No newline at end of file +} diff --git a/manifests/server.pp b/manifests/server.pp index bc1e3d7..cbc61a9 100644 --- a/manifests/server.pp +++ b/manifests/server.pp @@ -1,46 +1,68 @@ +# == Class samba::server +# class samba::server($interfaces = '', $security = '', $server_string = '', $unix_password_sync = '', - $workgroup = '') { + $netbios_name = '', + $workgroup = '', + $socket_options = '', + $deadtime = '', + $keepalive = '', + $load_printers = '', + $printing = '', + $printcap_name = '', + $map_to_guest = 'Never', + $guest_account = '', + $disable_spoolss = '', + $kernel_oplocks = '', + $pam_password_change = '', + $os_level = '', + $preferred_master = '', + $bind_interfaces_only = 'yes', + $shares = {}, + $users = {}, ) { include samba::server::install include samba::server::config include samba::server::service + $incl = '/etc/samba/smb.conf' $context = '/files/etc/samba/smb.conf' - $target = "target[. = 'global']" + $target = 'target[. = "global"]' augeas { 'global-section': + incl => $incl, + lens => 'Samba.lns', context => $context, changes => "set ${target} global", require => Class['samba::server::config'], notify => Class['samba::server::service'] } - - set_samba_option { + samba::server::option { 'interfaces': value => $interfaces; - 'bind interfaces only': value => 'yes'; + 'bind interfaces only': value => $bind_interfaces_only; 'security': value => $security; 'server string': value => $server_string; 'unix password sync': value => $unix_password_sync; + 'netbios name': value => $netbios_name; 'workgroup': value => $workgroup; - } -} - -define set_samba_option ( $value = '', $signal = 'samba::server::service' ) { - $context = $samba::server::context - $target = $samba::server::target - $changes = $value ? { - default => "set \"${target}/$name\" \"$value\"", - '' => "rm ${target}/$name", + 'socket options': value => $socket_options; + 'deadtime': value => $deadtime; + 'keepalive': value => $keepalive; + 'load printers': value => $load_printers; + 'printing': value => $printing; + 'printcap name': value => $printcap_name; + 'map to guest': value => $map_to_guest; + 'guest account': value => $guest_account; + 'disable spoolss': value => $disable_spoolss; + 'kernel oplocks': value => $kernel_oplocks; + 'pam password change': value => $pam_password_change; + 'os level': value => $os_level; + 'preferred master': value => $preferred_master; } - augeas { "samba-$name": - context => $context, - changes => $changes, - require => Augeas['global-section'], - notify => Class[$signal] - } + create_resources(samba::server::share, $shares) + create_resources(samba::server::user, $users) } diff --git a/manifests/server/ads.pp b/manifests/server/ads.pp index 1f8e602..757d091 100644 --- a/manifests/server/ads.pp +++ b/manifests/server/ads.pp @@ -1,8 +1,6 @@ +# == Class samba::server::ads # This module join samba server to Active Dirctory # -# Copyright (c) 2013 Lebedev Vadim, abraham1901 at g mail dot c o m -# Licensed under the MIT License, http://opensource.org/licenses/MIT - class samba::server::ads($ensure = present, $winbind_acct = 'admin', $winbind_pass = 'SecretPass', @@ -25,30 +23,47 @@ class samba::server::ads($ensure = present, $map_readonly = 'no', $target_ou = 'Nix_Mashine') { + $krb5_user_package = $::osfamily ? { + 'RedHat' => 'krb5-workstation', + default => 'krb5-user', + } + + if $::osfamily == 'RedHat' { + if $::operatingsystemrelease =~ /^6\./ { + $winbind_package = 'samba-winbind' + } else { + $winbind_package = 'samba-common' + } + } else { + $winbind_package = 'winbind' + } + package{ - 'krb5-user': ensure => installed; - 'winbind': ensure => installed; - 'expect': ensure => installed; + $krb5_user_package: ensure => installed; + $winbind_package: ensure => installed; + 'expect': ensure => installed; } include samba::server::config include samba::server::winbind - $signal = 'samba::server::winbind' + # notify winbind + samba::server::option { + 'realm': value => $realm, + notify => Class['Samba::Server::Winbind']; + 'winbind uid': value => $winbind_uid, + notify => Class['Samba::Server::Winbind']; + 'winbind gid': value => $winbind_gid, + notify => Class['Samba::Server::Winbind']; + 'winbind enum groups': value => $winbind_enum_groups, + notify => Class['Samba::Server::Winbind']; + 'winbind enum users': value => $winbind_enum_users, + notify => Class['Samba::Server::Winbind']; + 'winbind use default domain': value => $winbind_use_default_domain, + notify => Class['Samba::Server::Winbind']; + } - set_samba_option { - 'realm': value => $realm, - signal => $signal; - 'winbind uid': value => $winbind_uid, - signal => $signal; - 'winbind gid': value => $winbind_gid, - signal => $signal; - 'winbind enum groups': value => $winbind_enum_groups, - signal => $signal; - 'winbind enum users': value => $winbind_enum_users, - signal => $signal; - 'winbind use default domain': value => $winbind_use_default_domain, - signal => $signal; + samba::server::option { 'acl group control': value => $acl_group_control; 'map acl inherit': value => $map_acl_inherit; 'inherit acls': value => $inherit_acls; @@ -61,14 +76,14 @@ class samba::server::ads($ensure = present, 'map readonly': value => $map_readonly; } - $nss_file='etc/nsswitch.conf' + $nss_file = 'etc/nsswitch.conf' - $changes=$nsswitch ? { + $changes = $nsswitch ? { true => [ - "set database[. = 'passwd']/service[1] compat", - "set database[. = 'passwd']/service[2] winbind", - "set database[. = 'group']/service[1] compat", - "set database[. = 'group']/service[2] winbind", + 'set database[. = "passwd"]/service[1] compat', + 'set database[. = "passwd"]/service[2] winbind', + 'set database[. = "group"]/service[1] compat', + 'set database[. = "group"]/service[2] winbind', ], false => [ "rm /files/${nss_file}/database[. = 'passwd']/service[. = 'winbind']", @@ -86,12 +101,12 @@ class samba::server::ads($ensure = present, path => '/sbin/verify_active_directory', owner => root, group => root, - mode => "0755", + mode => '0755', content => template("${module_name}/verify_active_directory.erb"), - require => [ Package['krb5-user', 'winbind', 'expect'], + require => [ Package[$krb5_user_package, $winbind_package, 'expect'], Augeas['samba-realm', 'samba-security', 'samba-winbind enum users', 'samba-winbind enum groups', 'samba-winbind uid', 'samba-winbind gid', - 'samba-winbind use default domain'] ], + 'samba-winbind use default domain'], Service['winbind'] ], } file {'configure_active_directory': @@ -99,18 +114,18 @@ class samba::server::ads($ensure = present, path => '/sbin/configure_active_directory', owner => root, group => root, - mode => "0755", + mode => '0755', content => template("${module_name}/configure_active_directory.erb"), - require => [ Package['krb5-user', 'winbind', 'expect'], + require => [ Package[$krb5_user_package, $winbind_package, 'expect'], Augeas['samba-realm', 'samba-security', 'samba-winbind enum users', 'samba-winbind enum groups', 'samba-winbind uid', 'samba-winbind gid', - 'samba-winbind use default domain'] ], + 'samba-winbind use default domain'], Service['winbind'] ], } exec {'join-active-directory': # join the domain configured in samba.conf command => '/sbin/configure_active_directory -j', unless => '/sbin/verify_active_directory', - require => [ File['configure_active_directory', 'verify_active_directory'], Class['samba::server::winbind'] ], + require => [ File['configure_active_directory', 'verify_active_directory'], Service['winbind'] ], } } diff --git a/manifests/server/config.pp b/manifests/server/config.pp index d51e432..eb9b78e 100644 --- a/manifests/server/config.pp +++ b/manifests/server/config.pp @@ -1,10 +1,11 @@ +# == Class samba::server::config +# class samba::server::config { - file { '/etc/samba': - ensure => directory, - owner => 'root', - group => 'root', - mode => '0755', + ensure => directory, + owner => 'root', + group => 'root', + mode => '0755', } file { '/etc/samba/smb.conf': @@ -15,5 +16,4 @@ class samba::server::config { require => [File['/etc/samba'], Class['samba::server::install']], notify => Class['samba::server::service'] } - } diff --git a/manifests/server/install.pp b/manifests/server/install.pp index 1454bfe..ec98a49 100644 --- a/manifests/server/install.pp +++ b/manifests/server/install.pp @@ -1,5 +1,7 @@ +# == Class samba::server::install +# class samba::server::install { package { 'samba': ensure => installed } -}
\ No newline at end of file +} diff --git a/manifests/server/option.pp b/manifests/server/option.pp new file mode 100644 index 0000000..bf491e8 --- /dev/null +++ b/manifests/server/option.pp @@ -0,0 +1,21 @@ +# == Define samba::server::option +# +define samba::server::option ( $value = '' ) { + $incl = $samba::server::incl + $context = $samba::server::context + $target = $samba::server::target + + $changes = $value ? { + '' => "rm ${target}/${name}", + default => "set \"${target}/${name}\" \"${value}\"", + } + + augeas { "samba-${name}": + incl => $incl, + lens => 'Samba.lns', + context => $context, + changes => $changes, + require => Augeas['global-section'], + notify => Class['Samba::Server::Service'] + } +} diff --git a/manifests/server/params.pp b/manifests/server/params.pp new file mode 100644 index 0000000..be9e01b --- /dev/null +++ b/manifests/server/params.pp @@ -0,0 +1,38 @@ +# == Class samba::server::params +# +class samba::server::params { + case $::osfamily { + 'Redhat': { $service_name = 'smb' } + 'Debian': { + case $::operatingsystem { + 'Debian': { + case $::operatingsystemmajrelease { + '8' : { $service_name = 'smbd' } + default: { $service_name = 'samba' } + } + } + 'Ubuntu': { + $service_name = 'smbd' + $nmbd_name = 'nmbd' + } + default: { $service_name = 'samba' } + } + } + 'Gentoo': { $service_name = 'samba' } + 'Archlinux': { + $service_name = 'smbd' + $nmbd_name = 'nmbd' + } + + # Currently Gentoo has $::osfamily = "Linux". This should change in + # Factor 1.7.0 <http://projects.puppetlabs.com/issues/17029>, so + # adding workaround. + 'Linux': { + case $::operatingsystem { + 'Gentoo': { $service_name = 'samba' } + default: { fail("${::operatingsystem} is not supported by this module.") } + } + } + default: { fail("${::osfamily} is not supported by this module.") } + } +} diff --git a/manifests/server/service.pp b/manifests/server/service.pp index 6d24cad..68db2d6 100644 --- a/manifests/server/service.pp +++ b/manifests/server/service.pp @@ -1,27 +1,24 @@ -class samba::server::service ($ensure = running, $enable = true) { - case $::osfamily { - Redhat: { $service_name = 'smb' } - Debian: { $service_name = 'samba' } - Gentoo: { $service_name = 'samba' } +# == Class samba::server::server +# +class samba::server::service ( + $ensure = running, + $enable = true +) inherits samba::server::params { - # Currently Gentoo has $::osfamily = "Linux". This should change in - # Factor 1.7.0 <http://projects.puppetlabs.com/issues/17029>, so - # adding workaround. - Linux: { - case $::operatingsystem { - Gentoo: { $service_name = 'samba' } - default: { fail("$::operatingsystem is not supported by this module.") } - } - } - default: { fail("$::osfamily is not supported by this module.") } - } - - service { "$service_name" : - ensure => $ensure, - hasstatus => true, - hasrestart => true, - enable => $enable, - require => Class['samba::server::config'] + service { $samba::server::params::service_name : + ensure => $ensure, + hasstatus => true, + hasrestart => true, + enable => $enable, + require => Class['samba::server::config'] } + if $samba::server::params::nmbd_name != undef { + service { $samba::server::params::nmbd_name : + ensure => $ensure, + hasrestart => false, + enable => $enable, + require => Class['samba::server::config'], + } + } } diff --git a/manifests/server/share.pp b/manifests/server/share.pp index b4eb02f..b0690bb 100644..100755 --- a/manifests/server/share.pp +++ b/manifests/server/share.pp @@ -1,209 +1,195 @@ +# == Define samba::server::share +# define samba::server::share($ensure = present, + $available = '', $browsable = '', $comment = '', $copy = '', $create_mask = '', $directory_mask = '', $force_create_mask = '', - $force_directory_mask = '', + $force_directory_mode = '', $force_group = '', $force_user = '', - $guest_account = '', $guest_ok = '', $guest_only = '', + $hide_unreadable = '', $path = '', + $op_locks = '', + $level2_oplocks = '', + $veto_oplock_files = '', $read_only = '', $public = '', + $write_list = '', $writable = '', - $printable = '') { - + $printable = '', + $valid_users = '', + $follow_symlinks = '', + $wide_links = '', + $map_acl_inherit = '', + $store_dos_attributes = '', + $strict_allocate = '', + $hide_dot_files = '', + ) { + + $incl = $samba::server::incl $context = $samba::server::context - $target = "target[. = '${name}']" + $target = "target[. = '${name}']" + + $section_changes = $ensure ? { + present => "set ${target} '${name}'", + default => "rm ${target} '${name}'", + } augeas { "${name}-section": + incl => $incl, + lens => 'Samba.lns', context => $context, - changes => $ensure ? { - present => "set ${target} '${name}'", - default => "rm ${target} '${name}'", - }, + changes => $section_changes, require => Class['samba::server::config'], notify => Class['samba::server::service'] } if $ensure == 'present' { - augeas { "${name}-browsable": - context => $context, - changes => $browsable ? { - true => "set ${target}/browsable yes", - false => "set ${target}/browsable no", - default => "rm ${target}/browsable", - }, - require => Augeas["${name}-section"], - notify => Class['samba::server::service'] - } - - augeas { "${name}-comment": - context => $context, - changes => $comment ? { - default => "set ${target}/comment '${comment}'", - '' => "rm ${target}/comment", - }, - require => Augeas["${name}-section"], - notify => Class['samba::server::service'] - } - - augeas { "${name}-copy": - context => $context, - changes => $copy ? { - default => "set ${target}/copy '${copy}'", - '' => "rm ${target}/copy", - }, - require => Augeas["${name}-section"], - notify => Class['samba::server::service'] - } - - augeas { "${name}-create_mask": - context => $context, - changes => $create_mask ? { + $changes = [ + $available ? { + true => "set \"${target}/available\" yes", + false => "set \"${target}/available\" no", + default => "rm \"${target}/available\"", + }, + $browsable ? { + true => "set \"${target}/browsable\" yes", + false => "set \"${target}/browsable\" no", + default => "rm \"${target}/browsable\"", + }, + $comment ? { + default => "set \"${target}/comment\" '${comment}'", + '' => "rm \"${target}/comment\"", + }, + $copy ? { + '' => "rm \"${target}/copy\"", + default => "set \"${target}/copy\" '${copy}'", + }, + $create_mask ? { + '' => "rm \"${target}/create mask\"", default => "set \"${target}/create mask\" '${create_mask}'", - '' => "rm \"${target}/create mask\"", }, - require => Augeas["${name}-section"], - notify => Class['samba::server::service'] - } - - augeas { "${name}-directory_mask": - context => $context, - changes => $directory_mask ? { + $directory_mask ? { + '' => "rm \"${target}/directory mask\"", default => "set \"${target}/directory mask\" '${directory_mask}'", - '' => "rm \"${target}/directory mask\"", }, - require => Augeas["${name}-section"], - notify => Class['samba::server::service'] - } - - augeas { "${name}-force_create_mask": - context => $context, - changes => $force_create_mask ? { + $force_create_mask ? { + '' => "rm \"${target}/force create mask\"", default => "set \"${target}/force create mask\" '${force_create_mask}'", - '' => "rm \"${target}/force create mask\"", }, - require => Augeas["${name}-section"], - notify => Class['samba::server::service'] - } - - augeas { "${name}-force_directory_mask": - context => $context, - changes => $force_directory_mask ? { - default => "set \"${target}/force directory mask\" '${force_directory_mask}'", - '' => "rm \"${target}/force directory mask\"", + $force_directory_mode ? { + '' => "rm \"${target}/force directory mode\"", + default => "set \"${target}/force directory mode\" '${force_directory_mode}'", }, - require => Augeas["${name}-section"], - notify => Class['samba::server::service'] - } - - augeas { "${name}-force_group": - context => $context, - changes => $force_group ? { + $force_group ? { + '' => "rm \"${target}/force group\"", default => "set \"${target}/force group\" '${force_group}'", - '' => "rm \"${target}/force group\"", }, - require => Augeas["${name}-section"], - notify => Class['samba::server::service'] - } - - augeas { "${name}-force_user": - context => $context, - changes => $force_user ? { + $force_user ? { + '' => "rm \"${target}/force user\"", default => "set \"${target}/force user\" '${force_user}'", - '' => "rm \"${target}/force user\"", - }, - require => Augeas["${name}-section"], - notify => Class['samba::server::service'] - } - - augeas { "${name}-guest_account": - context => $context, - changes => $guest_account ? { - default => "set \"${target}/guest account\" '${guest_account}'", - '' => "rm \"${target}/guest account\"", }, - require => Augeas["${name}-section"], - notify => Class['samba::server::service'] - } - - augeas { "${name}-guest_ok": - context => $context, - changes => $guest_ok ? { + $guest_ok ? { true => "set \"${target}/guest ok\" yes", false => "set \"${target}/guest ok\" no", - default => "rm \"${target}/guest ok\"", + default => "rm \"${target}/guest ok\"", }, - require => Augeas["${name}-section"], - notify => Class['samba::server::service'] - } - - augeas { "${name}-guest_only": - context => $context, - changes => $guest_only ? { + $guest_only ? { true => "set \"${target}/guest only\" yes", false => "set \"${target}/guest only\" no", - default => "rm \"${target}/guest only\"", + default => "rm \"${target}/guest only\"", }, - require => Augeas["${name}-section"], - notify => Class['samba::server::service'] - } - - augeas { "${name}-path": - context => $context, - changes => $path ? { + $hide_unreadable ? { + true => "set \"${target}/hide unreadable\" yes", + false => "set \"${target}/hide unreadable\" no", + default => "rm \"${target}/hide unreadable\"", + }, + $path ? { default => "set ${target}/path '${path}'", - '' => "rm ${target}/path", + '' => "rm ${target}/path", }, - require => Augeas["${name}-section"], - notify => Class['samba::server::service'] - } - - augeas { "${name}-read_only": - context => $context, - changes => $read_only ? { + $read_only ? { true => "set \"${target}/read only\" yes", false => "set \"${target}/read only\" no", - default => "rm \"${target}/read_only\"", + default => "rm \"${target}/read only\"", }, - require => Augeas["${name}-section"], - notify => Class['samba::server::service'] - } - - augeas { "${name}-public": - context => $context, - changes => $public ? { + $public ? { true => "set \"${target}/public\" yes", false => "set \"${target}/public\" no", - default => "rm \"${target}/public\"", + default => "rm \"${target}/public\"", }, - require => Augeas["${name}-section"], - notify => Class['samba::server::service'] - } - - augeas { "${name}-writable": - context => $context, - changes => $writable ? { + $writable ? { true => "set \"${target}/writable\" yes", false => "set \"${target}/writable\" no", - default => "rm \"${target}/writable\"", + default => "rm \"${target}/writable\"", }, - require => Augeas["${name}-section"], - notify => Class['samba::server::service'] - } - - augeas { "${name}-printable": - context => $context, - changes => $printable ? { + $printable ? { true => "set \"${target}/printable\" yes", false => "set \"${target}/printable\" no", - default => "rm \"${target}/printable\"", + default => "rm \"${target}/printable\"", + }, + $follow_symlinks ? { + true => "set \"${target}/follow symlinks\" yes", + false => "set \"${target}/follow symlinks\" no", + default => "rm \"${target}/follow symlinks\"", }, + $wide_links ? { + true => "set \"${target}/wide links\" yes", + false => "set \"${target}/wide links\" no", + default => "rm \"${target}/wide links\"", + }, + $map_acl_inherit ? { + true => "set \"${target}/map acl inherit\" yes", + false => "set \"${target}/map acl inherit\" no", + default => "rm \"${target}/map acl inherit\"", + }, + $store_dos_attributes ? { + true => "set \"${target}/store dos attributes\" yes", + false => "set \"${target}/store dos attributes\" no", + default => "rm \"${target}/store dos attributes\"", + }, + $strict_allocate ? { + true => "set \"${target}/strict allocate\" yes", + false => "set \"${target}/strict allocate\" no", + default => "rm \"${target}/strict allocate\"", + }, + $valid_users ? { + '' => "rm \"${target}/valid users\"", + default => "set \"${target}/valid users\" '${valid_users}'", + }, + $op_locks ? { + '' => "rm \"${target}/oplocks\"", + default => "set \"${target}/oplocks\" '${op_locks}'", + }, + $level2_oplocks ? { + '' => "rm \"${target}/level2 oplocks\"", + default => "set \"${target}/level2 oplocks\" '${level2_oplocks}'", + }, + $veto_oplock_files ? { + '' => "rm \"${target}/veto oplock files\"", + default => "set \"${target}/veto oplock files\" '${veto_oplock_files}'", + }, + $write_list ? { + '' => "rm \"${target}/write list\"", + default => "set \"${target}/write list\" '${write_list}'", + }, + $hide_dot_files ? { + true => "set \"${target}/hide dot files\" yes", + false => "set \"${target}/hide dot files\" no", + default => "rm \"${target}/hide dot files\"", + }, + ] + + augeas { "${name}-changes": + incl => $incl, + lens => 'Samba.lns', + context => $context, + changes => $changes, require => Augeas["${name}-section"], notify => Class['samba::server::service'] } diff --git a/manifests/server/user.pp b/manifests/server/user.pp new file mode 100644 index 0000000..d10a602 --- /dev/null +++ b/manifests/server/user.pp @@ -0,0 +1,15 @@ +# == Class samba::server::user +# +define samba::server::user ( + $password, + $user_name = $name, +) { + require ::samba::server::install + + exec { "add smb account for ${user_name}": + command => "/bin/echo -e '${password}\\n${password}\\n' | /usr/bin/pdbedit --password-from-stdin -a '${user_name}'", + unless => "/usr/bin/pdbedit '${user_name}'", + require => [ User[$user_name] ], + notify => Class['samba::server::service'] #TODO: Is this really required?? + } +} diff --git a/manifests/server/winbind.pp b/manifests/server/winbind.pp index 76136b9..a379bb7 100644 --- a/manifests/server/winbind.pp +++ b/manifests/server/winbind.pp @@ -1,16 +1,13 @@ +# == Class samba::server::winbind +# class samba::server::winbind ($ensure = running, $enable = true) { $service_name = 'winbind' - notify { 'winbind-service': - message => 'Check winbind service', - } - service { $service_name: - ensure => $ensure, - hasstatus => true, - hasrestart => true, - enable => $enable, - require => Class['samba::server::config'] + ensure => $ensure, + hasstatus => true, + hasrestart => true, + enable => $enable, + require => Class['samba::server::config'] } - } diff --git a/metadata.json b/metadata.json new file mode 100644 index 0000000..173933f --- /dev/null +++ b/metadata.json @@ -0,0 +1,37 @@ +{ + "name": "ajjahn-samba", + "version": "0.4.1", + "author": "Adam Jahn", + "summary": "Module for provisioning Samba", + "license": "Apache-2.0", + "source": "https://github.com/ajjahn/puppet-samba", + "project_page": "https://github.com/ajjahn/puppet-samba", + "issues_url": "https://github.com/ajjahn/puppet-samba/issues", + "description": "Module for provisioning Samba", + "operatingsystem_support": [ + { + "operatingsystem": "RedHat", + "operatingsystemrelease": [ + "6.0", + "7.0" + ] + }, + { + "operatingsystem": "Ubuntu", + "operatingsystemrelease": [ + "12.04", + "14.04" + ] + }, + { + "operatingsystem": "Debian", + "operatingsystemrelease": [ + "7.0", + "8.0" + ] + } + ], + "dependencies": [ + + ] +} diff --git a/spec/acceptance/basic_samba_spec.rb b/spec/acceptance/basic_samba_spec.rb new file mode 100644 index 0000000..8a9e363 --- /dev/null +++ b/spec/acceptance/basic_samba_spec.rb @@ -0,0 +1,36 @@ +require 'spec_helper_acceptance' + +describe 'basic samba' do + context 'default parameters' do + let(:pp) {" + class { 'samba::server': + workgroup => 'example', + server_string => 'Example Samba Server' + } + + samba::server::share {'example-share': + comment => 'Example Share', + path => '/path/to/share', + guest_only => true, + guest_ok => true, + guest_account => 'guest', + browsable => false, + create_mask => 0777, + force_create_mask => 0777, + directory_mask => 0777, + force_directory_mode => 0777, + force_group => 'group', + force_user => 'user', + hide_dot_files => false, + } + "} + + it 'should apply with no errors' do + apply_manifest(pp, :catch_failures=>true) + end + + it 'should be idempotent' do + apply_manifest(pp, :catch_changes=>true) + end + end +end diff --git a/spec/acceptance/nodesets/centos-66-x64.yml b/spec/acceptance/nodesets/centos-66-x64.yml new file mode 100644 index 0000000..1fffff6 --- /dev/null +++ b/spec/acceptance/nodesets/centos-66-x64.yml @@ -0,0 +1,12 @@ +HOSTS: + centos-66-x64: + roles: + - master + platform: el-6-x86_64 + box: puppetlabs/centos-6.6-64-nocm + box_url: https://vagrantcloud.com/puppetlabs/boxes/centos-6.6-64-nocm + hypervisor: vagrant +CONFIG: + log_level: verbose + type: foss + color: false diff --git a/spec/acceptance/nodesets/centos-70-x64.yml b/spec/acceptance/nodesets/centos-70-x64.yml new file mode 100644 index 0000000..845e47e --- /dev/null +++ b/spec/acceptance/nodesets/centos-70-x64.yml @@ -0,0 +1,12 @@ +HOSTS: + centos-70-x64: + roles: + - master + platform: el-7-x86_64 + box: puppetlabs/centos-7.0-64-nocm + box_url: https://vagrantcloud.com/puppetlabs/boxes/centos-7.0-64-nocm + hypervisor : vagrant +CONFIG: + log_level: verbose + type: foss + color: false diff --git a/spec/acceptance/nodesets/debian-78-x64.yml b/spec/acceptance/nodesets/debian-78-x64.yml new file mode 100644 index 0000000..c4062fd --- /dev/null +++ b/spec/acceptance/nodesets/debian-78-x64.yml @@ -0,0 +1,12 @@ +HOSTS: + debian-78-x64: + roles: + - master + platform: debian-7-amd64 + box: puppetlabs/debian-7.8-64-nocm + box_url: https://vagrantcloud.com/puppetlabs/boxes/debian-7.8-64-nocm + hypervisor: vagrant + +CONFIG: + log_level: verbose + type: foss diff --git a/spec/acceptance/nodesets/debian-81-x64.yml b/spec/acceptance/nodesets/debian-81-x64.yml new file mode 100644 index 0000000..3b1d8aa --- /dev/null +++ b/spec/acceptance/nodesets/debian-81-x64.yml @@ -0,0 +1,12 @@ +HOSTS: + debian-81-x64: + roles: + - master + platform: debian-8-amd64 + box: lazyfrosch/debian-8-jessie-amd64-puppet + box_url: https://vagrantcloud.com/lazyfrosch/boxes/debian-8-jessie-amd64-puppet + hypervisor: vagrant + +CONFIG: + log_level: verbose + type: foss diff --git a/spec/acceptance/nodesets/ubuntu-server-1204-x86.yml b/spec/acceptance/nodesets/ubuntu-server-1204-x86.yml new file mode 100644 index 0000000..c2e8657 --- /dev/null +++ b/spec/acceptance/nodesets/ubuntu-server-1204-x86.yml @@ -0,0 +1,13 @@ +HOSTS: + ubuntu-server-1204-x64: + roles: + - master + platform: ubuntu-1204-amd64 + box: puppetlabs/ubuntu-12.04-64-nocm + box_url: https://vagrantcloud.com/puppetlabs/boxes/ubuntu-12.04-64-nocm + hypervisor: vagrant + +CONFIG: + log_level: verbose + type: foss + color: false diff --git a/spec/acceptance/nodesets/ubuntu-server-1404-x64.yml b/spec/acceptance/nodesets/ubuntu-server-1404-x64.yml new file mode 100644 index 0000000..62e2ea9 --- /dev/null +++ b/spec/acceptance/nodesets/ubuntu-server-1404-x64.yml @@ -0,0 +1,12 @@ +HOSTS: + ubuntu-server-1404-x64: + roles: + - master + platform: ubuntu-1404-amd64 + box: puppetlabs/ubuntu-14.04-64-nocm + box_url: https://vagrantcloud.com/puppetlabs/ubuntu-14.04-64-nocm + hypervisor: vagrant +CONFIG: + log_level: verbose + type: foss + color: false diff --git a/spec/classes/samba__server__config_spec.rb b/spec/classes/samba__server__config_spec.rb new file mode 100644 index 0000000..5f13aa4 --- /dev/null +++ b/spec/classes/samba__server__config_spec.rb @@ -0,0 +1,10 @@ +require 'spec_helper' + +describe 'samba::server::config', :type => :class do + context "on a Debian OS" do + let( :facts ) { { :osfamily => 'Debian' } } + + it { should contain_file('/etc/samba/smb.conf').with_owner('root') } + end +end + diff --git a/spec/classes/samba__server__install_spec.rb b/spec/classes/samba__server__install_spec.rb new file mode 100644 index 0000000..9764687 --- /dev/null +++ b/spec/classes/samba__server__install_spec.rb @@ -0,0 +1,9 @@ +require 'spec_helper' + +describe 'samba::server::install', :type => :class do + context "on a Debian OS" do + let(:facts) {{ :osfamily => 'Debian' }} + it { should contain_package('samba') } + end +end + diff --git a/spec/classes/samba__server__service_spec.rb b/spec/classes/samba__server__service_spec.rb new file mode 100644 index 0000000..4352ec2 --- /dev/null +++ b/spec/classes/samba__server__service_spec.rb @@ -0,0 +1,54 @@ +require 'spec_helper' + +describe 'samba::server::service' do + context 'on a Debian os family' do + let(:facts) {{ :osfamily => 'Debian' }} + + it { should contain_service('samba').with_require('Class[Samba::Server::Config]') } + + context 'Debian' do + context 'wheezy' do + let(:facts) {{ :osfamily => 'Debian', + :operatingsystem => 'Debian', + :operatingsystemmajrelease => '7' }} + it { should contain_service('samba') } + end + context 'jessie' do + let(:facts) {{ :osfamily => 'Debian', + :operatingsystem => 'Debian', + :operatingsystemmajrelease => '8' }} + it { should contain_service('smbd') } + end + end + + context 'Ubuntu' do + let(:facts) {{ :osfamily => 'Debian', :operatingsystem => 'Ubuntu' }} + it { should contain_service('smbd') } + end + end + + context 'on a Redhat os family' do + let(:facts) {{ :osfamily => 'Redhat' }} + it { should contain_service('smb') } + end + + context 'on a Archlinux os family' do + let(:facts) {{ :osfamily => 'Archlinux' }} + it { should contain_service('smbd') } + end + + context 'on Linux os family' do + let(:facts) {{ :osfamily => 'Linux' }} + it { should raise_error(/is not supported by this module./) } + + context 'Gentoo' do + let(:facts) {{ :osfamily => 'Linux', :operatingsystem => 'Gentoo' }} + it { should contain_service('samba') } + end + end + + context 'on an unsupported OS' do + let(:facts) {{ :osfamily => 'Solaris' }} + it { should raise_error(/Solaris is not supported by this module./) } + end +end diff --git a/spec/classes/samba__server_spec.rb b/spec/classes/samba__server_spec.rb new file mode 100644 index 0000000..46c5b15 --- /dev/null +++ b/spec/classes/samba__server_spec.rb @@ -0,0 +1,66 @@ +require 'spec_helper' + +describe 'samba::server' do + let(:facts) {{ :osfamily => 'Debian' }} + + it { should contain_class('samba::server::install') } + it { should contain_class('samba::server::config') } + it { should contain_class('samba::server::service') } + + it { should contain_samba__server__option('interfaces') } + it { should contain_samba__server__option('bind interfaces only') } + it { should contain_samba__server__option('security') } + it { should contain_samba__server__option('server string') } + it { should contain_samba__server__option('unix password sync') } + it { should contain_samba__server__option('workgroup') } + it { should contain_samba__server__option('socket options') } + it { should contain_samba__server__option('deadtime') } + it { should contain_samba__server__option('keepalive') } + it { should contain_samba__server__option('load printers') } + it { should contain_samba__server__option('printing') } + it { should contain_samba__server__option('printcap name') } + it { should contain_samba__server__option('disable spoolss') } + + context 'with hiera shares hash' do + let(:params) {{ + 'shares' => { + 'testShare' => { + 'path' => '/path/to/some/share', + 'browsable' => true, + 'writable' => true, + 'guest_ok' => true, + 'guest_only' => true, + }, + 'testShare2' => { + 'path' => '/some/other/path' + } + } + }} + it { + should contain_samba__server__share( 'testShare' ).with({ + 'path' => '/path/to/some/share', + 'browsable' => true, + 'writable' => true, + 'guest_ok' => true, + 'guest_only' => true, + }) + } + it { should contain_samba__server__share( 'testShare2' ).with_path('/some/other/path') } + end + + context 'with hiera users hash' do + let(:params) {{ + 'users' => { + 'testUser' => { + 'password' => 'testpass01' + }, + 'testUser2' => { + 'password' => 'testpass02' + } + } + }} + it { should contain_samba__server__user( 'testUser' ).with_password('testpass01') } + it { should contain_samba__server__user( 'testUser2' ).with_password('testpass02') } + end + +end diff --git a/spec/defines/samba__server__user_spec.rb b/spec/defines/samba__server__user_spec.rb new file mode 100644 index 0000000..c7ae00c --- /dev/null +++ b/spec/defines/samba__server__user_spec.rb @@ -0,0 +1,14 @@ +require 'spec_helper' + +describe 'samba::server::user', :type => :define do + let(:title) { 'test_user' } + let(:params) {{ :password => 'secret' }} + + it { is_expected.to contain_samba__server__user('test_user') } + it { is_expected.to contain_exec('add smb account for test_user').with( + :command => '/bin/echo -e \'secret\nsecret\n\' | /usr/bin/pdbedit --password-from-stdin -a \'test_user\'', + :unless => '/usr/bin/pdbedit \'test_user\'', + :require => 'User[test_user]', + :notify => 'Class[Samba::Server::Service]' + ) } +end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb new file mode 100644 index 0000000..81f98ac --- /dev/null +++ b/spec/spec_helper.rb @@ -0,0 +1,8 @@ +require 'puppetlabs_spec_helper/module_spec_helper' + +RSpec.configure do |c| + c.before do + # avoid "Only root can execute commands as other users" + Puppet.features.stubs(:root? => true) + end +end diff --git a/spec/spec_helper_acceptance.rb b/spec/spec_helper_acceptance.rb new file mode 100644 index 0000000..74187d8 --- /dev/null +++ b/spec/spec_helper_acceptance.rb @@ -0,0 +1,29 @@ +require 'beaker-rspec/spec_helper' +require 'beaker-rspec/helpers/serverspec' +require 'pry' + +unless ENV['BEAKER_provision'] == 'no' + hosts.each do |host| + # Install Puppet + if host.is_pe? + install_pe + else + install_puppet + end + end +end + +RSpec.configure do |c| + # Project root + proj_root = File.expand_path(File.join(File.dirname(__FILE__), '..')) + + # Readable test descriptions + c.formatter = :documentation + + # Configure all nodes in nodeset + c.before :suite do + # Install module and dependencies + puppet_module_install(:source => proj_root, :module_name => 'samba') + end +end + diff --git a/templates/configure_active_directory.erb b/templates/configure_active_directory.erb index 35ba86f..4f9b6e0 100644 --- a/templates/configure_active_directory.erb +++ b/templates/configure_active_directory.erb @@ -54,7 +54,7 @@ do esac done -password="<%= scope.lookupvar('samba::server::ads::winbind_pass') -%>" +password='<%= scope.lookupvar('samba::server::ads::winbind_pass') -%>' # short hostname from facter my_hostname="<%= hostname -%>" @@ -80,7 +80,7 @@ echo "Please do not kill me; I may be slow" >&2 if [ "$action" = "leave" ]; then logger -st $PROG "Leaving AD domain" - $NET ads $action -U ${winbind_acct}%${password} | grep Deleted && success=true || success=false + $NET ads $action -U "${winbind_acct}%${password}" | grep Deleted && success=true || success=false kdestroy rm -f /etc/krb5.keytab if [ $success = "true" ]; then @@ -105,8 +105,14 @@ ad_settle() { export KRB5CCNAME=$(umask 0077; mktemp -q winbind_cache.XXXXXXXX) if [ "$action" = "join" ]; then + if [ "${target_ou}" != "" ]; then + ou_parameter="createcomputer=\"${target_ou}\"" + else + ou_parameter="" + fi + logger -st $PROG "Joining AD domain" >&2 - $NET ads $action -U ${winbind_acct}%${password} createcomputer="${target_ou}"\ + $NET ads $action -U "${winbind_acct}%${password}" ${ou_parameter} \ | grep Joined && success=true || success=false if [ $success = "false" ]; then @@ -121,7 +127,8 @@ for attempt in $(seq 1 $max_attempts); do echo "Getting TGT for ${winbind_acct}@${my_realm}" >&2 $EXPECT -c "spawn -noecho kinit -c $KRB5CCNAME ${winbind_acct}@${my_realm}; expect :; - send ${password}\n; + send {${password}}; + send \n; expect eof" klist -c $KRB5CCNAME &> /dev/null && break done diff --git a/templates/verify_active_directory.erb b/templates/verify_active_directory.erb index 5a2a506..0917c49 100644 --- a/templates/verify_active_directory.erb +++ b/templates/verify_active_directory.erb @@ -21,7 +21,7 @@ fi # } >&2 #fi -password="<%= scope.lookupvar('samba::server::ads::winbind_pass') -%>" +password='<%= scope.lookupvar('samba::server::ads::winbind_pass') -%>' # short hostname from facter my_hostname="<%= hostname -%>" @@ -62,7 +62,8 @@ get_tgt() { ( $EXPECT -c "spawn -noecho kinit -c $KRB5CCNAME ${winbind_acct}@${default_realm}; expect :; - send ${password}\n; + send {${password}}; + send \n; expect eof" ) &> /dev/null klist -c $KRB5CCNAME &> /dev/null diff --git a/tests/init.pp b/tests/init.pp new file mode 100644 index 0000000..e1dd99d --- /dev/null +++ b/tests/init.pp @@ -0,0 +1,3 @@ +# Smoketest. + +class {'samba::server': } |