aws_runas 0.4.2 → 0.5.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: 354da6c78da53eb8386cfb4bd53251271e4f19c3
4
- data.tar.gz: 39b6306ebfe1599e54abb61507d73a0a3e7b428e
3
+ metadata.gz: 9eeec3efe7aee175787d2ac5479086e7fed933ef
4
+ data.tar.gz: cf85fb2f0b0da64650789774d7b197d46b94a21d
5
5
  SHA512:
6
- metadata.gz: 26d43b13c4c6f7b051f88a053da1ee80ab15b3bc6e9d854eecf9a3db8dc4b952f3dafd35c52e386e48083a8e9137b1fd17536f1532990b5f51e450e5411286e5
7
- data.tar.gz: 416193ead9c704909597dd3ee6d94da7b02b0e1845f89a801309f0a764ee7db1a3f5b53ae5bd550826cb5faf796a0d9303980bf202a645d500ee6580fb5c749f
6
+ metadata.gz: 553fb10ff06a4aad52e00e44c5bb97a8dc2c14b23c4d36817162e129789105d8d6e8b4bb076c092e784167a6df343937adad70e3176760d3fb875184ebf8a62f
7
+ data.tar.gz: 11ec64975cc9e6396d32c2b58e60ec411d94d2c684093a5ada606ef288de810ab5672073c9d5ce361d5e3589ce7aba12977169fef16dff5f54545ca9b92d1675
Binary file
data.tar.gz.sig CHANGED
Binary file
@@ -1,3 +1,45 @@
1
+ ## v0.5.0
2
+
3
+ ### Zsh Support
4
+
5
+ `zsh` is now supported for the fancy prompt. When using the shell, your
6
+ existing profile data from `.zshrc` will be copied over into the temporary
7
+ configuration.
8
+
9
+ ### Additional Functionality for Bash and Zsh
10
+
11
+ 2 additional functions are available for `bash` and `zsh` as well:
12
+
13
+ * `aws_session_expired`, which reads `AWS_SESSION_EXPIRATION_UNIX` (see below)
14
+ and compares this with the current Unix timestamp supplied by `date`. It
15
+ returns 0 on true and 1 on false, which can be used semantically in shell
16
+ scripts.
17
+ * `aws_session_status_color`, which works off of `aws_session_expired` to
18
+ render an ANSI numeric color code - red when `aws_session_expired` is `true`,
19
+ yellow otherwise.
20
+
21
+ The prompts for `bash` and `zsh` now work off of these functions to render the
22
+ right color. The prompt will go red when the session has expired.
23
+
24
+ ### Skip Fancy Interactive Prompt
25
+
26
+ The default interactive prompt that you get when you run `aws-runas` with no
27
+ command supplied can now by skipped by adding `--skip-prompt` to the CLI
28
+ arguments. The profile functions mentioned above are still passed in. This
29
+ allows you to leverage their functionality inside your own scripts and custom
30
+ prompts if you want in other ways.
31
+
32
+ ### Additional Variables
33
+
34
+ Several environment variables have been added for more quality-of-life when
35
+ working in the shell or aware tools:
36
+
37
+ * `AWS_REGION` and `AWS_DEFAULT_REGION`, which pass through the region
38
+ configured in the profile, if present
39
+ * `AWS_SESSION_EXPIRATION` and `AWS_SESSION_EXPIRATION_UNIX` to supply the
40
+ session expiration time, in both human and UNIX timestamps, respectively
41
+ named.
42
+
1
43
  ## v0.4.2
2
44
 
3
45
  The role that aws-runas assumed and the profile it used are now exposed as
data/README.md CHANGED
@@ -51,14 +51,39 @@ help you determine what credentials are in use locally:
51
51
  * `AWS_RUNAS_ASSUMED_ROLE_ARN` - set when a role is assumed (not set if
52
52
  `--no-role` is used)
53
53
  * `AWS_RUNAS_PROFILE` - set with the profile used when `aws-runas` was run
54
+ * `AWS_REGION` and `AWS_DEFAULT_REGION` - set with the region name defined in
55
+ the profile being used
56
+ * `AWS_SESSION_EXPIRATION` - set with the expiry timestamp in UTC
57
+ * `AWS_SESSION_EXPIRATION_UNIX` - set with the expiry timestamp in Unix time,
58
+ useful for scripting
54
59
 
55
- ### Fancy Bash Prompt
60
+ ### Fancy Bash/Zsh Prompt
56
61
 
57
- If you use `aws-runas` without any options and your default shell is Bash, a
58
- colorized prompt will appear with the profile that is in use if a role is
62
+ If you use `aws-runas` without any options and your default shell is Bash or
63
+ Zsh, a colorized prompt will appear with the profile that is in use if a role is
59
64
  assumed, or a simple `(AWS)` indicator added to the prompt if a session token is
