awskeyring 0.3.1 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 872f5a554d55d638f03155e0b3411bf3d96fb719
4
- data.tar.gz: 4cb3938b6a21b369372b933f541432861b7ee790
3
+ metadata.gz: 045e119cd7be746d03d7b12c73d804958cc5331b
4
+ data.tar.gz: 1e7bc87c08887ed8625a80d629d5822ca60a3d08
5
5
  SHA512:
6
- metadata.gz: def1b159bc413bc54dcb75161cb211e65d2eec1cecefe40bf7d5811eaa101594f05d8be24a50e18cab0c7751a1691fcebc1b6d979c8ec14f1b7ac79e9befceb9
7
- data.tar.gz: 1daafcf9f1c1451d08000645626675c0c4e7ea399bb1a7a0939872412857d75efd71a775426e22f4482c32f937ec937e8b8cf9fef33566c92ea360f8afc9bb25
6
+ metadata.gz: 92b6df41a05aef2d2c4246b86daad7a6fdc4c8092192e05341167e6b707663ca73d9babbcc8ef871644743d40b2e84207f985eb4cfc140296a8297c18afebe94
7
+ data.tar.gz: 4c32c86b6ed103a50e4218e1f6a258e0bbe29ddd79de7470a56b149567fa2a66ca5515540092714c57cde7c98987a211d7ac87dfed17c11c682039db92455728
data/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # Change Log
2
2
 
