aws-asmr 0.0.5 → 0.0.7
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/README.md +43 -13
- data/bin/asmr +16 -18
- data/bin/asmr-login +3 -8
- data/lib/aws/asmr/alias.rb +7 -1
- data/lib/aws/asmr/cache.rb +11 -5
- data/lib/aws/asmr/cli.rb +36 -9
- data/lib/aws/asmr/local.rb +79 -0
- data/lib/aws/asmr/options.rb +15 -21
- data/lib/aws/asmr/version.rb +1 -1
- data/lib/aws/asmr.rb +1 -0
- metadata +3 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 5f82db6a4f331d524f5c56dab14452abe7e6b727e4870990fec14410eb728cdd
|
|
4
|
+
data.tar.gz: 62c1380dbe38966db335122e19e285fb1b3c6d0b3ba960c1e9d3023312d689ba
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 5ce7c9d028f0e67023005ff923e663d1fa79ea32229656ace998ce56736251264644ca87e1f61615534097c633927b729a7fbaa2444e2652caaa285651ff8276
|
|
7
|
+
data.tar.gz: 0dd4c41871053793bece7cd69f82e8776f342137f2f927a07272023a39fd9e6badb13dfee37c2f308fc035ffbc5781b8972b1b1abb8efa2b175ef16272f6fc37
|
data/README.md
CHANGED
|
@@ -33,12 +33,14 @@ Of course you can set `AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY` respectively
|
|
|
33
33
|
AWS_ACCESS_KEY_ID=xxxx AWS_SECRET_ACCESS_KEY=yyyy asmr --name=arn:aws:iam::0000:role/AwesomeRole aws sts get-caller-identity
|
|
34
34
|
```
|
|
35
35
|
|
|
36
|
-
To specify ARN (or alias name of assumed role),
|
|
37
|
-
This is due to a development circumstance. This tool is supposed to run 2 commands. One is assume_role, and the other is subsequential(this is main though) command. To safely separate options for assume_role and subsequential commands, all components of the `asmr` args must be start with `-`. Curse my programming ability!
|
|
36
|
+
To specify ARN (or alias name of assumed role), set the `name` option in any of the usual forms. Option parsing stops at the first argument that is not an option (or at a literal `--`), and everything from there on is the subsequential command, including its own options such as `--filter`.
|
|
38
37
|
|
|
39
38
|
```
|
|
40
39
|
asmr --name=arn:aws:iam::0000:role/AwesomeRole
|
|
40
|
+
asmr --name arn:aws:iam::0000:role/AwesomeRole
|
|
41
41
|
asmr -narn:aws:iam::0000:role/AwesomeRole
|
|
42
|
+
asmr -n arn:aws:iam::0000:role/AwesomeRole
|
|
43
|
+
asmr -n arn:aws:iam::0000:role/AwesomeRole -- aws sts get-caller-identity
|
|
42
44
|
```
|
|
43
45
|
|
|
44
46
|
Of course you can set options for subsequential command.
|
|
@@ -47,10 +49,13 @@ Of course you can set options for subsequential command.
|
|
|
47
49
|
asmr --name=arn:aws:iam::0000:role/AwesomeRole aws ec2 describe-instances --filter '[{"Name":"instance-state-name","Values":["stopped"]}]'
|
|
48
50
|
```
|
|
49
51
|
|
|
50
|
-
|
|
52
|
+
When the subsequential command is given as several arguments, it is executed directly (no shell in between): each argument reaches the command exactly as your shell handed it to `asmr`, so quotes, spaces and `$` in arguments need no extra escaping. Note that your shell still interprets `|`, `&&` and redirects *before* `asmr` runs, so in `asmr aws s3 ls | grep foo` only `aws s3 ls` gets the credentials (which is usually what you want).
|
|
53
|
+
|
|
54
|
+
To run a whole pipeline as the assumed role, pass it as a single argument; a single argument is run through `sh`, so pipes, redirects and variable expansion work inside it.
|
|
51
55
|
|
|
52
56
|
```
|
|
53
57
|
asmr --name=arn:aws:iam::0000:role/AwesomeRole "aws sts get-caller-identity | grep Arn"
|
|
58
|
+
asmr --name=arn:aws:iam::0000:role/AwesomeRole 'echo $AWS_ACCESS_KEY_ID'
|
|
54
59
|
```
|
|
55
60
|
|
|
56
61
|
Without subsequential command, it just prints environment variables for assume_role.
|
|
@@ -95,6 +100,39 @@ Or you can specify alias name.
|
|
|
95
100
|
asmr --name=awesome-app-staging aws sts get-caller-identity
|
|
96
101
|
```
|
|
97
102
|
|
|
103
|
+
## Pin a role to a directory (`asmr local`)
|
|
104
|
+
|
|
105
|
+
Following the `rbenv local` convention, you can pin an alias (or a role ARN) to a directory. `asmr local NAME` writes the name to `.asmr` in the current directory; from then on, `asmr` and `asmr-login` run there **without `--name`** assume that role instead of asking you to choose one. The nearest `.asmr` in the current directory or any of its parents wins, so pinning a project root covers its subdirectories.
|
|
106
|
+
|
|
107
|
+
```
|
|
108
|
+
cd ~/src/awesome-app
|
|
109
|
+
asmr local awesome-app-staging # writes ./.asmr
|
|
110
|
+
asmr aws sts get-caller-identity # assumes awesome-app-staging, no prompt
|
|
111
|
+
asmr-login # opens the console as awesome-app-staging
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
`asmr local` refuses a name that is neither an alias defined in `~/.aws-asmr/alias` nor a role ARN, the same way rbenv refuses a version that is not installed. A pin whose alias was deleted later fails with a message pointing at the `.asmr` file.
|
|
115
|
+
|
|
116
|
+
```
|
|
117
|
+
asmr local # prints the name pinned in the current directory
|
|
118
|
+
asmr local --unset # removes ./.asmr
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
`--name` always takes precedence over the pin. Note that pinning is by directory, not by shell: entering a pinned directory silently switches the role, so be careful with production aliases (checking `asmr local` before a destructive command is cheap). Like `.ruby-version`, `.asmr` is yours to commit or ignore.
|
|
122
|
+
|
|
123
|
+
## Session duration
|
|
124
|
+
|
|
125
|
+
The lifetime of the temporary credentials (seconds, 900-43200) is set via the alias's optional `session_duration`. It is passed as `DurationSeconds` to `assume_role`, so a longer value means fewer MFA prompts: the cached credentials stay valid until they expire.
|
|
126
|
+
|
|
127
|
+
```
|
|
128
|
+
[my-awesome-project]
|
|
129
|
+
arn = arn:aws:iam::xxxx:role/AdminRole
|
|
130
|
+
profile = smcdk-prejp
|
|
131
|
+
session_duration = 43200
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
When omitted, the role's default (1 hour) applies. The value must not exceed the role's *Maximum session duration* in IAM, and it cannot exceed 1 hour when the credentials used to assume the role are themselves temporary (role chaining). When STS rejects it, `asmr` retries without `session_duration` and tells you so, **except** when an MFA code was just consumed: a TOTP code cannot be reused, so `asmr` fails with guidance instead of asking you for another code. A change to `session_duration` only takes effect after the currently cached credentials expire (or after `asmr --clear`).
|
|
135
|
+
|
|
98
136
|
## Web Login (AWS Management Console)
|
|
99
137
|
|
|
100
138
|
The companion command `asmr-login` opens the **AWS Management Console** in your browser as the assumed role, using the [AWS federation endpoint](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_enable-console-custom-url.html). This is handy when you want a *browser* session for a role you normally only use from the CLI.
|
|
@@ -120,14 +158,6 @@ Then `asmr-login --name=my-awesome-project` opens the console home of `ap-northe
|
|
|
120
158
|
|
|
121
159
|
### Session duration
|
|
122
160
|
|
|
123
|
-
The console session duration
|
|
124
|
-
|
|
125
|
-
```
|
|
126
|
-
[my-awesome-project]
|
|
127
|
-
arn = arn:aws:iam::xxxx:role/AdminRole
|
|
128
|
-
profile = smcdk-prejp
|
|
129
|
-
region = ap-northeast-1
|
|
130
|
-
session_duration = 3600
|
|
131
|
-
```
|
|
161
|
+
The console session duration is the alias's `session_duration` described above; it is sent as `SessionDuration` to the federation endpoint as well. When omitted, `asmr-login` requests 43200 (12h).
|
|
132
162
|
|
|
133
|
-
Note: the requested duration must be **less than the assumed role's maximum session duration** (1 hour by default). When the federation endpoint rejects it (e.g. the role's max is shorter, or you reached the role via role chaining), `asmr-login` automatically retries *without* it, falling back to the lifetime of the temporary credentials. To get a full 12-hour console session, raise the role's *Maximum session duration* in IAM
|
|
163
|
+
Note: the requested duration must be **less than the assumed role's maximum session duration** (1 hour by default). When the federation endpoint rejects it (e.g. the role's max is shorter, or you reached the role via role chaining), `asmr-login` automatically retries *without* it, falling back to the lifetime of the temporary credentials. To get a full 12-hour console session, raise the role's *Maximum session duration* in IAM and set `session_duration = 43200`.
|
data/bin/asmr
CHANGED
|
@@ -2,28 +2,26 @@
|
|
|
2
2
|
|
|
3
3
|
require "aws/asmr/cli"
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
# Runs command with the temporary credentials in its environment. The
|
|
6
|
+
# credentials never go through a shell command line, so they are not visible
|
|
7
|
+
# in `ps` output or shell history of the child.
|
|
8
|
+
#
|
|
9
|
+
# asmr # no command: print the variables
|
|
10
|
+
# asmr "aws sts get-caller-identity | grep Arn"
|
|
11
|
+
# # one argument: a shell command line, so pipes and redirects work
|
|
12
|
+
# asmr aws ec2 describe-instances --filter '[{"Name":"instance-state-name","Values":["stopped"]}]'
|
|
13
|
+
# # several arguments: executed directly, each argument passed verbatim
|
|
14
|
+
def run(cache, command)
|
|
6
15
|
if command.empty?
|
|
7
|
-
|
|
16
|
+
puts cache.shell_variables
|
|
8
17
|
else
|
|
9
|
-
|
|
10
|
-
# Ex: asmr "aws sts get-caller-identity | grep Arn"
|
|
11
|
-
command
|
|
12
|
-
else
|
|
13
|
-
# Ex: asmr aws ec2 describe-instances --filter '[{"Name":"instance-state-name","Values":["stopped"]}]'
|
|
14
|
-
command.map{|plain|
|
|
15
|
-
if plain.match?(/[\"\'\ ]/)
|
|
16
|
-
quoted = plain.gsub("'"){"\\'"}
|
|
17
|
-
"'#{quoted}'"
|
|
18
|
-
else
|
|
19
|
-
plain
|
|
20
|
-
end
|
|
21
|
-
}
|
|
22
|
-
end
|
|
23
|
-
exec([*shell_variables, *command].join(' '))
|
|
18
|
+
exec(cache.environment, *command)
|
|
24
19
|
end
|
|
20
|
+
rescue Errno::ENOENT
|
|
21
|
+
STDERR.puts "asmr: command not found: #{command.first}"
|
|
22
|
+
exit(127)
|
|
25
23
|
end
|
|
26
24
|
|
|
27
25
|
Aws::ASMR::CLI.main(ARGV) do |cache, command_args, _options|
|
|
28
|
-
run(
|
|
26
|
+
run(cache, command_args)
|
|
29
27
|
end
|
data/bin/asmr-login
CHANGED
|
@@ -2,16 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
require "aws/asmr/cli"
|
|
4
4
|
|
|
5
|
-
# Session duration is read from the alias only
|
|
6
|
-
#
|
|
7
|
-
def alias_session_duration(asmr_alias)
|
|
8
|
-
raw = asmr_alias&.session_duration
|
|
9
|
-
raw.to_i if raw && !raw.empty?
|
|
10
|
-
end
|
|
11
|
-
|
|
5
|
+
# Session duration is read from the alias only; nil lets WebLogin fall back to
|
|
6
|
+
# its default.
|
|
12
7
|
Aws::ASMR::CLI.main(ARGV) do |cache, _command_args, _options, asmr_alias|
|
|
13
8
|
args = { region: asmr_alias&.region }
|
|
14
|
-
duration =
|
|
9
|
+
duration = asmr_alias&.duration_seconds
|
|
15
10
|
args[:session_duration] = duration if duration
|
|
16
11
|
url = Aws::ASMR::WebLogin.signin_url(cache, **args)
|
|
17
12
|
Aws::ASMR::WebLogin.open_browser(url)
|
data/lib/aws/asmr/alias.rb
CHANGED
|
@@ -58,7 +58,13 @@ module Aws
|
|
|
58
58
|
end
|
|
59
59
|
|
|
60
60
|
def assume_role_args
|
|
61
|
-
{external_id: external_id, role_session_name: role_session_name}.compact
|
|
61
|
+
{external_id: external_id, role_session_name: role_session_name, duration_seconds: duration_seconds}.compact
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
# session_duration as an Integer, or nil when unset. Used both as
|
|
65
|
+
# DurationSeconds of assume_role and as SessionDuration of the console.
|
|
66
|
+
def duration_seconds
|
|
67
|
+
session_duration.to_i if session_duration && !session_duration.empty?
|
|
62
68
|
end
|
|
63
69
|
end
|
|
64
70
|
end
|
data/lib/aws/asmr/cache.rb
CHANGED
|
@@ -52,12 +52,18 @@ module Aws
|
|
|
52
52
|
end
|
|
53
53
|
end
|
|
54
54
|
|
|
55
|
-
|
|
55
|
+
# Environment for a process running as the assumed role, ready for
|
|
56
|
+
# Kernel#exec / Kernel#spawn.
|
|
57
|
+
def environment
|
|
56
58
|
{
|
|
57
|
-
AWS_ACCESS_KEY_ID
|
|
58
|
-
AWS_SECRET_ACCESS_KEY
|
|
59
|
-
AWS_SESSION_TOKEN
|
|
60
|
-
}
|
|
59
|
+
"AWS_ACCESS_KEY_ID" => access_key_id,
|
|
60
|
+
"AWS_SECRET_ACCESS_KEY" => secret_access_key,
|
|
61
|
+
"AWS_SESSION_TOKEN" => session_token,
|
|
62
|
+
}
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def shell_variables
|
|
66
|
+
environment.map{|k,v| "#{k}=#{v}"}
|
|
61
67
|
end
|
|
62
68
|
end
|
|
63
69
|
end
|
data/lib/aws/asmr/cli.rb
CHANGED
|
@@ -20,8 +20,8 @@ module Aws
|
|
|
20
20
|
# resolved alias is nil when an ARN was given directly. Top-level errors
|
|
21
21
|
# are reported here (with a backtrace under --verbose) and exit non-zero.
|
|
22
22
|
def main(argv)
|
|
23
|
-
|
|
24
|
-
|
|
23
|
+
options, command_args = Options.parse(argv)
|
|
24
|
+
Local.run(command_args.drop(1)) if command_args.first == "local"
|
|
25
25
|
|
|
26
26
|
if options[:version]
|
|
27
27
|
require "aws/asmr/version"
|
|
@@ -47,12 +47,13 @@ module Aws
|
|
|
47
47
|
end
|
|
48
48
|
end
|
|
49
49
|
|
|
50
|
-
# Resolves the role to assume (from --name/-n or an
|
|
51
|
-
# selection) and returns [cache, asmr_alias]: a Cache
|
|
52
|
-
# credentials (reusing a valid cache entry or performing
|
|
53
|
-
# MFA prompt), and the resolved Alias (nil when an ARN
|
|
50
|
+
# Resolves the role to assume (from --name/-n, the nearest .asmr pin, or an
|
|
51
|
+
# interactive alias selection) and returns [cache, asmr_alias]: a Cache
|
|
52
|
+
# holding temporary credentials (reusing a valid cache entry or performing
|
|
53
|
+
# assume_role with an MFA prompt), and the resolved Alias (nil when an ARN
|
|
54
|
+
# was given directly).
|
|
54
55
|
def resolve_credentials(options, prompt)
|
|
55
|
-
name = options[:name] || begin
|
|
56
|
+
name = options[:name] || pinned_name || begin
|
|
56
57
|
alias_keys = Alias.base.keys
|
|
57
58
|
if alias_keys.empty?
|
|
58
59
|
STDERR.puts "Please specify --name=ARN to assume_role or make alias at #{ROOT}/alias"
|
|
@@ -80,13 +81,39 @@ module Aws
|
|
|
80
81
|
assume_role_args = assume_role_args.merge(serial_number: serial_number, token_code: token_code)
|
|
81
82
|
end
|
|
82
83
|
|
|
83
|
-
res =
|
|
84
|
+
res = perform_assume_role(assume_role_arn, assume_role_args, mfa: !serial_number.nil?)
|
|
84
85
|
cache = Cache.new(**res.credentials.to_h)
|
|
85
86
|
cache.save!(assume_role_arn)
|
|
86
87
|
[cache, asmr_alias]
|
|
87
88
|
end
|
|
88
89
|
|
|
89
|
-
|
|
90
|
+
# Name pinned by the nearest .asmr (see Local), validated so that a stale
|
|
91
|
+
# pin fails with a clear message instead of an obscure assume_role error.
|
|
92
|
+
def pinned_name
|
|
93
|
+
name, file = Local.find
|
|
94
|
+
return nil unless name
|
|
95
|
+
Local.validate!(name, source: file)
|
|
96
|
+
name
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
# Calls assume_role. When DurationSeconds is rejected (the role's max
|
|
100
|
+
# session duration is shorter, or the source credentials are temporary so
|
|
101
|
+
# role chaining caps it at 1h), retries without it -- unless an MFA code
|
|
102
|
+
# was consumed, since a TOTP code cannot be reused; then it fails with
|
|
103
|
+
# guidance rather than asking for another code.
|
|
104
|
+
def perform_assume_role(arn, args, mfa:)
|
|
105
|
+
Aws::ASMR.assume_role(arn, **args)
|
|
106
|
+
rescue Aws::STS::Errors::ValidationError => e
|
|
107
|
+
raise unless args[:duration_seconds] && e.message.match?(/durationseconds/i)
|
|
108
|
+
hint = "assume_role with DurationSeconds=#{args[:duration_seconds]} was rejected: #{e.message}"
|
|
109
|
+
if mfa
|
|
110
|
+
raise "#{hint}\nLower session_duration in the alias (or raise the role's maximum session duration) and try again."
|
|
111
|
+
end
|
|
112
|
+
STDERR.puts "#{hint} Retrying without DurationSeconds..."
|
|
113
|
+
Aws::ASMR.assume_role(arn, **args.reject { |k, _| k == :duration_seconds })
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
module_function :main, :resolve_credentials, :pinned_name, :perform_assume_role
|
|
90
117
|
end
|
|
91
118
|
end
|
|
92
119
|
end
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
require 'pathname'
|
|
2
|
+
require 'aws/asmr'
|
|
3
|
+
|
|
4
|
+
module Aws
|
|
5
|
+
module ASMR
|
|
6
|
+
# Per-directory pinning of the role to assume, modelled after `rbenv local`.
|
|
7
|
+
#
|
|
8
|
+
# asmr local NAME # write NAME (alias or ARN) to ./.asmr
|
|
9
|
+
# asmr local # print the name pinned in the current directory
|
|
10
|
+
# asmr local --unset # remove ./.asmr
|
|
11
|
+
#
|
|
12
|
+
# When asmr runs without --name, the nearest .asmr found in the current
|
|
13
|
+
# directory or any of its parents decides the role, so the interactive
|
|
14
|
+
# alias selection is skipped.
|
|
15
|
+
module Local
|
|
16
|
+
FILE_NAME = ".asmr"
|
|
17
|
+
ARN_PATTERN = %r{\Aarn:aws[\w-]*:iam::\d{12}:role/}
|
|
18
|
+
|
|
19
|
+
# Runs the `local` subcommand with its remaining args and exits.
|
|
20
|
+
def run(args)
|
|
21
|
+
if args.empty?
|
|
22
|
+
name = read(Dir.pwd)
|
|
23
|
+
abort "asmr: no local role configured for this directory" unless name
|
|
24
|
+
puts name
|
|
25
|
+
elsif args == ["--unset"]
|
|
26
|
+
unset(Dir.pwd)
|
|
27
|
+
elsif args.length == 1 && !args.first.start_with?('-')
|
|
28
|
+
write(args.first, Dir.pwd)
|
|
29
|
+
else
|
|
30
|
+
abort "Usage: asmr local [NAME|--unset]"
|
|
31
|
+
end
|
|
32
|
+
exit(0)
|
|
33
|
+
rescue RuntimeError => e
|
|
34
|
+
abort e.message
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def path(dir)
|
|
38
|
+
File.join(dir, FILE_NAME)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# Name pinned exactly in dir (first non-empty, non-comment line), or nil.
|
|
42
|
+
def read(dir)
|
|
43
|
+
file = path(dir)
|
|
44
|
+
return nil unless File.file?(file)
|
|
45
|
+
File.readlines(file).map(&:strip).find { |l| !l.empty? && !l.start_with?('#') }
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# Walks up from dir to the filesystem root and returns [name, file] of the
|
|
49
|
+
# nearest .asmr, or nil when none is found.
|
|
50
|
+
def find(dir = Dir.pwd)
|
|
51
|
+
Pathname.new(dir).expand_path.ascend do |d|
|
|
52
|
+
name = read(d.to_s)
|
|
53
|
+
return [name, path(d.to_s)] if name
|
|
54
|
+
end
|
|
55
|
+
nil
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def write(name, dir)
|
|
59
|
+
validate!(name)
|
|
60
|
+
File.write(path(dir), "#{name}\n")
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def unset(dir)
|
|
64
|
+
file = path(dir)
|
|
65
|
+
File.delete(file) if File.exist?(file)
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
# A name must be a defined alias or a role ARN, the same way rbenv refuses
|
|
69
|
+
# to pin a version that is not installed.
|
|
70
|
+
def validate!(name, source: nil)
|
|
71
|
+
return if Alias.get(name) || name.match?(ARN_PATTERN)
|
|
72
|
+
where = source ? " (pinned at #{source})" : ""
|
|
73
|
+
raise "asmr: '#{name}'#{where} is neither an alias defined at #{Alias::PATH} nor a role ARN"
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
module_function :run, :path, :read, :find, :write, :unset, :validate!
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|
data/lib/aws/asmr/options.rb
CHANGED
|
@@ -3,27 +3,24 @@ require "aws/asmr"
|
|
|
3
3
|
|
|
4
4
|
module Aws::ASMR
|
|
5
5
|
module Options
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
end
|
|
16
|
-
[asmr_args, command_args]
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
def parse(args)
|
|
6
|
+
# Parses asmr's own options from the head of argv and returns
|
|
7
|
+
# [options, command_args]. Parsing stops at the first non-option argument
|
|
8
|
+
# (or after a literal "--"), so anything from there on -- including
|
|
9
|
+
# arguments like --filter that start with "-" -- belongs to the command:
|
|
10
|
+
#
|
|
11
|
+
# asmr --name=foo aws ec2 describe-instances --filter '...'
|
|
12
|
+
# asmr --name foo aws sts get-caller-identity
|
|
13
|
+
# asmr -n foo -- aws sts get-caller-identity
|
|
14
|
+
def parse(argv)
|
|
20
15
|
options = {}
|
|
16
|
+
command_args = argv.dup
|
|
21
17
|
OptionParser.new do |opts|
|
|
22
18
|
# opts.banner = "Usage: asmr [options]"
|
|
23
19
|
opts.banner = <<~EOS
|
|
24
20
|
You can use ALIAS to shortcut name input by setting it at #{Aws::ASMR::ROOT}/alias
|
|
25
21
|
|
|
26
|
-
Usage: asmr [options] [command] [arg...]
|
|
22
|
+
Usage: asmr [options] [--] [command] [arg...]
|
|
23
|
+
asmr local [NAME|--unset] Pin NAME (alias or ARN) to the current directory
|
|
27
24
|
EOS
|
|
28
25
|
|
|
29
26
|
opts.on("-nNAME", "--name=NAME", "Name to perform assume role with ARN or ALIAS") do |name|
|
|
@@ -42,14 +39,11 @@ module Aws::ASMR
|
|
|
42
39
|
end
|
|
43
40
|
opts.on("--clear", "Clear cache") do
|
|
44
41
|
options[:clear] = true
|
|
45
|
-
# require "aws/asmr/version"
|
|
46
|
-
# puts Aws::ASMR::VERSION
|
|
47
|
-
# exit(0)
|
|
48
42
|
end
|
|
49
|
-
end.
|
|
50
|
-
options
|
|
43
|
+
end.order!(command_args)
|
|
44
|
+
[options, command_args]
|
|
51
45
|
end
|
|
52
46
|
|
|
53
|
-
module_function :
|
|
47
|
+
module_function :parse
|
|
54
48
|
end
|
|
55
49
|
end
|
data/lib/aws/asmr/version.rb
CHANGED
data/lib/aws/asmr.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: aws-asmr
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.0.
|
|
4
|
+
version: 0.0.7
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- metheglin
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-
|
|
11
|
+
date: 2026-09-03 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: rake
|
|
@@ -81,6 +81,7 @@ files:
|
|
|
81
81
|
- lib/aws/asmr/alias.rb
|
|
82
82
|
- lib/aws/asmr/cache.rb
|
|
83
83
|
- lib/aws/asmr/cli.rb
|
|
84
|
+
- lib/aws/asmr/local.rb
|
|
84
85
|
- lib/aws/asmr/options.rb
|
|
85
86
|
- lib/aws/asmr/prompt.rb
|
|
86
87
|
- lib/aws/asmr/version.rb
|