├── .gitignore
├── README.md
├── demo.gif
├── index.js
├── package-lock.json
├── package.json
├── postinstall.sh
├── run.sh
└── screenshot.png
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules/
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # AWSP - AWS Profile Switcher
2 |
3 | Easily switch between AWS Profiles
4 |
5 |
6 |
7 | ## Prereqs
8 | Setup your profiles using the aws cli
9 |
10 | ```sh
11 | aws configure --profile PROFILE_NAME
12 | ```
13 |
14 | You can also leave out the `--profile PROFILE_NAME` param to set your `default` credentials
15 |
16 | Refer to this doc for more information
17 | https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-getting-started.html
18 |
19 | ## Setup
20 |
21 | ```sh
22 | npm install -g awsp
23 | ```
24 |
25 | Add the following to your `.bashrc` or `.zshrc` config
26 | ```sh
27 | alias awsp="source _awsp"
28 | ```
29 |
30 | ## Usage
31 | ```sh
32 | awsp
33 | ```
34 |
35 | ## Show your AWS Profile in your shell prompt
36 | For better visibility into what your shell is set to it's helpful to configure your prompt to show the value of the env variable `AWS_PROFILE`.
37 |
38 |
39 |
40 | Here's a sample of my zsh prompt config using oh-my-zsh themes
41 |
42 | ```sh
43 | function aws_prof {
44 | local profile="${AWS_PROFILE:=default}"
45 |
46 | echo "%{$fg_bold[blue]%}aws:(%{$fg[yellow]%}${profile}%{$fg_bold[blue]%})%{$reset_color%} "
47 | }
48 | ```
49 |
50 | ```sh
51 | PROMPT='OTHER_PROMPT_STUFF $(aws_prof)'
52 | ```
--------------------------------------------------------------------------------
/demo.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johnnyopao/awsp/0656893f9521887d3af3d869cc757a64cdfcd179/demo.gif
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 |
3 | const fs = require('fs');
4 | const inquirer = require('inquirer');
5 |
6 | console.log('AWS Profile Switcher');
7 |
8 | const homeDir = process.env['HOME']
9 | const profileRegex = /\[profile .*]/g;
10 | const bracketsRemovalRegx = /(\[profile )|(\])/g;
11 | const defaultProfileChoice = 'default';
12 |
13 | const promptProfileChoice = (data) => {
14 | const matches = data.match(profileRegex);
15 |
16 | if (!matches) {
17 | console.log('No profiles found.');
18 | console.log('Refer to this guide for help on setting up a new AWS profile:');
19 | console.log('https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-getting-started.html');
20 |
21 | return;
22 | }
23 |
24 | const profiles = matches.map((match) => {
25 | return match.replace(bracketsRemovalRegx, '');
26 | });
27 |
28 | profiles.push(defaultProfileChoice);
29 |
30 | const profileChoice = [
31 | {
32 | type: 'list',
33 | name: 'profile',
34 | message: 'Choose a profile',
35 | choices: profiles,
36 | default: process.env.AWS_PROFILE || defaultProfileChoice
37 | }
38 | ];
39 |
40 | return inquirer.prompt(profileChoice);
41 | }
42 |
43 | const readAwsProfiles = () => {
44 | return new Promise((resolve, reject) => {
45 | fs.readFile(`${homeDir}/.aws/config`, 'utf8', (err, data) => {
46 | if (err) {
47 | reject(err);
48 | } else {
49 | resolve(data);
50 | }
51 | });
52 | });
53 | };
54 |
55 | const writeToConfig = (answers) => {
56 | const profileChoice =
57 | answers.profile === defaultProfileChoice ? '' : answers.profile;
58 |
59 | return new Promise((resolve, reject) => {
60 | fs.writeFile(`${homeDir}/.awsp`, profileChoice, { flag: 'w' }, function (err) {
61 | if (err) {
62 | reject(err);
63 | } else {
64 | resolve();
65 | }
66 | });
67 | });
68 | };
69 |
70 | readAwsProfiles()
71 | .then(promptProfileChoice)
72 | .then(writeToConfig)
73 | .catch(error => {
74 | console.log('Error:', error);
75 | process.exit(1);
76 | });
77 |
--------------------------------------------------------------------------------
/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "awsp",
3 | "version": "0.2.0",
4 | "lockfileVersion": 1,
5 | "requires": true,
6 | "dependencies": {
7 | "ansi-escapes": {
8 | "version": "3.1.0",
9 | "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.1.0.tgz",
10 | "integrity": "sha512-UgAb8H9D41AQnu/PbWlCofQVcnV4Gs2bBJi9eZPxfU/hgglFh3SMDMENRIqdr7H6XFnXdoknctFByVsCOotTVw=="
11 | },
12 | "ansi-regex": {
13 | "version": "3.0.0",
14 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
15 | "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg="
16 | },
17 | "ansi-styles": {
18 | "version": "3.2.1",
19 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
20 | "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
21 | "requires": {
22 | "color-convert": "^1.9.0"
23 | }
24 | },
25 | "chalk": {
26 | "version": "2.4.1",
27 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz",
28 | "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==",
29 | "requires": {
30 | "ansi-styles": "^3.2.1",
31 | "escape-string-regexp": "^1.0.5",
32 | "supports-color": "^5.3.0"
33 | }
34 | },
35 | "chardet": {
36 | "version": "0.4.2",
37 | "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.4.2.tgz",
38 | "integrity": "sha1-tUc7M9yXxCTl2Y3IfVXU2KKci/I="
39 | },
40 | "cli-cursor": {
41 | "version": "2.1.0",
42 | "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz",
43 | "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=",
44 | "requires": {
45 | "restore-cursor": "^2.0.0"
46 | }
47 | },
48 | "cli-width": {
49 | "version": "2.2.0",
50 | "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz",
51 | "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk="
52 | },
53 | "color-convert": {
54 | "version": "1.9.3",
55 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
56 | "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
57 | "requires": {
58 | "color-name": "1.1.3"
59 | }
60 | },
61 | "color-name": {
62 | "version": "1.1.3",
63 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
64 | "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU="
65 | },
66 | "escape-string-regexp": {
67 | "version": "1.0.5",
68 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
69 | "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ="
70 | },
71 | "external-editor": {
72 | "version": "2.2.0",
73 | "resolved": "http://registry.npmjs.org/external-editor/-/external-editor-2.2.0.tgz",
74 | "integrity": "sha512-bSn6gvGxKt+b7+6TKEv1ZycHleA7aHhRHyAqJyp5pbUFuYYNIzpZnQDk7AsYckyWdEnTeAnay0aCy2aV6iTk9A==",
75 | "requires": {
76 | "chardet": "^0.4.0",
77 | "iconv-lite": "^0.4.17",
78 | "tmp": "^0.0.33"
79 | }
80 | },
81 | "figures": {
82 | "version": "2.0.0",
83 | "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz",
84 | "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=",
85 | "requires": {
86 | "escape-string-regexp": "^1.0.5"
87 | }
88 | },
89 | "has-flag": {
90 | "version": "3.0.0",
91 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
92 | "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0="
93 | },
94 | "iconv-lite": {
95 | "version": "0.4.24",
96 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
97 | "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
98 | "requires": {
99 | "safer-buffer": ">= 2.1.2 < 3"
100 | }
101 | },
102 | "inquirer": {
103 | "version": "5.2.0",
104 | "resolved": "http://registry.npmjs.org/inquirer/-/inquirer-5.2.0.tgz",
105 | "integrity": "sha512-E9BmnJbAKLPGonz0HeWHtbKf+EeSP93paWO3ZYoUpq/aowXvYGjjCSuashhXPpzbArIjBbji39THkxTz9ZeEUQ==",
106 | "requires": {
107 | "ansi-escapes": "^3.0.0",
108 | "chalk": "^2.0.0",
109 | "cli-cursor": "^2.1.0",
110 | "cli-width": "^2.0.0",
111 | "external-editor": "^2.1.0",
112 | "figures": "^2.0.0",
113 | "lodash": "^4.3.0",
114 | "mute-stream": "0.0.7",
115 | "run-async": "^2.2.0",
116 | "rxjs": "^5.5.2",
117 | "string-width": "^2.1.0",
118 | "strip-ansi": "^4.0.0",
119 | "through": "^2.3.6"
120 | }
121 | },
122 | "is-fullwidth-code-point": {
123 | "version": "2.0.0",
124 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
125 | "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8="
126 | },
127 | "is-promise": {
128 | "version": "2.1.0",
129 | "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz",
130 | "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o="
131 | },
132 | "lodash": {
133 | "version": "4.17.11",
134 | "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz",
135 | "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg=="
136 | },
137 | "mimic-fn": {
138 | "version": "1.2.0",
139 | "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz",
140 | "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ=="
141 | },
142 | "mute-stream": {
143 | "version": "0.0.7",
144 | "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz",
145 | "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s="
146 | },
147 | "onetime": {
148 | "version": "2.0.1",
149 | "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz",
150 | "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=",
151 | "requires": {
152 | "mimic-fn": "^1.0.0"
153 | }
154 | },
155 | "os-tmpdir": {
156 | "version": "1.0.2",
157 | "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
158 | "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ="
159 | },
160 | "restore-cursor": {
161 | "version": "2.0.0",
162 | "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz",
163 | "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=",
164 | "requires": {
165 | "onetime": "^2.0.0",
166 | "signal-exit": "^3.0.2"
167 | }
168 | },
169 | "run-async": {
170 | "version": "2.3.0",
171 | "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz",
172 | "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=",
173 | "requires": {
174 | "is-promise": "^2.1.0"
175 | }
176 | },
177 | "rxjs": {
178 | "version": "5.5.12",
179 | "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-5.5.12.tgz",
180 | "integrity": "sha512-xx2itnL5sBbqeeiVgNPVuQQ1nC8Jp2WfNJhXWHmElW9YmrpS9UVnNzhP3EH3HFqexO5Tlp8GhYY+WEcqcVMvGw==",
181 | "requires": {
182 | "symbol-observable": "1.0.1"
183 | }
184 | },
185 | "safer-buffer": {
186 | "version": "2.1.2",
187 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
188 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
189 | },
190 | "signal-exit": {
191 | "version": "3.0.2",
192 | "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz",
193 | "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0="
194 | },
195 | "string-width": {
196 | "version": "2.1.1",
197 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
198 | "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
199 | "requires": {
200 | "is-fullwidth-code-point": "^2.0.0",
201 | "strip-ansi": "^4.0.0"
202 | }
203 | },
204 | "strip-ansi": {
205 | "version": "4.0.0",
206 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
207 | "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
208 | "requires": {
209 | "ansi-regex": "^3.0.0"
210 | }
211 | },
212 | "supports-color": {
213 | "version": "5.5.0",
214 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
215 | "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
216 | "requires": {
217 | "has-flag": "^3.0.0"
218 | }
219 | },
220 | "symbol-observable": {
221 | "version": "1.0.1",
222 | "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.0.1.tgz",
223 | "integrity": "sha1-g0D8RwLDEi310iKI+IKD9RPT/dQ="
224 | },
225 | "through": {
226 | "version": "2.3.8",
227 | "resolved": "http://registry.npmjs.org/through/-/through-2.3.8.tgz",
228 | "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU="
229 | },
230 | "tmp": {
231 | "version": "0.0.33",
232 | "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",
233 | "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==",
234 | "requires": {
235 | "os-tmpdir": "~1.0.2"
236 | }
237 | }
238 | }
239 | }
240 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "awsp",
3 | "version": "0.2.0",
4 | "description": "Switch AWS Profiles easily",
5 | "main": "index.js",
6 | "homepage": "https://github.com/johnnyopao/awsp",
7 | "scripts": {
8 | "test": "echo \"Error: no test specified\" && exit 1",
9 | "postinstall": "./postinstall.sh"
10 | },
11 | "author": "Johnny Opao",
12 | "license": "ISC",
13 | "bin": {
14 | "_awsp_prompt": "./index.js",
15 | "_awsp": "./run.sh"
16 | },
17 | "dependencies": {
18 | "inquirer": "^5.0.1"
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/postinstall.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | echo "Add the following to your .bashrc or .zshrc config"
4 | echo ' alias awsp="source _awsp"'
5 | echo ""
--------------------------------------------------------------------------------
/run.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | AWS_PROFILE="$AWS_PROFILE" _awsp_prompt
4 |
5 | selected_profile="$(cat ~/.awsp)"
6 |
7 | if [ -z "$selected_profile" ]
8 | then
9 | unset AWS_PROFILE
10 | else
11 | export AWS_PROFILE="$selected_profile"
12 | fi
13 |
--------------------------------------------------------------------------------
/screenshot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johnnyopao/awsp/0656893f9521887d3af3d869cc757a64cdfcd179/screenshot.png
--------------------------------------------------------------------------------