Module: Awskeyring

Defined in:
lib/awskeyring.rb,
lib/awskeyring/input.rb,
lib/awskeyring/awsapi.rb,
lib/awskeyring/version.rb,
lib/awskeyring/validate.rb,
lib/awskeyring/credential_provider.rb

Overview

Awskeyring Module, gives you an interface to access keychains and items.

Defined Under Namespace

Modules: Awsapi, Input, Validate Classes: CredentialProvider

Constant Summary collapse

PREFS_FILE =

Default rpeferences fole path

(File.expand_path '~/.awskeyring').freeze
ROLE_PREFIX =

Prefix for Roles

'role '
ACCOUNT_PREFIX =

Prefix for Accounts

'account '
SESSION_KEY_PREFIX =

Prefix for Session Keys

'session-key '
SESSION_TOKEN_PREFIX =

Prefix for Session Tokens

'session-token '
FIVE_MINUTES =

Default keychain Lock period

300
DEFAULT_KEY_AGE =

Default warning of key age in days.

90
DEFAULT_CONSOLE_LIST =

Default Console Paths

%w[cloudformation ec2/v2 iam rds route53 s3 sns sqs vpc].freeze
DEFAULT_BROWSER_LIST =

Default Browsers

%w[Brave FireFox Opera Safari Vivaldi].freeze
VERSION =

The Gem’s version number

'1.13.0'
HOMEPAGE =

The Gem’s homepage

'https://github.com/tristanmorgan/awskeyring'
GEM_VERSION_URL =

RubyGems Version url

'https://rubygems.org/api/v1/versions/awskeyring/latest.json'

Class Method Summary collapse

Class Method Details

.access_key_not_exists(access_key) ⇒ Object

Validate access key does not exists

Parameters:

  • access_key (String)

    the associated access key.



364
365
366
367
368
369
# File 'lib/awskeyring.rb', line 364

def self.access_key_not_exists(access_key)
  Awskeyring::Validate.access_key(access_key)
  raise 'Access KEY already exists' if (access_key)

  access_key
end

.account_exists(account_name) ⇒ Object

Validate account exists

Parameters:

  • account_name (String)

    the associated account name.



344
345
346
347
348
349
# File 'lib/awskeyring.rb', line 344

def self.()
  Awskeyring::Validate.()
  raise 'Account does not exist' unless ( = solo_select(, ))

  
end

.account_not_exists(account_name) ⇒ Object

Validate account does not exists

Parameters:

  • account_name (String)

    the associated account name.



354
355
356
357
358
359
# File 'lib/awskeyring.rb', line 354

def self.()
  Awskeyring::Validate.()
  raise 'Account already exists' if .include?()

  
end

.add_account(account:, key:, secret:, mfa:) ⇒ Object

Add an account item

Parameters:

  • account (String)

    The account name to create

  • key (String)

    The aws_access_key_id

  • secret (String)

    The aws_secret_key

  • mfa (String)

    The arn of the MFA device



119
120
121
122
123
124
125
126
# File 'lib/awskeyring.rb', line 119

def self.(account:, key:, secret:, mfa:)
  all_items.create(
    label: ACCOUNT_PREFIX + ,
    account: key,
    password: secret,
    comment: mfa
  )
end

.add_role(role:, arn:) ⇒ Object

Add a Role item

Parameters:

  • role (String)

    The role name to add

  • arn (String)

    The arn of the role



144
145
146
147
148
149
150
151
# File 'lib/awskeyring.rb', line 144

def self.add_role(role:, arn:)
  all_items.create(
    label: ROLE_PREFIX + role,
    account: arn,
    password: '',
    comment: ''
  )
end

.add_token(params = {}) ⇒ Object

add a session token pair of items

Parameters:

  • params (Hash) (defaults to: {})

    including account The name of the accont key The aws_access_key_id secret The aws_secret_access_key token The aws_sesson_token expiry time of expiry role The role used



162
163
164
165
166
167
168
169
170
171
# File 'lib/awskeyring.rb', line 162

def self.add_token(params = {})
  all_items.create(label: SESSION_KEY_PREFIX + params[:account],
                   account: params[:key],
                   password: params[:secret],
                   comment: params[:role].nil? ? '' : ROLE_PREFIX + params[:role])
  all_items.create(label: SESSION_TOKEN_PREFIX + params[:account],
                   account: params[:expiry],
                   password: params[:token],
                   comment: params[:role] || '')
