@salto-io/da-playa
Version:
Deploy locks management (CLI and Slackbot)
115 lines (108 loc) • 4.11 kB
text/typescript
import { Command } from 'commander'
import { Locker, LockRejected } from '../locker'
import { log, prettify } from './common'
export { LockModelDetails } from '../locker'
const UBERLOCK_UNIVERSAL_SIGN = '(ノ≥∇≤)ノ'
const RETRY_SECONDS = 5
export const lockCommands = (
envDynamoDBRegion?: string
): Command => {
const program = new Command('locks')
.description('Manage locks')
program
.command('lock')
.description('Locks an environment for a user')
.requiredOption('--user <user>', 'User to lock for')
.requiredOption('--env <env>', 'Environment to lock')
.option(
'--dynamoDBRegion <dynamoDBRegion>',
'DynamoDB Region (Optional, Taken from DAPLAYA_AWS_REGION if set)',
envDynamoDBRegion,
)
.option('--uberlock', 'Lock current env until explicitly released')
.option('--meta <meta>', 'Extra metadata to save')
.action(async ({ user, env, uberlock, meta, ...rest }) => {
const locker = await Locker(rest)
const lockInterval = setInterval(async () => {
const lockResult = await locker.lock({ user, env, uberlock, meta })
if ('currentLock' in lockResult) {
const { currentLock } = lockResult as LockRejected
if (currentLock.uberlock) {
log(
`${prettify.env(env)} is uberlocked ${prettify.misc(
UBERLOCK_UNIVERSAL_SIGN,
)} by ${prettify.user(currentLock.user)}`,
)
process.exit(1)
}
log(
`${prettify.env(env)} is currently locked by ${prettify.user(
currentLock.user,
)}, retrying in ${prettify.misc(RETRY_SECONDS)} seconds`,
)
} else {
log(
`${prettify.env(env)} succesfully locked for ${prettify.user(user)}${lockResult.uberlock ? ` uberlock ${prettify.misc(UBERLOCK_UNIVERSAL_SIGN)}` : ''
}`,
)
clearInterval(lockInterval)
}
}, RETRY_SECONDS * 1000)
})
program
.command('release')
.description('Releases an environment for a user')
.requiredOption('--user <user>', 'User to release')
.requiredOption('--env <env>', 'Environment to release')
.option('--uberlock', 'Release even if UBERLOCKED')
.option(
'--dynamoDBRegion <dynamoDBRegion>',
'DynamoDB Region (Optional, Taken from DAPLAYA_AWS_REGION if set)',
envDynamoDBRegion,
)
.action(async ({ user, env, uberlock, ...rest }) => {
const locker = await Locker(rest)
const releaseResult = await locker.release({ user, env, uberlock })
if ('notLockedBy' in releaseResult) {
log(`${prettify.env(env)} was not locked...`)
} else if ('currentLock' in releaseResult) {
log(`${prettify.env(env)} is uberlocked ${prettify.misc(UBERLOCK_UNIVERSAL_SIGN)} by user ${prettify.user(user)}...`)
} else {
log(
`Released ${prettify.env(env)} for user ${prettify.user(user)}${releaseResult.uberlock
? ` no longer uberlocked ${prettify.misc(UBERLOCK_UNIVERSAL_SIGN)}`
: ''
}`,
)
}
})
program
.command('list')
.description('List current locks')
.requiredOption('--env <env>', 'Environment to release')
.option(
'--dynamoDBRegion <dynamoDBRegion>',
'DynamoDB Region (Optional, Taken from DAPLAYA_AWS_REGION if set)',
envDynamoDBRegion,
)
.action(async ({ env, ...rest }) => {
const locker = await Locker(rest)
const locks = await locker.locks(env)
if (!locks.length) {
log(`No locks found for ${prettify.env(env)}`)
} else {
log(
`Found ${prettify.misc(locks.length)} lock${locks.length > 1 ? 's' : ''} for ${prettify.env(
env,
)}:`,
)
locks.forEach(lock => {
log(
`User: ${prettify.user(lock.user)}${lock.uberlock ? ` uberlock ${prettify.misc(UBERLOCK_UNIVERSAL_SIGN)}` : ''
}${lock.meta ? ` ${prettify.misc(lock.meta)}` : ''}`,
)
})
}
})
return program
}