diff --git a/.fixtures.yml b/.fixtures.yml new file mode 100644 index 0000000..8da261d --- /dev/null +++ b/.fixtures.yml @@ -0,0 +1,8 @@ +fixtures: + symlinks: + duo_unix: "#{source_dir}" + repositories: + stdlib: + repo: https://github.com/puppetlabs/puppetlabs-stdlib.git + ref: 4.3.2 + forge_modules: diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..daa0751 --- /dev/null +++ b/.gitignore @@ -0,0 +1,11 @@ +.*.sw? +pkg +spec/fixtures +.rspec_system +.vagrant +.bundle +vendor +.idea +.project +.DS_Store + diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..cdd8257 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,17 @@ +--- +sudo: false +language: ruby +bundler_args: --without system_tests +script: + - "bundle exec rake validate" + - "bundle exec rake lint" + - "bundle exec rake spec SPEC_OPTS='--format documentation'" +matrix: + fast_finish: true + include: + - rvm: 1.9.3 + env: PUPPET_GEM_VERSION="~> 3.0" STRICT_VARIABLES="yes" ORDERING="random" + - rvm: 2.0.0 + env: PUPPET_GEM_VERSION="~> 3.0" STRICT_VARIABLES="yes" ORDERING="random" + - rvm: 2.1.6 + env: PUPPET_GEM_VERSION="~> 4.0" STRICT_VARIABLES="yes" ORDERING="random" diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100755 index 0000000..a884f0d --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,83 @@ +This module has grown over time based on a range of contributions from +people using it. If you follow these contributing guidelines your patch +will likely make it into a release a little quicker. + +## Contributing + +1. Fork the repo. + +2. Run the tests. We only take pull requests with passing tests, and + it's great to know that you have a clean slate + +3. Add a test for your change. Only refactoring and documentation + changes require no new tests. If you are adding functionality + or fixing a bug, please add a test. + +4. Make the test pass. + +5. Push to your fork and submit a pull request. + + +## Dependencies + +The testing and development tools have a bunch of dependencies, +all managed by [bundler](http://bundler.io/) according to the +[Puppet support matrix](http://docs.puppetlabs.com/guides/platforms.html#ruby-versions). + +By default the tests use a baseline version of Puppet. + +If you have Ruby 2.x or want a specific version of Puppet, +you must set an environment variable such as: + + export PUPPET_VERSION="~> 3.2.0" + +Install the dependencies like so... + + bundle install + +## Syntax and style + +The test suite will run [Puppet Lint](http://puppet-lint.com/) and +[Puppet Syntax](https://github.com/gds-operations/puppet-syntax) to +check various syntax and style things. You can run these locally with: + + bundle exec rake lint + bundle exec rake syntax + +## Running the unit tests + +The unit test suite covers most of the code, as mentioned above please +add tests if you're adding new functionality. If you've not used +[rspec-puppet](http://rspec-puppet.com/) before then feel free to ask +about how best to test your new feature. Running the test suite is done +with: + + bundle exec rake spec + +Note also you can run the syntax, style and unit tests in one go with: + + bundle exec rake test + +## Automatically run the Integration tests + +During development of your puppet module you might want to run your unit tests a couple of times. You can use the following command to automate running the unit tests on every change made in the manifests folder. + + bundle exec guard + +## Integration tests + +The unit tests just check the code runs, not that it does exactly what +we want on a real machine. For that we're using +[beaker](https://github.com/puppetlabs/beaker). + +This fires up a new virtual machine (using vagrant) and runs a series of +simple tests against it after applying the module. You can run this +with: + + bundle exec rake acceptance + +If you don't want to have to recreate the virtual machine every time you +can use `BEAKER_DESTROY=no` and `BEAKER_PROVISION=no`. On the first run you will +at least need `BEAKER_PROVISION` set to yes (the default). The Vagrantfile +for the created virtual machines will be in `.vagrant/beaker_vagrant_files`. + diff --git a/Gemfile b/Gemfile new file mode 100644 index 0000000..58a62e0 --- /dev/null +++ b/Gemfile @@ -0,0 +1,39 @@ +source 'http://rubygems.org' + +group :test do + if puppetversion = ENV['PUPPET_GEM_VERSION'] + gem 'puppet', puppetversion, :require => false + else + gem 'puppet', ENV['PUPPET_VERSION'] || '~> 3.8.0' + end + + gem 'rake' + gem 'puppet-lint' + gem 'rspec-puppet', :git => 'https://github.com/rodjek/rspec-puppet.git' + gem 'puppet-syntax' + gem 'puppetlabs_spec_helper' + gem 'simplecov' + gem 'metadata-json-lint' + gem 'rspec-puppet-facts' + + gem "puppet-lint-absolute_classname-check" + gem "puppet-lint-leading_zero-check" + gem "puppet-lint-trailing_comma-check" + gem "puppet-lint-version_comparison-check" + gem "puppet-lint-classes_and_types_beginning_with_digits-check" + gem "puppet-lint-unquoted_string-check" + gem 'puppet-lint-resource_reference_syntax' + gem 'rspec-puppet-facts' +end + +group :development do + gem 'puppet-blacksmith' + gem 'guard-rake' + gem 'listen', '<= 3.0.6' +end + +group :system_tests do + gem "beaker" + gem "beaker-rspec" + gem "beaker-puppet_install_helper", :require => false +end diff --git a/Gemfile.lock b/Gemfile.lock new file mode 100644 index 0000000..310e1ce --- /dev/null +++ b/Gemfile.lock @@ -0,0 +1,398 @@ +GIT + remote: https://github.com/rodjek/rspec-puppet.git + revision: 79d5373dcbfa4cd56c863f9e9ffe8f3b5e02b8a0 + specs: + rspec-puppet (2.4.0) + rspec + +GEM + remote: http://rubygems.org/ + specs: + CFPropertyList (2.2.8) + addressable (2.4.0) + aws-sdk-v1 (1.66.0) + json (~> 1.4) + nokogiri (>= 1.4.4) + beaker (2.49.0) + aws-sdk-v1 (~> 1.57) + beaker-answers (~> 0.0) + beaker-hiera (~> 0.0) + beaker-hostgenerator + beaker-pe (~> 0.0) + docker-api + fission (~> 0.4) + fog (~> 1.25, < 1.35.0) + fog-google (~> 0.0.9) + google-api-client (~> 0.8, < 0.9.5) + hocon (~> 1.0) + in-parallel (~> 0.1) + inifile (~> 2.0) + json (~> 1.8) + mime-types (~> 2.99) + minitest (~> 5.4) + net-scp (~> 1.2) + net-ssh (~> 2.9) + open_uri_redirections (~> 0.2.1) + rbvmomi (~> 1.8) + rsync (~> 1.0.9) + stringify-hash (~> 0.0) + unf (~> 0.1) + beaker-answers (0.10.0) + hocon (~> 1.0) + require_all (~> 1.3.2) + stringify-hash (~> 0.0.0) + beaker-hiera (0.1.1) + stringify-hash (~> 0.0.0) + beaker-hostgenerator (0.7.3) + deep_merge (~> 1.0) + stringify-hash (~> 0.0.0) + beaker-pe (0.9.0) + stringify-hash (~> 0.0.0) + beaker-puppet_install_helper (0.4.4) + beaker (~> 2.0) + beaker-rspec (5.6.0) + beaker (~> 2.0) + rspec + serverspec (~> 2) + specinfra (~> 2) + builder (3.2.2) + coderay (1.1.1) + deep_merge (1.1.1) + diff-lcs (1.2.5) + docile (1.1.5) + docker-api (1.31.0) + excon (>= 0.38.0) + json + domain_name (0.5.20160615) + unf (>= 0.0.5, < 1.0.0) + excon (0.51.0) + facter (2.4.6) + CFPropertyList (~> 2.2.6) + facterdb (0.3.6) + facter + jgrep + faraday (0.9.2) + multipart-post (>= 1.2, < 3) + ffi (1.9.14) + fission (0.5.0) + CFPropertyList (~> 2.2) + fog (1.34.0) + fog-atmos + fog-aws (>= 0.6.0) + fog-brightbox (~> 0.4) + fog-core (~> 1.32) + fog-dynect (~> 0.0.2) + fog-ecloud (~> 0.1) + fog-google (>= 0.0.2) + fog-json + fog-local + fog-powerdns (>= 0.1.1) + fog-profitbricks + fog-radosgw (>= 0.0.2) + fog-riakcs + fog-sakuracloud (>= 0.0.4) + fog-serverlove + fog-softlayer + fog-storm_on_demand + fog-terremark + fog-vmfusion + fog-voxel + fog-xml (~> 0.1.1) + ipaddress (~> 0.5) + nokogiri (~> 1.5, >= 1.5.11) + fog-atmos (0.1.0) + fog-core + fog-xml + fog-aws (0.11.0) + fog-core (~> 1.38) + fog-json (~> 1.0) + fog-xml (~> 0.1) + ipaddress (~> 0.8) + fog-brightbox (0.11.0) + fog-core (~> 1.22) + fog-json + inflecto (~> 0.0.2) + fog-core (1.42.0) + builder + excon (~> 0.49) + formatador (~> 0.2) + fog-dynect (0.0.3) + fog-core + fog-json + fog-xml + fog-ecloud (0.3.0) + fog-core + fog-xml + fog-google (0.0.9) + fog-core + fog-json + fog-xml + fog-json (1.0.2) + fog-core (~> 1.0) + multi_json (~> 1.10) + fog-local (0.3.0) + fog-core (~> 1.27) + fog-powerdns (0.1.1) + fog-core (~> 1.27) + fog-json (~> 1.0) + fog-xml (~> 0.1) + fog-profitbricks (0.0.5) + fog-core + fog-xml + nokogiri + fog-radosgw (0.0.5) + fog-core (>= 1.21.0) + fog-json + fog-xml (>= 0.0.1) + fog-riakcs (0.1.0) + fog-core + fog-json + fog-xml + fog-sakuracloud (1.7.5) + fog-core + fog-json + fog-serverlove (0.1.2) + fog-core + fog-json + fog-softlayer (1.1.3) + fog-core + fog-json + fog-storm_on_demand (0.1.1) + fog-core + fog-json + fog-terremark (0.1.0) + fog-core + fog-xml + fog-vmfusion (0.1.0) + fission + fog-core + fog-voxel (0.1.0) + fog-core + fog-xml + fog-xml (0.1.2) + fog-core + nokogiri (~> 1.5, >= 1.5.11) + formatador (0.2.5) + google-api-client (0.9.4) + addressable (~> 2.3) + googleauth (~> 0.5) + httpclient (~> 2.7) + hurley (~> 0.1) + memoist (~> 0.11) + mime-types (>= 1.6) + representable (~> 2.3.0) + retriable (~> 2.0) + thor (~> 0.19) + googleauth (0.5.1) + faraday (~> 0.9) + jwt (~> 1.4) + logging (~> 2.0) + memoist (~> 0.12) + multi_json (~> 1.11) + os (~> 0.9) + signet (~> 0.7) + guard (2.14.0) + formatador (>= 0.2.4) + listen (>= 2.7, < 4.0) + lumberjack (~> 1.0) + nenv (~> 0.1) + notiffany (~> 0.0) + pry (>= 0.9.12) + shellany (~> 0.0) + thor (>= 0.18.1) + guard-rake (1.0.0) + guard + rake + hiera (1.3.4) + json_pure + hocon (1.1.2) + http-cookie (1.0.2) + domain_name (~> 0.5) + httpclient (2.8.2.2) + hurley (0.2) + in-parallel (0.1.15) + inflecto (0.0.2) + inifile (2.0.2) + ipaddress (0.8.3) + jgrep (1.4.1) + json + json (1.8.3) + json_pure (2.0.2) + jwt (1.5.4) + listen (3.0.6) + rb-fsevent (>= 0.9.3) + rb-inotify (>= 0.9.7) + little-plugger (1.1.4) + logging (2.1.0) + little-plugger (~> 1.1) + multi_json (~> 1.10) + lumberjack (1.0.10) + mcollective-client (2.9.0) + json + stomp + systemu + memoist (0.14.0) + metaclass (0.0.4) + metadata-json-lint (0.0.11) + json + spdx-licenses (~> 1.0) + method_source (0.8.2) + mime-types (2.99.2) + mini_portile2 (2.1.0) + minitest (5.9.0) + mocha (1.1.0) + metaclass (~> 0.0.1) + multi_json (1.12.1) + multipart-post (2.0.0) + nenv (0.3.0) + net-scp (1.2.1) + net-ssh (>= 2.6.5) + net-ssh (2.9.4) + net-telnet (0.1.1) + netrc (0.11.0) + nokogiri (1.6.8) + mini_portile2 (~> 2.1.0) + pkg-config (~> 1.1.7) + notiffany (0.1.1) + nenv (~> 0.1) + shellany (~> 0.0) + open_uri_redirections (0.2.1) + os (0.9.6) + pkg-config (1.1.7) + pry (0.10.4) + coderay (~> 1.1.0) + method_source (~> 0.8.1) + slop (~> 3.4) + puppet (3.8.7) + facter (> 1.6, < 3) + hiera (~> 1.0) + json_pure + puppet-blacksmith (3.4.0) + puppet (>= 2.7.16) + rest-client (~> 1.8.0) + puppet-lint (2.0.2) + puppet-lint-absolute_classname-check (0.2.4) + puppet-lint (>= 1.0, < 3.0) + puppet-lint-classes_and_types_beginning_with_digits-check (0.1.2) + puppet-lint (>= 1.0, < 3.0) + puppet-lint-leading_zero-check (0.1.1) + puppet-lint (>= 1.0, < 3.0) + puppet-lint-resource_reference_syntax (1.0.9) + puppet-lint (>= 1.0, < 3.0) + puppet-lint-trailing_comma-check (0.3.2) + puppet-lint (>= 1.0, < 3.0) + puppet-lint-unquoted_string-check (0.3.0) + puppet-lint (>= 1.0, < 3.0) + puppet-lint-version_comparison-check (0.2.1) + puppet-lint (>= 1.0, < 3.0) + puppet-syntax (2.1.0) + rake + puppetlabs_spec_helper (1.1.1) + mocha + puppet-lint + puppet-syntax + rake + rspec-puppet + rake (11.2.2) + rb-fsevent (0.9.7) + rb-inotify (0.9.7) + ffi (>= 0.5.0) + rbvmomi (1.9.1) + builder (~> 3.2) + json (>= 1.8) + nokogiri (~> 1.5) + trollop (~> 2.1) + representable (2.3.0) + uber (~> 0.0.7) + require_all (1.3.3) + rest-client (1.8.0) + http-cookie (>= 1.0.2, < 2.0) + mime-types (>= 1.16, < 3.0) + netrc (~> 0.7) + retriable (2.1.0) + rspec (3.5.0) + rspec-core (~> 3.5.0) + rspec-expectations (~> 3.5.0) + rspec-mocks (~> 3.5.0) + rspec-core (3.5.2) + rspec-support (~> 3.5.0) + rspec-expectations (3.5.0) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.5.0) + rspec-its (1.2.0) + rspec-core (>= 3.0.0) + rspec-expectations (>= 3.0.0) + rspec-mocks (3.5.0) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.5.0) + rspec-puppet-facts (1.6.1) + facter + facterdb (>= 0.3.0) + json + mcollective-client + puppet + rspec-support (3.5.0) + rsync (1.0.9) + serverspec (2.36.0) + multi_json + rspec (~> 3.0) + rspec-its + specinfra (~> 2.53) + sfl (2.2) + shellany (0.0.1) + signet (0.7.3) + addressable (~> 2.3) + faraday (~> 0.9) + jwt (~> 1.5) + multi_json (~> 1.10) + simplecov (0.12.0) + docile (~> 1.1.0) + json (>= 1.8, < 3) + simplecov-html (~> 0.10.0) + simplecov-html (0.10.0) + slop (3.6.0) + spdx-licenses (1.1.0) + specinfra (2.61.1) + net-scp + net-ssh (>= 2.7, < 4.0) + net-telnet + sfl + stomp (1.4.3) + stringify-hash (0.0.2) + systemu (2.6.5) + thor (0.19.1) + trollop (2.1.2) + uber (0.0.15) + unf (0.1.4) + unf_ext + unf_ext (0.0.7.2) + +PLATFORMS + ruby + +DEPENDENCIES + beaker + beaker-puppet_install_helper + beaker-rspec + guard-rake + listen (<= 3.0.6) + metadata-json-lint + puppet (~> 3.8.0) + puppet-blacksmith + puppet-lint + puppet-lint-absolute_classname-check + puppet-lint-classes_and_types_beginning_with_digits-check + puppet-lint-leading_zero-check + puppet-lint-resource_reference_syntax + puppet-lint-trailing_comma-check + puppet-lint-unquoted_string-check + puppet-lint-version_comparison-check + puppet-syntax + puppetlabs_spec_helper + rake + rspec-puppet! + rspec-puppet-facts + simplecov + +BUNDLED WITH + 1.12.5 diff --git a/Rakefile b/Rakefile new file mode 100644 index 0000000..cb01c29 --- /dev/null +++ b/Rakefile @@ -0,0 +1,45 @@ +require 'puppetlabs_spec_helper/rake_tasks' +require 'puppet-lint/tasks/puppet-lint' +require 'puppet-syntax/tasks/puppet-syntax' + +# These two gems aren't always present, for instance +# on Travis with --without development +begin + require 'puppet_blacksmith/rake_tasks' +rescue LoadError +end + +PuppetLint.configuration.relative = true +PuppetLint.configuration.send("disable_80chars") +PuppetLint.configuration.log_format = "%{path}:%{linenumber}:%{check}:%{KIND}:%{message}" +PuppetLint.configuration.fail_on_warnings = true + +# 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_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 + +desc "Run acceptance tests" +RSpec::Core::RakeTask.new(:acceptance) do |t| + t.pattern = 'spec/acceptance' +end + +task :metadata do + sh "metadata-json-lint metadata.json" +end + +desc "Run syntax, lint, and spec tests." +task :test => [ + :syntax, + :lint, + :spec, +] diff --git a/manifests/init.pp b/manifests/init.pp index 61104e4..33de563 100644 --- a/manifests/init.pp +++ b/manifests/init.pp @@ -6,12 +6,12 @@ # # Mark Stanislav class duo_unix ( - $usage = '', - $ikey = '', - $skey = '', - $host = '', - $group = '', - $http_proxy = '', + $usage = undef, + $ikey = undef, + $skey = undef, + $host = undef, + $group = undef, + $http_proxy = undef, $fallback_local_ip = 'no', $failmode = 'safe', $pushinfo = 'no', @@ -24,12 +24,21 @@ $pam_unix_control = 'requisite', $package_version = 'installed', ) { - if $ikey == '' or $skey == '' or $host == '' { + + unless $ikey and $skey and $host { fail('ikey, skey, and host must all be defined.') } - if $usage != 'login' and $usage != 'pam' { - fail('You must configure a usage of duo_unix, either login or pam.') + case $variable { + 'login': { + include ::duo_unix::login + } + 'pam': { + include ::duo_unix::pam + } + default: { + fail("You must configure a usage of duo_unix, either login or pam (got '${usage}')") + } } case $::osfamily { @@ -44,13 +53,13 @@ } $pam_module = $::architecture ? { - i386 => '/lib/security/pam_duo.so', - i686 => '/lib/security/pam_duo.so', - x86_64 => '/lib64/security/pam_duo.so' + 'i386' => '/lib/security/pam_duo.so', + 'i686' => '/lib/security/pam_duo.so', + 'x86_64' => '/lib64/security/pam_duo.so' } - include duo_unix::yum - include duo_unix::generic + include ::duo_unix::yum + include ::duo_unix::generic } 'Debian': { $duo_package = 'duo-unix' @@ -59,22 +68,17 @@ $pam_file = '/etc/pam.d/common-auth' $pam_module = $::architecture ? { - i386 => '/lib/security/pam_duo.so', - i686 => '/lib/security/pam_duo.so', - amd64 => '/lib64/security/pam_duo.so' + 'i386' => '/lib/security/pam_duo.so', + 'i686' => '/lib/security/pam_duo.so', + 'amd64' => '/lib64/security/pam_duo.so' } - include duo_unix::apt - include duo_unix::generic + include ::duo_unix::apt + include ::duo_unix::generic } default: { fail("Module ${module_name} does not support ${::operatingsystem}") } } - if $usage == 'login' { - include duo_unix::login - } else { - include duo_unix::pam - } } diff --git a/manifests/yum.pp b/manifests/yum.pp index c1c3738..9941a73 100644 --- a/manifests/yum.pp +++ b/manifests/yum.pp @@ -19,7 +19,7 @@ } $os = $::operatingsystem } elsif ( $::operatingsystem == 'RedHat' and - $::operatingsystemmajrelease == 5 ) { + versioncmp($::operatingsystemmajrelease, '5') == 0 ) { $os = 'CentOS' $releasever = '$releasever' } elsif ( $::operatingsystem == 'OracleLinux' ) { diff --git a/spec/classes/duo_unix_spec.rb b/spec/classes/duo_unix_spec.rb new file mode 100644 index 0000000..4f49a8f --- /dev/null +++ b/spec/classes/duo_unix_spec.rb @@ -0,0 +1,43 @@ +require 'spec_helper' + + +describe 'duo_unix' do + # by default the hiera integration uses hiera data from the shared_contexts.rb file + # but basically to mock hiera you first need to add a key/value pair + # to the specific context in the spec/shared_contexts.rb file + # Note: you can only use a single hiera context per describe/context block + # rspec-puppet does not allow you to swap out hiera data on a per test block + #include_context :hiera + + # below is the facts hash that gives you the ability to mock + # facts on a per describe/context block. If you use a fact in your + # manifest you should mock the facts below. + on_supported_os.each do |os, facts| + context "on #{os}" do + let(:facts) do + facts + end + + # below is a list of the resource parameters that you can override. + # By default all non-required parameters are commented out, + # while all required parameters will require you to add a value + let(:params) do + { + :usage => 'pam', + :ikey => 'foo', + :skey => 'bar', + :host => 'baz', + } + end + # add these two lines in a single test block to enable puppet and hiera debug mode + # Puppet::Util::Log.level = :debug + # Puppet::Util::Log.newdestination(:console) + it do + is_expected.to compile.with_all_deps + end + + + end + end + +end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb new file mode 100644 index 0000000..bd05d7a --- /dev/null +++ b/spec/spec_helper.rb @@ -0,0 +1,8 @@ +require 'puppetlabs_spec_helper/module_spec_helper' +require 'rspec-puppet-facts' +include RspecPuppetFacts + +RSpec.configure do |c| + c.formatter = 'documentation' + c.mock_with :rspec +end