60
65
  only obtained. See the video at the start of the doc for a demo!
61
66
 
67
+ #### Shell Integration Functions
68
+
69
+ 2 functions currently get exported when you run under one of the two supported
70
+ shells:
71
+
72
+ * `aws_session_expired`, which reads `AWS_SESSION_EXPIRATION_UNIX` (see above)
73
+ and compares this with the current Unix timestamp supplied by `date`. It
74
+ returns 0 on true and 1 on false, which can be used semantically in shell
75
+ scripts.
76
+ * `aws_session_status_color`, which works off of `aws_session_expired` to
77
+ render an ANSI numeric color code - red when `aws_session_expired` is `true`,
78
+ yellow otherwise.
79
+
80
+ #### Skipping the Fancy Prompt
81
+
82
+ If you are doing your own prompt customization based on aws-runas data and don't
83
+ want the prompt modified, you can supply `--skip-prompt` to skip the prompt
84
+ modification. The aforementioned integration functions will still be available
85
+ to you however, which you can use in your own scripts.
86
+
62
87
  Usage
63
88
  ------
64
89
 
@@ -76,6 +101,7 @@ depending on your system) will launch.
76
101
 
77
102
  [options] are:
78
103
  -n, --no-role Get a session token only, do not assume a role
104
+ -s, --skip-prompt Do not launch interactive sessions with the fancy prompt
79
105
  -p, --path=<s> Path to the AWS config file
80
106
  -r, --profile=<s> The AWS profile to load (default: default)
81
107
  -h, --help Show this message
@@ -37,6 +37,7 @@ module AwsRunAs
37
37
  EOS
38
38
 
39
39
  opt :no_role, 'Get a session token only, do not assume a role', type: TrueClass, default: nil
40
+ opt :skip_prompt, 'Do not launch interactive sessions with the fancy prompt', type: TrueClass, default: nil
40
41
  opt :path, 'Path to the AWS config file', type: String
41
42
  opt :profile, 'The AWS profile to load', type: String, default: 'default'
42
43
  stop_on_unknown
@@ -51,7 +52,7 @@ module AwsRunAs
51
52
  @main = AwsRunAs::Main.new(path: opts[:path], profile: opts[:profile], mfa_code: mfa_code, no_role: opts[:no_role])
52
53
  @main.assume_role
53
54
  command = ARGV.shift
54
- @main.handoff(command: command, argv: ARGV)
55
+ @main.handoff(command: command, argv: ARGV, skip_prompt: opts[:skip_prompt])
55
56
  end
56
57
 
57
58
  # Reads the MFA code from standard input.
@@ -52,35 +52,52 @@ module AwsRunAs
52
52
  mfa_serial = @cfg.load_config_value(key: 'mfa_serial') unless ENV.include?('AWS_SESSION_TOKEN')
53
53
  if @no_role
54
54
  raise 'No mfa_serial in selected profile, session will be useless' if mfa_serial.nil?
55
- @role_credentials = sts_client.get_session_token(
55
+ @session = sts_client.get_session_token(
56
56
  duration_seconds: 3600,
57
57
  serial_number: mfa_serial,
58
58
  token_code: @mfa_code
59
- ).credentials
59
+ )
60
60
  else
61
- @role_credentials = Aws::AssumeRoleCredentials.new(
61
+ @session = Aws::AssumeRoleCredentials.new(
62
62
  client: sts_client,
63
63
  role_arn: role_arn,
64
64
  serial_number: mfa_serial,
65
65
  token_code: @mfa_code,
66
66
  role_session_name: session_id
67
- ).credentials
67
+ )
68
68
  end
69
69
  end
70
70
 
71
+ def session_credentials
72
+ @session.credentials
73
+ end
74
+
71
75
  def credentials_env
72
76
  env = {}
73
- env['AWS_ACCESS_KEY_ID'] = @role_credentials.access_key_id
74
- env['AWS_SECRET_ACCESS_KEY'] = @role_credentials.secret_access_key
75
- env['AWS_SESSION_TOKEN'] = @role_credentials.session_token
77
+ env['AWS_ACCESS_KEY_ID'] = session_credentials.access_key_id
78
+ env['AWS_SECRET_ACCESS_KEY'] = session_credentials.secret_access_key
79
+ env['AWS_SESSION_TOKEN'] = session_credentials.session_token
76
80
  env['AWS_RUNAS_PROFILE'] = @cfg.profile
