def update_users(users, agent_identity, new_policy)
      # Create cache of public keys from stored instance state
      # but there won't be any on initial launch
      public_keys_cache = {}
      if old_policy = InstanceState.login_policy
        public_keys_cache = old_policy.users.inject({}) do |keys, user|
          user.public_key_fingerprints ||= user.public_keys.map { |key| fingerprint(key, user.username) }
          user.public_keys.zip(user.public_key_fingerprints).each { |(k, f)| keys[f] = k if f }
          keys
        end
      end

      # See if there are any missing keys and if so, send a request to retrieve them
      # Then make one more pass to populate any missing keys and reject any that are still not populated
      unless (missing = populate_public_keys(users, public_keys_cache)).empty?
        payload = {:agent_identity => agent_identity, :public_key_fingerprints => missing.map { |(u, f)| f }}
        request = RightScale::RetryableRequest.new("/key_server/retrieve_public_keys", payload)

        request.callback do |public_keys|
          if public_keys
            missing = populate_public_keys(users, public_keys, remove_if_missing = true)
            finalize_policy(new_policy, agent_identity, users, missing.map { |(u, f)| u }.uniq) do |audit_content|
              yield audit_content
            end
          end
        end

        request.errback do |error|
          Log.error("Failed to retrieve public keys for users #{missing.map { |(u, f)| u.username }.uniq.inspect} (#{error})")
          missing = populate_public_keys(users, {}, remove_if_missing = true)
          finalize_policy(new_policy, agent_identity, users, missing.map { |(u, f)| u }.uniq) do |audit_content|
            yield audit_content
          end
        end

        request.run
      else
        finalize_policy(new_policy, agent_identity, users, missing.map { |(u, f)| u }.uniq) do |audit_content|
          yield audit_content
        end
      end

      true
    end
def update_users(users, agent_identity, new_policy)
      # Create cache of public keys from stored instance state
      # but there won't be any on initial launch
      public_keys_cache = {}
      if old_policy = InstanceState.login_policy
        public_keys_cache = old_policy.users.inject({}) do |keys, user|
          user.public_key_fingerprints ||= user.public_keys.map { |key| fingerprint(key, user.username) }
          user.public_keys.zip(user.public_key_fingerprints).each { |(k, f)| keys[f] = k if f }
          keys
        end
      end

      # See if there are any missing keys and if so, send a request to retrieve them
      # Then make one more pass to populate any missing keys and reject any that are still not populated
      unless (missing = populate_public_keys(users, public_keys_cache)).empty?
        payload = {:agent_identity => agent_identity, :public_key_fingerprints => missing.map { |(u, f)| f }}
        request = RightScale::RetryableRequest.new("/key_server/retrieve_public_keys", payload)

        request.callback do |public_keys|
          if public_keys
            missing = populate_public_keys(users, public_keys, remove_if_missing = true)
            finalize_policy(new_policy, agent_identity, users, missing.map { |(u, f)| u }.uniq) do |audit_content|
              yield audit_content
            end
          end
        end

        request.errback do |error|
          Log.error("Failed to retrieve public keys for users #{missing.map { |(u, f)| u.username }.uniq.inspect} (#{error})")
          missing = populate_public_keys(users, {}, remove_if_missing = true)
          finalize_policy(new_policy, agent_identity, users, missing.map { |(u, f)| u }.uniq) do |audit_content|
            yield audit_content
          end
        end

        request.run
      else
        finalize_policy(new_policy, agent_identity, users, missing.map { |(u, f)| u }.uniq) do |audit_content|
          yield audit_content
        end
      end

      true
    end
For any user with a public key fingerprint but no public key, obtain the public key
 from the old policy or by querying RightScale using the fingerprints
 Remove a user if no public keys are available for it

 == Parameters:
 @param [Array<LoginUsers>] Login users whose public keys are to be populated
 @param [String] Serialized instance agent identity
 @param [RightScale::LoginPolicy] New login policy

 == Yields:
 @yield [String] audit content yielded to the block provided

 == Returns:
 @return [TrueClass] always returns true