ssm-parameters
Version:
Lightweight AWS Parameter Store wrapper
230 lines • 15.4 kB
JavaScript
"use strict";
/*
* Copyright (c) 2021 Gustavo Salomão
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __generator = (this && this.__generator) || function (thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (_) try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.SSMParameters = void 0;
var aws_sdk_1 = require("aws-sdk");
/**
* Class responsible to load and cache parameters from the AWS SSM Parameters
* Store.
*/
var SSMParameters = /** @class */ (function () {
/**
* Create an instance of the *SSMParameters*.
*
* @example
* new SSMParameters({ LogLevel: '/LogLevel' });
* new SSMParameters({ LogLevel: '/LogLevel' }, { maxAge: 60 });
*
* @param parameters Map with parameter's keys and parameter's names on AWS.
* @param options *SSMParametersOptions*
*/
function SSMParameters(parameters, options) {
var _this = this;
var _a, _b;
this.DEFAULT_WITH_DECRYPTION = true;
this.DEFAULT_MAX_AGE_IN_SECONDS = 3600;
this.MAX_PARAMETERS_PER_REQUEST = 10;
this.parametersValue = {};
this.parameterLoaded = {};
this.parametersName = parameters;
this.maxAge = (_a = options === null || options === void 0 ? void 0 : options.maxAge) !== null && _a !== void 0 ? _a : this.DEFAULT_MAX_AGE_IN_SECONDS;
this.ssmClient = new aws_sdk_1.SSM(options === null || options === void 0 ? void 0 : options.ssmConfiguration);
this.withDecryption =
(_b = options === null || options === void 0 ? void 0 : options.withDecryption) !== null && _b !== void 0 ? _b : this.DEFAULT_WITH_DECRYPTION;
Object.values(parameters).forEach(function (name) {
_this.parametersValue[name] = undefined;
_this.parameterLoaded[name] = false;
});
}
/**
* Load parameters from AWS SSM Parameter Store.
*
* @note
* - If the parameters have not been loaded yet, they will be loaded.
* - If the parameters have been loaded and cache didn't expired yet,
* it uses the cache.
* - If the parameters have been loaded but the cache has expired, it loads
* the parameters again.
*
* @param options *SSMParametersLoadOptions*
* @returns Promise to when parameters have been loaded or cache is used.
*/
SSMParameters.prototype.load = function (options) {
if (options === void 0) { options = { ignoreCache: false }; }
return __awaiter(this, void 0, void 0, function () {
var cacheAge, parametersToLoad;
return __generator(this, function (_a) {
cacheAge = this.lastLoadTime
? Math.round((new Date().getTime() - this.lastLoadTime.getTime()) / 1000)
: this.maxAge + 1;
if (!options.ignoreCache && this.maxAge && cacheAge <= this.maxAge) {
return [2 /*return*/, Promise.resolve()];
}
Object.entries(this.parameterLoaded).forEach(function (param) { return (param[1] = false); });
parametersToLoad = this.getParametersToLoad();
return [2 /*return*/, this.loadParameters(parametersToLoad)];
});
});
};
/**
* Get parameter.
*
* @note
* - If the parameters have not been loaded yet, they will be loaded.
* - If the parameters have been loaded and cache didn't expired yet,
* it uses the cache.
* - If the parameters have been loaded but the cache has expired, it loads
* the parameters again.
*
* @param key Key of the parameter.
* @param options *SSMParametersLoadOptions*
* @returns Promise to parameter's value or undefined if it does not exist.
*/
SSMParameters.prototype.get = function (key, options) {
if (options === void 0) { options = { ignoreCache: false }; }
return __awaiter(this, void 0, void 0, function () {
var _this = this;
return __generator(this, function (_a) {
return [2 /*return*/, this.load(options).then(function () { return _this.parametersValue[_this.parametersName[key]]; })];
});
});
};
/**
* Get parameters.
*
* @note
* - If the parameters have not been loaded yet, they will be loaded.
* - If the parameters have been loaded and cache didn't expired yet,
* it uses the cache.
* - If the parameters have been loaded but the cache has expired, it loads
* the parameters again.
*
* @param options *SSMParametersLoadOptions*
* @returns Promise to all parameters.
*/
SSMParameters.prototype.getAll = function (options) {
if (options === void 0) { options = { ignoreCache: false }; }
return __awaiter(this, void 0, void 0, function () {
var _this = this;
return __generator(this, function (_a) {
return [2 /*return*/, this.load(options).then(function () {
var response = {};
Object.entries(_this.parametersName).forEach(function (_a) {
var name = _a[0], value = _a[1];
response[name] = _this.parametersValue[value];
});
return response;
})];
});
});
};
/**
* Get parameters to load.
*
* @note The array returned by this function contains a maximum number of
* parameters defined by `MAX_PARAMETERS_PER_REQUEST`.
*
* @returns Array of parameters to load.
*/
SSMParameters.prototype.getParametersToLoad = function () {
return Object.entries(this.parameterLoaded)
.filter(function (param) { return !param[1]; })
.map(function (param) { return param[0]; })
.slice(0, this.MAX_PARAMETERS_PER_REQUEST);
};
/**
* Load parameters from AWS SSM.
*
* @param parameters Parameters to load from AWS SSM.
* @returns Promise to when parameters have been loaded.
*/
SSMParameters.prototype.loadParameters = function (parameters) {
return __awaiter(this, void 0, void 0, function () {
var ssmRequest;
var _this = this;
return __generator(this, function (_a) {
ssmRequest = {
Names: parameters,
WithDecryption: this.withDecryption,
};
return [2 /*return*/, this.ssmClient
.getParameters(ssmRequest)
.promise()
.then(function (response) {
response.Parameters.forEach(function (param) {
_this.parametersValue[param.Name] = param.Value;
});
parameters.forEach(function (param) {
_this.parameterLoaded[param] = true;
});
parameters = _this.getParametersToLoad();
if (parameters.length) {
return _this.loadParameters(parameters);
}
_this.lastLoadTime = new Date();
return Promise.resolve();
})];
});
});
};
return SSMParameters;
}());
exports.SSMParameters = SSMParameters;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3NtLXBhcmFtZXRlcnMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvc3NtLXBhcmFtZXRlcnMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FxQkc7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUVILG1DQUE4QjtBQXdCOUI7OztHQUdHO0FBQ0g7SUFhRTs7Ozs7Ozs7O09BU0c7SUFDSCx1QkFBWSxVQUFzQixFQUFFLE9BQThCO1FBQWxFLGlCQVdDOztRQWpDZ0IsNEJBQXVCLEdBQUcsSUFBSSxDQUFDO1FBQy9CLCtCQUEwQixHQUFHLElBQUksQ0FBQztRQUNsQywrQkFBMEIsR0FBRyxFQUFFLENBQUM7UUFNekMsb0JBQWUsR0FBdUMsRUFBRSxDQUFDO1FBQ3pELG9CQUFlLEdBQTRCLEVBQUUsQ0FBQztRQWNwRCxJQUFJLENBQUMsY0FBYyxHQUFHLFVBQVUsQ0FBQztRQUNqQyxJQUFJLENBQUMsTUFBTSxHQUFHLE1BQUEsT0FBTyxhQUFQLE9BQU8sdUJBQVAsT0FBTyxDQUFFLE1BQU0sbUNBQUksSUFBSSxDQUFDLDBCQUEwQixDQUFDO1FBQ2pFLElBQUksQ0FBQyxTQUFTLEdBQUcsSUFBSSxhQUFHLENBQUMsT0FBTyxhQUFQLE9BQU8sdUJBQVAsT0FBTyxDQUFFLGdCQUFnQixDQUFDLENBQUM7UUFDcEQsSUFBSSxDQUFDLGNBQWM7WUFDakIsTUFBQSxPQUFPLGFBQVAsT0FBTyx1QkFBUCxPQUFPLENBQUUsY0FBYyxtQ0FBSSxJQUFJLENBQUMsdUJBQXVCLENBQUM7UUFFMUQsTUFBTSxDQUFDLE1BQU0sQ0FBQyxVQUFVLENBQUMsQ0FBQyxPQUFPLENBQUMsVUFBQyxJQUFZO1lBQzdDLEtBQUksQ0FBQyxlQUFlLENBQUMsSUFBSSxDQUFDLEdBQUcsU0FBUyxDQUFDO1lBQ3ZDLEtBQUksQ0FBQyxlQUFlLENBQUMsSUFBSSxDQUFDLEdBQUcsS0FBSyxDQUFDO1FB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