cookbooks/fb_users/libraries/default.rb (117 lines of code) (raw):

# # Copyright (c) 2019-present, Vicarious, Inc. # Copyright (c) 2020-present, Facebook, Inc. # All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # 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. # module FB class Users # To be called at runtime only. def self._validate(node) # if they're not using the API to add users or groups, then # don't fail on them not defining UID_MAP and GID_MAP if node['fb_users']['users'].empty? && node['fb_users']['groups'].empty? return end uids = {} UID_MAP.each do |user, info| if uids[info['uid']] fail "fb_users[user]: User #{user} in UID map has a UID conflict" end if defined?(RESERVED_UID_RANGES) RESERVED_UID_RANGES.each do |identifier, range| if range.include?(info['uid']) fail "fb_users[user]: User #{user} in UID map is in the " + "reserved range for '#{identifier}'" end end end uids[info['uid']] = nil end gids = {} GID_MAP.each do |group, info| if gids[info['gid']] fail "fb_users[group]: group #{group} in GID map has a GID conflict" end if defined?(RESERVED_GID_RANGES) RESERVED_GID_RANGES.each do |identifier, range| if range.include?(info['gid']) fail "fb_users[group]: Group #{group} in GID map is in the " + "reserved range for '#{identifier}'" end end end uids[info['gid']] = nil end if node['fb_users']['user_defaults']['gid'] gid = node['fb_users']['user_defaults']['gid'] unless GID_MAP[gid] fail "fb_users[user]: Default group #{gid} has no GID in the " + 'GID_MAP - update, or unset it.' end end node['fb_users']['users'].each do |user, info| unless [nil, :add, :delete].include?(info['action']) fail "fb_users[users]: User #{user} has unknown action #{action}" end if info['action'] == :delete # Most keys are not allowed to be passed during remove operations # Keep in sync with the properties on the internal user resource allowed_remove_properties = %w{manage_home action} extra_keys = info.keys - allowed_remove_properties unless extra_keys.empty? fail "fb_users[user]: User #{user} has action :delete with " + "invalid keys: #{extra_keys}. Allowed keys are " + allowed_remove_properties.to_s end next end unless UID_MAP[user] fail "fb_users[user]: User #{user} has no UID in the UID_MAP" end if info['gid'] gid = info['gid'] unless GID_MAP[gid] fail "fb_users[user]: User #{user} has a group of #{gid} which " + 'is not in the GID_MAP' end gid_int = false # rubocop:disable Style/DoubleNegation # rubocop:disable Lint/HandleExceptions begin gid_int = !!Integer(gid) rescue ArgumentError # expected end # rubocop:enable Style/DoubleNegation # rubocop:enable Lint/HandleExceptions if gid_int fail "fb_users[user]: User #{user} has an integer for primary" + ' group. Please specify a name.' end elsif !node['fb_users']['user_defaults']['gid'] fail "fb_users[user]: User #{user} has no primary group (gid) " + 'and there is no default set.' end end node['fb_users']['groups'].each do |group, info| unless [nil, :add, :delete].include?(info['action']) fail "fb_users[group]: Group #{group} has unknown action #{action}" end if info['action'] == :delete if info.keys.count > 1 fail "fb_users[group]: Group #{group} has action :delete, but " + "also other keys: #{info}" end next end unless GID_MAP[group] fail "fb_users[group]: Group #{group} has no GID in the GID_MAP" end end end def self.gid_to_gname(gid) GID_MAP.select { |_, info| info['gid'] == gid }.keys.first end def self.uid_to_uname(uid) UID_MAP.select { |_, info| info['uid'] == uid }.keys.first end def self.initialize_group(node, group) if node['fb_users']['groups'][group] && node['fb_users']['groups'][group]['action'] != :delete Chef::Log.debug( "fb_users: Group #{group} already initialized, doing nothing", ) return end node.default['fb_users']['groups'][group] = { 'members' => [], 'action' => :add, } end end end