77
- env['AWS_RUNAS_ASSUMED_ROLE_ARN'] = @cfg.load_config_value(key: 'role_arn') unless @no_role
81
+ unless @cfg.load_config_value(key: 'region').nil?
82
+ env['AWS_REGION'] = @cfg.load_config_value(key: 'region')
83
+ env['AWS_DEFAULT_REGION'] = @cfg.load_config_value(key: 'region')
84
+ end
85
+ if @no_role
86
+ env['AWS_SESSION_EXPIRATION'] = session_credentials.expiration.to_s
87
+ env['AWS_SESSION_EXPIRATION_UNIX'] = DateTime.parse(session_credentials.expiration.to_s).strftime('%s')
88
+ else
89
+ env['AWS_SESSION_EXPIRATION'] = @session.expiration.to_s
90
+ env['AWS_SESSION_EXPIRATION_UNIX'] = DateTime.parse(@session.expiration.to_s).strftime('%s')
91
+ env['AWS_RUNAS_ASSUMED_ROLE_ARN'] = @cfg.load_config_value(key: 'role_arn')
92
+ end
78
93
  env
79
94
  end
80
95
 
81
- def handoff(command: nil, argv: nil)
96
+ def handoff(command: nil, argv: nil, skip_prompt:)
82
97
  env = credentials_env
83
- AwsRunAs::Utils.handoff_to_shell(env: env, profile: @no_role ? nil : @cfg.profile) unless command
98
+ unless command
99
+ AwsRunAs::Utils.handoff_to_shell(env: env, profile: @no_role ? nil : @cfg.profile, skip_prompt: skip_prompt)
100
+ end
84
101
  exec(env, command, *argv)
85
102
  end
86
103
  end
@@ -14,6 +14,8 @@
14
14
 
15
15
  require 'rbconfig'
16
16
  require 'tempfile'
17
+ require 'tmpdir'
18
+ require 'fileutils'
17
19
  require 'English'
18
20
 
19
21
  module AwsRunAs
@@ -21,20 +23,49 @@ module AwsRunAs
21
23
  module Utils
22
24
  module_function
23
25
 
26
+ # Return the path to the shell_profiles directory vendored with the gem.
27
+ def shell_profiles_dir
28
+ File.expand_path('../../../shell_profiles', __FILE__)
29
+ end
30
+
24
31
  # Run an interactive bash session with a special streamed RC file. The RC
25
32
  # merges a local .bashrc if it exists, with a prompt that includes the
26
33
  # computed message from handoff_to_shell.
27
- def bash_with_prompt(env:, path:, message:)
34
+ def handoff_bash(env:, path:, message:, skip_prompt:)
28
35
  rc_data = IO.read("#{ENV['HOME']}/.bashrc") if File.exist?("#{ENV['HOME']}/.bashrc")
29
36
  rc_file = Tempfile.new('aws_runas_bashrc')
30
37
  rc_file.write("#{rc_data}\n") unless rc_data.nil?
31
- rc_file.write("PS1=\"\\[\\e[33m\\](#{message})\\[\\e[0m\\] $PS1\"\n")
38
+ rc_file.write(IO.read("#{shell_profiles_dir}/sh.profile"))
39
+ unless skip_prompt
40
+ rc_file.write("PS1=\"\\[\\e[\\$(aws_session_status_color)m\\](#{message})\\[\\e[0m\\] $PS1\"\n")
41
+ end
32
42
  rc_file.close
33
43
  system(env, path, '--rcfile', rc_file.path)
34
44
  ensure
35
45
  rc_file.unlink
36
46
  end
37
47
 
48
+ # Run an interactive zsh session with a special streamed RC file. The RC
49
+ # merges a local .zshrc if it exists, with a prompt that includes the
50
+ # computed message from handoff_to_shell.
51
+ def handoff_zsh(env:, path:, message:, skip_prompt:)
52
+ rc_data = IO.read("#{ENV['HOME']}/.zshrc") if File.exist?("#{ENV['HOME']}/.zshrc")
53
+ rc_dir = Dir.mktmpdir('aws_runas_zsh')
54
+ rc_file = File.new("#{rc_dir}/.zshrc", 'w')
55
+ rc_file.write("#{rc_data}\n") unless rc_data.nil?
56
+ rc_file.write(IO.read("#{shell_profiles_dir}/sh.profile"))
57
+ unless skip_prompt
58
+ rc_file.write("setopt PROMPT_SUBST\n")
59
+ rc_file.write("export OLDPROMPT=\"${PROMPT}\"\n")
60
+ rc_file.write("PROMPT=$'%{\\e[\\%}$(aws_session_status_color)m(#{message})%{\\e[0m%} $OLDPROMPT'\n")
61
+ end
62
+ rc_file.close
63
+ env.store('ZDOTDIR', rc_dir)
64
+ system(env, path)
65
+ ensure
66
+ FileUtils.rmtree(rc_dir)
67
+ end
68
+
38
69
  # load the shell for a specific operating system.
