diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index daab19d..c755e3b 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -4,237 +4,175 @@ # https://puppet.com/misc/puppet-enterprise-lifecycle # https://puppet.com/docs/pe/2017.3/overview/getting_support_for_pe.html#standard-releases-and-long-term-support-releases # ------------------------------------------------------------------------------ -# release pup ruby eol -# PE 2016.4 4.7 2.1.9 2018-10 (LTS) -# SIMP6.0.0 4.8 2.1.9 TBD -# PE 2017.2 4.10 2.1.9 2018-02-21 -# PE 2017.3 5.3 2.4.1 2018-07 -# PE 2018.1 ??? ????? ????-?? (LTS) +# release pup ruby eol +# PE 2016.4 4.7 2.1.9 2018-10 (LTS)*** +# SIMP 6.0 4.8 2.1.9 TBD*** +# SIMP 6.2 4.10 2.1.9 TBD +# PE 2017.2 4.10 2.1.9 2018-02 +# PE 2017.3 5.3 2.4.1 2018-08 +# PE 2018.1 5.5 2.4.1 2020-05 (LTS) +# +# *** = Modules created for SIMP 6.2+ are not required to support Puppet < 4.10 --- -.cache_bundler: &cache_bundler +stages: + - 'sanity' + - 'validation' + - 'acceptance' + - 'deployment' + +image: 'ruby:2.1' + +variables: + PUPPET_VERSION: 'UNDEFINED' # <- Matrixed jobs MUST override this (or fail) + BUNDLER_VERSION: '1.16.1' + + # Force dependencies into a path the gitlab-runner user can write to. + # (This avoids some failures on Runners with misconfigured ruby environments.) + GEM_HOME: .vendor/gem_install + BUNDLE_CACHE_PATH: .vendor/bundle + BUNDLE_PATH: .vendor/bundle + BUNDLE_BIN: .vendor/gem_install/bin + BUNDLE_NO_PRUNE: 'true' + + +# bundler dependencies and caching +# +# - Cache bundler gems between pipelines foreach Ruby version +# - Try to use cached and local resources before downloading dependencies +# -------------------------------------- +.setup_bundler_env: &setup_bundler_env cache: untracked: true - # A broad attempt at caching between runs (ala Travis CI) - key: "${CI_PROJECT_NAMESPACE}__bundler" + key: "${CI_PROJECT_NAMESPACE}_ruby-${MATRIX_RUBY_VERSION}_bundler" paths: - '.vendor' - - 'vendor' - -.setup_bundler_env: &setup_bundler_env before_script: - - 'echo Files in cache: $(find .vendor | wc -l) || :' - - 'export GEM_HOME=.vendor/gem_install' - - 'export BUNDLE_CACHE_PATH=.vendor/bundler' - - 'declare GEM_BUNDLER_VER=(-v ''~> ${BUNDLER_VERSION:-1.16.0}'')' - - declare GEM_INSTALL=(gem install --no-document) - - declare BUNDLER_INSTALL=(bundle install --no-binstubs --jobs $(nproc) --path=.vendor "${FLAGS[@]}") - - gem list -ie "${GEM_BUNDLE_VER[@]}" --silent bundler || "${GEM_INSTALL[@]}" --local "${GEM_BUNDLE_VER[@]}" bundler || "${GEM_INSTALL[@]}" "${GEM_BUNDLE_VER[@]}" bundler + - 'declare GEM_BUNDLER_VER=(-v "~> ${BUNDLER_VERSION:-1.16.0}")' + - 'declare GEM_INSTALL_CMD=(gem install --no-document)' + - 'declare BUNDLER_INSTALL_CMD=(bundle install --no-binstubs --jobs $(nproc) "${FLAGS[@]}")' + - 'mkdir -p ${GEM_HOME} ${BUNDLER_BIN}' + - 'gem list -ie "${GEM_BUNDLER_VER[@]}" --silent bundler || "${GEM_INSTALL_CMD[@]}" --local "${GEM_BUNDLER_VER[@]}" bundler || "${GEM_INSTALL_CMD[@]}" "${GEM_BUNDLER_VER[@]}" bundler' - 'rm -rf pkg/ || :' - - bundle check || rm -f Gemfile.lock && ("${BUNDLER_INSTALL[@]}" --local || "${BUNDLER_INSTALL[@]}") + - 'bundle check || rm -f Gemfile.lock && ("${BUNDLER_INSTALL_CMD[@]}" --local || "${BUNDLER_INSTALL_CMD[@]}" || bundle pristine || "${BUNDLER_INSTALL_CMD[@]}") || echo "PIPELNE: Bundler could not find everything"' - -.validation_checks: &validation_checks - script: - - bundle exec rake syntax - - bundle exec rake check:dot_underscore - - bundle exec rake check:test_file - - bundle exec rake pkg:check_version - - bundle exec rake pkg:compare_latest_tag - - bundle exec rake lint - - bundle exec rake clean - - bundle exec puppet module build - -.spec_tests: &spec_tests - script: - - bundle exec rake spec - -stages: - - validation - - unit - - acceptance - - deploy - -# Puppet 4.7 for PE 2016.4 LTS Support (EOL: 2018-10-21) -# See: https://puppet.com/misc/puppet-enterprise-lifecycle +# Puppet + testing environments # -------------------------------------- -pup4_7-validation: - stage: validation - tags: - - docker - image: ruby:2.1 +.pup_4_10_0: &pup_4_10_0 + image: 'ruby:2.1' variables: - PUPPET_VERSION: '~> 4.7.0' - <<: *cache_bundler - <<: *setup_bundler_env - <<: *validation_checks + PUPPET_VERSION: '~> 4.10.0' + MATRIX_RUBY_VERSION: '2.1' -pup4_7-unit: - stage: unit - tags: - - docker - image: ruby:2.1 +.pup_4_latest: &pup_4_latest + image: 'ruby:2.1' variables: - PUPPET_VERSION: '~> 4.7.0' - <<: *cache_bundler - <<: *setup_bundler_env - <<: *spec_tests - + PUPPET_VERSION: '~> 4.0' + MATRIX_RUBY_VERSION: '2.1' -# Puppet 4.8 for SIMP 6.0 + 6.1 support -# -------------------------------------- -pup4_8-validation: - stage: validation - tags: - - docker - image: ruby:2.1 +.pup_5_3_2: &pup_5_3_2 + image: 'ruby:2.4' variables: - PUPPET_VERSION: '~> 4.8.0' - <<: *cache_bundler - <<: *setup_bundler_env - <<: *validation_checks + PUPPET_VERSION: '~> 5.3.2' + BEAKER_PUPPET_COLLECTION: 'puppet5' + MATRIX_RUBY_VERSION: '2.4' -pup4_8-unit: - stage: unit - tags: - - docker - image: ruby:2.1 +.pup_5_5_1: &pup_5_5_1 + image: 'ruby:2.4' variables: - PUPPET_VERSION: '~> 4.8.0' - <<: *cache_bundler - <<: *setup_bundler_env - <<: *spec_tests + PUPPET_VERSION: '~> 5.5.1' + BEAKER_PUPPET_COLLECTION: 'puppet5' + MATRIX_RUBY_VERSION: '2.4' +.pup_5_latest: &pup_5_latest + image: 'ruby:2.4' + variables: + PUPPET_VERSION: '~> 5.0' + BEAKER_PUPPET_COLLECTION: 'puppet5' + MATRIX_RUBY_VERSION: '2.4' -# Puppet 4.10 for PE 2017.2 support (EOL:2018-02-21) -# See: https://puppet.com/misc/puppet-enterprise-lifecycle +# jobs # -------------------------------------- -pup4_10-validation: - stage: validation - tags: - - docker - image: ruby:2.1 - variables: - PUPPET_VERSION: '~> 4.10.0' - <<: *cache_bundler +.lint_tests: &lint_tests + stage: 'validation' + tags: ['docker'] <<: *setup_bundler_env - <<: *validation_checks + script: + - 'bundle exec rake syntax' + - 'bundle exec rake lint' -pup4_10-unit: - stage: unit - tags: - - docker - image: ruby:2.1 - variables: - PUPPET_VERSION: '~> 4.10.0' - <<: *cache_bundler +.unit_tests: &unit_tests + stage: 'validation' + tags: ['docker'] <<: *setup_bundler_env - <<: *spec_tests - + script: + - 'bundle exec rake spec' -# Puppet 5.3 for PE 2017.3 support (EOL: 2018-07) -# See: https://puppet.com/misc/puppet-enterprise-lifecycle -# -------------------------------------- -pup5_3-validation: - stage: validation - tags: - - docker - image: ruby:2.4 - variables: - PUPPET_VERSION: '~> 5.3.0' - <<: *cache_bundler +.acceptance_base: &acceptance_base + stage: 'acceptance' + tags: ['beaker'] <<: *setup_bundler_env - <<: *validation_checks -pup5_3-unit: - stage: unit - tags: - - docker - image: ruby:2.4 - variables: - PUPPET_VERSION: '~> 5.3.0' - <<: *cache_bundler +# Pipeline / testing matrix +#======================================================================= + +sanity_checks: + <<: *pup_4_latest <<: *setup_bundler_env - <<: *spec_tests + stage: 'sanity' + tags: ['docker'] + script: + - 'bundle exec rake check:dot_underscore' + - 'bundle exec rake check:test_file' + - 'bundle exec rake pkg:check_version' + - 'bundle exec rake pkg:compare_latest_tag' -# Keep an eye on the latest puppet 5 -# ---------------------------------- -pup5_latest-validation: - stage: validation - tags: - - docker - image: ruby:2.4 - variables: - PUPPET_VERSION: '~> 5.0' - <<: *cache_bundler - <<: *setup_bundler_env - <<: *validation_checks +pup4-lint: + <<: *pup_4_latest + <<: *lint_tests -pup5_latest-unit: - stage: unit - tags: - - docker - image: ruby:2.4 - variables: - PUPPET_VERSION: '~> 5.0' - <<: *cache_bundler - <<: *setup_bundler_env - <<: *spec_tests +pup5-lint: + <<: *pup_5_latest + <<: *lint_tests +pup4.10-unit: + <<: *pup_4_10_0 + <<: *unit_tests -# Acceptance tests -# ============================================================================== -default-acceptance: - stage: acceptance - tags: - - beaker - <<: *cache_bundler - <<: *setup_bundler_env - variables: - PUPPET_VERSION: '4.10' - script: - - bundle exec rake beaker:suites[default] +pup5.3-unit: + <<: *pup_5_3_2 + <<: *unit_tests -fips-acceptance: - stage: acceptance - tags: - - beaker - <<: *cache_bundler - <<: *setup_bundler_env - variables: - PUPPET_VERSION: '4.10' - BEAKER_fips: 'yes' +pup5.5-unit: + <<: *pup_5_5_1 + <<: *unit_tests + +pup5.latest-unit: + <<: *pup_5_latest + <<: *unit_tests + + +pup4.10-acceptance: + <<: *pup_4_10_0 + <<: *acceptance_base script: - - bundle exec rake beaker:suites[default] - -acceptance-puppet5-default: - stage: acceptance - tags: - - beaker - <<: *cache_bundler - <<: *setup_env_beaker + - 'bundle exec rake beaker:suites' + +pup4.10-fips-acceptance: + <<: *pup_4_10_0 + <<: *acceptance_base script: - - bundle exec rake beaker:suites[default,puppet5] - -acceptance-fips-puppet5-default: - stage: acceptance - tags: - - beaker - <<: *cache_bundler - <<: *setup_env_beaker - variables: - BEAKER_fips: 'yes' + - 'BEAKER_fips=yes bundle exec rake beaker:suites' + +pup5.5-acceptance: + <<: *pup_5_5_1 + <<: *acceptance_base script: - - bundle exec rake beaker:suites[default,puppet5] - -acceptance-oel-puppet5-default: - stage: acceptance - tags: - - beaker - <<: *cache_bundler - <<: *setup_env_beaker - variables: - PUPPET_VERSION: '5.4' + - 'bundle exec rake beaker:suites' + +pup5.5-fips-acceptance: + <<: *pup_5_5_1 + <<: *acceptance_base script: - - bundle exec rake beaker:suites[default,oel_p5] + - 'BEAKER_fips=yes bundle exec rake beaker:suites' diff --git a/.travis.yml b/.travis.yml index 8ae27ba..49755f6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -27,7 +27,7 @@ before_install: jobs: include: - stage: check - rvm: 2.4.1 + rvm: 2.4.4 env: STRICT_VARIABLES=yes TRUSTED_NODE_DATA=yes PUPPET_VERSION="~> 5" script: - bundle exec rake check:dot_underscore @@ -40,7 +40,7 @@ jobs: - bundle exec puppet module build - stage: spec - rvm: 2.4.1 + rvm: 2.4.4 env: STRICT_VARIABLES=yes TRUSTED_NODE_DATA=yes PUPPET_VERSION="~> 5.0" script: - bundle exec rake spec @@ -51,20 +51,8 @@ jobs: script: - bundle exec rake spec - - stage: spec - rvm: 2.1.9 - env: STRICT_VARIABLES=yes TRUSTED_NODE_DATA=yes PUPPET_VERSION="~> 4.9.2" - script: - - bundle exec rake spec - - - stage: spec - rvm: 2.1.9 - env: STRICT_VARIABLES=yes TRUSTED_NODE_DATA=yes PUPPET_VERSION="~> 4.7.0" - script: - - bundle exec rake spec - - stage: deploy - rvm: 2.4.1 + rvm: 2.4.4 script: - true before_deploy: diff --git a/CHANGELOG b/CHANGELOG index 59c10b0..e1eac1b 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,8 @@ +* Wed Oct 24 2018 Trevor Vaughan - 1.0.6-0 +- Refactored the module to work with Puppet > 5.5.6 + - Puppet 5.5.7 broke the Type/Provider interface in the 'group' type so + required an emergency refactor + * Tue Mar 20 2018 Trevor Vaughan - 1.0.5-0 - Added support for OEL and Puppet 5 diff --git a/Gemfile b/Gemfile index 09b5459..6d8a00e 100644 --- a/Gemfile +++ b/Gemfile @@ -7,9 +7,7 @@ gem_sources.each { |gem_source| source gem_source } group :test do gem 'rake' - gem 'puppet', ENV.fetch('PUPPET_VERSION', '~> 4.0') - gem 'rspec' - gem 'rspec-puppet' + gem 'puppet', ENV.fetch('PUPPET_VERSION', '~> 5.0') gem 'hiera-puppet-helper' gem 'puppetlabs_spec_helper' gem 'metadata-json-lint' @@ -24,19 +22,13 @@ group :development do gem 'travis' gem 'travis-lint' gem 'travish' - gem 'puppet-blacksmith' - gem 'guard-rake' gem 'pry' gem 'pry-byebug' gem 'pry-doc' - - # `listen` is a dependency of `guard` - # from `listen` 3.1+, `ruby_dep` requires Ruby version >= 2.2.3, ~> 2.2 - gem 'listen', '~> 3.0.6' end group :system_tests do gem 'beaker' gem 'beaker-rspec' - gem 'simp-beaker-helpers', ENV.fetch('SIMP_BEAKER_HELPERS_VERSION', '~> 1.10') + gem 'simp-beaker-helpers', ENV.fetch('SIMP_BEAKER_HELPERS_VERSION', ['>= 1.12.1', '< 2.0']) end diff --git a/lib/puppet/provider/group/gpasswd.rb b/lib/puppet/provider/group/gpasswd.rb index 7e68104..e65dffc 100644 --- a/lib/puppet/provider/group/gpasswd.rb +++ b/lib/puppet/provider/group/gpasswd.rb @@ -15,18 +15,23 @@ has_feature :libuser if Puppet.features.libuser? has_feature :system_groups unless %w{HP-UX Solaris}.include? Facter.value(:operatingsystem) + def is_new_format? + defined?(Puppet::Property::List) && + @resource.parameter('members').class.ancestors.include?(Puppet::Property::List) + end + def addcmd # This pulls in the main group add command should the group need # to be added from scratch. cmd = Array(super.map{|x| x = "#{x}"}.shelljoin) - if @resource[:members] - cmd += @resource[:members].map{ |x| + if @resource.parameter('members') + cmd += @resource.property('members').shouldorig.map{ |x| [ command(:addmember),'-a',x,@resource[:name] ].shelljoin } end - mod_group(cmd) + mod_group(cmd) # We're returning /bin/true here since the Nameservice classes # would execute whatever is returned here. @@ -48,32 +53,55 @@ def modifycmd(param, value) end def members - getinfo(true) if @objectinfo.nil? - retval = @objectinfo.mem + members_to_set = @resource.parameter('members').shouldorig + + @current_members = [] + begin + current_members = Puppet::Etc.send('getgrnam', name) + if current_members + @current_members = current_members.mem + end + rescue ArgumentError + # Noop + end + + retval = @current_members - if !@resource[:auth_membership] && (@resource[:members] - @objectinfo.mem).empty? - retval = @resource[:members] + if !@resource[:auth_membership] && (members_to_set - @current_members).empty? + retval = members_to_set end - retval.sort + retval = retval.sort + + # Puppet 5.5.7 breaking change workaround + if is_new_format? + return retval.join(',') + else + return retval + end end def members_insync?(is, should) Array(is).uniq.sort == Array(should).uniq.sort end - def members=(members) + def members=(to_set) cmd = [] - to_be_added = members.dup + if is_new_format? + to_be_added = to_set.split(',') + else + to_be_added = to_set.dup + end + if @resource[:auth_membership] - to_be_removed = @objectinfo.mem - to_be_added - to_be_added = to_be_added - @objectinfo.mem + to_be_removed = @current_members - to_be_added + to_be_added = to_be_added - @current_members !to_be_removed.empty? && cmd += to_be_removed.map { |x| [ command(:addmember),'-d',x,@resource[:name] ].shelljoin } else - to_be_added = to_be_added | @objectinfo.mem + to_be_added = to_be_added | @current_members end !to_be_added.empty? && cmd += to_be_added.map { |x| diff --git a/metadata.json b/metadata.json index 613e574..b3dd9bf 100644 --- a/metadata.json +++ b/metadata.json @@ -1,6 +1,6 @@ { "name": "onyxpoint-gpasswd", - "version": "1.0.5", + "version": "1.0.6", "author": "Trevor Vaughan ", "summary": "Adds support for :manages_members to the Linux group native type", "license": "Apache-2.0", @@ -47,7 +47,7 @@ "requirements": [ { "name": "puppet", - "version_requirement": ">= 4.7.0 < 6.0.0" + "version_requirement": ">= 4.10.4 < 6.0.0" } ] } diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index f2014d0..40c6495 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -25,11 +25,13 @@ default_hiera_config =<<-EOM --- :backends: + - "rspec" - "yaml" :yaml: :datadir: "stub" :hierarchy: - "%{custom_hiera}" + - "%{spec_title}" - "%{module_name}" - "default" EOM @@ -67,7 +69,7 @@ def set_environment(environment = :production) # # Note: Any colons (:) are replaced with underscores (_) in the class name. def set_hieradata(hieradata) - RSpec.configure { |c| c.default_facts['custom_hiera'] = hieradata } + RSpec.configure { |c| c.default_facts['custom_hiera'] = hieradata } end if not File.directory?(File.join(fixture_path,'hieradata')) then @@ -118,31 +120,16 @@ def set_hieradata(hieradata) end c.before(:each) do - @spec_global_env_temp = Dir.mktmpdir('simpspec') - if defined?(environment) set_environment(environment) - FileUtils.mkdir_p(File.join(@spec_global_env_temp,environment.to_s)) end - # ensure the user running these tests has an accessible environmentpath - Puppet[:environmentpath] = @spec_global_env_temp - Puppet[:user] = Etc.getpwuid(Process.uid).name - Puppet[:group] = Etc.getgrgid(Process.gid).name - - # sanitize hieradata if defined?(hieradata) set_hieradata(hieradata.gsub(':','_')) elsif defined?(class_name) set_hieradata(class_name.gsub(':','_')) end end - - c.after(:each) do - # clean up the mocked environmentpath - FileUtils.rm_rf(@spec_global_env_temp) - @spec_global_env_temp = nil - end end Dir.glob("#{RSpec.configuration.module_path}/*").each do |dir| diff --git a/spec/spec_helper_acceptance.rb b/spec/spec_helper_acceptance.rb index e5556ad..079dfde 100644 --- a/spec/spec_helper_acceptance.rb +++ b/spec/spec_helper_acceptance.rb @@ -12,6 +12,9 @@ else install_puppet end + # Install git, it's a dependency for inspec profiles + # Found this when experiencing https://github.com/chef/inspec/issues/1270 + install_package(host, 'git') end end @@ -33,6 +36,7 @@ rescue ArgumentError =>e server = only_host_with_role(hosts, 'default') end + # Generate and install PKI certificates on each SUT Dir.mktmpdir do |cert_dir| run_fake_pki_ca_on(server, hosts, cert_dir ) diff --git a/spec/unit/provider/group/gpasswd_spec.rb b/spec/unit/provider/group/gpasswd_spec.rb old mode 100755 new mode 100644 index b3bf489..08c5b38 --- a/spec/unit/provider/group/gpasswd_spec.rb +++ b/spec/unit/provider/group/gpasswd_spec.rb @@ -8,15 +8,21 @@ described_class.stubs(:command).with(:modify).returns '/usr/sbin/groupmod' described_class.stubs(:command).with(:addmember).returns '/usr/bin/gpasswd' described_class.stubs(:command).with(:delmember).returns '/usr/bin/gpasswd' + + if members + @resource = Puppet::Type.type(:group).new(:name => 'mygroup', :members => members, :provider => provider) + else + @resource = Puppet::Type.type(:group).new(:name => 'mygroup', :provider => provider) + end end - let(:resource) { Puppet::Type.type(:group).new(:name => 'mygroup', :provider => provider) } let(:provider) { described_class.new(:name => 'mygroup') } + let(:members) { nil } describe "#create" do it "should add -o when allowdupe is enabled and the group is being created" do - resource[:allowdupe] = :true - resource[:gid] = '555' + @resource[:allowdupe] = :true + @resource[:gid] = '555' # This is an unfortunate hack to prevent the parent class from # breaking when we execute everything in gpasswd instead of # returning the expected string to execute. @@ -30,7 +36,7 @@ describe "on system that feature system_groups", :if => described_class.system_groups? do it "should add -r when system is enabled and the group is being created" do - resource[:system] = :true + @resource[:system] = :true provider.expects(:execute).with('/bin/true', :custom_environment => {}, :failonfail => true, @@ -42,7 +48,7 @@ describe "on system that do not feature system_groups", :unless => described_class.system_groups? do it "should not add -r when system is enabled and the group is being created" do - resource[:system] = :true + @resource[:system] = :true provider.expects(:execute).with('/bin/true', :custom_environment => {}, :failonfail => true, @@ -53,75 +59,86 @@ end describe "when adding additional group members to a new group" do + let(:members) { ['test_one','test_two','test_three'] } + it "should pass all members individually as group add options to gpasswd" do provider.expects(:execute).with('/bin/true', :custom_environment => {}, :failonfail => true, :combine => true) provider.expects(:execute).with('/usr/sbin/groupadd mygroup', {:custom_environment => {}}) - resource[:members] = ['test_one','test_two','test_three'] - resource[:members].each do |member| + members.each do |member| provider.expects(:execute).with("/usr/bin/gpasswd -a #{member} mygroup", {:custom_environment => {}}) end + provider.create end end describe "when adding additional group members to an existing group with no members" do + let(:members) { ['test_one','test_two','test_three'] } + it "should add all new members" do Etc.stubs(:getgrnam).with('mygroup').returns( Struct::Group.new('mygroup','x','99999',[]) ) - resource[:members] = ['test_one','test_two','test_three'] - resource[:auth_membership] = :false - resource[:members].each do |member| + @resource[:auth_membership] = :false + members.each do |member| provider.expects(:execute).with("/usr/bin/gpasswd -a #{member} mygroup", {:custom_environment => {}}) end provider.create - provider.members=(resource[:members]) + + provider.members + provider.members=(@resource.property('members').should) end end describe "when adding additional group members to an existing group with members" do + let(:members) { ['test_one','test_two','test_three'] } + it "should add all new members and preserve all existing members" do old_members = ['old_one','old_two','old_three','test_three'] Etc.stubs(:getgrnam).with('mygroup').returns( Struct::Group.new('mygroup','x','99999',old_members) ) - resource[:auth_membership] = :false - resource[:members] = ['test_one','test_two','test_three'] - (resource[:members] | old_members).each do |member| + @resource[:auth_membership] = :false + (members | old_members).each do |member| provider.expects(:execute).with("/usr/bin/gpasswd -a #{member} mygroup", {:custom_environment => {}}) end provider.create - provider.members=(resource[:members]) + + provider.members + provider.members=(@resource.property('members').should) end end describe "when adding exclusive group members to an existing group with members" do + let(:members) { ['test_one','test_two','test_three'] } + it "should add all new members and delete all, non-matching, existing members" do old_members = ['old_one','old_two','old_three','test_three'] Etc.stubs(:getgrnam).with('mygroup').returns( Struct::Group.new('mygroup','x','99999',old_members) ) - resource[:auth_membership] = :true - resource[:members] = ['test_one','test_two','test_three'] + @resource[:auth_membership] = :true - (resource[:members] - old_members).each do |to_add| + (members - old_members).each do |to_add| provider.expects(:execute).with("/usr/bin/gpasswd -a #{to_add} mygroup", {:custom_environment => {}}) end - (old_members - resource[:members]).each do |to_del| + (old_members - members).each do |to_del| provider.expects(:execute).with("/usr/bin/gpasswd -d #{to_del} mygroup", {:custom_environment => {}}) end provider.create - provider.members=(resource[:members]) + + provider.members + provider.members=(@resource.property('members').should) end end end describe "#gid=" do it "should add -o when allowdupe is enabled and the gid is being modified" do - resource[:allowdupe] = :true + @resource[:allowdupe] = :true if Gem::Version.new(Puppet.version) >= Gem::Version.new('5.4.0') provider.expects(:execute).with(['/usr/sbin/groupmod', '-g', 150, '-o', 'mygroup'], {:failonfail => true, :combine => true, :custom_environment => {}}) else