awskeyring 0.3.1 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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