39
70
  # if $SHELL exists, load that.
40
71
  def shell
@@ -60,10 +91,12 @@ module AwsRunAs
60
91
  # an interactive shell with the shell prompt customized to the current
61
92
  # running AWS profile. If the shell is not something we can handle
62
93
  # specifically, just run the shell.
63
- def handoff_to_shell(env:, profile: nil)
94
+ def handoff_to_shell(env:, profile: nil, skip_prompt:)
64
95
  path = shell
65
96
  if path.end_with?('/bash')
66
- bash_with_prompt(env: env, path: path, message: compute_message(profile: profile))
97
+ handoff_bash(env: env, path: path, message: compute_message(profile: profile), skip_prompt: skip_prompt)
98
+ elsif path.end_with?('/zsh')
99
+ handoff_zsh(env: env, path: path, message: compute_message(profile: profile), skip_prompt: skip_prompt)
67
100
  else
68
101
  system(env, path)
69
102
  end
@@ -13,5 +13,5 @@
13
13
  # limitations under the License.
14
14
 
15
15
  module AwsRunAs
16
- VERSION = '0.4.2'
16
+ VERSION = '0.5.0'
17
17
  end
@@ -0,0 +1,23 @@
1
+ # vim:filetype=sh
2
+ #
3
+ # aws_session_expired checks to see if the current session has expired, based
4
+ # off of the value stored in AWS_SESSION_EXPIRATION_UNIX. This functionality
5
+ # relies on date being in $PATH.
6
+ aws_session_expired() {
7
+ if [[ "${AWS_SESSION_EXPIRATION_UNIX}" -lt "$(date +%s)" ]]; then
8
+ return 0
9
+ fi
10
+ return 1
11
+ }
12
+
13
+ # aws_session_status_color returns an ANSI color number for the specific status
14
+ # of the session. Note that if session_expired is not correctly functioning,
15
+ # this will always be yellow. Red is shown when it's verified that the session
16
+ # has expired.
17
+ aws_session_status_color() {
18
+ if aws_session_expired; then
19
+ echo "31"
20
+ else
21
+ echo "33"
22
+ fi
23
+ }
@@ -102,14 +102,26 @@ describe AwsRunAs::Main do
102
102
  before do
103
103
  allow_any_instance_of(AwsRunAs::Main).to receive(:sts_client).and_return(
104
104
  Aws::STS::Client.new(
105
- stub_responses: true
105
+ stub_responses: {
106
+ get_session_token: {
107
+ credentials: {
108
+ access_key_id: 'accessKeyIdType',
109
+ secret_access_key: 'accessKeySecretType',
110
+ session_token: 'tokenType',
111
+ expiration: Time.utc(2017, 'jul', 10, 19, 56, 11)
112
+ }
113
+ }
114
+ }
106
115
  )
107
116
  )
117
+ allow_any_instance_of(Aws::AssumeRoleCredentials).to receive(:expiration).and_return(
118
+ Time.utc(2017, 'jul', 10, 19, 56, 11)
119
+ )
108
120
  end
109
121
  subject(:env) do
110
122
  ENV.delete('AWS_SESSION_TOKEN')
