Skip to content

Commit

Permalink
aws-sdk@aws-lite/client
Browse files Browse the repository at this point in the history
[Breaking change] Refactor AWS credential initialization steps and mutation of `AWS_PROFILE`, `ARC_AWS_CREDS`
Temporarily revert to `tap-spec`
  • Loading branch information
ryanblock committed Oct 19, 2023
1 parent f23247f commit bf3cec2
Show file tree
Hide file tree
Showing 8 changed files with 152 additions and 290 deletions.
16 changes: 16 additions & 0 deletions banner/_get-creds.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
let awsLite = require('@aws-lite/client')
async function main () {
try {
let options = { autoloadPlugins: false, region: 'us-west-1' }
if (process.env._ARC_PROFILE) options.profile = process.env._ARC_PROFILE
await awsLite(options)
console.log(JSON.stringify({ ok: true }))
}
catch (err) {
console.log(JSON.stringify({
error: err.message,
stack: err.stack,
}))
}
}
main()
44 changes: 44 additions & 0 deletions banner/cred-check.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
let { join } = require('path')

/**
* Credential check and possible backstop
* - aws-lite requires credentials to initialize
* - Architect needs credentials for some things (e.g. Deploy), but also has a variety of offline workflows that interface with AWS service API emulators (e.g. Sandbox)
* - Thus, sometimes it's ok to use dummy creds, sometimes we need to halt
*/
module.exports = function credCheck ({ checkCreds = true, inventory, needsValidCreds = false }) {
if (!checkCreds) return

// eslint-disable-next-line
let { execFileSync } = require('child_process')
let script = join(__dirname, '_get-creds.js')
function check () {
try {
let env = { ...process.env }
if (inventory.inv?.aws?.profile) {
env._ARC_PROFILE = inventory.inv?.aws?.profile
}
let result = execFileSync('node', [ script ], { env })
return JSON.parse(result)
}
catch (err) {
console.error('Unknown credential check error')
throw err
}
}

let creds = check()
if (creds.error && needsValidCreds) {
return Error('Valid credentials needed to run this command; missing or invalid credentials')
}
else if (creds.error) {
/**
* Backfill creds - any creds will do for local service emulation
* - Be sure we backfill Lambda's prepopulated env vars
* - sessionToken / AWS_SESSION_TOKEN is optional, skip so as not to introduce unintended side-effects
*/
process.env.ARC_AWS_CREDS = 'dummy'
process.env.AWS_ACCESS_KEY_ID = 'arc_dummy_access_key'
process.env.AWS_SECRET_ACCESS_KEY = 'arc_dummy_secret_key'
}
}
21 changes: 13 additions & 8 deletions banner/index.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
let chalk = require('chalk')
let chars = require('../chars')
let initAWS = require('./init-aws')
let credCheck = require('./cred-check')

