diff --git a/.fixtures.yml b/.fixtures.yml index c2714b2..868e403 100644 --- a/.fixtures.yml +++ b/.fixtures.yml @@ -9,6 +9,9 @@ fixtures: augeasproviders_grub: https://github.com/simp/augeasproviders_grub compliance_markup: https://github.com/simp/pupmod-simp-compliance_markup concat: https://github.com/simp/puppetlabs-concat + firewalld: + repo: https://github.com/simp/pupmod-voxpupuli-firewalld + ref: v4.1.0 haveged: https://github.com/simp/pupmod-simp-haveged iptables: https://github.com/simp/pupmod-simp-iptables logrotate: https://github.com/simp/pupmod-simp-logrotate diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 09249a9..c8c9004 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -69,10 +69,10 @@ variables: BEAKER_PUPPET_COLLECTION: 'puppet5' MATRIX_RUBY_VERSION: '2.4' -.pup_5_5_10: &pup_5_5_10 +.pup_5_5_16: &pup_5_5_16 image: 'ruby:2.4' variables: - PUPPET_VERSION: '5.5.10' + PUPPET_VERSION: '5.5.16' BEAKER_PUPPET_COLLECTION: 'puppet5' MATRIX_RUBY_VERSION: '2.4' @@ -149,8 +149,8 @@ pup5-unit: <<: *pup_5 <<: *unit_tests -pup5.5.10-unit: - <<: *pup_5_5_10 +pup5.5.16-unit: + <<: *pup_5_5_16 <<: *unit_tests pup6-unit: @@ -159,26 +159,26 @@ pup6-unit: # Acceptance tests # ============================================================================== -pup5.5.10: - <<: *pup_5_5_10 +pup5.5.16: + <<: *pup_5_5_16 <<: *acceptance_base script: - - 'bundle exec rake beaker:suites' + - 'bundle exec rake beaker:suites[default,default]' -pup5.5.10-fips: - <<: *pup_5_5_10 +pup5.5.16-fips: + <<: *pup_5_5_16 <<: *acceptance_base script: - - 'BEAKER_fips=yes bundle exec rake beaker:suites' + - 'BEAKER_fips=yes bundle exec rake beaker:suites[default,default]' -pup5.5.10-oel: - <<: *pup_5_5_10 +pup5.5.16-oel: + <<: *pup_5_5_16 <<: *acceptance_base script: - 'bundle exec rake beaker:suites[default,oel]' -pup5.5.10-oel-fips: - <<: *pup_5_5_10 +pup5.5.16-oel-fips: + <<: *pup_5_5_16 <<: *acceptance_base <<: *only_with_SIMP_FULL_MATRIX script: @@ -188,10 +188,10 @@ pup6: <<: *pup_6 <<: *acceptance_base script: - - 'bundle exec rake beaker:suites' + - 'bundle exec rake beaker:suites[default,default]' pup6-fips: <<: *pup_6 <<: *acceptance_base script: - - 'BEAKER_fips=yes bundle exec rake beaker:suites' + - 'BEAKER_fips=yes bundle exec rake beaker:suites[default,default]' diff --git a/CHANGELOG b/CHANGELOG index e2d40fe..c9aaf69 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,4 +1,8 @@ -* Fri Aug 02 2019 Robert Vincent - 6.3.1-0 +* Fri Jan 10 2020 Liz Nemsick - 6.4.0-0 +- Add EL8 support +- Update the upper bound of simp-simplib to < 5.0.0 + +* Fri Aug 02 2019 Robert Vincent - 6.4.0-0 - Support puppetlabs/concat 6.x. * Thu Aug 01 2019 Mike Renfro - 6.3.0-0 diff --git a/Gemfile b/Gemfile index f71b1ab..32aee40 100644 --- a/Gemfile +++ b/Gemfile @@ -13,8 +13,8 @@ group :test do gem 'puppet-strings' gem 'puppet-lint-empty_string-check', :require => false gem 'puppet-lint-trailing_comma-check', :require => false - gem 'simp-rspec-puppet-facts', ENV.fetch('SIMP_RSPEC_PUPPET_FACTS_VERSION', '~> 2.2') - gem 'simp-rake-helpers', ENV.fetch('SIMP_RAKE_HELPERS_VERSION', '~> 5.6') + gem 'simp-rspec-puppet-facts', ENV.fetch('SIMP_RSPEC_PUPPET_FACTS_VERSION', ['>= 2.4.0', '< 3.0.0'] ) + gem 'simp-rake-helpers', ENV.fetch('SIMP_RAKE_HELPERS_VERSION', ['>= 5.9', '< 6.0']) end group :development do @@ -26,5 +26,5 @@ end group :system_tests do gem 'beaker' gem 'beaker-rspec' - gem 'simp-beaker-helpers', ENV.fetch('SIMP_BEAKER_HELPERS_VERSION', '~> 1.12') + gem 'simp-beaker-helpers', ENV.fetch('SIMP_BEAKER_HELPERS_VERSION', ['>= 1.17.0', '< 2.0.0']) end diff --git a/README.md b/README.md index 21a6d23..9044a05 100644 --- a/README.md +++ b/README.md @@ -13,11 +13,12 @@ If you find any issues, they can be submitted to our [JIRA](https://simp-project Please read our [Contribution Guide](https://simp.readthedocs.io/en/stable/contributors_guide/index.html). -## Work in Progress +## Module Description -Please excuse us as we transition this code into the public domain. +This module configures rsync for sharing large files that would be problematic to +share using the native Puppet fileserving type. -Downloads, discussion, and patches are still welcome! +## Setup ### Configuring Host as Server and Client @@ -50,3 +51,21 @@ NOTE: If not using stunnel for the server/client connections, both values for `rsync::server::trusted_nets` and `rsync::server::global::trusted_nets` will need to match, as well as the `trusted_nets` values for any `rsync::server::section` resources. These all default to '127.0.0.1' for stunnel usage. + +## Reference + +Please refer to the [REFERENCE.md](./REFERENCE.md). + +## Limitations + +SIMP Puppet modules are generally intended for use on Red Hat Enterprise +Linux and compatible distributions, such as CentOS. Please see the +[`metadata.json` file](./metadata.json) for the most up-to-date list of +supported operating systems, Puppet versions, and module dependencies. + +## Development + +Please read our [Contribution Guide](https://simp.readthedocs.io/en/stable/contributors_guide/index.html). + +Visit the project homepage on [GitHub](https://simp-project.com), +and look at our issues on [JIRA](https://simp-project.atlassian.net/). diff --git a/REFERENCE.md b/REFERENCE.md new file mode 100644 index 0000000..4b8ca32 --- /dev/null +++ b/REFERENCE.md @@ -0,0 +1,1129 @@ +# Reference + + +## Table of Contents + +**Classes** + +* [`rsync`](#rsync): Provides an rsync client library with a stub exec for certain edge cases +* [`rsync::selinux`](#rsyncselinux): This will configure selinux for rsync +* [`rsync::server`](#rsyncserver): Sets up a fully functioning rsync server. +* [`rsync::server::global`](#rsyncserverglobal): Setup the global section of /etc/rsyncd.conf. See ``rsyncd.conf(5)`` for details of parameters not listed below. + +**Defined types** + +* [`rsync::push`](#rsyncpush): This is simply a call to rsync::retrieve with $pull set to false. It's present for clarity and hopefully won't break any dependency chains if +* [`rsync::retrieve`](#rsyncretrieve): Retrieve a file over the rsync protocol +* [`rsync::server::section`](#rsyncserversection): Set up a 'section' of /etc/rsyncd.conf pertaining to a particular rsync share. See ``rsyncd.conf(5)`` for descriptions of most variables. + +**Resource types** + +* [`rsync`](#rsync): Run an rsync command; almost all options are directly from the rsync man page. Though we've done what we can to mimize SELinux impact. If yo + +## Classes + +### rsync + +Provides an rsync client library with a stub exec for certain edge cases + +#### Parameters + +The following parameters are available in the `rsync` class. + +##### `sebool_anon_write` + +Data type: `Boolean` + +Allow anonymous rsync users to write to shares + +* Share spaces must be labeled as ``public_content_rw_t`` +* Only functional if ``selinux`` is not disabled + +Default value: `false` + +##### `sebool_client` + +Data type: `Boolean` + +Allow rsync to act as a client + +* Only functional if ``selinux`` is not disabled + +Default value: `true` + +##### `sebool_export_all_ro` + +Data type: `Boolean` + +Allow rsync to export of anything on the system as read only + +* Only functional if ``selinux`` is not disabled + +Default value: `true` + +##### `sebool_full_access` + +Data type: `Boolean` + +Allow rsync management of **ALL** files on the system + +* Only functional if ``selinux`` is not disabled + +Default value: `false` + +##### `sebool_use_nfs` + +Data type: `Boolean` + +Allow rsync servers to share nfs files systems + +* Only functional if ``selinux`` is not disabled +* Only applies to El6 + +Default value: `false` + +##### `sebool_use_cifs` + +Data type: `Boolean` + +Allow rsync servers to share cifs files systems + +* Only functional if ``selinux`` is not disabled +* Only applies to El6 + +Default value: `false` + +##### `package_ensure` + +Data type: `String` + +The ensure status of the package to be managed + +Default value: simplib::lookup('simp_options::package_ensure', { 'default_value' => 'installed' }) + +### rsync::selinux + +This will configure selinux for rsync + +### rsync::server + +The main idea behind this was to work around limitations of the native Puppet +fileserving type. + +Most usual options are supported, but there are far too many to tackle all of +them at once. + +This mainly daemonizes rsync and keeps it running. It will also subscribe it +to the stunnel service if it has been declared. + +#### Parameters + +The following parameters are available in the `rsync::server` class. + +##### `stunnel` + +Data type: `Boolean` + +Use Stunnel to encrypt this connection. It is *highly* recommended to leave +this enabled. + +Default value: simplib::lookup('simp_options::stunnel', { default_value => true }) + +##### `stunnel_port` + +Data type: `Simplib::Port` + +The port upon which Stunnel should listen for connections. + +Default value: 8730 + +##### `listen_address` + +Data type: `Simplib::IP` + +The IP Address upon which to listen. Set to 0.0.0.0 to listen on all +addresses. + +Default value: '0.0.0.0' + +##### `drop_rsyslog_noise` + +Data type: `Boolean` + +Ensure that any noise from rsync is dropped. The only items that will be +retained will be startup, shutdown, and remote connection activities. +Anything from 127.0.0.1 will be dropped as useless. + +Default value: `true` + +##### `firewall` + +Data type: `Boolean` + +If true, use the SIMP iptables class to manage firewall rules for this +module. + +Default value: simplib::lookup('simp_options::firewall', { default_value => false }) + +##### `trusted_nets` + +Data type: `Simplib::Netlist` + +A list of networks and/or hostnames that are allowed to connect to this +service. + +Default value: simplib::lookup('simp_options::trusted_nets', { default_value => ['127.0.0.1'] }) + +### rsync::server::global + +Setup the global section of /etc/rsyncd.conf. + +See ``rsyncd.conf(5)`` for details of parameters not listed below. + +#### Parameters + +The following parameters are available in the `rsync::server::global` class. + +##### `motd_file` + +Data type: `Optional[Stdlib::Absolutepath]` + +The path to the default MOTD file that should be displayed upon connection + +Default value: `undef` + +##### `pid_file` + +Data type: `Stdlib::Absolutepath` + +The path to the service PID file + +Default value: '/var/run/rsyncd.pid' + +##### `syslog_facility` + +Data type: `String` + +A valid syslog ``facility`` to use for logging + +Default value: 'daemon' + +##### `port` + +Data type: `Simplib::Port` + +The port upon which to listen for client connections + +Default value: 873 + +##### `address` + +Data type: `Simplib::IP` + +The IP address upon which to listen for connections + +* Leave this at ``127.0.0.1`` if using stunnel + +Default value: '127.0.0.1' + +##### `trusted_nets` + +Data type: `Simplib::Netlist` + +The networks to allow to connect to this service + +Default value: simplib::lookup('simp_options::trusted_nets', { default_value => ['127.0.0.1'] }) + +##### `tcpwrappers` + +Data type: `Boolean` + +Use tcpwrappers to secure the rsync service + +Default value: simplib::lookup('simp_options::tcpwrappers', { default_value => false }) + +## Defined types + +### rsync::push + +This is simply a call to rsync::retrieve with $pull set to false. It's +present for clarity and hopefully won't break any dependency chains if you +use it. + +See the documentation for ``rsync::retrieve`` for details. + +#### Parameters + +The following parameters are available in the `rsync::push` defined type. + +##### `source_path` + +Data type: `String` + + + +##### `target_path` + +Data type: `String` + + + +##### `rsync_server` + +Data type: `Simplib::Host` + + + +##### `proto` + +Data type: `String` + + + +Default value: 'rsync' + +##### `rsync_path` + +Data type: `Stdlib::Absolutepath` + + + +Default value: '/usr/bin/rsync' + +##### `preserve_perms` + +Data type: `Boolean` + + + +Default value: `true` + +##### `preserve_acl` + +Data type: `Boolean` + + + +Default value: `true` + +##### `preserve_xattrs` + +Data type: `Boolean` + + + +Default value: `true` + +##### `preserve_owner` + +Data type: `Boolean` + + + +Default value: `true` + +##### `preserve_group` + +Data type: `Boolean` + + + +Default value: `true` + +##### `preserve_devices` + +Data type: `Boolean` + + + +Default value: `false` + +##### `exclude` + +Data type: `Array[String]` + + + +Default value: ['.svn/','.git/'] + +##### `rsync_timeout` + +Data type: `Integer[0]` + + + +Default value: 2 + +##### `logoutput` + +Data type: `Variant[Boolean,String]` + + + +Default value: 'on_failure' + +##### `delete` + +Data type: `Boolean` + + + +Default value: `false` + +##### `bwlimit` + +Data type: `Optional[Integer[0]]` + + + +Default value: `undef` + +##### `copy_links` + +Data type: `Boolean` + + + +Default value: `false` + +##### `size_only` + +Data type: `Boolean` + + + +Default value: `false` + +##### `no_implied_dirs` + +Data type: `Boolean` + + + +Default value: `true` + +##### `user` + +Data type: `Optional[String]` + + + +Default value: `undef` + +##### `pass` + +Data type: `Optional[String]` + + + +Default value: `undef` + +##### `rsubscribe` + +Data type: `Optional[Catalogentry]` + + + +Default value: `undef` + +##### `rnotify` + +Data type: `Optional[Catalogentry]` + + + +Default value: `undef` + +### rsync::retrieve + +Retrieve a file over the rsync protocol + +* **See also** +rsync(1) + +#### Parameters + +The following parameters are available in the `rsync::retrieve` defined type. + +##### `source_path` + +Data type: `String` + +The path *on the rsync server* from which to retrieve files + +* This will, most likely, not start with a forward slash + +##### `target_path` + +Data type: `String` + +The path to which to write on the client system + +##### `rsync_server` + +Data type: `Variant[Simplib::Host, Simplib::Host::Port]` + +The host to which to connect + +Default value: simplib::lookup('simp_options::rsync::server') + +##### `proto` + +Data type: `String` + +The protocol to use + +* This will go before the ``://`` in the rsync connection string +* You probably won't change this + +Default value: 'rsync' + +##### `rsync_path` + +Data type: `Stdlib::Absolutepath` + +The path to the 'rsync' command + +Default value: '/usr/bin/rsync' + +##### `preserve_perms` + +Data type: `Boolean` + +Preserve the file permissions from the server + +Default value: `true` + +##### `preserve_acl` + +Data type: `Boolean` + +Preserve the file ACLs from the server + +Default value: `true` + +##### `preserve_xattrs` + +Data type: `Boolean` + +Preserve the extended attributes from the server + +Default value: `true` + +##### `preserve_owner` + +Data type: `Boolean` + +Preserve the file owner from the server + +Default value: `true` + +##### `preserve_group` + +Data type: `Boolean` + +Preserve the file group from the server + +Default value: `true` + +##### `preserve_devices` + +Data type: `Boolean` + +Preserve device special IDs from the server + +Default value: `false` + +##### `exclude` + +Data type: `Array[String]` + +Paths and globs to exclude from transfers + +Default value: ['.svn/','.git/'] + +##### `rsync_timeout` + +Data type: `Integer[0]` + +The number of seconds to wait for a transfer to begin before timing out + +Default value: 2 + +##### `logoutput` + +Data type: `String` + +Log the output of the rsync run at the provided trigger + +Default value: 'on_failure' + +##### `delete` + +Data type: `Boolean` + +Delete local files that do not exist on the remote server + +Default value: `false` + +##### `bwlimit` + +Data type: `Optional[String]` + +The bandwidth limit for the connection + +Default value: simplib::lookup('rsync::bwlimit', { 'default_value' => undef }) + +##### `copy_links` + +Data type: `Boolean` + +Preserve symlinks during the transfer + +Default value: `false` + +##### `size_only` + +Data type: `Boolean` + +Only compare files by size to determine if they need a transfer + +Default value: `false` + +##### `no_implied_dirs` + +Data type: `Boolean` + +Don't send implied directories with relative pathnames + +Default value: `true` + +##### `user` + +Data type: `Optional[String]` + +The username to use when connecting to the server + +Default value: `undef` + +##### `pass` + +Data type: `Optional[String]` + +The password to use when connecting to the server + +* If left blank, and a username is provided, the ``simplib::passgen()`` + function will be used to look up the password + +Default value: `undef` + +##### `pull` + +Data type: `Boolean` + +Pull files from the remote server + +* If set to ``false``, will push files to the server instead of pulling +them from the server + +Default value: `true` + +##### `rnotify` + +Data type: `Optional[Catalogentry]` + +Wrap a ``notify`` so that this process will send a Puppet notification to a +resource after completion + +* Use like the regular Puppet ``notify`` meta-parameter + +Default value: `undef` + +##### `rsubscribe` + +Data type: `Optional[Catalogentry]` + +Wrap a ``subscribe`` so that this process will subscribe to a Puppet +resource after completion + +* Use like the regular Puppet ``subscribe`` meta-parameter + +Default value: `undef` + +### rsync::server::section + +Set up a 'section' of /etc/rsyncd.conf pertaining to a particular rsync share. + +See ``rsyncd.conf(5)`` for descriptions of most variables. + +#### Parameters + +The following parameters are available in the `rsync::server::section` defined type. + +##### `name` + +The arbitrary name of this configuration section + +##### `path` + +Data type: `Stdlib::Absolutepath` + +The directory to make available to clients + +##### `auth_users` + +Data type: `Optional[Array[String]]` + +A list of usernames that are allowed to connect to this section + +* ``simplib::passgen()`` will be used to generated random passwords for + these users, if they do not already exist in the system +* Ignored if ``user_pass`` is set. + +Default value: `undef` + +##### `user_pass` + +Data type: `Optional[Array[String]]` + +An optional array of ``username:password`` combinations to be added to the +secrets file + +* Not recommended. Instead, use ``auth_users`` to let the + ``simplib::passgen()`` function generate your passwords +* Entries in this Array should be of the following form: + ``username:password`` + +Default value: `undef` + +##### `comment` + +Data type: `Optional[String]` + +A comment for the section + +Default value: `undef` + +##### `use_chroot` + +Data type: `Boolean` + +Use a ``chroot`` for this service + +Default value: `false` + +##### `max_connections` + +Data type: `Integer[0]` + +The maximum number of connections allowed + +Default value: 0 + +##### `max_verbosity` + +Data type: `Integer[0]` + +The logging verbosity that the daemon should use for connections to this +service + +Default value: 1 + +##### `lock_file` + +Data type: `Stdlib::Absolutepath` + +The path to the lock file for this service + +Default value: '/var/run/rsyncd.lock' + +##### `read_only` + +Data type: `Boolean` + +Do not allow clients to write to this share + +Default value: `true` + +##### `write_only` + +Data type: `Boolean` + +Only allow clients to write to this share + +Default value: `false` + +##### `list` + +Data type: `Boolean` + +List this share when clients ask for a list of available modules + +Default value: `false` + +##### `uid` + +Data type: `String` + +The user ID that transfers should take place as + +* This user must have access to all of the relevant files + +Default value: 'root' + +##### `gid` + +Data type: `String` + +The group ID that transfers should take place as + +* Must have access to all of the relevant files + +Default value: 'root' + +##### `outgoing_chmod` + +Data type: `String` + +A symbolic ``chmod`` that will be applied to files that are transferred +outbound + +Default value: 'o-w' + +##### `ignore_nonreadable` + +Data type: `Boolean` + +Completely ignore any file that is not readable by the user + +Default value: `true` + +##### `transfer_logging` + +Data type: `Boolean` + +Enable per-file logging of transfers + +Default value: `true` + +##### `log_format` + +Data type: `String` + +Format used for logging file transfers when transfer logging is enabled + +Default value: "'%o %h [%a] %m (%u) %f %l'" + +##### `dont_compress` + +Data type: `Array[String]` + +Filenames and globs that should not be compressed upon transfer + +Default value: [ + '*.gz', + '*.tgz', + '*.zip', + '*.z', + '*.rpm', + '*.deb', + '*.iso', + '*.bz2', + '*.tbz', + '*.rar', + '*.jar', + '*.pdf', + '*.sar', + '*.war' + ] + +##### `hosts_allow` + +Data type: `Variant[Enum['*'], Simplib::Netlist]` + +Hosts that should be allowed to connect to this share + +* Set to ``['127.0.0.1']`` if using ``stunnel`` for the overall system +* May also be set to the String ``*`` to allow all hosts + +Default value: simplib::lookup('simp_options::trusted_nets', { 'default_value' => ['127.0.0.1'] }) + +##### `hosts_deny` + +Data type: `Variant[Enum['*'], Simplib::Netlist]` + +Hosts to explicitly deny from connection to this share + +* Should be set to the String ``*`` as it is overridden by ``$hosts_allow`` + +Default value: '*' + +## Resource types + +### rsync + +Run an rsync command; almost all options are directly from the rsync man +page. + +Though we've done what we can to mimize SELinux impact. If you have the +situation where your Puppet server's rsync space does *not* have SELinux +attributes but your client is Permissive or Enforcing. Then you will most +certainly see error messages of the type that extended attributes have +changed. + +Your best bet is to ensure that your Puppet server runs in at least +Permissive mode. If you need to refresh your rsync data attributes, then +running 'fixfiles -R simp-rsync restore'. + +#### Properties + +The following properties are available in the `rsync` type. + +##### `action` + +Valid values: push, pull + +Whether to push or pull from rsync server. Defaults to pull + +Default value: pull + +#### Parameters + +The following parameters are available in the `rsync` type. + +##### `name` + +namevar + + + +##### `ignore_selinux` + +Valid values: `true`, `false` + +If this is set to 'true' then this type will ignore SELinux errors. If +set to false, then an SELinux permissions copy error is a complete +failure state. + +Default value: `true` + +##### `password` + +The password to use. Only used if a username is specified +If you want the password to be auto-generated, you can use the +SIMP 'simplib::passgen' function. + + $user = 'foo' + + rsync::retrieve { \"foo\": + source => 'bar', + target => '/tmp/foo', + server => 'puppet', + user => $user, + password => simplib::passgen($user) + } + +##### `pass` + +The password to use. Only used if a username is specified +If you want the password to be auto-generated, you can use the +SIMP 'simplib::passgen' function. + + $user = 'foo' + + rsync::retrieve { \"foo\": + source => 'bar', + target => '/tmp/foo', + server => 'puppet', + user => $user, + password => simplib::passgen($user) + } + +##### `source` + +The fully qualified source path on the rsync server + +##### `source_path` + +The fully qualified source path on the rsync server + +##### `target` + +The fully qualified target path on the rsync client + +##### `target_path` + +The fully qualified target path on the rsync client + +##### `server` + +The hostname or IP of the rsync server + +##### `rsync_server` + +The hostname or IP of the rsync server + +##### `proto` + +The protocol to use in connecting to the rsync server. Defaults to "rsync" + +##### `protocol` + +The protocol to use in connecting to the rsync server. Defaults to "rsync" + +##### `rsync_path` + +The fully qualified path to the rsync executable + +##### `path` + +The fully qualified path to the rsync executable + +##### `preserve_perms` + +Valid values: `true`, `false` + +Whether or not to preserve permissions. Defaults to true. + +Default value: `true` + +##### `preserve_acl` + +Valid values: `true`, `false` + +Whether or not to preserve ACL. Defaults to true. + +Default value: `true` + +##### `preserve_xattrs` + +Valid values: `true`, `false` + +Whether or not to preserve extended attributes. Defaults to true. + +Default value: `true` + +##### `preserve_owner` + +Valid values: `true`, `false` + +Whether or not to preserve owner. Defaults to true. + +Default value: `true` + +##### `preserve_group` + +Valid values: `true`, `false` + +Whether or not to preserve group. Defaults to true. + +Default value: `true` + +##### `preserve_devices` + +Valid values: `true`, `false` + +Whether or not to preserve device files. Defaults to false. + +Default value: `false` + +##### `compress` + +Valid values: `true`, `false` + +Whether or not to compress content prior to transfer. Defaults to true. + +Default value: `true` + +##### `recurse` + +Valid values: `true`, `false` + +Whether or not to recursively copy. Defaults to true. + +Default value: `true` + +##### `hard_links` + +Valid values: `true`, `false` + +Preserve hard links. Defaults to true. + +Default value: `true` + +##### `exclude` + +Exclude files matching PATTERN. Multiple values may be specified as an +array. Defaults to ['.svn/','.git/'] + +Default value: ['.svn/','.git/'] + +##### `timeout` + +Connection timeout in seconds. Note: This is different from what the man +page states due to backward compatibility issues. Use iotimeout for the +man page compatible timeout value. + +##### `contimeout` + +Connection timeout in seconds. + +##### `rsync_timeout` + + + +##### `iotimeout` + +I/O timeout in seconds. + +##### `logoutput` + +Valid values: `true`, `false`, on_failure + +Whether to log output. Defaults to logging output at the loglevel for +the `exec` resource. Use *on_failure* to only log the output when the +command reports an error. Values are **true**, *false*, *on_failure*, +and any legal log level. + +Default value: on_failure + +##### `delete` + +Valid values: `true`, `false` + +Whether to delete files that do not exist on server. Defaults to false + +Default value: `false` + +##### `bwlimit` + +KB/s to limit I/O bandwidth to + +##### `copy_links` + +Valid values: `true`, `false` + +Whether to copy links as symlinks. Defaults to false + +Default value: `false` + +##### `size_only` + +Valid values: `true`, `false` + +Whether to skip files that match in size. Defaults to true + +Default value: `false` + +##### `no_implied_dirs` + +Valid values: `true`, `false` + +Do not send implied dirs. Defaults to true + +Default value: `true` + +##### `user` + +The username to use + diff --git a/data/os/CentOS-6.yaml b/data/os/CentOS-6.yaml new file mode 100644 index 0000000..0eee7af --- /dev/null +++ b/data/os/CentOS-6.yaml @@ -0,0 +1,2 @@ +--- +rsync::server::package: rsync diff --git a/data/os/CentOS-7.yaml b/data/os/CentOS-7.yaml new file mode 100644 index 0000000..0eee7af --- /dev/null +++ b/data/os/CentOS-7.yaml @@ -0,0 +1,2 @@ +--- +rsync::server::package: rsync diff --git a/data/os/CentOS-8.yaml b/data/os/CentOS-8.yaml new file mode 100644 index 0000000..995bd97 --- /dev/null +++ b/data/os/CentOS-8.yaml @@ -0,0 +1,2 @@ +--- +rsync::server::package: rsync-daemon diff --git a/data/os/OracleLinux-6.yaml b/data/os/OracleLinux-6.yaml new file mode 100644 index 0000000..0eee7af --- /dev/null +++ b/data/os/OracleLinux-6.yaml @@ -0,0 +1,2 @@ +--- +rsync::server::package: rsync diff --git a/data/os/OracleLinux-7.yaml b/data/os/OracleLinux-7.yaml new file mode 100644 index 0000000..0eee7af --- /dev/null +++ b/data/os/OracleLinux-7.yaml @@ -0,0 +1,2 @@ +--- +rsync::server::package: rsync diff --git a/data/os/OracleLinux-8.yaml b/data/os/OracleLinux-8.yaml new file mode 100644 index 0000000..995bd97 --- /dev/null +++ b/data/os/OracleLinux-8.yaml @@ -0,0 +1,2 @@ +--- +rsync::server::package: rsync-daemon diff --git a/data/os/RedHat-6.yaml b/data/os/RedHat-6.yaml new file mode 100644 index 0000000..0eee7af --- /dev/null +++ b/data/os/RedHat-6.yaml @@ -0,0 +1,2 @@ +--- +rsync::server::package: rsync diff --git a/data/os/RedHat-7.yaml b/data/os/RedHat-7.yaml new file mode 100644 index 0000000..0eee7af --- /dev/null +++ b/data/os/RedHat-7.yaml @@ -0,0 +1,2 @@ +--- +rsync::server::package: rsync diff --git a/data/os/RedHat-8.yaml b/data/os/RedHat-8.yaml new file mode 100644 index 0000000..995bd97 --- /dev/null +++ b/data/os/RedHat-8.yaml @@ -0,0 +1,2 @@ +--- +rsync::server::package: rsync-daemon diff --git a/hiera.yaml b/hiera.yaml new file mode 100644 index 0000000..7f744ef --- /dev/null +++ b/hiera.yaml @@ -0,0 +1,16 @@ +--- +version: 5 +defaults: + datadir: data + data_hash: yaml_data +hierarchy: + - name: "OS + Release" + path: "os/%{facts.operatingsystem}-%{facts.operatingsystemmajrelease}.yaml" + - name: "OS" + path: "os/%{facts.operatingsystem}.yaml" + - name: "OSFamily" + path: "os/%{facts.osfamily}.yaml" + - name: "Kernel" + path: "os/%{facts.kernel}.yaml" + - name: "Common" + path: "common.yaml" diff --git a/manifests/init.pp b/manifests/init.pp index cba95a0..575a53c 100644 --- a/manifests/init.pp +++ b/manifests/init.pp @@ -21,6 +21,18 @@ # # * Only functional if ``selinux`` is not disabled # +# @param sebool_use_nfs +# Allow rsync servers to share nfs files systems +# +# * Only functional if ``selinux`` is not disabled +# * Only applies to El6 +# +# @param sebool_use_cifs +# Allow rsync servers to share cifs files systems +# +# * Only functional if ``selinux`` is not disabled +# * Only applies to El6 +# # @param package_ensure The ensure status of the package to be managed # # @author https://github.com/simp/pupmod-simp-rsync/graphs/contributors diff --git a/manifests/server.pp b/manifests/server.pp index a8b9bea..e312258 100644 --- a/manifests/server.pp +++ b/manifests/server.pp @@ -1,4 +1,4 @@ -# This class provides a method to set up a fully functioning rsync server. +# @summary Sets up a fully functioning rsync server. # # The main idea behind this was to work around limitations of the native Puppet # fileserving type. @@ -9,24 +9,37 @@ # This mainly daemonizes rsync and keeps it running. It will also subscribe it # to the stunnel service if it has been declared. # -# == Parameters == +# @param stunnel +# Use Stunnel to encrypt this connection. It is *highly* recommended to leave +# this enabled. # -# @param stunnel [Boolean] Use Stunnel to encrypt this connection. It is -# *highly* recommended to leave this enabled. +# @param stunnel_port +# The port upon which Stunnel should listen for connections. # -# @param stunnel_port [Port] The port upon which Stunnel should listen for -# connections. +# @param listen_address +# The IP Address upon which to listen. Set to 0.0.0.0 to listen on all +# addresses. # -# @param listen_address [IPAddress] The IP Address upon which to listen. Set to -# 0.0.0.0 to listen on all addresses. +# @param drop_rsyslog_noise +# Ensure that any noise from rsync is dropped. The only items that will be +# retained will be startup, shutdown, and remote connection activities. +# Anything from 127.0.0.1 will be dropped as useless. # -# @param drop_rsyslog_noise [Boolean] Ensure that any noise from rsync is -# dropped. The only items that will be retained will be startup, shutdown, -# and remote connection activities. Anything from 127.0.0.1 will be dropped -# as useless. +# @param firewall +# If true, use the SIMP iptables class to manage firewall rules for this +# module. # -# @param trusted_nets [NetList] A list of networks and/or hostnames that are -# allowed to connect to this service. +# @param trusted_nets +# A list of networks and/or hostnames that are allowed to connect to this +# service. +# +# @param package_ensure +# The ensure status of the package to be managed +# +# @param package +# The rsync daemon package +# +# @author https://github.com/simp/pupmod-simp-rsync/graphs/contributors # class rsync::server ( Boolean $stunnel = simplib::lookup('simp_options::stunnel', { default_value => true }), @@ -34,11 +47,18 @@ Simplib::IP $listen_address = '0.0.0.0', Boolean $drop_rsyslog_noise = true, Boolean $firewall = simplib::lookup('simp_options::firewall', { default_value => false }), - Simplib::Netlist $trusted_nets = simplib::lookup('simp_options::trusted_nets', { default_value => ['127.0.0.1'] }) + Simplib::Netlist $trusted_nets = simplib::lookup('simp_options::trusted_nets', { default_value => ['127.0.0.1'] }), + String $package_ensure = simplib::lookup('simp_options::package_ensure', { 'default_value' => 'installed' }), + String $package # module data ) { include '::rsync' include '::rsync::server::global' + # ensure_resource instead of package resource, because for some OS versions, + # the client package managed by the rsync class also contains the rsync + # daemon files. + ensure_resource('package', $package , { ensure => $package_ensure }) + $_subscribe = $stunnel ? { true => Service['stunnel'], default => undef @@ -70,7 +90,7 @@ order => 'numeric', ensure_newline => true, warn => true, - require => Package['rsync'] + require => Package[$package] } if 'systemd' in $facts['init_systems'] { @@ -79,7 +99,7 @@ enable => true, hasstatus => true, hasrestart => true, - require => Package['rsync'], + require => Package[$package], subscribe => $_subscribe } } @@ -97,7 +117,7 @@ enable => true, hasstatus => true, hasrestart => true, - require => Package['rsync'], + require => Package[$package], provider => 'redhat', subscribe => $_subscribe } diff --git a/manifests/server/section.pp b/manifests/server/section.pp index 7a6f6da..33d2b4f 100644 --- a/manifests/server/section.pp +++ b/manifests/server/section.pp @@ -63,12 +63,15 @@ # A symbolic ``chmod`` that will be applied to files that are transferred # outbound # -# @param ignore_noreadable +# @param ignore_nonreadable # Completely ignore any file that is not readable by the user # # @param transfer_logging # Enable per-file logging of transfers # +# @param log_format +# Format used for logging file transfers when transfer logging is enabled +# # @param dont_compress # Filenames and globs that should not be compressed upon transfer # diff --git a/metadata.json b/metadata.json index 98453b8..cfd8bb1 100644 --- a/metadata.json +++ b/metadata.json @@ -1,6 +1,6 @@ { "name": "simp-rsync", - "version": "6.3.1", + "version": "6.4.0", "author": "SIMP Team", "summary": "manage an rsync server, secured by stunnel", "license": "Apache-2.0", @@ -27,7 +27,7 @@ }, { "name": "simp/simplib", - "version_requirement": ">= 3.5.0 < 4.0.0" + "version_requirement": ">= 3.5.0 < 5.0.0" }, { "name": "simp/stunnel", @@ -43,21 +43,24 @@ "operatingsystem": "CentOS", "operatingsystemrelease": [ "6", - "7" + "7", + "8" ] }, { "operatingsystem": "RedHat", "operatingsystemrelease": [ "6", - "7" + "7", + "8" ] }, { "operatingsystem": "OracleLinux", "operatingsystemrelease": [ "6", - "7" + "7", + "8" ] } ], diff --git a/spec/acceptance/helpers/utils.rb b/spec/acceptance/helpers/utils.rb new file mode 100644 index 0000000..db9f47d --- /dev/null +++ b/spec/acceptance/helpers/utils.rb @@ -0,0 +1,24 @@ +module Acceptance; end +module Acceptance::Helpers; end + +module Acceptance::Helpers::Utils + + # @return Array of pairs of host indices that contains the position-invariant + # permutations of hosts in which the indices are unique + # + # ['host1', 'host2'] returns [[0,1]] + # ['host1', 'host2', 'host3'] returns [[0,1], [0,2], [0,3], [1,2], [1,3], [2,3]] + def unique_host_pairs(hosts) + require 'set' + unique_pairs = Set.new + hosts.each_index do |index1| + hosts.each_index do |index2| + if index1 != index2 + unique_pairs.add([index1, index2].sort) + end + end + end + + unique_pairs.to_a + end +end diff --git a/spec/acceptance/nodesets/default.yml b/spec/acceptance/nodesets/default.yml index b7e94d1..8021f6e 100644 --- a/spec/acceptance/nodesets/default.yml +++ b/spec/acceptance/nodesets/default.yml @@ -6,11 +6,18 @@ end -%> HOSTS: - el7: + el8: roles: - default - master - client + platform: el-8-x86_64 + box: centos/8 + hypervisor: <%= hypervisor %> + + el7: + roles: + - client platform: el-7-x86_64 box: centos/7 hypervisor: <%= hypervisor %> @@ -24,7 +31,7 @@ HOSTS: CONFIG: type: aio - vagrant_memsize: 256 + vagrant_memsize: 512 log_level: verbose synced_folder: disabled <% if ENV['BEAKER_PUPPET_COLLECTION'] -%> diff --git a/spec/acceptance/nodesets/oel.yml b/spec/acceptance/nodesets/oel.yml index 4d1896e..e0717e1 100644 --- a/spec/acceptance/nodesets/oel.yml +++ b/spec/acceptance/nodesets/oel.yml @@ -6,11 +6,18 @@ end -%> HOSTS: - el7: + el8: roles: - default - master - client + platform: el-8-x86_64 + box: generic/oracle8 + hypervisor: <%= hypervisor %> + + el7: + roles: + - client platform: el-7-x86_64 box: onyxpoint/oel-7-x86_64 hypervisor: <%= hypervisor %> @@ -24,7 +31,7 @@ HOSTS: CONFIG: type: aio - vagrant_memsize: 256 + vagrant_memsize: 512 log_level: verbose synced_folder: disabled <% if ENV['BEAKER_PUPPET_COLLECTION'] -%> diff --git a/spec/acceptance/suites/default/00_default_spec.rb b/spec/acceptance/suites/default/00_default_spec.rb index 4a49344..e5e1ce9 100644 --- a/spec/acceptance/suites/default/00_default_spec.rb +++ b/spec/acceptance/suites/default/00_default_spec.rb @@ -5,9 +5,9 @@ describe 'rsync class' do let(:manifest) { <<-EOS - include '::rsync::server' + include 'rsync::server' - include '::iptables' + include 'iptables' iptables::listen::tcp_stateful { 'ssh': dports => 22, @@ -57,7 +57,12 @@ end it 'should be idempotent' do - apply_manifest(manifest, {:catch_changes => true}) + # FIXME - Workaround for systemd::dropin_file idempotency issue: + # Selinux type of the override unit file (from simp-rsyslog module) + # gets fixed with a second puppet run. + apply_manifest_on(host, manifest, :catch_failures => true) + + apply_manifest_on(host, manifest, {:catch_changes => true}) end it 'should have a file transferred' do diff --git a/spec/acceptance/suites/default/10_server_client_spec.rb b/spec/acceptance/suites/default/10_server_client_spec.rb index 3a7e6aa..0b4f7c2 100644 --- a/spec/acceptance/suites/default/10_server_client_spec.rb +++ b/spec/acceptance/suites/default/10_server_client_spec.rb @@ -8,129 +8,148 @@ skip('You need at least two hosts in your nodeset to run this test') end else - server1 = hosts[0] - server2 = hosts[1] - - let(:manifest) { - <<-EOS - include '::rsync::server' - - include '::iptables' - - iptables::listen::tcp_stateful { 'ssh': - dports => 22, - trusted_nets => ['any'] - } - - file { '/srv/rsync': - ensure => 'directory' + index_pairs = unique_host_pairs(hosts) + index_pairs.each do |index1,index2| + # Test interoperability between a pair of hosts in the node set, each + # acting as a rsync server to the other. + server1 = hosts[index1] + server2 = hosts[index2] + context "Interoperability between #{server1} and #{server2}" do + + let(:file_content) { + "What a Test File for #{server1} and #{server2} testing" } - file { '/srv/rsync/test': - ensure => 'directory' + let(:manifest) { + <<-EOS + include 'rsync::server' + + include 'iptables' + + iptables::listen::tcp_stateful { 'ssh': + dports => 22, + trusted_nets => ['any'] + } + + file { '/srv/rsync': + ensure => 'directory' + } + + file { '/srv/rsync/test': + ensure => 'directory' + } + + file { '/srv/rsync/test/test_file_srvcli': + ensure => 'file', + content => '#{file_content}' + } + + rsync::server::section { 'test': + auth_users => ['test_user'], + user_pass => ['test_user:test_pass'], + comment => 'A test system', + hosts_allow => ['#{server1_ip}', '#{server2_ip}'], + path => '/srv/rsync/test', + require => File['/srv/rsync/test/test_file_srvcli'] + } + EOS } - file { '/srv/rsync/test/test_file_srvcli': - ensure => 'file', - content => 'What a Test File' + let(:manifest_test_server1) { + <<-EOS + rsync::retrieve { 'test_pull': + user => 'test_user', + pass => 'test_pass', + source_path => 'test/test_file_srvcli', + target_path => '/tmp', + rsync_server => '#{server2_fqdn}:8873', + } + EOS } - rsync::server::section { 'test': - auth_users => ['test_user'], - user_pass => ['test_user:test_pass'], - comment => 'A test system', - hosts_allow => ['#{server1_ip}', '#{server2_ip}'], - path => '/srv/rsync/test', - require => File['/srv/rsync/test/test_file_srvcli'] + let(:manifest_test_server2) { + <<-EOS + rsync::retrieve { 'test_pull': + user => 'test_user', + pass => 'test_pass', + source_path => 'test/test_file_srvcli', + target_path => '/tmp', + rsync_server => '#{server1_fqdn}', + } + EOS } - EOS - } - - let(:manifest_test_server1) { - <<-EOS - rsync::retrieve { 'test_pull': - user => 'test_user', - pass => 'test_pass', - source_path => 'test/test_file_srvcli', - target_path => '/tmp', - rsync_server => '#{server2_fqdn}:8873', - } - EOS - } - - let(:manifest_test_server2) { - <<-EOS - rsync::retrieve { 'test_pull': - user => 'test_user', - pass => 'test_pass', - source_path => 'test/test_file_srvcli', - target_path => '/tmp', - rsync_server => '#{server1_fqdn}', - } - EOS - } - - let(:hieradata_server1) {{ - 'simp_options::pki' => false, - 'simp_options::firewall' => true, - 'rsync::server::stunnel' => false, - 'rsync::server::trusted_nets' => [server2_ip], - 'rsync::server::global::trusted_nets' => [server2_ip], - 'rsync::server::global::address' => '0.0.0.0', - }} - - let(:hieradata_server2) {{ - 'simp_options::pki' => false, - 'simp_options::firewall' => true, - 'rsync::server::stunnel' => false, - 'rsync::server::global::port' => 8873, - 'rsync::server::trusted_nets' => [server1_ip], - 'rsync::server::global::trusted_nets' => [server1_ip], - 'rsync::server::global::address' => '0.0.0.0', - }} - - let(:server1_interface) { get_private_network_interface(server1) } - let(:server1_ip) { fact_on(server1, %(ipaddress_#{server1_interface})) } - let(:server1_fqdn) { fact_on(server1, 'fqdn') } - let(:server2_interface) { get_private_network_interface(server2) } - let(:server2_ip) { fact_on(server2, %(ipaddress_#{server2_interface})) } - let(:server2_fqdn) { fact_on(server2, 'fqdn') } - - context 'setup server and client hosts' do - it "should set hieradata on #{server1}" do - set_hieradata_on(server1, hieradata_server1) - end - it "should set hieradata on #{server2}" do - set_hieradata_on(server2, hieradata_server2) - end + let(:hieradata_server1) {{ + 'simp_options::pki' => false, + 'simp_options::firewall' => true, + 'rsync::server::stunnel' => false, + 'rsync::server::trusted_nets' => [server2_ip], + 'rsync::server::global::trusted_nets' => [server2_ip], + 'rsync::server::global::address' => '0.0.0.0', + }} + + let(:hieradata_server2) {{ + 'simp_options::pki' => false, + 'simp_options::firewall' => true, + 'rsync::server::stunnel' => false, + 'rsync::server::global::port' => 8873, + 'rsync::server::trusted_nets' => [server1_ip], + 'rsync::server::global::trusted_nets' => [server1_ip], + 'rsync::server::global::address' => '0.0.0.0', + }} + + let(:server1_interface) { get_private_network_interface(server1) } + let(:server1_ip) { fact_on(server1, %(ipaddress_#{server1_interface})) } + let(:server1_fqdn) { fact_on(server1, 'fqdn') } + let(:server2_interface) { get_private_network_interface(server2) } + let(:server2_ip) { fact_on(server2, %(ipaddress_#{server2_interface})) } + let(:server2_fqdn) { fact_on(server2, 'fqdn') } + + context 'setup server and client hosts' do + it "should set hieradata on #{server1}" do + set_hieradata_on(server1, hieradata_server1) + end - hosts.each do |host| - context "on #{host}" do - it 'should work with no errors' do - apply_manifest_on(host, manifest, :catch_failures => true) + it "should set hieradata on #{server2}" do + set_hieradata_on(server2, hieradata_server2) end - it 'should be idempotent' do - apply_manifest(manifest, {:catch_changes => true}) + [server1, server2].each do |host| + context "on #{host}" do + it 'should work with no errors' do + apply_manifest_on(host, manifest, :catch_failures => true) + end + + it 'should be idempotent' do + apply_manifest_on(host, manifest, {:catch_changes => true}) + end + end end + end - end - end + context 'test a file retrieval' do + [server1, server2].each do |host| + it 'should start with a clean state' do + on(host, 'rm -rf /tmp/test_file_srvcli') + end + end - context 'test a file retrieval' do - it "should run retrieval code on #{server1}" do - apply_manifest_on(server1, manifest_test_server1, :catch_failures => true) - end + it "should run retrieval code on #{server1}" do + apply_manifest_on(server1, manifest_test_server1, :catch_failures => true) + end - it "should run retrieval code on #{server2}" do - apply_manifest_on(server2, manifest_test_server2, :catch_failures => true) - end + it "should run retrieval code on #{server2}" do + apply_manifest_on(server2, manifest_test_server2, :catch_failures => true) + end - hosts.each do |host| - it 'should have a file transferred' do - on(host, 'ls /tmp/test_file_srvcli', :acceptable_exit_codes => [0]) + [server1, server2].each do |host| + it 'should have a file transferred' do + on(host, 'ls /tmp/test_file_srvcli', :acceptable_exit_codes => [0]) + result = on(host, 'cat /tmp/test_file_srvcli').stdout + expect( result ).to match(/#{Regexp.escape(file_content)}/) + end + end end end end diff --git a/spec/acceptance/suites/default/20_server_client_stunnel_spec.rb b/spec/acceptance/suites/default/20_server_client_stunnel_spec.rb index 3636b94..ac59321 100644 --- a/spec/acceptance/suites/default/20_server_client_stunnel_spec.rb +++ b/spec/acceptance/suites/default/20_server_client_stunnel_spec.rb @@ -8,182 +8,205 @@ skip('You need at least two hosts in your nodeset to run this test') end else - server1 = hosts[0] - server2 = hosts[1] - - let(:manifest_server1) { - <<-EOS - include '::rsync::server' - - include '::iptables' - - iptables::listen::tcp_stateful { 'ssh': - dports => 22, - trusted_nets => ['any'] - } - - file { '/srv/rsync': - ensure => 'directory' + index_pairs = unique_host_pairs(hosts) + index_pairs.each do |index1,index2| + # Test interoperability between a pair of hosts in the node set, each + # acting as a rsync server to the other. + server1 = hosts[index1] + server2 = hosts[index2] + context "Interoperability between #{server1} and #{server2}" do + + let(:file_content1) { + "What a Test File for #{server1} and #{server2} testing" } - file { '/srv/rsync/test': - ensure => 'directory' + let(:file_content2) { + "What a Test File for #{server2} and #{server1} testing" } - file { '/srv/rsync/test/test_file_srvcli2_server1': - ensure => 'file', - content => 'What a Test File' + let(:manifest_server1) { + <<-EOS + include 'rsync::server' + + include 'iptables' + + iptables::listen::tcp_stateful { 'ssh': + dports => 22, + trusted_nets => ['any'] + } + + file { '/srv/rsync': + ensure => 'directory' + } + + file { '/srv/rsync/test': + ensure => 'directory' + } + + file { '/srv/rsync/test/test_file_srvcli2_server1': + ensure => 'file', + content => '#{file_content1}' + } + + rsync::server::section { 'test': + auth_users => ['test_user'], + user_pass => ['test_user:test_pass'], + comment => 'A test system', + path => '/srv/rsync/test', + require => File['/srv/rsync/test/test_file_srvcli2_server1'] + } + + stunnel::connection { 'rsync': + connect => ["#{server2_fqdn}:8730"], + accept => '127.0.0.1:8873' + } + EOS } - rsync::server::section { 'test': - auth_users => ['test_user'], - user_pass => ['test_user:test_pass'], - comment => 'A test system', - path => '/srv/rsync/test', - require => File['/srv/rsync/test/test_file_srvcli2_server1'] + let(:manifest_server2) { + <<-EOS + include 'rsync::server' + + include 'iptables' + + iptables::listen::tcp_stateful { 'ssh': + dports => 22, + trusted_nets => ['any'] + } + + file { '/srv/rsync': + ensure => 'directory' + } + + file { '/srv/rsync/test': + ensure => 'directory' + } + + file { '/srv/rsync/test/test_file_srvcli2_server2': + ensure => 'file', + content => '#{file_content2}' + } + + rsync::server::section { 'test': + auth_users => ['test_user'], + user_pass => ['test_user:test_pass'], + comment => 'A test system', + path => '/srv/rsync/test', + require => File['/srv/rsync/test/test_file_srvcli2_server2'] + } + + stunnel::connection { 'rsync': + connect => ["#{server1_fqdn}:8730"], + accept => '127.0.0.1:873' + } + EOS } - stunnel::connection { 'rsync': - connect => ["#{server2_fqdn}:8730"], - accept => '127.0.0.1:8873' + let(:manifest_test_server1) { + <<-EOS + rsync::retrieve { 'test_pull': + user => 'test_user', + pass => 'test_pass', + source_path => 'test/test_file_srvcli2_server1', + target_path => '/tmp', + rsync_server => '127.0.0.1', + } + EOS } - EOS - } - let(:manifest_server2) { - <<-EOS - include '::rsync::server' - - include '::iptables' - - iptables::listen::tcp_stateful { 'ssh': - dports => 22, - trusted_nets => ['any'] + let(:manifest_test_server2) { + <<-EOS + rsync::retrieve { 'test_pull': + user => 'test_user', + pass => 'test_pass', + source_path => 'test/test_file_srvcli2_server2', + target_path => '/tmp', + rsync_server => '127.0.0.1:8873', + } + EOS } - file { '/srv/rsync': - ensure => 'directory' - } - - file { '/srv/rsync/test': - ensure => 'directory' - } - - file { '/srv/rsync/test/test_file_srvcli2_server2': - ensure => 'file', - content => 'What a Test File' - } - - rsync::server::section { 'test': - auth_users => ['test_user'], - user_pass => ['test_user:test_pass'], - comment => 'A test system', - path => '/srv/rsync/test', - require => File['/srv/rsync/test/test_file_srvcli2_server2'] - } - - stunnel::connection { 'rsync': - connect => ["#{server1_fqdn}:8730"], - accept => '127.0.0.1:873' - } - EOS - } - - let(:manifest_test_server1) { - <<-EOS - rsync::retrieve { 'test_pull': - user => 'test_user', - pass => 'test_pass', - source_path => 'test/test_file_srvcli2_server1', - target_path => '/tmp', - rsync_server => '127.0.0.1', - } - EOS - } - - let(:manifest_test_server2) { - <<-EOS - rsync::retrieve { 'test_pull': - user => 'test_user', - pass => 'test_pass', - source_path => 'test/test_file_srvcli2_server2', - target_path => '/tmp', - rsync_server => '127.0.0.1:8873', - } - EOS - } - - let(:hieradata_server1) {{ - 'simp_options::pki' => true, - 'simp_options::pki::source' => '/etc/pki/simp-testing/pki', - 'simp_options::firewall' => true, - 'rsync::server::stunnel' => true, - 'rsync::server::trusted_nets' => [server2_ip], - }} - - let(:hieradata_server2) {{ - 'simp_options::pki' => true, - 'simp_options::pki::source' => '/etc/pki/simp-testing/pki', - 'simp_options::firewall' => true, - 'rsync::server::stunnel' => true, - 'rsync::server::global::port' => 8873, - 'rsync::server::trusted_nets' => [server1_ip], - }} - - let(:server1_interface) { get_private_network_interface(server1) } - let(:server1_ip) { fact_on(server1, %(ipaddress_#{server1_interface})) } - let(:server1_fqdn) { fact_on(server1, 'fqdn') } - let(:server2_interface) { get_private_network_interface(server2) } - let(:server2_ip) { fact_on(server2, %(ipaddress_#{server2_interface})) } - let(:server2_fqdn) { fact_on(server2, 'fqdn') } - - context 'setup server and client hosts' do - context "on #{server1}" do - it "should set hieradata" do - set_hieradata_on(server1, hieradata_server1) - end - - it 'should work with no errors' do - apply_manifest_on(server1, manifest_server1, :catch_failures => true) - end - - it 'should be idempotent' do - apply_manifest_on(server1, manifest_server1, :catch_changes => true) - end - end - - context "on #{server2}" do - it "should set hieradata" do - set_hieradata_on(server2, hieradata_server2) - end - - it 'should work with no errors' do - apply_manifest_on(server2, manifest_server2, :catch_failures => true) - end - - it 'should be idempotent' do - apply_manifest_on(server2, manifest_server2, :catch_changes => true) - end - end - - end - - context 'test a file retrieval' do - hosts.each do |host| - it "should run server1 retrieval code on #{host}" do - apply_manifest_on(host, manifest_test_server1, :catch_failures => true) - end - - it 'should have a file transferred' do - on(host, 'ls /tmp/test_file_srvcli2_server1', :acceptable_exit_codes => [0]) - end + let(:hieradata_server1) {{ + 'simp_options::pki' => true, + 'simp_options::pki::source' => '/etc/pki/simp-testing/pki', + 'simp_options::firewall' => true, + 'rsync::server::stunnel' => true, + 'rsync::server::trusted_nets' => [server2_ip], + }} + + let(:hieradata_server2) {{ + 'simp_options::pki' => true, + 'simp_options::pki::source' => '/etc/pki/simp-testing/pki', + 'simp_options::firewall' => true, + 'rsync::server::stunnel' => true, + 'rsync::server::global::port' => 8873, + 'rsync::server::trusted_nets' => [server1_ip], + }} + + let(:server1_interface) { get_private_network_interface(server1) } + let(:server1_ip) { fact_on(server1, %(ipaddress_#{server1_interface})) } + let(:server1_fqdn) { fact_on(server1, 'fqdn') } + let(:server2_interface) { get_private_network_interface(server2) } + let(:server2_ip) { fact_on(server2, %(ipaddress_#{server2_interface})) } + let(:server2_fqdn) { fact_on(server2, 'fqdn') } + + context 'setup server and client hosts' do + context "on #{server1}" do + it "should set hieradata" do + set_hieradata_on(server1, hieradata_server1) + end + + it 'should work with no errors' do + apply_manifest_on(server1, manifest_server1, :catch_failures => true) + end + + it 'should be idempotent' do + apply_manifest_on(server1, manifest_server1, :catch_changes => true) + end + end + + context "on #{server2}" do + it "should set hieradata" do + set_hieradata_on(server2, hieradata_server2) + end + + it 'should work with no errors' do + apply_manifest_on(server2, manifest_server2, :catch_failures => true) + end + + it 'should be idempotent' do + apply_manifest_on(server2, manifest_server2, :catch_changes => true) + end + end - it "should run server2 retrieval code on #{host}" do - apply_manifest_on(host, manifest_test_server2, :catch_failures => true) end - it 'should have a file transferred' do - on(host, 'ls /tmp/test_file_srvcli2_server2', :acceptable_exit_codes => [0]) + context 'test a file retrieval' do + [server1, server2].each do |host| + it 'should start with a clean state' do + on(host, 'rm -rf /tmp/test_file_srvcli*') + end + + it "should run server1 retrieval code on #{host}" do + apply_manifest_on(host, manifest_test_server1, :catch_failures => true) + end + + it 'should have a file transferred' do + on(host, 'ls /tmp/test_file_srvcli2_server1', :acceptable_exit_codes => [0]) + result = on(host, 'cat /tmp/test_file_srvcli2_server1').stdout + expect( result ).to match(/#{Regexp.escape(file_content1)}/) + end + + it "should run server2 retrieval code on #{host}" do + apply_manifest_on(host, manifest_test_server2, :catch_failures => true) + end + + it 'should have a file transferred' do + on(host, 'ls /tmp/test_file_srvcli2_server2', :acceptable_exit_codes => [0]) + result = on(host, 'cat /tmp/test_file_srvcli2_server2').stdout + expect( result ).to match(/#{Regexp.escape(file_content2)}/) + end + end end end end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 53fd772..c3d5107 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -139,6 +139,7 @@ def set_hieradata(hieradata) end # ensure the user running these tests has an accessible environmentpath + Puppet[:digest_algorithm] = 'sha256' Puppet[:environmentpath] = @spec_global_env_temp Puppet[:user] = Etc.getpwuid(Process.uid).name Puppet[:group] = Etc.getgrgid(Process.gid).name diff --git a/spec/spec_helper_acceptance.rb b/spec/spec_helper_acceptance.rb index ce8058d..2417802 100644 --- a/spec/spec_helper_acceptance.rb +++ b/spec/spec_helper_acceptance.rb @@ -2,7 +2,10 @@ require 'tmpdir' require 'yaml' require 'simp/beaker_helpers' +require_relative 'acceptance/helpers/utils' + include Simp::BeakerHelpers +include Acceptance::Helpers::Utils unless ENV['BEAKER_provision'] == 'no' hosts.each do |host|