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 +4 -4
- data/CHANGELOG.md +8 -0
- data/README.md +5 -1
- data/awskeyring.gemspec +1 -0
- data/i18n/en.yml +82 -0
- data/lib/awskeyring/awsapi.rb +2 -2
- data/lib/awskeyring/version.rb +1 -1
- data/lib/awskeyring.rb +14 -10
- data/lib/awskeyring_command.rb +86 -72
- metadata +17 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 045e119cd7be746d03d7b12c73d804958cc5331b
|
4
|
+
data.tar.gz: 1e7bc87c08887ed8625a80d629d5822ca60a3d08
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
81
|
+
awsenv() { eval "$(awskeyring env $@)"; }
|
78
82
|
|
79
83
|
## Development
|
80
84
|
|
data/awskeyring.gemspec
CHANGED
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
|
data/lib/awskeyring/awsapi.rb
CHANGED
@@ -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
|
182
|
+
warn key_message
|
183
183
|
exit 1
|
184
184
|
end
|
185
185
|
|
data/lib/awskeyring/version.rb
CHANGED
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
|
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
|
-
|
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 '
|
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
|
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
|
-
|
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: '
|
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: '
|
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
|
data/lib/awskeyring_command.rb
CHANGED
@@ -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', '
|
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', '
|
28
|
-
method_option :keychain, type: :string, aliases: '-n', desc: '
|
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
|
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:
|
40
|
+
keychain = ask_missing(existing: options[:keychain], message: I18n.t('message.keychain'))
|
37
41
|
keychain = 'awskeyring' if keychain.empty?
|
38
42
|
|
39
|
-
puts '
|
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 '
|
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', '
|
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', '
|
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', '
|
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
|
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', '
|
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
|
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...', '
|
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', '
|
113
|
-
method_option :key, type: :string, aliases: '-k', desc: '
|
114
|
-
method_option :secret, type: :string, aliases: '-s', desc: '
|
115
|
-
method_option :mfa, type: :string, aliases: '-m', desc: '
|
116
|
-
method_option :local, type: :boolean, aliases: '-l', desc: '
|
117
|
-
method_option :update, type: :boolean, aliases: '-u', desc: '
|
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
|
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: '
|
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
|
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
|
140
|
+
puts I18n.t('message.upaccount', account: account)
|
138
141
|
else
|
139
142
|
mfa = ask_check(
|
140
|
-
existing: options[:mfa], message: 'mfa
|
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
|
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', '
|
155
|
-
method_option :arn, type: :string, aliases: '-a', desc: '
|
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(
|
159
|
-
|
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',
|
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
|
180
|
+
puts I18n.t('message.addrole', role: role)
|
170
181
|
end
|
171
182
|
|
172
|
-
desc 'remove ACCOUNT', '
|
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
|
187
|
+
existing: account, message: I18n.t('message.account'), validator: Awskeyring::Validate.method(:account_name)
|
177
188
|
)
|
178
|
-
Awskeyring.delete_account(account: account, message:
|
189
|
+
Awskeyring.delete_account(account: account, message: I18n.t('message.delaccount', account: account))
|
179
190
|
end
|
180
191
|
|
181
|
-
desc 'remove-token ACCOUNT', '
|
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
|
196
|
+
existing: account, message: I18n.t('message.account'), validator: Awskeyring::Validate.method(:account_name)
|
186
197
|
)
|
187
|
-
Awskeyring.delete_token(account: account, message:
|
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', '
|
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(
|
195
|
-
|
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', '
|
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
|
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
|
237
|
+
puts I18n.t('message.upaccount', account: account)
|
224
238
|
end
|
225
239
|
|
226
|
-
desc 'token ACCOUNT [ROLE] [MFA]', '
|
227
|
-
method_option :role, type: :string, aliases: '-r', desc: '
|
228
|
-
method_option :code, type: :string, aliases: '-c', desc: '
|
229
|
-
method_option :duration, type: :string, aliases: '-d', desc: '
|
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
|
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
|
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: '
|
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
|
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', '
|
286
|
-
method_option :path, type: :string, aliases: '-p', desc: '
|
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
|
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', '
|
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
|
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
|
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.
|
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-
|
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
|