@cloudsnorkel/cdk-github-runners
Version:
CDK construct to create GitHub Actions self-hosted runners. Creates ephemeral runners on demand. Easy to deploy and highly customizable.
140 lines • 15.4 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.MINIMAL_EC2_SSM_SESSION_MANAGER_POLICY_STATEMENT = exports.MINIMAL_ECS_SSM_SESSION_MANAGER_POLICY_STATEMENT = exports.MINIMAL_SSM_SESSION_MANAGER_POLICY_STATEMENT = exports.SingletonLogType = void 0;
exports.singletonLambda = singletonLambda;
exports.singletonLogGroup = singletonLogGroup;
exports.discoverCertificateFiles = discoverCertificateFiles;
const fs = require("fs");
const path = require("path");
const aws_cdk_lib_1 = require("aws-cdk-lib");
const cdk = require("aws-cdk-lib");
/**
* Initialize or return a singleton Lambda function instance.
*
* @internal
*/
function singletonLambda(functionType, scope, id, props) {
const constructName = `${id}-dcc036c8-876b-451e-a2c1-552f9e06e9e1`;
const existing = cdk.Stack.of(scope).node.tryFindChild(constructName);
if (existing) {
// Just assume this is true
return existing;
}
return new functionType(cdk.Stack.of(scope), constructName, props);
}
/**
* Central log group type.
*
* @internal
*/
var SingletonLogType;
(function (SingletonLogType) {
SingletonLogType["RUNNER_IMAGE_BUILD"] = "Runner Image Build Helpers Log";
SingletonLogType["ORCHESTRATOR"] = "Orchestrator Log";
SingletonLogType["SETUP"] = "Setup Log";
})(SingletonLogType || (exports.SingletonLogType = SingletonLogType = {}));
/**
* Initialize or return central log group instance.
*
* @internal
*/
function singletonLogGroup(scope, type) {
const existing = cdk.Stack.of(scope).node.tryFindChild(type);
if (existing) {
// Just assume this is true
return existing;
}
return new aws_cdk_lib_1.aws_logs.LogGroup(cdk.Stack.of(scope), type, {
retention: aws_cdk_lib_1.aws_logs.RetentionDays.ONE_MONTH,
removalPolicy: cdk.RemovalPolicy.DESTROY,
});
}
/**
* The absolute minimum permissions required for SSM Session Manager to work. Unlike `AmazonSSMManagedInstanceCore`, it doesn't give permission to read all SSM parameters.
*
* @internal
*/
exports.MINIMAL_SSM_SESSION_MANAGER_POLICY_STATEMENT = new aws_cdk_lib_1.aws_iam.PolicyStatement({
actions: [
'ssmmessages:CreateControlChannel',
'ssmmessages:CreateDataChannel',
'ssmmessages:OpenControlChannel',
'ssmmessages:OpenDataChannel',
],
resources: ['*'],
});
/**
* The absolute minimum permissions required for SSM Session Manager on ECS to work. Unlike `AmazonSSMManagedInstanceCore`, it doesn't give permission to read all SSM parameters.
*
* @internal
*/
exports.MINIMAL_ECS_SSM_SESSION_MANAGER_POLICY_STATEMENT = new aws_cdk_lib_1.aws_iam.PolicyStatement({
actions: [
'ssmmessages:CreateControlChannel',
'ssmmessages:CreateDataChannel',
'ssmmessages:OpenControlChannel',
'ssmmessages:OpenDataChannel',
's3:GetEncryptionConfiguration',
],
resources: ['*'],
});
/**
* The absolute minimum permissions required for SSM Session Manager on EC2 to work. Unlike `AmazonSSMManagedInstanceCore`, it doesn't give permission to read all SSM parameters.
*
* @internal
*/
exports.MINIMAL_EC2_SSM_SESSION_MANAGER_POLICY_STATEMENT = new aws_cdk_lib_1.aws_iam.PolicyStatement({
actions: [
'ssmmessages:CreateControlChannel',
'ssmmessages:CreateDataChannel',
'ssmmessages:OpenControlChannel',
'ssmmessages:OpenDataChannel',
's3:GetEncryptionConfiguration',
'ssm:UpdateInstanceInformation',
],
resources: ['*'],
});
/**
* Discovers certificate files from a given path (file or directory).
*
* If the path is a directory, finds all .pem and .crt files in it.
* If the path is a file, returns it as a single certificate file.
*
* @param sourcePath path to a certificate file or directory containing certificate files
* @returns array of certificate file paths, sorted alphabetically
* @throws Error if path doesn't exist, is neither file nor directory, or directory has no certificate files
*
* @internal
*/
function discoverCertificateFiles(sourcePath) {
let certificateFiles = [];
try {
const stat = fs.statSync(sourcePath);
if (stat.isDirectory()) {
// Read directory and find all .pem and .crt files
const files = fs.readdirSync(sourcePath);
certificateFiles = files
.filter(file => file.endsWith('.pem') || file.endsWith('.crt'))
.map(file => path.join(sourcePath, file))
.sort(); // Sort for consistent ordering
if (certificateFiles.length === 0) {
throw new Error(`No certificate files (.pem or .crt) found in directory: ${sourcePath}`);
}
}
else if (stat.isFile()) {
// Single file - backwards compatible
certificateFiles = [sourcePath];
}
else {
throw new Error(`Certificate source path is neither a file nor a directory: ${sourcePath}`);
}
}
catch (error) {
if (error.code === 'ENOENT') {
throw new Error(`Certificate source path does not exist: ${sourcePath}`);
}
throw error;
}
return certificateFiles;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvdXRpbHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBV0EsMENBWUM7QUFrQkQsOENBV0M7QUE4REQsNERBOEJDO0FBaEpELHlCQUF5QjtBQUN6Qiw2QkFBNkI7QUFDN0IsNkNBQXFGO0FBQ3JGLG1DQUFtQztBQUduQzs7OztHQUlHO0FBQ0gsU0FBZ0IsZUFBZSxDQUM3QixZQUF1RixFQUN2RixLQUFnQixFQUFFLEVBQVUsRUFBRSxLQUE4QjtJQUU1RCxNQUFNLGFBQWEsR0FBRyxHQUFHLEVBQUUsdUNBQXVDLENBQUM7SUFDbkUsTUFBTSxRQUFRLEdBQUcsR0FBRyxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsS0FBSyxDQUFDLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxhQUFhLENBQUMsQ0FBQztJQUN0RSxJQUFJLFFBQVEsRUFBRSxDQUFDO1FBQ2IsMkJBQTJCO1FBQzNCLE9BQU8sUUFBd0IsQ0FBQztJQUNsQyxDQUFDO0lBRUQsT0FBTyxJQUFJLFlBQVksQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQyxLQUFLLENBQUMsRUFBRSxhQUFhLEVBQUUsS0FBSyxDQUFDLENBQUM7QUFDckUsQ0FBQztBQUVEOzs7O0dBSUc7QUFDSCxJQUFZLGdCQUlYO0FBSkQsV0FBWSxnQkFBZ0I7SUFDMUIseUVBQXFELENBQUE7SUFDckQscURBQWlDLENBQUE7SUFDakMsdUNBQW1CLENBQUE7QUFDckIsQ0FBQyxFQUpXLGdCQUFnQixnQ0FBaEIsZ0JBQWdCLFFBSTNCO0FBRUQ7Ozs7R0FJRztBQUNILFNBQWdCLGlCQUFpQixDQUFDLEtBQWdCLEVBQUUsSUFBc0I7SUFDeEUsTUFBTSxRQUFRLEdBQUcsR0FBRyxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsS0FBSyxDQUFDLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUM3RCxJQUFJLFFBQVEs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LENBQUM7SUFDZCxDQUFDO0lBRUQsT0FBTyxnQkFBZ0IsQ0FBQztBQUMxQixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgZnMgZnJvbSAnZnMnO1xuaW1wb3J0ICogYXMgcGF0aCBmcm9tICdwYXRoJztcbmltcG9ydCB7IGF3c19pYW0gYXMgaWFtLCBhd3NfbGFtYmRhIGFzIGxhbWJkYSwgYXdzX2xvZ3MgYXMgbG9ncyB9IGZyb20gJ2F3cy1jZGstbGliJztcbmltcG9ydCAqIGFzIGNkayBmcm9tICdhd3MtY2RrLWxpYic7XG5pbXBvcnQgeyBDb25zdHJ1Y3QgfSBmcm9tICdjb25zdHJ1Y3RzJztcblxuLyoqXG4gKiBJbml0aWFsaXplIG9yIHJldHVybiBhIHNpbmdsZXRvbiBMYW1iZGEgZnVuY3Rpb24gaW5zdGFuY2UuXG4gKlxuICogQGludGVybmFsXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzaW5nbGV0b25MYW1iZGE8RnVuY3Rpb25UeXBlIGV4dGVuZHMgbGFtYmRhLkZ1bmN0aW9uPihcbiAgZnVuY3Rpb25UeXBlOiBuZXcgKHM6IENvbnN0cnVjdCwgaTogc3RyaW5nLCBwPzogbGFtYmRhLkZ1bmN0aW9uT3B0aW9ucykgPT4gRnVuY3Rpb25UeXBlLFxuICBzY29wZTogQ29uc3RydWN0LCBpZDogc3RyaW5nLCBwcm9wcz86IGxhbWJkYS5GdW5jdGlvbk9wdGlvbnMpOiBGdW5jdGlvblR5cGUge1xuXG4gIGNvbnN0IGNvbnN0cnVjdE5hbWUgPSBgJHtpZH0tZGNjMDM2YzgtODc2Yi00NTFlLWEyYzEtNTUyZjllMDZlOWUxYDtcbiAgY29uc3QgZXhpc3RpbmcgPSBjZGsuU3RhY2sub2Yoc2NvcGUpLm5vZGUudHJ5RmluZENoaWxkKGNvbnN0cnVjdE5hbWUpO1xuICBpZiAoZXhpc3RpbmcpIHtcbiAgICAvLyBKdXN0IGFzc3VtZSB0aGlzIGlzIHRydWVcbiAgICByZXR1cm4gZXhpc3RpbmcgYXMgRnVuY3Rpb25UeXBlO1xuICB9XG5cbiAgcmV0dXJuIG5ldyBmdW5jdGlvblR5cGUoY2RrLlN0YWNrLm9mKHNjb3BlKSwgY29uc3RydWN0TmFtZSwgcHJvcHMpO1xufVxuXG4vKipcbiAqIENlbnRyYWwgbG9nIGdyb3VwIHR5cGUuXG4gKlxuICogQGludGVybmFsXG4gKi9cbmV4cG9ydCBlbnVtIFNpbmdsZXRvbkxvZ1R5cGUge1xuICBSVU5ORVJfSU1BR0VfQlVJTEQgPSAnUnVubmVyIEltYWdlIEJ1aWxkIEhlbHBlcnMgTG9nJyxcbiAgT1JDSEVTVFJBVE9SID0gJ09yY2hlc3RyYXRvciBMb2cnLFxuICBTRVRVUCA9ICdTZXR1cCBMb2cnLFxufVxuXG4vKipcbiAqIEluaXRpYWxpemUgb3IgcmV0dXJuIGNlbnRyYWwgbG9nIGdyb3VwIGluc3RhbmNlLlxuICpcbiAqIEBpbnRlcm5hbFxuICovXG5leHBvcnQgZnVuY3Rpb24gc2luZ2xldG9uTG9nR3JvdXAoc2NvcGU6IENvbnN0cnVjdCwgdHlwZTogU2luZ2xldG9uTG9nVHlwZSk6IGxvZ3MuSUxvZ0dyb3VwIHtcbiAgY29uc3QgZXhpc3RpbmcgPSBjZGsuU3RhY2sub2Yoc2NvcGUpLm5vZGUudHJ5RmluZENoaWxkKHR5cGUpO1xuICBpZiAoZXhpc3RpbmcpIHtcbiAgICAvLyBKdXN0IGFzc3VtZSB0aGlzIGlzIHRydWVcbiAgICByZXR1cm4gZXhpc3RpbmcgYXMgbG9ncy5JTG9nR3JvdXA7XG4gIH1cblxuICByZXR1cm4gbmV3IGxvZ3MuTG9nR3JvdXAoY2RrLlN0YWNrLm9mKHNjb3BlKSwgdHlwZSwge1xuICAgIHJldGVudGlvbjogbG9ncy5SZXRlbnRpb25EYXlzLk9ORV9NT05USCxcbiAgICByZW1vdmFsUG9saWN5OiBjZGsuUmVtb3ZhbFBvbGljeS5ERVNUUk9ZLFxuICB9KTtcbn1cblxuLyoqXG4gKiBUaGUgYWJzb2x1dGUgbWluaW11bSBwZXJtaXNzaW9ucyByZXF1aXJlZCBmb3IgU1NNIFNlc3Npb24gTWFuYWdlciB0byB3b3JrLiBVbmxpa2UgYEFtYXpvblNTTU1hbmFnZWRJbnN0YW5jZUNvcmVgLCBpdCBkb2Vzbid0IGdpdmUgcGVybWlzc2lvbiB0byByZWFkIGFsbCBTU00gcGFyYW1ldGVycy5cbiAqXG4gKiBAaW50ZXJuYWxcbiAqL1xuZXhwb3J0IGNvbnN0IE1JTklNQUxfU1NNX1NFU1NJT05fTUFOQUdFUl9QT0xJQ1lfU1RBVEVNRU5UID0gbmV3IGlhbS5Qb2xpY3lTdGF0ZW1lbnQoe1xuICBhY3Rpb25zOiBbXG4gICAgJ3NzbW1lc3NhZ2VzOkNyZWF0ZUNvbnRyb2xDaGFubmVsJyxcbiAgICAnc3NtbWVzc2FnZXM6Q3JlYXRlRGF0YUNoYW5uZWwnLFxuICAgICdzc21tZXNzYWdlczpPcGVuQ29udHJvbENoYW5uZWwnLFxuICAgICdzc21tZXNzYWdlczpPcGVuRGF0YUNoYW5uZWwnLFxuICBdLFxuICByZXNvdXJjZXM6IFsnKiddLFxufSk7XG5cbi8qKlxuICogVGhlIGFic29sdXRlIG1pbmltdW0gcGVybWlzc2lvbnMgcmVxdWlyZWQgZm9yIFNTTSBTZXNzaW9uIE1hbmFnZXIgb24gRUNTIHRvIHdvcmsuIFVubGlrZSBgQW1hem9uU1NNTWFuYWdlZEluc3RhbmNlQ29yZWAsIGl0IGRvZXNuJ3QgZ2l2ZSBwZXJtaXNzaW9uIHRvIHJlYWQgYWxsIFNTTSBwYXJhbWV0ZXJzLlxuICpcbiAqIEBpbnRlcm5hbFxuICovXG5leHBvcnQgY29uc3QgTUlOSU1BTF9FQ1NfU1NNX1NFU1NJT05fTUFOQUdFUl9QT0xJQ1lfU1RBVEVNRU5UID0gbmV3IGlhbS5Qb2xpY3lTdGF0ZW1lbnQoe1xuICBhY3Rpb25zOiBbXG4gICAgJ3NzbW1lc3NhZ2VzOkNyZWF0ZUNvbnRyb2xDaGFubmVsJyxcbiAgICAnc3NtbWVzc2FnZXM6Q3JlYXRlRGF0YUNoYW5uZWwnLFxuICAgICdzc21tZXNzYWdlczpPcGVuQ29udHJvbENoYW5uZWwnLFxuICAgICdzc21tZXNzYWdlczpPcGVuRGF0YUNoYW5uZWwnLFxuICAgICdzMzpHZXRFbmNyeXB0aW9uQ29uZmlndXJhdGlvbicsXG4gIF0sXG4gIHJlc291cmNlczogWycqJ10sXG59KTtcblxuLyoqXG4gKiBUaGUgYWJzb2x1dGUgbWluaW11bSBwZXJtaXNzaW9ucyByZXF1aXJlZCBmb3IgU1NNIFNlc3Npb24gTWFuYWdlciBvbiBFQzIgdG8gd29yay4gVW5saWtlIGBBbWF6b25TU01NYW5hZ2VkSW5zdGFuY2VDb3JlYCwgaXQgZG9lc24ndCBnaXZlIHBlcm1pc3Npb24gdG8gcmVhZCBhbGwgU1NNIHBhcmFtZXRlcnMuXG4gKlxuICogQGludGVybmFsXG4gKi9cbmV4cG9ydCBjb25zdCBNSU5JTUFMX0VDMl9TU01fU0VTU0lPTl9NQU5BR0VSX1BPTElDWV9TVEFURU1FTlQgPSBuZXcgaWFtLlBvbGljeVN0YXRlbWVudCh7XG4gIGFjdGlvbnM6IFtcbiAgICAnc3NtbWVzc2FnZXM6Q3JlYXRlQ29udHJvbENoYW5uZWwnLFxuICAgICdzc21tZXNzYWdlczpDcmVhdGVEYXRhQ2hhbm5lbCcsXG4gICAgJ3NzbW1lc3NhZ2VzOk9wZW5Db250cm9sQ2hhbm5lbCcsXG4gICAgJ3NzbW1lc3NhZ2VzOk9wZW5EYXRhQ2hhbm5lbCcsXG4gICAgJ3MzOkdldEVuY3J5cHRpb25Db25maWd1cmF0aW9uJyxcbiAgICAnc3NtOlVwZGF0ZUluc3RhbmNlSW5mb3JtYXRpb24nLFxuICBdLFxuICByZXNvdXJjZXM6IFsnKiddLFxufSk7XG5cbi8qKlxuICogRGlzY292ZXJzIGNlcnRpZmljYXRlIGZpbGVzIGZyb20gYSBnaXZlbiBwYXRoIChmaWxlIG9yIGRpcmVjdG9yeSkuXG4gKlxuICogSWYgdGhlIHBhdGggaXMgYSBkaXJlY3RvcnksIGZpbmRzIGFsbCAucGVtIGFuZCAuY3J0IGZpbGVzIGluIGl0LlxuICogSWYgdGhlIHBhdGggaXMgYSBmaWxlLCByZXR1cm5zIGl0IGFzIGEgc2luZ2xlIGNlcnRpZmljYXRlIGZpbGUuXG4gKlxuICogQHBhcmFtIHNvdXJjZVBhdGggcGF0aCB0byBhIGNlcnRpZmljYXRlIGZpbGUgb3IgZGlyZWN0b3J5IGNvbnRhaW5pbmcgY2VydGlmaWNhdGUgZmlsZXNcbiAqIEByZXR1cm5zIGFycmF5IG9mIGNlcnRpZmljYXRlIGZpbGUgcGF0aHMsIHNvcnRlZCBhbHBoYWJldGljYWxseVxuICogQHRocm93cyBFcnJvciBpZiBwYXRoIGRvZXNuJ3QgZXhpc3QsIGlzIG5laXRoZXIgZmlsZSBub3IgZGlyZWN0b3J5LCBvciBkaXJlY3RvcnkgaGFzIG5vIGNlcnRpZmljYXRlIGZpbGVzXG4gKlxuICogQGludGVybmFsXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBkaXNjb3ZlckNlcnRpZmljYXRlRmlsZXMoc291cmNlUGF0aDogc3RyaW5nKTogc3RyaW5nW10ge1xuICBsZXQgY2VydGlmaWNhdGVGaWxlczogc3RyaW5nW10gPSBbXTtcblxuICB0cnkge1xuICAgIGNvbnN0IHN0YXQgPSBmcy5zdGF0U3luYyhzb3VyY2VQYXRoKTtcbiAgICBpZiAoc3RhdC5pc0RpcmVjdG9yeSgpKSB7XG4gICAgICAvLyBSZWFkIGRpcmVjdG9yeSBhbmQgZmluZCBhbGwgLnBlbSBhbmQgLmNydCBmaWxlc1xuICAgICAgY29uc3QgZmlsZXMgPSBmcy5yZWFkZGlyU3luYyhzb3VyY2VQYXRoKTtcbiAgICAgIGNlcnRpZmljYXRlRmlsZXMgPSBmaWxlc1xuICAgICAgICAuZmlsdGVyKGZpbGUgPT4gZmlsZS5lbmRzV2l0aCgnLnBlbScpIHx8IGZpbGUuZW5kc1dpdGgoJy5jcnQnKSlcbiAgICAgICAgLm1hcChmaWxlID0+IHBhdGguam9pbihzb3VyY2VQYXRoLCBmaWxlKSlcbiAgICAgICAgLnNvcnQoKTsgLy8gU29ydCBmb3IgY29uc2lzdGVudCBvcmRlcmluZ1xuXG4gICAgICBpZiAoY2VydGlmaWNhdGVGaWxlcy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBObyBjZXJ0aWZpY2F0ZSBmaWxlcyAoLnBlbSBvciAuY3J0KSBmb3VuZCBpbiBkaXJlY3Rvcnk6ICR7c291cmNlUGF0aH1gKTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKHN0YXQuaXNGaWxlKCkpIHtcbiAgICAgIC8vIFNpbmdsZSBmaWxlIC0gYmFja3dhcmRzIGNvbXBhdGlibGVcbiAgICAgIGNlcnRpZmljYXRlRmlsZXMgPSBbc291cmNlUGF0aF07XG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgQ2VydGlmaWNhdGUgc291cmNlIHBhdGggaXMgbmVpdGhlciBhIGZpbGUgbm9yIGEgZGlyZWN0b3J5OiAke3NvdXJjZVBhdGh9YCk7XG4gICAgfVxuICB9IGNhdGNoIChlcnJvcikge1xuICAgIGlmICgoZXJyb3IgYXMgTm9kZUpTLkVycm5vRXhjZXB0aW9uKS5jb2RlID09PSAnRU5PRU5UJykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBDZXJ0aWZpY2F0ZSBzb3VyY2UgcGF0aCBkb2VzIG5vdCBleGlzdDogJHtzb3VyY2VQYXRofWApO1xuICAgIH1cbiAgICB0aHJvdyBlcnJvcjtcbiAgfVxuXG4gIHJldHVybiBjZXJ0aWZpY2F0ZUZpbGVzO1xufVxuIl19