UNPKG

@salto-io/da-playa

Version:

Deploy locks management (CLI and Slackbot)

127 lines 4.4 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.Locker = exports.LockModelDetails = exports.ModelName = void 0; const dynamodb_1 = __importDefault(require("dynamodb")); const joi_1 = __importDefault(require("joi")); const data_1 = require("../data"); const TTL = 20 * 60 * 1000; exports.ModelName = 'lock'; const locksDynamoDbModel = { hashKey: 'id', rangeKey: 'env', timestamps: false, schema: { user: joi_1.default.string().required(), id: dynamodb_1.default.types.uuid(), env: joi_1.default.string().required(), active: joi_1.default.boolean(), started: joi_1.default.number().required(), ended: joi_1.default.number(), uberlock: joi_1.default.boolean(), meta: joi_1.default.string(), }, tableName: 'DaPlayaLocks', }; exports.LockModelDetails = { Model: locksDynamoDbModel, ModelName: exports.ModelName, }; const Locker = async ({ dynamoDBRegion, dynamoDbUri, }) => { const LocksDB = (0, data_1.Data)({ model: locksDynamoDbModel, modelName: exports.ModelName, dynamoDBRegion, dynamoDbUri, }); const getActiveLocks = (env, user) => { const ttl = new Date().getTime() - TTL; const userFilterString = user ? ' AND #user = :user' : ''; const filterEnvExpression = '#env = :env'; const filterActiveOrUber = '(#started > :ttl OR #uberlock = :true) AND #active = :true'; const filterExpression = `${filterEnvExpression} AND (${filterActiveOrUber})${userFilterString}`; const filterAttributeValues = { ':true': true, ':env': env, ':ttl': ttl, ...(user ? { ':user': user, } : {}), }; const filterAttributeNames = { '#env': 'env', '#active': 'active', '#started': 'started', '#uberlock': 'uberlock', ...(user ? { '#user': 'user', } : {}), }; return LocksDB.get({ filterExpression, filterAttributeValues, filterAttributeNames, }); }; const updatePromiseByUser = async (env, user, uberlock = false) => { const currentLock = await getActiveLocks(env, user); if (!currentLock.length) { return { notLockedBy: user.toLowerCase(), }; } if (currentLock[0].uberlock && !uberlock) { return { currentLock: currentLock[0], }; } return LocksDB.set({ ...currentLock[0], active: false, ended: new Date().getTime(), }); }; const createLock = async ({ user, env, meta, uberlock, }) => LocksDB.create({ user: user.toLowerCase(), env: env.toLowerCase(), active: true, started: new Date().getTime(), meta, uberlock, }); return { lock: async ({ user, env, meta, uberlock = false }) => { const activeLocks = await getActiveLocks(env); const existingUberLock = activeLocks.find(x => x.uberlock); if (existingUberLock) { return existingUberLock.user !== user ? { // LockRejected due to other user uberlocking currentLock: existingUberLock, } : existingUberLock; } if (uberlock) { return createLock({ user, env, meta, uberlock }); } const currentUserLock = activeLocks.find(x => x.user === user); if (currentUserLock) { return currentUserLock; } if (!activeLocks.length) { return createLock({ user, env, meta, uberlock }); } return { currentLock: activeLocks[0], }; }, release: async ({ env, user, uberlock }) => updatePromiseByUser(env, user, uberlock), locks: async (env, user) => getActiveLocks(env, user), }; }; exports.Locker = Locker; //# sourceMappingURL=index.js.map