3
+ ## [v0.4.0](https://github.com/vibrato/awskeyring/tree/v0.4.0) (2018-08-21)
4
+ [Full Changelog](https://github.com/vibrato/awskeyring/compare/v0.3.1...v0.4.0)
5
+
6
+ **Implemented enhancements:**
7
+
8
+ - I18n - Internationalisation [\#26](https://github.com/vibrato/awskeyring/pull/26) ([tristanmorgan](https://github.com/tristanmorgan))
9
+ - Adds no token flag to skip saved token [\#25](https://github.com/vibrato/awskeyring/pull/25) ([tristanmorgan](https://github.com/tristanmorgan))
10
+
3
11
  ## [v0.3.1](https://github.com/vibrato/awskeyring/tree/v0.3.1) (2018-07-25)
4
12
  [Full Changelog](https://github.com/vibrato/awskeyring/compare/v0.3.0...v0.3.1)
5
13
 
data/README.md CHANGED
@@ -72,9 +72,13 @@ and autocomplete that can be installed with:
72
72
 
73
73
  $ complete -C /usr/local/bin/awskeyring awskeyring
74
74
 
75
+ There are also short forms of most commands if you prefer:
76
+
77
+ $ awskeyring ls
78
+
75
79
  To set your environment easily the following bash function helps:
76
80
 
77
- awsenv() { eval "$(awskeyring env $1)"; }
81
+ awsenv() { eval "$(awskeyring env $@)"; }
78
82
 
79
83
  ## Development
80
84
 
data/awskeyring.gemspec CHANGED
@@ -20,6 +20,7 @@ Gem::Specification.new do |spec|
20
20
 
21
21
  spec.add_dependency('aws-sdk-iam')
22
22
  spec.add_dependency('highline')
23
+ spec.add_dependency('i18n')
23
24
  spec.add_dependency('ruby-keychain')
24
25
  spec.add_dependency('thor')
25
26
 
data/i18n/en.yml ADDED
@@ -0,0 +1,82 @@
1
+ ---
2
+ en:
3
+ __version:
4
+ desc: Prints the version
5
+ add:
6
+ desc: Adds an ACCOUNT to the keyring
7
+ add_role:
8
+ desc: Adds a ROLE to the keyring
9
+ awskeyring:
10
+ desc: Autocompletion for bourne shells
11
+ console:
12
+ desc: Open the AWS Console for the ACCOUNT
13
+ env:
14
+ desc: Outputs bourne shell environment exports for an ACCOUNT
15
+ exec:
16
+ desc: Execute a COMMAND with the environment set for an ACCOUNT
17
+ initialise:
18
+ desc: Initialises a new KEYCHAIN
19
+ json:
20
+ desc: Outputs AWS CLI compatible JSON for an ACCOUNT
21
+ list:
22
+ desc: Prints a list of accounts in the keyring
23
+ list_role:
24
+ desc: Prints a list of roles in the keyring
25
+ remove:
26
+ desc: Removes an ACCOUNT from the keyring
27
+ remove_role:
28
+ desc: Removes a ROLE from the keyring
29
+ remove_token:
30
+ desc: Removes a token for ACCOUNT from the keyring
31
+ rotate:
32
+ desc: Rotate access keys for an ACCOUNT
33
+ token:
34
+ desc: Create an STS Token from a ROLE or an MFA code
35
+ method_option:
36
+ arn: 'AWS role arn.'
37
+ code: 'Virtual mfa CODE.'
38
+ duration: 'Session DURATION in seconds.'
39
+ key: 'AWS account key id.'
40
+ keychain: 'Name of KEYCHAIN to initialise.'
41
+ local: 'Only validate locally.'
42
+ mfa: 'AWS virtual mfa arn.'
43
+ notoken: 'Do not use saved token.'
44
+ path: 'The service PATH to open.'
45
+ role: 'The ROLE to assume.'
46
+ secret: 'AWS account secret.'
47
+ update: 'Update existing.'
48
+ message:
49
+ keychain: 'Name for new keychain (default: awskeyring)'
50
+ account: 'account name'
51
+ arn: 'role arn'
52
+ code: 'current mfa code'
53
+ key: 'access key id'
54
+ mfa: 'mfa arn'
55
+ secret: 'secret access key'
56
+ role: 'role name'
57
+ addaccount: "# Added account %{account}"
58
+ upaccount: "# Updated account %{account}"
59
+ addrole: "# Added role %{role}"
60
+ addtoken: |
61
+ # Token saved for account %{account}
62
+ # Authentication valid until %{time}
63
+ age_check: '# Creds for account %{account} are %{age} days old.'
64
+ awskeyring: "# enable autocomplete with 'complete -C %{path} %{bin}'"
65
+ delaccount: '# Removing account %{account}'
66
+ delrole: '# Removing role %{role}'
67
+ deltoken: '# Removing token for account %{account}'
68
+ delexpired: '# Removing expired session credentials'
69
+ missing: '# Config missing, run `%{bin} initialise` to recreate.'
70
+ rotate: '# You have two access keys for account %{account}'
71
+ temporary: '# Using temporary session credentials.'
72
+ timeout: '# It is STRONGLY recommended to set your keychain to lock in 5 minutes or less.'
73
+ initialise: '# %{file} exists. no need to initialise.'
74
+ notfound: '# Credential not found with name: %{account}'
75
+ newkeychain:
76
+ Creating a new Keychain, you will be prompted for a password for it.
77
+ addkeychain: >
78
+ Your keychain has been initialised. It will auto-lock after 5 minutes
79
+ and when sleeping. Use Keychain Access to adjust.
80
+
81
+ Add accounts to your %{keychain} keychain with:
82
+ %{exec_name} add
@@ -175,11 +175,11 @@ module Awskeyring
175
175
  # @return [String] key The aws_access_key_id
176
176
  # @return [String] secret The aws_secret_access_key
177
177
  # @return [String] account the associated account name.
178
- def self.rotate(account:, key:, secret:) # rubocop:disable Metrics/MethodLength
178
+ def self.rotate(account:, key:, secret:, key_message:) # rubocop:disable Metrics/MethodLength
179
179
  iam = Aws::IAM::Client.new(access_key_id: key, secret_access_key: secret)
180
180
 
181
181
  if iam.list_access_keys[:access_key_metadata].length > 1
182
- warn "You have two access keys for account #{account}"
182
+ warn key_message
183
183
  exit 1
184
184
  end
185
185
 
@@ -1,4 +1,4 @@
1
1
  module Awskeyring
2
2
  # The Gems version number
3
- VERSION = '0.3.1'.freeze
3
+ VERSION = '0.4.0'.freeze
4
4
  end
data/lib/awskeyring.rb CHANGED
@@ -46,14 +46,13 @@ module Awskeyring # rubocop:disable Metrics/ModuleLength
46
46
  # @return [Keychain] keychain ready for use.
47
47
  private_class_method def self.load_keychain
48
48
  unless File.exist?(Awskeyring::PREFS_FILE) && !prefs.empty?
49
- warn "Config missing, run `#{File.basename($PROGRAM_NAME)} initialise` to recreate."
49
+ warn I18n.t('message.missing', bin: File.basename($PROGRAM_NAME))
50
50
  exit 1
51
51
  end
52
52
 
53
53
  keychain = Keychain.open(prefs['awskeyring'])
54
- if keychain && keychain.lock_interval > 300
55
- warn 'It is STRONGLY recommended to set your keychain to lock in 5 minutes or less.'
56
- end
54
+ warn I18n.t('message.timeout') if keychain && keychain.lock_interval > 300
55
+
57
56
  keychain
58
57
  end
59
58
 
@@ -151,21 +150,26 @@ module Awskeyring # rubocop:disable Metrics/ModuleLength
151
150
  session_key, session_token = delete_expired(key: session_key, token: session_token) if session_key
152
151
 
153
152
  if session_key && session_token
154
- puts '# Using temporary session credentials'
153
+ puts I18n.t('message.temporary')
155
154
  return session_key, session_token
156
155
  end
157
156
 
158
157
  item = get_item(account: account)
159
158
  if item.nil?
160
- warn "# Credential not found with name: #{account}"
159
+ warn I18n.t('message.notfound', account: account)
161
160
  exit 2
162
161
  end
163
162
  [item, nil]
164
163
  end
165
164
 
166
165
  # Return valid creds for account
167
- def self.get_valid_creds(account:)
168
- cred, temp_cred = get_valid_item_pair(account: account)
166
+ def self.get_valid_creds(account:, no_token: false)
167
+ if no_token
168
+ cred = get_item(account: account)
169
+ temp_cred = nil
170
+ else
171
+ cred, temp_cred = get_valid_item_pair(account: account)
172
+ end
169
173
  token = temp_cred.password unless temp_cred.nil?
170
174
  expiry = temp_cred.attributes[:account].to_i unless temp_cred.nil?
171
175
  {
@@ -201,7 +205,7 @@ module Awskeyring # rubocop:disable Metrics/ModuleLength
201
205
  private_class_method def self.delete_expired(key:, token:)
202
206
  expires_at = Time.at(token.attributes[:account].to_i)
203
207
  if expires_at < Time.now
204
- delete_pair(key: key, token: token, message: '# Removing expired session credentials')
208
+ delete_pair(key: key, token: token, message: I18n.t('message.delexpired'))
205
209
  key = nil
206
210
  token = nil
207
211
  end
@@ -224,7 +228,7 @@ module Awskeyring # rubocop:disable Metrics/ModuleLength
224
228
 
225
229
  # Delete an Account
226
230
  def self.delete_account(account:, message:)
227
- delete_token(account: account, message: '# Removing expired session credentials')
231
+ delete_token(account: account, message: I18n.t('message.delexpired'))
228
232
  cred = get_item(account: account)
229
233
  return unless cred
230
234
  puts message if message
@@ -1,4 +1,5 @@
1
1
  require 'highline'
2
+ require 'i18n'
2
3
  require 'thor'
3
4
 
4
5
  require 'awskeyring'
@@ -8,6 +9,9 @@ require 'awskeyring/version'
8
9
 
9
10
  # AWSkeyring command line interface.
10
11
  class AwskeyringCommand < Thor # rubocop:disable Metrics/ClassLength
12
+ I18n.load_path = Dir.glob(File.join(File.realpath(__dir__), '..', 'i18n', '*.{yml,yaml}'))
13
+ I18n.backend.load_translations
14
+
11
15
  map %w[--version -v] => :__version
12
16
  map ['init'] => :initialise
13
17
  map ['con'] => :console
@@ -18,56 +22,53 @@ class AwskeyringCommand < Thor # rubocop:disable Metrics/ClassLength
18
22
  map ['rmt'] => :remove_token
19
23
  map ['rot'] => :rotate
20
24
 
21
- desc '--version, -v', 'Prints the version'
25
+ desc '--version, -v', I18n.t('__version.desc')
22
26
  # print the version number
23
27
  def __version
24
28
  puts Awskeyring::VERSION
25
29
  end
26
30
 
27
- desc 'initialise', 'Initialises a new KEYCHAIN'
28
- method_option :keychain, type: :string, aliases: '-n', desc: 'Name of KEYCHAIN to initialise.'
31
+ desc 'initialise', I18n.t('initialise.desc')
32
+ method_option :keychain, type: :string, aliases: '-n', desc: I18n.t('method_option.keychain')
29
33
  # initialise the keychain
30
34
  def initialise
31
35
  unless Awskeyring.prefs.empty?
32
- puts "#{Awskeyring::PREFS_FILE} exists. no need to initialise."
36
+ puts I18n.t('message.initialise', file: Awskeyring::PREFS_FILE)
33
37
  exit 1
34
38
  end
35
39
 
36
- keychain = ask_missing(existing: options[:keychain], message: "Name for new keychain (default: 'awskeyring')")
40
+ keychain = ask_missing(existing: options[:keychain], message: I18n.t('message.keychain'))
37
41
  keychain = 'awskeyring' if keychain.empty?
38
42
 
39
- puts 'Creating a new Keychain, you will be prompted for a password for it.'
43
+ puts I18n.t('message.newkeychain')
40
44
  Awskeyring.init_keychain(awskeyring: keychain)
41
45
 
42
46
  exec_name = File.basename($PROGRAM_NAME)
43
47
 
44
- puts 'Your keychain has been initialised. It will auto-lock after 5 minutes'
45
- puts 'and when sleeping. Use Keychain Access to adjust.'
46
- puts
47
- puts "Add accounts to your #{keychain} keychain with:"
48
- puts " #{exec_name} add"
48
+ puts I18n.t('message.addkeychain', keychain: keychain, exec_name: exec_name)
49
49
  end
50
50
 
51
- desc 'list', 'Prints a list of accounts in the keyring'
51
+ desc 'list', I18n.t('list.desc')
52
52
  # list the accounts
53
53
  def list
54
54
  puts Awskeyring.list_account_names.join("\n")
55
55
  end
56
56
 
57
57
  map 'list-role' => :list_role
58
- desc 'list-role', 'Prints a list of roles in the keyring'
58
+ desc 'list-role', I18n.t('list_role.desc')
59
59
  # List roles
60
60
  def list_role
61
61
  puts Awskeyring.list_role_names.join("\n")
62
62
  end
63
63
 
64
- desc 'env ACCOUNT', 'Outputs bourne shell environment exports for an ACCOUNT'
64
+ desc 'env ACCOUNT', I18n.t('env.desc')
65
+ method_option 'no-token', type: :boolean, aliases: '-n', desc: I18n.t('method_option.notoken'), default: false
65
66
  # Print Env vars
66
67
  def env(account = nil)
67
68
  account = ask_check(
68
- existing: account, message: 'account name', validator: Awskeyring::Validate.method(:account_name)
69
+ existing: account, message: I18n.t('message.account'), validator: Awskeyring::Validate.method(:account_name)
69
70
  )
70
- cred = Awskeyring.get_valid_creds(account: account)
71
+ cred = Awskeyring.get_valid_creds(account: account, no_token: options['no-token'])
71
72
  age_check(account, cred[:updated])
72
73
  put_env_string(
73
74
  account: cred[:account],
@@ -77,13 +78,14 @@ class AwskeyringCommand < Thor # rubocop:disable Metrics/ClassLength
77
78
  )
78
79
  end
79
80
 
80
- desc 'json ACCOUNT', 'Outputs AWS CLI compatible JSON for an ACCOUNT'
81
+ desc 'json ACCOUNT', I18n.t('json.desc')
82
+ method_option 'no-token', type: :boolean, aliases: '-n', desc: I18n.t('method_option.notoken'), default: false
81
83
  # Print JSON for use with credential_process
82
84
  def json(account = nil)
83
85
  account = ask_check(
84
- existing: account, message: 'account name', validator: Awskeyring::Validate.method(:account_name)
86
+ existing: account, message: I18n.t('message.account'), validator: Awskeyring::Validate.method(:account_name)
85
87
  )
86
- cred = Awskeyring.get_valid_creds(account: account)
88
+ cred = Awskeyring.get_valid_creds(account: account, no_token: options['no-token'])
87
89
  age_check(account, cred[:updated])
88
90
  expiry = Time.at(cred[:expiry]) unless cred[:expiry].nil?
89
91
  puts Awskeyring::Awsapi.get_cred_json(
@@ -94,10 +96,11 @@ class AwskeyringCommand < Thor # rubocop:disable Metrics/ClassLength
94
96
  )
95
97
  end
96
98
 
97
- desc 'exec ACCOUNT command...', 'Execute a COMMAND with the environment set for an ACCOUNT'
99
+ desc 'exec ACCOUNT command...', I18n.t('exec.desc')
100
+ method_option 'no-token', type: :boolean, aliases: '-n', desc: I18n.t('method_option.notoken'), default: false
98
101
  # execute an external command with env set
99
102
  def exec(account, *command)
100
- cred = Awskeyring.get_valid_creds(account: account)
103
+ cred = Awskeyring.get_valid_creds(account: account, no_token: options['no-token'])
101
104
  age_check(account, cred[:updated])
102
105
  env_vars = env_vars(
103
106
  account: cred[:account],
@@ -109,22 +112,22 @@ class AwskeyringCommand < Thor # rubocop:disable Metrics/ClassLength
109
112
  Process.wait pid
110
113
  end
111
114
 
112
- desc 'add ACCOUNT', 'Adds an ACCOUNT to the keyring'
113
- method_option :key, type: :string, aliases: '-k', desc: 'AWS account key id.'
114
- method_option :secret, type: :string, aliases: '-s', desc: 'AWS account secret.'
115
- method_option :mfa, type: :string, aliases: '-m', desc: 'AWS virtual mfa arn.'
116
- method_option :local, type: :boolean, aliases: '-l', desc: 'Only validate locally.', default: false
117
- method_option :update, type: :boolean, aliases: '-u', desc: 'Update existing.', default: false
115
+ desc 'add ACCOUNT', I18n.t('add.desc')
116
+ method_option :key, type: :string, aliases: '-k', desc: I18n.t('method_option.key')
117
+ method_option :secret, type: :string, aliases: '-s', desc: I18n.t('method_option.secret')
118
+ method_option :mfa, type: :string, aliases: '-m', desc: I18n.t('method_option.mfa')
119
+ method_option :local, type: :boolean, aliases: '-l', desc: I18n.t('method_option.local'), default: false
120
+ method_option :update, type: :boolean, aliases: '-u', desc: I18n.t('method_option.update'), default: false
118
121
  # Add an Account
119
122
  def add(account = nil) # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
120
123
  account = ask_check(
121
- existing: account, message: 'account name', validator: Awskeyring::Validate.method(:account_name)
124
+ existing: account, message: I18n.t('message.account'), validator: Awskeyring::Validate.method(:account_name)
122
125
  )
123
126
  key = ask_check(
124
- existing: options[:key], message: 'access key id', validator: Awskeyring::Validate.method(:access_key)
127
+ existing: options[:key], message: I18n.t('message.key'), validator: Awskeyring::Validate.method(:access_key)
125
128
  )
126
129
  secret = ask_check(
127
- existing: options[:secret], message: 'secret access key',
130
+ existing: options[:secret], message: I18n.t('message.secret'),
128
131
  secure: true, validator: Awskeyring::Validate.method(:secret_access_key)
129
132
  )
130
133
  if options[:update]
@@ -134,10 +137,11 @@ class AwskeyringCommand < Thor # rubocop:disable Metrics/ClassLength
134
137
  key: key,
135
138
  secret: secret
136
139
  )
137
- puts "# Updated account #{account}"
140
+ puts I18n.t('message.upaccount', account: account)
138
141
  else
139
142
  mfa = ask_check(
140
- existing: options[:mfa], message: 'mfa arn', optional: true, validator: Awskeyring::Validate.method(:mfa_arn)
143
+ existing: options[:mfa], message: I18n.t('message.mfa'),
144
+ optional: true, validator: Awskeyring::Validate.method(:mfa_arn)
141
145
  )
142
146
  Awskeyring::Awsapi.verify_cred(key: key, secret: secret) unless options[:local]
143
147
  Awskeyring.add_account(
@@ -146,19 +150,26 @@ class AwskeyringCommand < Thor # rubocop:disable Metrics/ClassLength
146
150
  secret: secret,
147
151
  mfa: mfa
148
152
  )
149
- puts "# Added account #{account}"
153
+ puts I18n.t('message.addaccount', account: account)
150
154
  end
151
155
  end
152
156
 
153
157
  map 'add-role' => :add_role
154
- desc 'add-role ROLE', 'Adds a ROLE to the keyring'
155
- method_option :arn, type: :string, aliases: '-a', desc: 'AWS role arn.'
158
+ desc 'add-role ROLE', I18n.t('add_role.desc')
159
+ method_option :arn, type: :string, aliases: '-a', desc: I18n.t('method_option.arn')
156
160
  # Add a role
157
- def add_role(role = nil)
158
- role = ask_check(existing: role, message: 'role name', validator: Awskeyring::Validate.method(:role_name))
159
- arn = ask_check(existing: options[:arn], message: 'role arn', validator: Awskeyring::Validate.method(:role_arn))
161
+ def add_role(role = nil) # rubocop:disable Metrics/MethodLength
162
+ role = ask_check(
163
+ existing: role, message: I18n.t('message.role'),
164
+ validator: Awskeyring::Validate.method(:role_name)
165
+ )
166
+ arn = ask_check(
167
+ existing: options[:arn], message: I18n.t('message.arn'),
168
+ validator: Awskeyring::Validate.method(:role_arn)
169
+ )
160
170
  account = ask_check(
161
- existing: account, message: 'account', optional: true, validator: Awskeyring::Validate.method(:account_name)
171
+ existing: account, message: I18n.t('message.account'),
172
+ optional: true, validator: Awskeyring::Validate.method(:account_name)
162
173
  )
163
174
 
164
175
  Awskeyring.add_role(
@@ -166,40 +177,42 @@ class AwskeyringCommand < Thor # rubocop:disable Metrics/ClassLength
166
177
  arn: arn,
167
178
  account: account
168
179
  )
169
- puts "# Added role #{role}"
180
+ puts I18n.t('message.addrole', role: role)
170
181
  end
171
182
 
172
- desc 'remove ACCOUNT', 'Removes an ACCOUNT from the keyring'
183
+ desc 'remove ACCOUNT', I18n.t('remove.desc')
173
184
  # Remove an account
174
185
  def remove(account = nil)
175
186
  account = ask_check(
176
- existing: account, message: 'account name', validator: Awskeyring::Validate.method(:account_name)
187
+ existing: account, message: I18n.t('message.account'), validator: Awskeyring::Validate.method(:account_name)
177
188
  )
178
- Awskeyring.delete_account(account: account, message: "# Removing account #{account}")
189
+ Awskeyring.delete_account(account: account, message: I18n.t('message.delaccount', account: account))
179
190
  end
180
191
 
181
- desc 'remove-token ACCOUNT', 'Removes a token for ACCOUNT from the keyring'
192
+ desc 'remove-token ACCOUNT', I18n.t('remove_token.desc')
182
193
  # remove a session token
183
194
  def remove_token(account = nil)
184
195
  account = ask_check(
185
- existing: account, message: 'account name', validator: Awskeyring::Validate.method(:account_name)
196
+ existing: account, message: I18n.t('message.account'), validator: Awskeyring::Validate.method(:account_name)
186
197
  )
187
- Awskeyring.delete_token(account: account, message: "# Removing token for account #{account}")
198
+ Awskeyring.delete_token(account: account, message: I18n.t('message.deltoken', account: account))
188
199
  end
189
200
 
190
201
  map 'remove-role' => :remove_role
191
- desc 'remove-role ROLE', 'Removes a ROLE from the keyring'
202
+ desc 'remove-role ROLE', I18n.t('remove_role.desc')
192
203
  # remove a role
193
204
  def remove_role(role = nil)
194
- role = ask_check(existing: role, message: 'role name', validator: Awskeyring::Validate.method(:role_name))
195
- Awskeyring.delete_role(role_name: role, message: "# Removing role #{role}")
205
+ role = ask_check(
206
+ existing: role, message: I18n.t('message.role'), validator: Awskeyring::Validate.method(:role_name)
207
+ )
208
+ Awskeyring.delete_role(role_name: role, message: I18n.t('message.delrole', role: role))
196
209
  end
197
210
 
198
- desc 'rotate ACCOUNT', 'Rotate access keys for an ACCOUNT'
211
+ desc 'rotate ACCOUNT', I18n.t('rotate.desc')
199
212
  # rotate Account keys
200
213
  def rotate(account = nil) # rubocop:disable Metrics/MethodLength
201
214
  account = ask_check(
202
- existing: account, message: 'account name', validator: Awskeyring::Validate.method(:account_name)
215
+ existing: account, message: I18n.t('message.account'), validator: Awskeyring::Validate.method(:account_name)
203
216
  )
204
217
  item_hash = Awskeyring.get_account_hash(account: account)
205
218
 
@@ -207,7 +220,8 @@ class AwskeyringCommand < Thor # rubocop:disable Metrics/ClassLength
207
220
  new_key = Awskeyring::Awsapi.rotate(
208
221
  account: item_hash[:account],
209
222
  key: item_hash[:key],
210
- secret: item_hash[:secret]
223
+ secret: item_hash[:secret],
224
+ key_message: I18n.t('message.rotate', account: account)
211
225
  )
212
226
  rescue Aws::Errors::ServiceError => err
213
227
  warn err.to_s
@@ -220,28 +234,28 @@ class AwskeyringCommand < Thor # rubocop:disable Metrics/ClassLength
220
234
  secret: new_key[:secret]
221
235
  )
222
236
 
223
- puts "# Updated account #{account}"
237
+ puts I18n.t('message.upaccount', account: account)
224
238
  end
225
239
 
226
- desc 'token ACCOUNT [ROLE] [MFA]', 'Create an STS Token from a ROLE or an MFA code'
227
- method_option :role, type: :string, aliases: '-r', desc: 'The ROLE to assume.'
228
- method_option :code, type: :string, aliases: '-c', desc: 'Virtual mfa CODE.'
229
- method_option :duration, type: :string, aliases: '-d', desc: 'Session DURATION in seconds.'
240
+ desc 'token ACCOUNT [ROLE] [MFA]', I18n.t('token.desc')
241
+ method_option :role, type: :string, aliases: '-r', desc: I18n.t('method_option.role')
242
+ method_option :code, type: :string, aliases: '-c', desc: I18n.t('method_option.code')
243
+ method_option :duration, type: :string, aliases: '-d', desc: I18n.t('method_option.duration')
230
244
  # generate a sessiopn token
231
245
  def token(account = nil, role = nil, code = nil) # rubocop:disable all
232
246
  account = ask_check(
233
- existing: account, message: 'account name', validator: Awskeyring::Validate.method(:account_name)
247
+ existing: account, message: I18n.t('message.account'), validator: Awskeyring::Validate.method(:account_name)
234
248
  )
235
249
  role ||= options[:role]
236
250
  if role
237
251
  role = ask_check(
238
- existing: role, message: 'role name', validator: Awskeyring::Validate.method(:role_name)
252
+ existing: role, message: I18n.t('message.role'), validator: Awskeyring::Validate.method(:role_name)
239
253
  )
240
254
  end
241
255
  code ||= options[:code]
242
256
  if code
243
257
  code = ask_check(
244
- existing: code, message: 'current mfa code', validator: Awskeyring::Validate.method(:mfa_code)
258
+ existing: code, message: I18n.t('message.code'), validator: Awskeyring::Validate.method(:mfa_code)
245
259
  )
246
260
  end
247
261
  duration = options[:duration]
@@ -278,18 +292,18 @@ class AwskeyringCommand < Thor # rubocop:disable Metrics/ClassLength
278
292
  role: role
279
293
  )
280
294
 
281
- puts "# Token saved for account #{account}"
282
- puts "# Authentication valid until #{Time.at(new_creds[:expiry].to_i)}"
295
+ puts I18n.t('message.addtoken', account: account, time: Time.at(new_creds[:expiry].to_i))
283
296
  end
284
297
 
285
- desc 'console ACCOUNT', 'Open the AWS Console for the ACCOUNT'
286
- method_option :path, type: :string, aliases: '-p', desc: 'The service PATH to open.'
298
+ desc 'console ACCOUNT', I18n.t('console.desc')
299
+ method_option :path, type: :string, aliases: '-p', desc: I18n.t('method_option.path')
300
+ method_option 'no-token', type: :boolean, aliases: '-n', desc: I18n.t('method_option.notoken'), default: false
287
301
  # Open the AWS Console
288
- def console(account = nil) # rubocop:disable Metrics/MethodLength
302
+ def console(account = nil) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
289
303
  account = ask_check(
290
- existing: account, message: 'account name', validator: Awskeyring::Validate.method(:account_name)
304
+ existing: account, message: I18n.t('message.account'), validator: Awskeyring::Validate.method(:account_name)
291
305
  )
292
- cred = Awskeyring.get_valid_creds(account: account)
306
+ cred = Awskeyring.get_valid_creds(account: account, no_token: options['no-token'])
293
307
  age_check(account, cred[:updated])
294
308
 
295
309
  path = options[:path] || 'console'
@@ -311,13 +325,13 @@ class AwskeyringCommand < Thor # rubocop:disable Metrics/ClassLength
311
325
  Process.wait pid
312
326
  end
313
327
 
314
- desc 'awskeyring CURR PREV', 'Autocompletion for bourne shells', hide: true
328
+ desc 'awskeyring CURR PREV', I18n.t('awskeyring.desc'), hide: true
315
329
  # autocomplete
316
330
  def awskeyring(curr, prev)
317
331
  comp_line = ENV['COMP_LINE']
318
332
  unless comp_line
319
333
  exec_name = File.basename($PROGRAM_NAME)
320
- warn "enable autocomplete with 'complete -C #{$PROGRAM_NAME} #{exec_name}'"
334
+ warn I18n.t('message.awskeyring', path: $PROGRAM_NAME, bin: exec_name)
321
335
  exit 1
322
336
  end
323
337
  comp_len = comp_line.split.index(prev)
@@ -337,13 +351,13 @@ class AwskeyringCommand < Thor # rubocop:disable Metrics/ClassLength
337
351
  def age_check(account, updated)
338
352
  maxage = Awskeyring.prefs[:keyage] || Awskeyring::DEFAULT_KEY_AGE
339
353
  age = (Time.new - updated).div Awskeyring::Awsapi::ONE_DAY
340
- warn "# Creds for account #{account} are #{age} days old." unless age < maxage
354
+ warn I18n.t('message.age_check', account: account, age: age) unless age < maxage
341
355
  end
342
356
 
343
357
  def print_auto_resp(curr, len)
344
358
  case len
345
359
  when 0
346
- puts list_commands.select { |elem| elem.start_with?(curr) }.join("\n")
360
+ puts list_commands.select { |elem| elem.start_with?(curr) }.sort.join("\n")
347
361
  when 1
348
362
  puts Awskeyring.list_account_names.select { |elem| elem.start_with?(curr) }.join("\n")
349
363
  when 2
@@ -354,7 +368,7 @@ class AwskeyringCommand < Thor # rubocop:disable Metrics/ClassLength
354
368
  end
355
369
 
356
370
  def list_commands
357
- self.class.all_commands.keys.map { |elem| elem.tr('_', '-') }
371
+ self.class.all_commands.keys.map { |elem| elem.tr('_', '-') }.reject { |elem| elem == 'awskeyring' }
358
372
  end
359
373
 
360
374
  def env_vars(account:, key:, secret:, token:)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: awskeyring
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.1
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tristan Morgan
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-07-25 00:00:00.000000000 Z
11
+ date: 2018-08-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: aws-sdk-iam
@@ -38,6 +38,20 @@ dependencies:
38
38
  - - ">="
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: i18n
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
41
55
  - !ruby/object:Gem::Dependency
42
56
  name: ruby-keychain
43
57
  requirement: !ruby/object:Gem::Requirement
@@ -156,6 +170,7 @@ files:
156
170
  - Rakefile
157
171
  - awskeyring.gemspec
158
172
  - exe/awskeyring
173
+ - i18n/en.yml
159
174
  - lib/awskeyring.rb
160
175
  - lib/awskeyring/awsapi.rb
161
176
  - lib/awskeyring/validate.rb