end

.delete_account(account:, message:) ⇒ Object

Delete an Account

Parameters:

  • account (String)

    The account to delete

  • message (String)

    The message to display



320
321
322
323
324
325
326
327
# File 'lib/awskeyring.rb', line 320

def self.(account:, message:)
  delete_token(account: , message: I18n.t('message.delexpired'))
  cred = get_item(account: )
  return unless cred

  puts message if message
  cred.delete
end

.delete_role(role_name:, message:) ⇒ Object

Delete a role

Parameters:

  • role_name (String)

    The role to delete

  • message (String)

    The message to display



333
334
335
336
337
338
339
# File 'lib/awskeyring.rb', line 333

def self.delete_role(role_name:, message:)
  role = get_role(role_name: role_name)
  return unless role

  puts message if message
  role.delete
end

.delete_token(account:, message:) ⇒ Object

Delete a session token

Parameters:

  • account (String)

    The account to delete a token for

  • message (String)

    The message to display



311
312
313
314
# File 'lib/awskeyring.rb', line 311

def self.delete_token(account:, message:)
  session_key, session_token = get_token_pair(account: )
  delete_pair(key: session_key, token: session_token, message: message)
end

.get_role_arn(role_name:) ⇒ Object

get the ARN for a role

Parameters:

  • role_name (String)

    The role name to retrieve



282
283
284
285
# File 'lib/awskeyring.rb', line 282

def self.get_role_arn(role_name:)
  role_item = get_role(role_name: role_name)
  role_item.attributes[:account] if role_item
end

.get_valid_creds(account:, no_token: false) ⇒ Object

Return valid creds for account

Parameters:

  • account (String)

    The account to retrieve

  • no_token (Boolean) (defaults to: false)

    Flag to skip tokens



264
265
266
267
268
269
270
271
272
273
274
275
276
277
# File 'lib/awskeyring.rb', line 264

def self.get_valid_creds(account:, no_token: false)
  cred, temp_cred = get_valid_item_pair(account: , no_token: no_token)
  token = temp_cred.password unless temp_cred.nil?
  expiry = temp_cred.attributes[:account].to_i unless temp_cred.nil?
  {
    account: ,
    expiry: expiry,
    key: cred.attributes[:account],
    mfa: no_token ? cred.attributes[:comment] : nil,
    secret: cred.password,
    token: token,
    updated: cred.attributes[:updated_at]
  }
end

.init_keychain(awskeyring:) ⇒ Object

Create a new Keychain

Parameters:

  • awskeyring (String)

    The keychain name to create



48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/awskeyring.rb', line 48

def self.init_keychain(awskeyring:)
  keychain = Keychain.create(awskeyring)
  keychain.lock_interval = FIVE_MINUTES
  keychain.lock_on_sleep = true

  prefs = {
    awskeyring: awskeyring,
    keyage: DEFAULT_KEY_AGE,
    browser: DEFAULT_BROWSER_LIST,
    console: DEFAULT_CONSOLE_LIST
  }
  File.new(Awskeyring::PREFS_FILE, 'w').write JSON.dump(prefs)
end

.key_ageObject

Return Key age warning number



238
239
240
# File 'lib/awskeyring.rb', line 238

def self.key_age
  prefs.key?('keyage') ? prefs['keyage'] : DEFAULT_KEY_AGE
end

.latest_versionObject

Retrieve the latest version from RubyGems



18
19
20
21
22
23
# File 'lib/awskeyring/version.rb', line 18

def self.latest_version
  uri       = URI(GEM_VERSION_URL)
  request   = Net::HTTP.new(uri.host, uri.port)
  request.use_ssl = true
  JSON.parse(request.get(uri).body)['version']
end

.list_account_namesObject

Return a list account item names



191
192
193
194
195
196
197
# File 'lib/awskeyring.rb', line 191

def self.
  items = list_items.map { |elem| elem.attributes[:label][(ACCOUNT_PREFIX.length)..] }

  tokens = list_tokens.map { |elem| elem.attributes[:label][(SESSION_KEY_PREFIX.length)..] }

  (items + tokens).uniq.sort
end

.list_account_names_plusObject

Return a list account item names plus account ids



200
201
202
203
204
205
206
207
208
209
210
# File 'lib/awskeyring.rb', line 200

