Skip to content

Commit

Permalink
Refactor credential checker into its own utility method
Browse files Browse the repository at this point in the history
  • Loading branch information
ryanblock committed Oct 25, 2023
1 parent 7dd623f commit 12a202a
Show file tree
Hide file tree
Showing 7 changed files with 110 additions and 118 deletions.
16 changes: 0 additions & 16 deletions banner/_get-creds.js

This file was deleted.

34 changes: 0 additions & 34 deletions banner/cred-check.js

This file was deleted.

80 changes: 32 additions & 48 deletions banner/index.js
Original file line number Diff line number Diff line change
@@ -1,65 +1,49 @@
let chalk = require('chalk')
let chars = require('../chars')
let credCheck = require('./cred-check')

module.exports = function printBanner (params = {}) {
let {
cwd = process.cwd(),
checkCreds,
inventory,
disableBanner,
disableRegion,
disableProfile,
needsValidCreds,
version = '–',
} = params
let quiet = process.env.ARC_QUIET || process.env.QUIET || params.quiet

if (disableBanner) return
else {
// Boilerplate
let log = (label, value) => {
if (!quiet) {
console.log(chalk.grey(`${label.padStart(12)} ${chars.buzz}`), chalk.cyan(value))
}
}

// Initialize config
process.env.ARC_APP_NAME = inventory.inv.app

// 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 = inventory.inv?.aws?.region || process.env.AWS_REGION || 'Region not configured'
if (!disableRegion) {
log('Region', region)
}

// Profile
let profile = process.env.AWS_ACCESS_KEY_ID &&
process.env.ARC_AWS_CREDS !== 'dummy'
? 'Set via environment'
: inventory.inv?.aws?.profile || process.env.AWS_PROFILE || 'Profile not configured'
if (!disableProfile) {
log('Profile', profile)
// Boilerplate
let log = (label, value) => {
if (!quiet) {
console.log(chalk.grey(`${label.padStart(12)} ${chars.buzz}`), chalk.cyan(value))
}

// Caller version
// Also: set deprecation status for legacy Arc installs
log('Version', version)

// cwd
log('cwd', cwd)

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

// Space
if (!quiet) console.log()
}

// App name
let name = inventory.inv.app || 'Architect project manifest not found'
log('App', name)

// Region
let region = inventory.inv?.aws?.region ||
process.env.AWS_REGION ||
'Region not configured'
log('Region', region)

// Profile
let credsViaEnv = process.env.AWS_ACCESS_KEY_ID ? 'Set via environment' : undefined
let profile = credsViaEnv ||
inventory.inv?.aws?.profile ||
process.env.AWS_PROFILE ||
'Not configured / default'
log('Profile', profile)

// Caller version
// Also: set deprecation status for legacy Arc installs
log('Version', version)

// cwd
log('cwd', cwd)

// Space
if (!quiet) console.log()
}
12 changes: 9 additions & 3 deletions changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,18 @@

## [4.0.0] 2023-10-19

### Added

- Added `checkCreds` method for manually performing basic AWS credential checks


### 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
- Initializing the Architect banner is significantly faster, as it no longer has any interactions with `aws-sdk`
- Breaking change: banner initialization no longer has any direct responsibility for credential checking
- Related: banner initialization no longer mutates `AWS_PROFILE`, or uses `ARC_AWS_CREDS` as a signal to other modules about credential loading
- 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
- Banner initialization no longer utilizes `disableRegion` or `disableProfile` params when printing

---

Expand Down
29 changes: 29 additions & 0 deletions check-creds/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/**
* Credential check
* - 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, but sometimes we need to halt (via this util)
*/
module.exports = function checkAwsCredentials (params, callback) {
// eslint-disable-next-line
let awsLite = require('@aws-lite/client')
let { inventory } = params

let promise
if (!callback) {
promise = new Promise((res, rej) => {
callback = (err, result) => err ? rej(err) : res(result)
})
}

let errMsg = 'Valid AWS credentials needed to continue; missing or invalid credentials'
awsLite({
autoloadPlugins: false,
profile: inventory.inv?.aws?.profile, // aws-lite falls back to AWS_PROFILE or 'default' if undefined
region: 'us-west-1',
})
.then(() => callback())
.catch(() => callback(Error(errMsg)))

return promise
}
4 changes: 3 additions & 1 deletion index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
let banner = require('./banner')
let chars = require('./chars')
let checkCreds = require('./check-creds')
let deepFrozenCopy = require('./deep-frozen-copy')
let fingerprint = require('./fingerprint')
let getLambdaName = require('./get-lambda-name')
Expand All @@ -8,8 +9,9 @@ let toLogicalID = require('./to-logical-id')
let updater = require('./updater')

module.exports = {
banner, // Prints banner and loads basic env vars and AWS creds
banner, // Prints banner
chars, // Returns platform appropriate characters for CLI UI printing
checkCreds, // Performs basic AWS credential check
deepFrozenCopy, // Fast deep frozen object copy
fingerprint, // Generates public/static.json for `@static fingerprint true`
getLambdaName, // Get Lambda name from Arc path
Expand Down
53 changes: 37 additions & 16 deletions test/banner/cred-check-test.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
let test = require('tape')
let credCheck = require('../../banner/cred-check')
let checkCreds = require('../../check-creds')

function reset (t) {
let envVars = [
Expand All @@ -21,33 +21,54 @@ let inventory = { inv: { aws: {} } }

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

test('Credential check is disabled', t => {
test('Credential checks (async)', async 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')

// Count on aws-lite finding creds (via env)
process.env.AWS_ACCESS_KEY_ID = 'yo'
process.env.AWS_SECRET_ACCESS_KEY = 'yo'
try {
await checkCreds({ inventory })
t.pass('No credential loading error reported')
}
catch (err) {
t.fail(err)
}

// Fail a cred check
reset(t)
process.env.AWS_PROFILE = 'random_profile_name_that_does_not_exist'
try {
await checkCreds({ inventory })
t.fail('Should have errored')
}
catch (err) {
t.ok(err, 'Reported credential loading error')
}
reset(t)
})

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

// 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')
checkCreds({ inventory }, err => {
reset(t)
if (err) t.fail(err)
else t.pass('No credential loading error reported')
})

// 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)
checkCreds({ inventory }, err => {
reset(t)
if (err) t.ok(err, 'Reported credential loading error')
else t.fail('Should have errored')
})
})

0 comments on commit 12a202a

Please sign in to comment.