module Awskeyring::Awsapi
AWS API methods for Awskeyring
Constants
- ADMIN_POLICY
Admin policy as json
- AWS_ENV_VARS
AWS Env vars
- AWS_SIGNIN_URL
AWS Signin url
- ONE_DAY
Days in seconds
- ONE_HOUR
One hour in seconds
- TWELVE_HOUR
Twelve hours in seconds
Public Class Methods
Genarates AWS CLI compatible JSON see credential_process in AWS Docs
@param [String] key The aws_access_key_id @param [String] secret The aws_secret_access_key @param [String] token The aws_session_token @param [String] expiry expiry time @return [String] credential_process json
# File lib/awskeyring/awsapi.rb, line 108 def self.get_cred_json(key:, secret:, token:, expiry:) JSON.pretty_generate( Version: 1, AccessKeyId: key, SecretAccessKey: secret, SessionToken: token, Expiration: expiry ) end
Retrieve credentials from the AWS Credentials file
@param [String] account the profile name wanted @return [Hash] with the new credentials
key The aws_access_key_id secret The aws_secret_access_key token The aws_session_token expiry expiry time
# File lib/awskeyring/awsapi.rb, line 168 def self.get_credentials_from_file(account:) creds = Aws::SharedCredentials.new(profile_name: account) { account: account, key: creds.credentials.access_key_id, secret: creds.credentials.secret_access_key, token: creds.credentials.session_token, expiry: Time.new + TWELVE_HOUR, role: nil } end
Generates Environment Variables for the AWS CLI
@param [Hash] params including
[String] account The aws account name [String] key The aws_access_key_id [String] secret The aws_secret_access_key [String] token The aws_session_token
@return [Hash] env_var hash
# File lib/awskeyring/awsapi.rb, line 126 def self.get_env_array(params = {}) env_var = {} env_var['AWS_DEFAULT_REGION'] = 'us-east-1' unless region params[:expiration] = Time.at(params[:expiry]).iso8601 unless params[:expiry].nil? params.each_key do |param_name| AWS_ENV_VARS.each do |var_name| if var_name.include?(param_name.to_s.upcase) && !params[param_name].nil? env_var[var_name] = params[param_name] end end end env_var end
Retrieves an AWS Console login url
@param [String] key The aws_access_key_id @param [String] secret The aws_secret_access_key @param [String] token The aws_session_token @param [String] user The local username @param [String] path within the Console to access @return [String] login_url to access
# File lib/awskeyring/awsapi.rb, line 188 def self.get_login_url(key:, secret:, token:, path:, user:) console_url = "https://console.aws.amazon.com/#{path}/home" unless token cred = get_token({ key: key, secret: secret, user: user, duration: TWELVE_HOUR }) key = cred[:key] secret = cred[:secret] token = cred[:token] end session_json = { sessionId: key, sessionKey: secret, sessionToken: token }.to_json destination_param = "&Destination=#{CGI.escape(console_url)}" "#{AWS_SIGNIN_URL}?Action=login#{token_param(session_json: session_json)}#{destination_param}" end
Retrieves a temporary session token from AWS
@param [Hash] params including
key The aws_access_key_id secret The aws_secret_access_key user The local username mfa The users MFA arn code The MFA code duration time in seconds until expiry role_arn ARN of the role to assume
@return [Hash] with the new credentials
key The aws_access_key_id secret The aws_secret_access_key token The aws_session_token expiry expiry time
# File lib/awskeyring/awsapi.rb, line 59 def self.get_token(params = {}) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength ENV['AWS_DEFAULT_REGION'] = 'us-east-1' unless region sts = Aws::STS::Client.new(access_key_id: params[:key], secret_access_key: params[:secret]) params[:mfa] = nil unless params[:code] begin response = if params[:role_arn] sts.assume_role( duration_seconds: params[:duration].to_i, role_arn: params[:role_arn], role_session_name: params[:user], serial_number: params[:mfa], token_code: params[:code] ) elsif params[:code] sts.get_session_token( duration_seconds: params[:duration].to_i, serial_number: params[:mfa], token_code: params[:code] ) else sts.get_federation_token( name: params[:user], policy: ADMIN_POLICY, duration_seconds: params[:duration] ) end rescue Aws::STS::Errors::AccessDenied => e warn e.to_s exit 1 end { key: response.credentials[:access_key_id], secret: response.credentials[:secret_access_key], token: response.credentials[:session_token], expiry: response.credentials[:expiration] } end
Get the current region
@return [String] current configured region
# File lib/awskeyring/awsapi.rb, line 226 def self.region keys = %w[AWS_REGION AMAZON_REGION AWS_DEFAULT_REGION] region = ENV.values_at(*keys).compact.first region || Aws.shared_config.region(profile: 'default') end
Retry the call with backoff
@param [Block] block the block to retry.
# File lib/awskeyring/awsapi.rb, line 269 def self.retry_backoff(&block) retries ||= 1 begin yield block rescue Aws::IAM::Errors::InvalidClientTokenId => e if retries < 4 sleep 2**retries retries += 1 retry end warn e.message exit 1 end end
Rotates the AWS access keys
@param [String] key The aws_access_key_id @param [String] secret The aws_secret_access_key @param [String] account the associated account name. @return [String] key The aws_access_key_id @return [String] secret The aws_secret_access_key @return [String] account the associated account name.
# File lib/awskeyring/awsapi.rb, line 240 def self.rotate(account:, key:, secret:, key_message:) # rubocop:disable Metrics/MethodLength ENV['AWS_DEFAULT_REGION'] = 'us-east-1' unless region iam = Aws::IAM::Client.new(access_key_id: key, secret_access_key: secret) if iam.list_access_keys[:access_key_metadata].length > 1 warn key_message exit 1 end new_key = iam.create_access_key[:access_key] iam = Aws::IAM::Client.new( access_key_id: new_key[:access_key_id], secret_access_key: new_key[:secret_access_key] ) retry_backoff do iam.delete_access_key( access_key_id: key ) end { account: account, key: new_key[:access_key_id], secret: new_key[:secret_access_key] } end
Verify Credentials are active and valid
@param [String] key The aws_access_key_id @param [String] secret The aws_secret_access_key @param [String] token The aws_session_token
# File lib/awskeyring/awsapi.rb, line 148 def self.verify_cred(key:, secret:, token: nil) begin ENV['AWS_DEFAULT_REGION'] = 'us-east-1' unless region sts = Aws::STS::Client.new(access_key_id: key, secret_access_key: secret, session_token: token) sts.get_caller_identity rescue Aws::Errors::ServiceError => e warn e.to_s exit 1 end true end
Private Class Methods
Get the signin token param
# File lib/awskeyring/awsapi.rb, line 210 def self.token_param(session_json:) get_signin_token_url = AWS_SIGNIN_URL + '?Action=getSigninToken' \ '&Session=' + CGI.escape(session_json) uri = URI(get_signin_token_url) request = Net::HTTP.new(uri.host, uri.port) request.use_ssl = true returned_content = request.get(uri).body signin_token = JSON.parse(returned_content)['SigninToken'] "&SigninToken=#{CGI.escape(signin_token)}" end