module Chef::Knife::AclBase
def add_to_acl!(member_type, member_name, object_type, object_name, perms)
def add_to_acl!(member_type, member_name, object_type, object_name, perms) acl = get_acl(object_type, object_name) perms.split(",").each do |perm| ui.msg "Adding '#{member_name}' to '#{perm}' ACE of '#{object_name}'" ace = acl[perm] case member_type when "client", "user" # Our PUT body depends on the type of reply we get from _acl?detail=granular # When the server replies with json attributes 'users' and 'clients', # we'll want to modify entries under the same keys they arrived.- their presence # in the body tells us that CS will accept them in a PUT. # Older version of chef-server will continue to use 'actors' for a combined list # and expect the same in the body. key = "#{member_type}s" key = "actors" unless ace.key? key next if ace[key].include?(member_name) ace[key] << member_name when "group" next if ace["groups"].include?(member_name) ace["groups"] << member_name end update_ace!(object_type, object_name, perm, ace) end end
def add_to_group!(member_type, member_name, group_name)
def add_to_group!(member_type, member_name, group_name) validate_member_exists!(member_type, member_name) existing_group = rest.get_rest("groups/#{group_name}") ui.msg "Adding '#{member_name}' to '#{group_name}' group" unless existing_group["#{member_type}s"].include?(member_name) existing_group["#{member_type}s"] << member_name new_group = { "groupname" => existing_group["groupname"], "orgname" => existing_group["orgname"], "actors" => { "users" => existing_group["users"], "clients" => existing_group["clients"], "groups" => existing_group["groups"], }, } rest.put_rest("groups/#{group_name}", new_group) end end
def get_ace(object_type, object_name, perm)
def get_ace(object_type, object_name, perm) get_acl(object_type, object_name)[perm] end
def get_acl(object_type, object_name)
def get_acl(object_type, object_name) rest.get_rest("#{object_type}/#{object_name}/_acl?detail=granular") end
def is_usag?(gname)
def is_usag?(gname) gname.length == 32 && gname =~ /^[0-9a-f]+$/ end
def remove_from_acl!(member_type, member_name, object_type, object_name, perms)
def remove_from_acl!(member_type, member_name, object_type, object_name, perms) acl = get_acl(object_type, object_name) perms.split(",").each do |perm| ui.msg "Removing '#{member_name}' from '#{perm}' ACE of '#{object_name}'" ace = acl[perm] case member_type when "client", "user" key = "#{member_type}s" key = "actors" unless ace.key? key next unless ace[key].include?(member_name) ace[key].delete(member_name) when "group" next unless ace["groups"].include?(member_name) ace["groups"].delete(member_name) end update_ace!(object_type, object_name, perm, ace) end end
def remove_from_group!(member_type, member_name, group_name)
def remove_from_group!(member_type, member_name, group_name) validate_member_exists!(member_type, member_name) existing_group = rest.get_rest("groups/#{group_name}") ui.msg "Removing '#{member_name}' from '#{group_name}' group" if existing_group["#{member_type}s"].include?(member_name) existing_group["#{member_type}s"].delete(member_name) new_group = { "groupname" => existing_group["groupname"], "orgname" => existing_group["orgname"], "actors" => { "users" => existing_group["users"], "clients" => existing_group["clients"], "groups" => existing_group["groups"], }, } rest.put_rest("groups/#{group_name}", new_group) end end
def update_ace!(object_type, object_name, ace_type, ace)
def update_ace!(object_type, object_name, ace_type, ace) rest.put_rest("#{object_type}/#{object_name}/_acl/#{ace_type}", ace_type => ace) end
def validate_member_exists!(member_type, member_name)
def validate_member_exists!(member_type, member_name) true if rest.get_rest("#{member_type}s/#{member_name}") rescue NameError # ignore "NameError: uninitialized constant Chef::ApiClient" when finding a client true rescue ui.fatal "#{member_type} '#{member_name}' does not exist" exit 1 end
def validate_member_name!(name)
def validate_member_name!(name) # Same rules apply to objects and members validate_object_name!(name) end
def validate_member_type!(type)
def validate_member_type!(type) unless MEMBER_TYPES.include?(type) ui.fatal "Unknown member type \"#{type}\". The following types are permitted: #{MEMBER_TYPES.join(", ")}" exit 1 end end
def validate_object_name!(name)
def validate_object_name!(name) unless OBJECT_NAME_SPEC.match(name) ui.fatal "Invalid name: #{name}" exit 1 end end
def validate_object_type!(type)
def validate_object_type!(type) unless OBJECT_TYPES.include?(type) ui.fatal "Unknown object type \"#{type}\". The following types are permitted: #{OBJECT_TYPES.join(", ")}" exit 1 end end
def validate_perm_type!(perms)
def validate_perm_type!(perms) perms.split(",").each do |perm| unless PERM_TYPES.include?(perm) ui.fatal "Invalid permission \"#{perm}\". The following permissions are permitted: #{PERM_TYPES.join(",")}" exit 1 end end end