awskeyring 1.3.3 → 1.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 +1 -0
- data/Rakefile +9 -3
- data/i18n/en.yml +2 -0
- data/lib/awskeyring.rb +29 -11
- data/lib/awskeyring/awsapi.rb +23 -2
- data/lib/awskeyring/version.rb +1 -1
- data/lib/awskeyring_command.rb +44 -4
- data/man/awskeyring.5 +7 -1
- data/man/awskeyring.5.ronn +4 -0
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ae2606582cb2a9c079bf4ebcb6223570148954cf66fe9938c9b4d969c1312da6
|
4
|
+
data.tar.gz: d6b24f01901e6c3161e1874f9bd9d018f9b62e734d7d73f5ffaed78f0125ecb1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d7704820e908585b67575c319e03493512917a9e5ea5db9620040402c49fbcd6466448e108949bcf32ea2d2f782e2ee8bf7e3e1bdd4e4138cb6d462c2c603635
|
7
|
+
data.tar.gz: 667e7d6d0417cda0a79c1d81680469f1ba2c7a03630bd8e7269e03f137ad669155126a927eb39542b1e9e0b07ee0f408678bb603bc77900cc7db9ff60e702c6b
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,13 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## [v1.4.0](https://github.com/servian/awskeyring/tree/v1.4.0) (2020-06-19)
|
4
|
+
|
5
|
+
[Full Changelog](https://github.com/servian/awskeyring/compare/v1.3.3...v1.4.0)
|
6
|
+
|
7
|
+
**Implemented enhancements:**
|
8
|
+
|
9
|
+
- Import Keys and Tokens from shared credentials files. [\#65](https://github.com/servian/awskeyring/pull/65) ([tristanmorgan](https://github.com/tristanmorgan))
|
10
|
+
|
3
11
|
## [v1.3.3](https://github.com/servian/awskeyring/tree/v1.3.3) (2020-06-04)
|
4
12
|
|
5
13
|
[Full Changelog](https://github.com/servian/awskeyring/compare/v1.3.2...v1.3.3)
|
data/README.md
CHANGED
@@ -65,6 +65,7 @@ The CLI is using [Thor](http://whatisthor.com) with help provided interactively.
|
|
65
65
|
awskeyring env ACCOUNT # Outputs bourne shell environment exports for an ACCOUNT
|
66
66
|
awskeyring exec ACCOUNT command... # Execute a COMMAND with the environment set for an ACCOUNT
|
67
67
|
awskeyring help [COMMAND] # Describe available commands or one specific command
|
68
|
+
awskeyring import ACCOUNT # Import an ACCOUNT to the keyring from ~/.aws/credentials
|
68
69
|
awskeyring initialise # Initialises a new KEYCHAIN
|
69
70
|
awskeyring json ACCOUNT # Outputs AWS CLI compatible JSON for an ACCOUNT
|
70
71
|
awskeyring list # Prints a list of accounts in the keyring
|
data/Rakefile
CHANGED
@@ -22,12 +22,18 @@ RuboCop::RakeTask.new do |rubocop|
|
|
22
22
|
rubocop.requires << 'rubocop-rubycw'
|
23
23
|
end
|
24
24
|
|
25
|
-
RSpec
|
26
|
-
|
25
|
+
desc 'Run RSpec code examples'
|
26
|
+
task :spec do
|
27
|
+
puts 'Running RSpec...'
|
28
|
+
require 'rspec/core'
|
29
|
+
runner = RSpec::Core::Runner
|
30
|
+
xcode = runner.run(%w[--pattern spec/**{,/*/**}/*_spec.rb --order rand --format documentation --color])
|
31
|
+
abort 'RSpec failed' if xcode.positive?
|
27
32
|
end
|
28
33
|
|
29
34
|
desc 'Check filemode bits'
|
30
35
|
task :filemode do
|
36
|
+
puts 'Running FileMode...'
|
31
37
|
files = Set.new(`git ls-files -z`.split("\x0"))
|
32
38
|
dirs = Set.new(files.map { |file| File.dirname(file) })
|
33
39
|
failure = []
|
@@ -42,7 +48,7 @@ end
|
|
42
48
|
|
43
49
|
desc 'generate manpage'
|
44
50
|
task :ronn do
|
45
|
-
puts '
|
51
|
+
puts 'Running Ronn...'
|
46
52
|
roff_text = Ronn::Document.new('man/awskeyring.5.ronn').to_roff
|
47
53
|
File.write('man/awskeyring.5', roff_text)
|
48
54
|
puts "done\n\n"
|
data/i18n/en.yml
CHANGED
@@ -14,6 +14,8 @@ en:
|
|
14
14
|
desc: Outputs bourne shell environment exports for an ACCOUNT
|
15
15
|
exec:
|
16
16
|
desc: Execute a COMMAND with the environment set for an ACCOUNT
|
17
|
+
import:
|
18
|
+
desc: Import an ACCOUNT to the keyring from ~/.aws/credentials
|
17
19
|
initialise:
|
18
20
|
desc: Initialises a new KEYCHAIN
|
19
21
|
json:
|
data/lib/awskeyring.rb
CHANGED
@@ -72,18 +72,17 @@ module Awskeyring # rubocop:disable Metrics/ModuleLength
|
|
72
72
|
|
73
73
|
# Return a list of all acount items
|
74
74
|
private_class_method def self.list_items
|
75
|
-
|
76
|
-
elem_a.attributes[:label] <=> elem_b.attributes[:label]
|
77
|
-
end
|
78
|
-
items.select { |elem| elem.attributes[:label].start_with?(ACCOUNT_PREFIX) }
|
75
|
+
all_items.all.select { |elem| elem.attributes[:label].start_with?(ACCOUNT_PREFIX) }
|
79
76
|
end
|
80
77
|
|
81
78
|
# Return a list of all role items
|
82
79
|
private_class_method def self.list_roles
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
80
|
+
all_items.all.select { |elem| elem.attributes[:label].start_with?(ROLE_PREFIX) }
|
81
|
+
end
|
82
|
+
|
83
|
+
# Return a list of all acount items
|
84
|
+
private_class_method def self.list_tokens
|
85
|
+
all_items.all.select { |elem| elem.attributes[:label].start_with?(SESSION_KEY_PREFIX) }
|
87
86
|
end
|
88
87
|
|
89
88
|
# Return all keychain items
|
@@ -175,12 +174,21 @@ module Awskeyring # rubocop:disable Metrics/ModuleLength
|
|
175
174
|
|
176
175
|
# Return a list account item names
|
177
176
|
def self.list_account_names
|
178
|
-
list_items.map { |elem| elem.attributes[:label][(ACCOUNT_PREFIX.length)..-1] }
|
177
|
+
items = list_items.map { |elem| elem.attributes[:label][(ACCOUNT_PREFIX.length)..-1] }
|
178
|
+
|
179
|
+
tokens = list_tokens.map { |elem| elem.attributes[:label][(SESSION_KEY_PREFIX.length)..-1] }
|
180
|
+
|
181
|
+
(items + tokens).uniq.sort
|
179
182
|
end
|
180
183
|
|
181
184
|
# Return a list role item names
|
182
185
|
def self.list_role_names
|
183
|
-
list_roles.map { |elem| elem.attributes[:label][(ROLE_PREFIX.length)..-1] }
|
186
|
+
list_roles.map { |elem| elem.attributes[:label][(ROLE_PREFIX.length)..-1] }.sort
|
187
|
+
end
|
188
|
+
|
189
|
+
# Return a list token item names
|
190
|
+
def self.list_token_names
|
191
|
+
list_tokens.map { |elem| elem.attributes[:label][(SESSION_KEY_PREFIX.length)..-1] }.sort
|
184
192
|
end
|
185
193
|
|
186
194
|
# Return a list role item names and arns
|
@@ -246,7 +254,7 @@ module Awskeyring # rubocop:disable Metrics/ModuleLength
|
|
246
254
|
# Delete session token items if expired
|
247
255
|
private_class_method def self.delete_expired(key:, token:)
|
248
256
|
expires_at = Time.at(token.attributes[:account].to_i)
|
249
|
-
if expires_at < Time.
|
257
|
+
if expires_at < Time.new
|
250
258
|
delete_pair(key: key, token: token, message: I18n.t('message.delexpired'))
|
251
259
|
key = nil
|
252
260
|
token = nil
|
@@ -347,6 +355,16 @@ module Awskeyring # rubocop:disable Metrics/ModuleLength
|
|
347
355
|
role_name
|
348
356
|
end
|
349
357
|
|
358
|
+
# Validate token exists
|
359
|
+
#
|
360
|
+
# @param [String] token_name the associated account name.
|
361
|
+
def self.token_exists(token_name)
|
362
|
+
Awskeyring::Validate.account_name(token_name)
|
363
|
+
raise 'Token does not exist' unless list_token_names.include?(token_name)
|
364
|
+
|
365
|
+
token_name
|
366
|
+
end
|
367
|
+
|
350
368
|
# Validate role arn not exists
|
351
369
|
#
|
352
370
|
# @param [String] role_arn the associated role arn.
|
data/lib/awskeyring/awsapi.rb
CHANGED
@@ -141,10 +141,11 @@ module Awskeyring
|
|
141
141
|
#
|
142
142
|
# @param [String] key The aws_access_key_id
|
143
143
|
# @param [String] secret The aws_secret_access_key
|
144
|
-
|
144
|
+
# @param [String] token The aws_session_token
|
145
|
+
def self.verify_cred(key:, secret:, token:)
|
145
146
|
begin
|
146
147
|
ENV['AWS_DEFAULT_REGION'] = 'us-east-1' unless region
|
147
|
-
sts = Aws::STS::Client.new(access_key_id: key, secret_access_key: secret)
|
148
|
+
sts = Aws::STS::Client.new(access_key_id: key, secret_access_key: secret, session_token: token)
|
148
149
|
sts.get_caller_identity
|
149
150
|
rescue Aws::Errors::ServiceError => e
|
150
151
|
warn e.to_s
|
@@ -153,6 +154,26 @@ module Awskeyring
|
|
153
154
|
true
|
154
155
|
end
|
155
156
|
|
157
|
+
# Retrieve credentials from the AWS Credentials file
|
158
|
+
#
|
159
|
+
# @param [String] account the profile name wanted
|
160
|
+
# @return [Hash] with the new credentials
|
161
|
+
# key The aws_access_key_id
|
162
|
+
# secret The aws_secret_access_key
|
163
|
+
# token The aws_session_token
|
164
|
+
# expiry expiry time
|
165
|
+
def self.get_credentials_from_file(account:)
|
166
|
+
creds = Aws::SharedCredentials.new(profile_name: account)
|
167
|
+
{
|
168
|
+
account: account,
|
169
|
+
key: creds.credentials.access_key_id,
|
170
|
+
secret: creds.credentials.secret_access_key,
|
171
|
+
token: creds.credentials.session_token,
|
172
|
+
expiry: Time.new + TWELVE_HOUR,
|
173
|
+
role: nil
|
174
|
+
}
|
175
|
+
end
|
176
|
+
|
156
177
|
# Retrieves an AWS Console login url
|
157
178
|
#
|
158
179
|
# @param [String] key The aws_access_key_id
|
data/lib/awskeyring/version.rb
CHANGED
data/lib/awskeyring_command.rb
CHANGED
@@ -122,6 +122,42 @@ class AwskeyringCommand < Thor # rubocop:disable Metrics/ClassLength
|
|
122
122
|
)
|
123
123
|
end
|
124
124
|
|
125
|
+
desc 'import ACCOUNT', I18n.t('import.desc')
|
126
|
+
method_option 'no-remote', type: :boolean, aliases: '-r', desc: I18n.t('method_option.noremote'), default: false
|
127
|
+
# Import an Account
|
128
|
+
def import(account = nil) # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
|
129
|
+
account = ask_check(
|
130
|
+
existing: account, message: I18n.t('message.account'), validator: Awskeyring.method(:account_not_exists)
|
131
|
+
)
|
132
|
+
new_creds = Awskeyring::Awsapi.get_credentials_from_file(account: account)
|
133
|
+
unless options['no-remote']
|
134
|
+
Awskeyring::Awsapi.verify_cred(
|
135
|
+
key: new_creds[:key],
|
136
|
+
secret: new_creds[:secret],
|
137
|
+
token: new_creds[:token]
|
138
|
+
)
|
139
|
+
end
|
140
|
+
if new_creds[:token].nil?
|
141
|
+
Awskeyring.add_account(
|
142
|
+
account: new_creds[:account],
|
143
|
+
key: new_creds[:key],
|
144
|
+
secret: new_creds[:secret],
|
145
|
+
mfa: ''
|
146
|
+
)
|
147
|
+
puts I18n.t('message.addaccount', account: account)
|
148
|
+
else
|
149
|
+
Awskeyring.add_token(
|
150
|
+
account: new_creds[:account],
|
151
|
+
key: new_creds[:key],
|
152
|
+
secret: new_creds[:secret],
|
153
|
+
token: new_creds[:token],
|
154
|
+
expiry: new_creds[:expiry].to_i.to_s,
|
155
|
+
role: nil
|
156
|
+
)
|
157
|
+
puts I18n.t('message.addtoken', account: account, time: Time.at(new_creds[:expiry].to_i))
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
125
161
|
desc 'exec ACCOUNT command...', I18n.t('exec.desc')
|
126
162
|
method_option 'no-token', type: :boolean, aliases: '-n', desc: I18n.t('method_option.notoken'), default: false
|
127
163
|
# execute an external command with env set
|
@@ -163,7 +199,7 @@ class AwskeyringCommand < Thor # rubocop:disable Metrics/ClassLength
|
|
163
199
|
existing: options[:mfa], message: I18n.t('message.mfa'),
|
164
200
|
flags: 'optional', validator: Awskeyring::Validate.method(:mfa_arn)
|
165
201
|
)
|
166
|
-
Awskeyring::Awsapi.verify_cred(key: key, secret: secret) unless options['no-remote']
|
202
|
+
Awskeyring::Awsapi.verify_cred(key: key, secret: secret, token: nil) unless options['no-remote']
|
167
203
|
Awskeyring.add_account(
|
168
204
|
account: account,
|
169
205
|
key: key,
|
@@ -235,8 +271,8 @@ class AwskeyringCommand < Thor # rubocop:disable Metrics/ClassLength
|
|
235
271
|
# remove a session token
|
236
272
|
def remove_token(account = nil)
|
237
273
|
account = ask_check(
|
238
|
-
existing: account, message: I18n.t('message.account'), validator: Awskeyring.method(:
|
239
|
-
limited_to: Awskeyring.
|
274
|
+
existing: account, message: I18n.t('message.account'), validator: Awskeyring.method(:token_exists),
|
275
|
+
limited_to: Awskeyring.list_token_names
|
240
276
|
)
|
241
277
|
Awskeyring.delete_token(account: account, message: I18n.t('message.deltoken', account: account))
|
242
278
|
end
|
@@ -415,6 +451,8 @@ class AwskeyringCommand < Thor # rubocop:disable Metrics/ClassLength
|
|
415
451
|
comp_len = 2
|
416
452
|
when '--path', '-p'
|
417
453
|
comp_len = 4
|
454
|
+
when 'remove-token', 'rmt'
|
455
|
+
comp_len = 5
|
418
456
|
end
|
419
457
|
|
420
458
|
[curr, comp_len, sub_cmd]
|
@@ -430,7 +468,7 @@ class AwskeyringCommand < Thor # rubocop:disable Metrics/ClassLength
|
|
430
468
|
self.class.map[sub_cmd].to_s
|
431
469
|
end
|
432
470
|
|
433
|
-
def print_auto_resp(curr, len, sub_cmd)
|
471
|
+
def print_auto_resp(curr, len, sub_cmd) # rubocop:disable Metrics/MethodLength, Metrics/CyclomaticComplexity
|
434
472
|
list = []
|
435
473
|
case len
|
436
474
|
when 0
|
@@ -443,6 +481,8 @@ class AwskeyringCommand < Thor # rubocop:disable Metrics/ClassLength
|
|
443
481
|
list = list_arguments(command: sub_cmd)
|
444
482
|
when 4
|
445
483
|
list = Awskeyring.list_console_path
|
484
|
+
when 5
|
485
|
+
list = Awskeyring.list_token_names
|
446
486
|
else
|
447
487
|
exit 1
|
448
488
|
end
|
data/man/awskeyring.5
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
.\" generated with Ronn/v0.7.3
|
2
2
|
.\" http://github.com/rtomayko/ronn/tree/0.7.3
|
3
3
|
.
|
4
|
-
.TH "AWSKEYRING" "5" "
|
4
|
+
.TH "AWSKEYRING" "5" "June 2020" "" ""
|
5
5
|
.
|
6
6
|
.SH "NAME"
|
7
7
|
\fBAwskeyring\fR \- is a small tool to manage AWS account keys in the macOS Keychain
|
@@ -61,6 +61,12 @@ help [COMMAND]:
|
|
61
61
|
Describe available commands or one specific command
|
62
62
|
.
|
63
63
|
.TP
|
64
|
+
import:
|
65
|
+
.
|
66
|
+
.IP
|
67
|
+
Import an ACCOUNT to the keyring from ~/\.aws/credentials
|
68
|
+
.
|
69
|
+
.TP
|
64
70
|
initialise:
|
65
71
|
.
|
66
72
|
.IP
|
data/man/awskeyring.5.ronn
CHANGED
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: 1.
|
4
|
+
version: 1.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: 2020-06-
|
11
|
+
date: 2020-06-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: aws-sdk-iam
|
@@ -97,8 +97,8 @@ licenses:
|
|
97
97
|
metadata:
|
98
98
|
bug_tracker_uri: https://github.com/servian/awskeyring/issues
|
99
99
|
changelog_uri: https://github.com/servian/awskeyring/blob/master/CHANGELOG.md
|
100
|
-
documentation_uri: https://rubydoc.info/gems/awskeyring/1.
|
101
|
-
source_code_uri: https://github.com/servian/awskeyring/tree/v1.
|
100
|
+
documentation_uri: https://rubydoc.info/gems/awskeyring/1.4.0
|
101
|
+
source_code_uri: https://github.com/servian/awskeyring/tree/v1.4.0
|
102
102
|
wiki_uri: https://github.com/servian/awskeyring/wiki
|
103
103
|
post_install_message:
|
104
104
|
rdoc_options: []
|