cookbooks/fb_users/spec/resource_spec.rb (373 lines of code) (raw):

# vim: syntax=ruby:expandtab:shiftwidth=2:softtabstop=2:tabstop=2 # # Copyright (c) 2016-present, Facebook, Inc. # All rights reserved. # # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require './spec/spec_helper' require_relative '../libraries/default' require_relative '../../fb_helpers/libraries/fb_helpers' # rubocop:disable Style/MultilineBlockChain recipe 'fb_users::default' do |tc| let(:node) { Chef::Node.new } let(:uid_map) do { 'existing' => { 'uid' => 42, }, 'new_basic' => { 'uid' => 99, 'system' => true, 'comment' => 'fakeuser for testing', }, 'simple' => { 'uid' => 88, }, 'complex' => { 'uid' => 77, 'system' => true, 'comment' => 'look a testuser', }, 'cleanup' => { 'uid' => 66, }, 'testuser' => { 'uid' => 55, }, } end let(:gid_map) do { 'existing' => { 'gid' => 4242, }, 'new_basic' => { 'gid' => 9999, 'system' => true, }, 'simple' => { 'gid' => 8888, }, 'complex' => { 'gid' => 7777, }, 'cleanup' => { 'gid' => 6666, }, 'testgroup' => { 'gid' => 5555, }, 'lazygroup' => { 'gid' => 5757, }, 'users' => { 'gid' => 100, 'system' => true, }, } end let(:mock_db_item) { { 'password' => 'w000t' } } let(:mock_fb_users_db) { { 'complex' => mock_db_item } } before(:example) do stub_const('FB::Users::UID_MAP', uid_map) stub_const('FB::Users::GID_MAP', gid_map) stub_data_bag('fb_users_auth').and_return(mock_fb_users_db) stub_data_bag_item('fb_users_auth', 'complex').and_return(mock_db_item) end context 'with user_defaults' do cached(:chef_run) do tc.chef_run(:step_into => ['fb_users']) do |node| node.automatic['etc']['passwd']['existing']['uid'] = 42 node.automatic['etc']['group']['existing']['gid'] = 4242 node.automatic['filesystem']['by_mountpoint'] = { '/home' => { 'fs_type' => 'nfs', }, '/var/localhome' => { 'fs_type' => 'foofs', }, } end.converge('fb_users::test', described_recipe) do |node| node.default['fb_users'] = { 'user_defaults' => { 'gid' => 'existing', 'manage_home' => false, 'shell' => '/usr/fakebin', }, 'users' => { 'existing' => { 'gid' => 'existing', 'shell' => '/bin/bash', 'action' => :add, }, 'new_basic' => { 'gid' => 'new_basic', 'manage_home' => true, 'action' => :add, }, 'simple' => { 'action' => :add, }, 'complex' => { 'gid' => 'complex', 'shell' => '/bin/myshell', 'home' => '/var/localhome/complex', 'homedir_group' => 'users', 'homedir_mode' => '0600', 'manage_home' => true, 'action' => :add, }, 'testuser' => { 'gid' => 'testgroup', 'home' => '/var/localhome/testuser', 'homedir_group' => 'users', 'manage_home' => false, 'password' => 'myfakepassword', 'shell' => '/bin/bash', 'action' => :add, 'notifies' => { 'test notif' => { 'resource' => 'file[test resource]', 'action' => 'create', }, }, }, 'cleanup' => { 'action' => :delete, }, }, 'groups' => { 'existing' => { 'members' => [], 'action' => :add, }, 'new_basic' => { 'members' => [], 'action' => :add, }, 'simple' => { 'members' => [], 'action' => :add, }, 'complex' => { 'members' => ['testuser'], 'action' => :add, }, 'lazygroup' => { 'members' => proc { ['testuser'] }, 'action' => :add, }, 'testgroup' => { 'members' => [], 'action' => :add, 'notifies' => { 'test notif' => { 'resource' => 'file[test resource]', 'action' => 'delete', }, }, }, 'cleanup' => { 'action' => :delete, }, }, } end end context 'manage user' do it 'creates the user with the values specified in UID_MAP' do expect(chef_run).to create_user('new_basic').with( :uid => 99, :gid => 9999, :home => '/home/new_basic', :manage_home => true, :shell => '/usr/fakebin', :system => true, :comment => 'fakeuser for testing', ) end it 'uses the user_defaults if no values were passed to the api' do expect(chef_run).to create_user('simple').with( :uid => 88, :gid => 4242, :home => '/home/simple', :manage_home => false, :shell => '/usr/fakebin', ) end it 'creates the user with the values provided to the api' do expect(chef_run).to create_user('testuser').with( :uid => 55, :gid => 5555, :shell => '/bin/bash', :home => '/var/localhome/testuser', :manage_home => false, :password => 'myfakepassword', ) end it 'uses the password from the databag if it exists' do expect(chef_run).to create_user('complex').with( :uid => 77, :gid => 7777, :shell => '/bin/myshell', :home => '/var/localhome/complex', :manage_home => true, :password => 'w000t', :comment => 'look a testuser', ) end it 'uses the homedir defaults if no values were passed to the api' do expect(chef_run).not_to create_directory('/home/existing') end it 'manages the users homedir' do expect(chef_run).to create_directory('/home/new_basic').with( :owner => 99, :group => 9999, ) end it 'manages the homedir with the homedir options passed to the api' do expect(chef_run).to create_directory('/var/localhome/complex').with( :owner => 77, :group => 100, :mode => '0600', ) end it 'does not manage homedir if manage_home is false' do expect(chef_run).not_to create_directory('/var/localhome/testuser') end # no need to test that the homedir is cleaned up, since the chef # user resource :delete action handles this for us if manage_home is true it 'deletes the user' do expect(chef_run).to remove_user('cleanup') end it 'notifies expected things' do expect(chef_run.user('testuser')).to notify('file[test resource]'). to(:create) end end context 'manage group' do it 'bootstraps missing groups' do expect(chef_run).to create_group('bootstrap new_basic').with( :group_name => 'new_basic', :gid => 9999, ) end it 'does not bootstrap groups that exist on system' do expect(chef_run).not_to create_group('bootstrap existing') end it 'does not bootstrap groups that will be deleted' do expect(chef_run).not_to create_group('bootstrap cleanup') end it 'creates the group with the values specified in GID_MAP' do expect(chef_run).to create_group('new_basic').with( :gid => 9999, :system => true, :members => [], :append => false, ) end it 'creates the group with the values provided to the api' do expect(chef_run).to create_group('simple').with( :gid => 8888, :members => [], :append => false, ) expect(chef_run).to create_group('complex').with( :gid => 7777, :members => ['testuser'], :append => false, ) expect(chef_run).to create_group('lazygroup').with( :gid => 5757, :members => ['testuser'], :append => false, ) end it 'deletes the group' do expect(chef_run).to remove_group('cleanup') end it 'notifies expected things' do expect(chef_run.group('testgroup')).to notify('file[test resource]'). to(:delete) end end end context 'with no user_defaults' do cached(:chef_run) do tc.chef_run(:step_into => ['fb_users']) do |node| node.automatic['etc']['passwd']['existing']['uid'] = 42 node.automatic['etc']['group']['existing']['gid'] = 4242 node.automatic['filesystem']['by_mountpoint'] = { '/home' => { 'fs_type' => 'nfs', }, '/var/localhome' => { 'fs_type' => 'foofs', }, } end.converge(described_recipe) do |node| node.default['fb_users']['users'] = { 'existing' => { 'gid' => 'existing', 'home' => '/var/localhome/existing', 'action' => :add, }, 'new_basic' => { 'action' => :add, }, 'simple' => { 'gid' => 'testgroup', 'home' => '/var/localhome/simple', 'manage_home' => true, 'action' => :add, }, 'testuser' => { 'gid' => 'testgroup', 'home' => '/home/testuser', 'manage_home' => false, 'action' => :add, }, } node.default['fb_users']['groups'] = { 'existing' => { 'members' => [], 'action' => :add, }, } end end context 'when manage_home is explicitly set' do it 'honors if manage_home is explicitly true' do expect(chef_run).to create_user('simple').with( :uid => 88, :gid => 5555, :home => '/var/localhome/simple', :manage_home => true, :shell => '/bin/bash', ) end it 'honors if manage_home is explicitly false' do expect(chef_run).to create_user('testuser').with( :uid => 55, :gid => 5555, :home => '/home/testuser', :manage_home => false, :shell => '/bin/bash', ) end end context 'manage_home not explicitly set' do it 'sets manage_home false for nfs/autofs mounts' do expect(chef_run).to create_user('new_basic').with( :uid => 99, :gid => 100, :home => '/home/new_basic', :manage_home => false, :shell => '/bin/bash', :system => true, :comment => 'fakeuser for testing', ) end it 'sets manage_home true for all other fstypes' do expect(chef_run).to create_user('existing').with( :uid => 42, :gid => 4242, :home => '/var/localhome/existing', :manage_home => true, :shell => '/bin/bash', ) end end end end # rubocop:enable Style/MultilineBlockChain