111
123
  main = AwsRunAs::Main.new(
112
- path: MOCK_AWS_CONFIGPATH,
124
+ path: cfg_path,
113
125
  profile: 'test-profile',
114
126
  mfa_code: '123456',
115
127
  no_role: no_role
@@ -118,6 +130,7 @@ describe AwsRunAs::Main do
118
130
  main.credentials_env
119
131
  end
120
132
  let(:no_role) { false }
133
+ let(:cfg_path) { MOCK_AWS_CONFIGPATH }
121
134
 
122
135
  context 'with role assumed' do
123
136
  it 'returns AWS_ACCESS_KEY_ID set in env' do
@@ -135,6 +148,18 @@ describe AwsRunAs::Main do
135
148
  it 'has AWS_RUNAS_ASSUMED_ROLE_ARN set to the assumed role ARN' do
136
149
  expect(env['AWS_RUNAS_ASSUMED_ROLE_ARN']).to eq('arn:aws:iam::123456789012:role/test-admin')
137
150
  end
151
+ it 'has AWS_SESSION_EXPIRATION set in env' do
152
+ expect(env['AWS_SESSION_EXPIRATION']).to eq('2017-07-10 19:56:11 UTC')
153
+ end
154
+ it 'has AWS_SESSION_EXPIRATION_UNIX set in env' do
155
+ expect(env['AWS_SESSION_EXPIRATION_UNIX']).to eq('1499716571')
156
+ end
157
+ it 'has AWS_REGION set in env' do
158
+ expect(env['AWS_REGION']).to eq('us-west-1')
159
+ end
160
+ it 'has AWS_DEFAULT_REGION set in env' do
161
+ expect(env['AWS_DEFAULT_REGION']).to eq('us-west-1')
162
+ end
138
163
  end
139
164
 
140
165
  context 'with no role assumed' do
@@ -143,6 +168,29 @@ describe AwsRunAs::Main do
143
168
  it 'does not have AWS_RUNAS_ASSUMED_ROLE_ARN set' do
144
169
  expect(env).to_not have_key('AWS_RUNAS_ASSUMED_ROLE_ARN')
145
170
  end
171
+ it 'has AWS_SESSION_EXPIRATION set in env' do
172
+ expect(env['AWS_SESSION_EXPIRATION']).to eq('2017-07-10 19:56:11 UTC')
173
+ end
174
+ it 'has AWS_SESSION_EXPIRATION_UNIX set in env' do
175
+ expect(env['AWS_SESSION_EXPIRATION_UNIX']).to eq('1499716571')
176
+ end
177
+ it 'has AWS_REGION set in env' do
178
+ expect(env['AWS_REGION']).to eq('us-west-1')
179
+ end
180
+ it 'has AWS_DEFAULT_REGION set in env' do
181
+ expect(env['AWS_DEFAULT_REGION']).to eq('us-west-1')
182
+ end
183
+ end
184
+
185
+ context 'with no region in config' do
186
+ let(:cfg_path) { MOCK_AWS_NO_REGION_PATH }
187
+
188
+ it 'does not have AWS_REGION set in env' do
189
+ expect(env).to_not have_key('AWS_REGION')
190
+ end
191
+ it 'does not have AWS_DEFAULT_REGION set in env' do
192
+ expect(env).to_not have_key('AWS_DEFAULT_REGION')
193
+ end
146
194
  end
147
195
  end
148
196
 
@@ -154,7 +202,7 @@ describe AwsRunAs::Main do
154
202
 
155
203
  it 'execs a command when a command is specified' do
156
204
  expect(@main).to receive(:exec).with(anything, '/usr/bin/foo', *['--bar', 'baz'])
157
- @main.handoff(command: '/usr/bin/foo', argv: ['--bar', 'baz'])
205
+ @main.handoff(command: '/usr/bin/foo', argv: ['--bar', 'baz'], skip_prompt: false)
158
206
  end
159
207
  end
160
208
  end
@@ -13,33 +13,113 @@
13
13
  # limitations under the License.
14
14
 
15
15
  require 'spec_helper'
16
+ require 'tmpdir'
16
17
 
17
18
  describe AwsRunAs::Utils do
18
- describe '::bash_with_prompt' do
19
+ describe '::shell_profiles_dir' do
20
+ it 'returns an existent path' do
21
+ expect(File.directory?(AwsRunAs::Utils.shell_profiles_dir)).to be true
22
+ end
23
+ it 'returns a path correctly relative to spec file' do
24
+ expect(AwsRunAs::Utils.shell_profiles_dir).to eq(File.expand_path('../../../shell_profiles', __FILE__))
25
+ end
26
+ end
27
+
28
+ describe '::handoff_bash' do
19
29
  context 'with RC file' do
20
30
  before(:example) do
21
31
  allow(IO).to receive(:read).with("#{ENV['HOME']}/.bashrc").and_return(BASHRC_FILE_CONTENTS)
32
+ allow(IO).to receive(:read).with("#{AwsRunAs::Utils.shell_profiles_dir}/sh.profile").and_call_original
22
33
  end
23
34
  it 'runs bash with a properly combined RC file' do
24
35
  expect(AwsRunAs::Utils).to receive(:system).with(EXPECTED_ENV, '/bin/bash', '--rcfile', anything)
25
36
  expect_any_instance_of(Tempfile).to receive(:write).with("#{BASHRC_FILE_CONTENTS}\n")
37
+ expect_any_instance_of(Tempfile).to receive(:write).with(IO.read("#{AwsRunAs::Utils.shell_profiles_dir}/sh.profile"))
26
38
  expect_any_instance_of(Tempfile).to receive(:write).with(BASHRC_EXPECTED_PROMPT)
27
- AwsRunAs::Utils.bash_with_prompt(env: EXPECTED_ENV, path: '/bin/bash', message: 'AWS:rspec')
39
+ AwsRunAs::Utils.handoff_bash(env: EXPECTED_ENV, path: '/bin/bash', message: 'AWS:rspec', skip_prompt: false)
28
40
  end
29
41
  end
30
42
 
31
43
  context 'without RC file' do
32
44
  before(:example) do
33
45
  allow(File).to receive(:exist?).with("#{ENV['HOME']}/.bashrc").and_return(false)
46
+ allow(IO).to receive(:read).with("#{AwsRunAs::Utils.shell_profiles_dir}/sh.profile").and_call_original
34
47
  end
35
48
  it 'runs bash (no RC file found)' do
36
49
  expect(AwsRunAs::Utils).to receive(:system).with(EXPECTED_ENV, '/bin/bash', '--rcfile', anything)
50
+ expect_any_instance_of(Tempfile).to receive(:write).with(IO.read("#{AwsRunAs::Utils.shell_profiles_dir}/sh.profile"))
37
51
  expect_any_instance_of(Tempfile).to receive(:write).with(BASHRC_EXPECTED_PROMPT)
38
- AwsRunAs::Utils.bash_with_prompt(env: EXPECTED_ENV, path: '/bin/bash', message: 'AWS:rspec')
52
+ AwsRunAs::Utils.handoff_bash(env: EXPECTED_ENV, path: '/bin/bash', message: 'AWS:rspec', skip_prompt: false)
53
+ end
54
+ end
55
+
56
+ context 'with skip_prompt enabled' do
57
+ before(:example) do
58
+ allow(IO).to receive(:read).with("#{ENV['HOME']}/.bashrc").and_return(BASHRC_FILE_CONTENTS)
59
+ allow(IO).to receive(:read).with("#{AwsRunAs::Utils.shell_profiles_dir}/sh.profile").and_call_original
60
+ end
61
+ it 'runs bash with a properly combined RC file, but no prompt modification' do
62
+ expect(AwsRunAs::Utils).to receive(:system).with(EXPECTED_ENV, '/bin/bash', '--rcfile', anything)
63
+ expect_any_instance_of(Tempfile).to receive(:write).with("#{BASHRC_FILE_CONTENTS}\n")
64
+ expect_any_instance_of(Tempfile).to receive(:write).with(IO.read("#{AwsRunAs::Utils.shell_profiles_dir}/sh.profile"))
65
+ AwsRunAs::Utils.handoff_bash(env: EXPECTED_ENV, path: '/bin/bash', message: 'AWS:rspec', skip_prompt: true)
39
66
  end
40
67
  end
41
68
  end
42
69
 
70
+ describe '::handoff_zsh' do
71
+ context 'with RC file' do
72
+ before(:example) do
73
+ allow(IO).to receive(:read).with("#{ENV['HOME']}/.zshrc").and_return(ZSHRC_FILE_CONTENTS)
74
+ allow(IO).to receive(:read).with("#{AwsRunAs::Utils.shell_profiles_dir}/sh.profile").and_call_original
75
+ end
76
+ it 'runs zsh with a properly combined RC file, in special tmp dir' do
77
+ expect(AwsRunAs::Utils).to receive(:system).with(EXPECTED_ENV_ZSH, '/usr/bin/zsh')
78
+ expect(Dir).to receive(:mktmpdir).with('aws_runas_zsh') { test_mktmpdir }
79
+ expect_any_instance_of(File).to receive(:write).with("#{ZSHRC_FILE_CONTENTS}\n")
80
+ expect_any_instance_of(File).to receive(:write).with(IO.read("#{AwsRunAs::Utils.shell_profiles_dir}/sh.profile"))
81
+ expect_any_instance_of(File).to receive(:write).with(ZSHRC_EXPECTED_SETSUBST)
82
+ expect_any_instance_of(File).to receive(:write).with(ZSHRC_EXPECTED_OLDPROMPT)
83
+ expect_any_instance_of(File).to receive(:write).with(ZSHRC_EXPECTED_PROMPT)
84
+ env = EXPECTED_ENV.dup
85
+ AwsRunAs::Utils.handoff_zsh(env: env, path: '/usr/bin/zsh', message: 'AWS:rspec', skip_prompt: false)
86
+ end
87
+ end
88
+
89
+ context 'without RC file' do
90
+ before(:example) do
91
+ allow(File).to receive(:exist?).with("#{ENV['HOME']}/.zshrc").and_return(false)
92
+ allow(IO).to receive(:read).with("#{AwsRunAs::Utils.shell_profiles_dir}/sh.profile").and_call_original
93
+ end
94
+ it 'runs zsh (no RC file found)' do
95
+ expect(AwsRunAs::Utils).to receive(:system).with(EXPECTED_ENV_ZSH, '/usr/bin/zsh')
96
+ expect(Dir).to receive(:mktmpdir).with('aws_runas_zsh') { test_mktmpdir }
97
+ expect_any_instance_of(File).to receive(:write).with(IO.read("#{AwsRunAs::Utils.shell_profiles_dir}/sh.profile"))
98
+ expect_any_instance_of(File).to receive(:write).with(ZSHRC_EXPECTED_SETSUBST)
99
+ expect_any_instance_of(File).to receive(:write).with(ZSHRC_EXPECTED_OLDPROMPT)
100
+ expect_any_instance_of(File).to receive(:write).with(ZSHRC_EXPECTED_PROMPT)
101
+ env = EXPECTED_ENV.dup
102
+ AwsRunAs::Utils.handoff_zsh(env: env, path: '/usr/bin/zsh', message: 'AWS:rspec', skip_prompt: false)
103
+ end
104
+ end
105
+
106
+ context 'with skip_prompt enabled' do
107
+ before(:example) do
108
+ allow(IO).to receive(:read).with("#{ENV['HOME']}/.zshrc").and_return(ZSHRC_FILE_CONTENTS)
109
+ allow(IO).to receive(:read).with("#{AwsRunAs::Utils.shell_profiles_dir}/sh.profile").and_call_original
110
+ end
111
+ it 'runs zsh with a properly combined RC file, in special tmp dir' do
112
+ expect(AwsRunAs::Utils).to receive(:system).with(EXPECTED_ENV_ZSH, '/usr/bin/zsh')
113
+ expect(Dir).to receive(:mktmpdir).with('aws_runas_zsh') { test_mktmpdir }
114
+ expect_any_instance_of(File).to receive(:write).with("#{ZSHRC_FILE_CONTENTS}\n")
115
+ expect_any_instance_of(File).to receive(:write).with(IO.read("#{AwsRunAs::Utils.shell_profiles_dir}/sh.profile"))
116
+ env = EXPECTED_ENV.dup
117
+ AwsRunAs::Utils.handoff_zsh(env: env, path: '/usr/bin/zsh', message: 'AWS:rspec', skip_prompt: true)
118
+ end
119
+ end
120
+
121
+ end
122
+
43
123
  describe '::shell' do
44
124
  context 'Non-Windows OS' do
45
125
  context 'No $SHELL set' do
@@ -97,8 +177,8 @@ describe AwsRunAs::Utils do
97
177
  end
98
178
 
99
179
  it 'Loads bash with the rspec profile prompt' do
100
- expect(AwsRunAs::Utils).to receive(:bash_with_prompt).with(env: EXPECTED_ENV, path: '/bin/bash', message: 'AWS:rspec')
101
- AwsRunAs::Utils.handoff_to_shell(env: EXPECTED_ENV, profile: 'rspec')
180
+ expect(AwsRunAs::Utils).to receive(:handoff_bash).with(env: EXPECTED_ENV, path: '/bin/bash', message: 'AWS:rspec', skip_prompt: false)
181
+ AwsRunAs::Utils.handoff_to_shell(env: EXPECTED_ENV, profile: 'rspec', skip_prompt: false)
102
182
  end
103
183
  end
104
184
 
@@ -110,7 +190,7 @@ describe AwsRunAs::Utils do
110
190
 
111
191
  it 'starts a default shell without any args' do
112
192
  expect(AwsRunAs::Utils).to receive(:system).with(EXPECTED_ENV, '/bin/sh')
113
- AwsRunAs::Utils.handoff_to_shell(env: EXPECTED_ENV, profile: nil)
193
+ AwsRunAs::Utils.handoff_to_shell(env: EXPECTED_ENV, profile: nil, skip_prompt: false)
114
194
  end
115
195
  end
116
196
  end
@@ -17,3 +17,4 @@ require 'spec_helper'
17
17
  MOCK_AWS_CONFIGPATH = File.expand_path('../files/aws_config', __FILE__)
18
18
  MOCK_AWS_NO_MFA_PATH = File.expand_path('../files/aws_config_nomfa', __FILE__)
19
19
  MOCK_AWS_NO_SOURCE_PATH = File.expand_path('../files/aws_config_nosource', __FILE__)
20
+ MOCK_AWS_NO_REGION_PATH = File.expand_path('../files/aws_config_noregion', __FILE__)
@@ -0,0 +1,6 @@
1
+ [default]
2
+
3
+ [profile test-profile]
4
+ role_arn = arn:aws:iam::123456789012:role/test-admin
5
+ mfa_serial = arn:aws:iam::123456789012:mfa/test
6
+ source_profile = test-credentials
@@ -1,4 +1,5 @@
1
1
  require 'spec_helper'
2
+ require 'tmpdir'
2
3
 
3
4
  MOCK_BASHRC_PATH = File.expand_path('../files/bashrc', __FILE__)
4
5
 
@@ -6,10 +7,30 @@ BASHRC_FILE_CONTENTS = <<EOS.freeze
6
7
  foobar
7
8
  EOS
8
9
 
9
- BASHRC_EXPECTED_PROMPT = "PS1=\"\\[\\e[33m\\](AWS:rspec)\\[\\e[0m\\] $PS1\"\n".freeze
10
+ ZSHRC_FILE_CONTENTS = <<EOS.freeze
11
+ bazqux
12
+ EOS
13
+
14
+ BASHRC_EXPECTED_PROMPT = "PS1=\"\\[\\e[\\$(aws_session_status_color)m\\](AWS:rspec)\\[\\e[0m\\] $PS1\"\n".freeze
15
+ ZSHRC_EXPECTED_PROMPT = "PROMPT=$'%{\\e[\\%}$(aws_session_status_color)m(AWS:rspec)%{\\e[0m%} $OLDPROMPT'\n".freeze
16
+ ZSHRC_EXPECTED_SETSUBST = "setopt PROMPT_SUBST\n".freeze
17
+ ZSHRC_EXPECTED_OLDPROMPT = "export OLDPROMPT=\"${PROMPT}\"\n".freeze
18
+ ZSH_MOCK_TMPDIR = "#{Dir.tmpdir}/aws_runas_zsh_rspec".freeze
10
19
 
11
20
  EXPECTED_ENV = {
12
21
  'AWS_ACCESS_KEY_ID' => 'AccessKeyId',
13
22
  'AWS_SECRET_ACCESS_KEY' => 'SecretAccessKey',
14
23
  'AWS_SESSION_TOKEN' => 'Token'
15
24
  }.freeze
25
+
26
+ EXPECTED_ENV_ZSH = {
27
+ 'AWS_ACCESS_KEY_ID' => 'AccessKeyId',
28
+ 'AWS_SECRET_ACCESS_KEY' => 'SecretAccessKey',
29
+ 'AWS_SESSION_TOKEN' => 'Token',
30
+ 'ZDOTDIR' => ZSH_MOCK_TMPDIR
31
+ }.freeze
32
+
33
+ def test_mktmpdir
34
+ Dir.mkdir(ZSH_MOCK_TMPDIR)
35
+ ZSH_MOCK_TMPDIR
36
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: aws_runas
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.2
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chris Marchesi
@@ -31,7 +31,7 @@ cert_chain:
31
31
  80WBA6xKwX0zwURD8J7WNieL2iY5AhBg26cHuFLMQGTCyNEeZHZHnJhCwuBcnV1w
32
32
  2zQ=
33
33
  -----END CERTIFICATE-----
34
- date: 2017-05-03 00:00:00.000000000 Z
34
+ date: 2017-07-16 00:00:00.000000000 Z
35
35
  dependencies:
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: aws-sdk
@@ -156,6 +156,7 @@ files:
156
156
  - lib/aws_runas/main.rb
157
157
  - lib/aws_runas/utils.rb
158
158
  - lib/aws_runas/version.rb
159
+ - shell_profiles/sh.profile
159
160
  - spec/aws_runas/cli_spec.rb
160
161
  - spec/aws_runas/config_spec.rb
161
162
  - spec/aws_runas/main_spec.rb
@@ -163,8 +164,8 @@ files:
163
164
  - spec/helpers/config_spec.rb
164
165
  - spec/helpers/files/aws_config
165
166
  - spec/helpers/files/aws_config_nomfa
167
+ - spec/helpers/files/aws_config_noregion
166
168
  - spec/helpers/files/aws_config_nosource
167
- - spec/helpers/files/bashrc
168
169
  - spec/helpers/utils_spec.rb
169
170
  - spec/spec_helper.rb
170
171
  homepage: https://github.com/vancluever/aws-runas
@@ -199,7 +200,7 @@ test_files:
199
200
  - spec/helpers/config_spec.rb
200
201
  - spec/helpers/files/aws_config
201
202
  - spec/helpers/files/aws_config_nomfa
203
+ - spec/helpers/files/aws_config_noregion
202
204
  - spec/helpers/files/aws_config_nosource
203
- - spec/helpers/files/bashrc
204
205
  - spec/helpers/utils_spec.rb
205
206
  - spec/spec_helper.rb
metadata.gz.sig CHANGED
@@ -1,3 +1,3 @@
1
- ����бa��v��ߝW�v [�d[R���_��JY����1�?�7
2
- ��O빜��
3
- 5���l@�i��_��%����{���Y
1
+ ��չۙ���j=7[^s*�3��_l�*� �!������t����U���H�Ř�l�����;��L(~LfE'O�"T_j8p��b؀*��b�,W}C����$C��ߪ,�o��b��9�I̼m+� ʊ�I���
2
+ ���fE�]�ĸB���I�?��/�ݾ��ڬ�
3
+ �6�Rp;pja���E�3��žFi��F������T���_�)�⳵����Kˀ��w�/[����|8��S��xlh����~E(
@@ -1 +0,0 @@
1
- foobar