def self. # rubocop:disable Metrics/AbcSize
  list_items.concat(list_tokens).map do |elem|
     = Awskeyring::Awsapi.(key: elem.attributes[:account])
     = if elem.attributes[:label].start_with?(ACCOUNT_PREFIX)
                     elem.attributes[:label][(ACCOUNT_PREFIX.length)..]
                   else
                     elem.attributes[:label][(SESSION_KEY_PREFIX.length)..]
                   end
    "#{}\t#{}"
  end.uniq.sort
end

.list_browsersObject

Return a list of browserss



233
234
235
# File 'lib/awskeyring.rb', line 233

def self.list_browsers
  prefs.key?('browser') ? prefs['browser'] : DEFAULT_BROWSER_LIST
end

.list_console_pathObject

Return a list of console paths



228
229
230
# File 'lib/awskeyring.rb', line 228

def self.list_console_path
  prefs.key?('console') ? prefs['console'] : DEFAULT_CONSOLE_LIST
end

.list_role_namesObject

Return a list role item names



213
214
215
# File 'lib/awskeyring.rb', line 213

def self.list_role_names
  list_roles.map { |elem| elem.attributes[:label][(ROLE_PREFIX.length)..] }.sort
end

.list_role_names_plusObject

Return a list role item names and arns



223
224
225
# File 'lib/awskeyring.rb', line 223

def self.list_role_names_plus
  list_roles.map { |elem| "#{elem.attributes[:label][(ROLE_PREFIX.length)..]}\t#{elem.attributes[:account]}" }
end

.list_token_namesObject

Return a list token item names



218
219
220
# File 'lib/awskeyring.rb', line 218

def self.list_token_names
  list_tokens.map { |elem| elem.attributes[:label][(SESSION_KEY_PREFIX.length)..] }.sort
end

.prefsHash

Retrieve the preferences

Returns:

  • (Hash)

    prefs of the gem



37
38
39
40
41
42
43
# File 'lib/awskeyring.rb', line 37

def self.prefs
  if File.exist? PREFS_FILE
    JSON.parse(File.read(PREFS_FILE))
  else
    {}
  end
end

.role_arn_not_exists(role_arn) ⇒ Object

Validate role arn not exists

Parameters:

  • role_arn (String)

    the associated role arn.



404
405
406
407
408
409
# File 'lib/awskeyring.rb', line 404

def self.role_arn_not_exists(role_arn)
  Awskeyring::Validate.role_arn(role_arn)
  raise 'Role ARN already exists' if (role_arn)

  role_arn
end

.role_exists(role_name) ⇒ Object

Validate role exists

Parameters:

  • role_name (String)

    the associated role name.



374
375
376
377
378
379
# File 'lib/awskeyring.rb', line 374

def self.role_exists(role_name)
  Awskeyring::Validate.role_name(role_name)
  raise 'Role does not exist' unless (role_name = solo_select(list_role_names, role_name))

  role_name
end

.role_not_exists(role_name) ⇒ Object

Validate role does not exists

Parameters:

  • role_name (String)

    the associated role name.



384
385
386
387
388
389
# File 'lib/awskeyring.rb', line 384

def self.role_not_exists(role_name)
  Awskeyring::Validate.role_name(role_name)
  raise 'Role already exists' if list_role_names.include?(role_name)

  role_name
end

.solo_select(list, prefix) ⇒ Object

return item that matches a prefix if only one.



103
104
105
106
107
108
109
110
111
# File 'lib/awskeyring.rb', line 103

def self.solo_select(list, prefix)
  return prefix if list.include?(prefix)

  list.select! { |elem| elem.start_with?(prefix) }

  return list.first if list.length == 1

  nil
end

.token_exists(token_name) ⇒ Object

Validate token exists

Parameters:

  • token_name (String)

    the associated account name.



394
395
396
397
398
399
# File 'lib/awskeyring.rb', line 394

def self.token_exists(token_name)
  Awskeyring::Validate.(token_name)
  raise 'Token does not exist' unless (token_name = solo_select(list_token_names, token_name))

  token_name
end

.update_account(account:, key:, secret:) ⇒ Object

update and account item

Parameters:

  • account (String)

    The account to update

  • key (String)

    The aws_access_key_id

  • secret (String)

    The aws_secret_key



133
134
135
136
137
138
# File 'lib/awskeyring.rb', line 133

def self.(account:, key:, secret:)
  item = get_item(account: )
  item.attributes[:account] = key
  item.password = secret
  item.save!
end