module.exports = function printBanner (params = {}) {
let {
cwd = process.cwd(),
checkCreds,
inventory,
disableBanner,
disableRegion,
Expand All @@ -25,22 +26,25 @@ module.exports = function printBanner (params = {}) {

// Initialize config
process.env.ARC_APP_NAME = inventory.inv.app
initAWS({ inventory, needsValidCreds })

// Check creds
let credError = credCheck({ checkCreds, inventory, needsValidCreds })

// App name
let name = process.env.ARC_APP_NAME || 'Architect project manifest not found'
log('App', name)

// Region
let region = process.env.AWS_REGION || '@aws region / AWS_REGION not configured'
let region = inventory.inv?.aws?.region || process.env.AWS_REGION || 'Region not configured'
if (!disableRegion) {
log('Region', region)
}

// Profile
let profile = process.env.ARC_AWS_CREDS === 'env'
let profile = process.env.AWS_ACCESS_KEY_ID &&
process.env.ARC_AWS_CREDS !== 'dummy'
? 'Set via environment'
: process.env.AWS_PROFILE || '@aws profile / AWS_PROFILE not configured'
: inventory.inv?.aws?.profile || process.env.AWS_PROFILE || 'Profile not configured'
if (!disableProfile) {
log('Profile', profile)
}
Expand All @@ -52,9 +56,10 @@ module.exports = function printBanner (params = {}) {
// cwd
log('cwd', cwd)

// Blow up (if necessary) after printing basic diagnostic stuff
if (credError) throw credError

// Space
if (!quiet) {
console.log()
}
if (!quiet) console.log()
}
}
116 changes: 0 additions & 116 deletions banner/init-aws.js

This file was deleted.

11 changes: 11 additions & 0 deletions changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,17 @@

---

## [4.0.0] 2023-10-19

### Changed

- Initializing the Architect banner is now significantly faster by way of relying on `aws-lite` (instead of `aws-sdk`)
- Breaking change: banner initialization no longer mutates `AWS_PROFILE`, or uses `ARC_AWS_CREDS` as a signal to other modules about credential loading
- While credential env vars (`AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`) are still backfilled in certain circumstances, modules relying on the banner for credential-related operations must review the changes and refactor accordingly
- Breaking change: banner initialization now throws on invalid credentials

---

## [3.1.7 - 3.1.9] 2023-04-22

### Changed
Expand Down
8 changes: 4 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@
},
"scripts": {
"test": "npm run lint && npm run test:unit:updater && npm run test:unit",
"test:unit": "cross-env tape 'test/**/*-test.js' | tap-arc",
"test:unit:updater": "cross-env tape test/updater/test.js | tap-arc",
"test:unit": "cross-env tape 'test/**/*-test.js' | tap-spec",
"test:unit:updater": "cross-env tape test/updater/test.js | tap-spec",
"lint": "npx eslint . --fix",
"rc": "npm version prerelease --preid RC"
},
Expand All @@ -20,6 +20,7 @@
"author": "Brian LeRoux <b@brian.io>",
"license": "Apache-2.0",
"dependencies": {
"@aws-lite/client": "0.11.1",
"chalk": "4.1.2",
"glob": "~10.2.2",
"path-sort": "~0.1.0",
Expand All @@ -31,12 +32,11 @@
"devDependencies": {
"@architect/eslint-config": "~2.1.2",
"@architect/inventory": "~3.4.3",
"aws-sdk": "^2.1363.0",
"cross-env": "~7.0.3",
"eslint": "~8.49.0",
"proxyquire": "~2.1.3",
"sinon": "~15.0.4",
"tap-arc": "~1.0.0",
"tap-spec": "5.0.0",
"tape": "~5.6.6",
"temp-write": "4.0.0"
},
Expand Down
64 changes: 64 additions & 0 deletions test/banner/cred-check-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
let test = require('tape')
let credCheck = require('../../banner/cred-check')

function reset (t) {
let envVars = [
'ARC_AWS_CREDS',
'AWS_PROFILE',
'AWS_REGION',
'AWS_ACCESS_KEY_ID',
'AWS_SECRET_ACCESS_KEY',
'AWS_SESSION_TOKEN',
'AWS_SHARED_CREDENTIALS_FILE',
]
envVars.forEach(v => delete process.env[v])
envVars.forEach(v => {
if (process.env[v]) t.fail(`Found errant env var: ${v}`)
})
}

let inventory = { inv: { aws: {} } }

test('Set up env', t => {
t.plan(1)
t.ok(credCheck, 'Found credCheck')
})

test('Credential check is disabled', t => {
t.plan(2)
let err = credCheck({ checkCreds: false, inventory })
t.notOk(err, 'No credential loading error reported')
t.notOk(process.env.ARC_AWS_CREDS, 'Did not mutate ARC_AWS_CREDS')
reset(t)
})

test('Credential checks', t => {
t.plan(3)
let err

// Count on aws-lite finding creds (via env)
process.env.AWS_ACCESS_KEY_ID = 'yo'
process.env.AWS_SECRET_ACCESS_KEY = 'yo'
err = credCheck({ inventory })
t.notOk(err, 'No credential loading error reported')
t.notOk(process.env.ARC_AWS_CREDS, 'Did not mutate ARC_AWS_CREDS')

// Fail a cred check
reset(t)
process.env.AWS_PROFILE = 'random_profile_name_that_does_not_exist'
err = credCheck({ inventory, needsValidCreds: true })
t.ok(err, 'Reported credential loading error')
console.log(err)
reset(t)
})

test('Credential backfill', t => {
t.plan(4)
process.env.AWS_PROFILE = 'random_profile_name_that_does_not_exist'
let err = credCheck({ inventory })
t.notOk(err, 'No credential loading error reported')
t.equal(process.env.ARC_AWS_CREDS, 'dummy', 'Mutated ARC_AWS_CREDS')
t.equal(process.env.AWS_ACCESS_KEY_ID, 'arc_dummy_access_key', 'Mutated AWS_ACCESS_KEY_ID')
t.equal(process.env.AWS_SECRET_ACCESS_KEY, 'arc_dummy_secret_key', 'Mutated AWS_SECRET_ACCESS_KEY')
reset(t)
})
Loading

0 comments on commit bf3cec2

Please sign in to comment.