UNPKG

@atomist/sdm

Version:

Atomist Software Delivery Machine SDK

189 lines 9.07 kB
"use strict"; /* * Copyright © 2020 Atomist, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ Object.defineProperty(exports, "__esModule", { value: true }); exports.configureSdm = void 0; const string_1 = require("@atomist/automation-client/lib/internal/util/string"); const logger_1 = require("@atomist/automation-client/lib/util/logger"); const _ = require("lodash"); const ConfigurationValues_1 = require("../../api/machine/ConfigurationValues"); const FulfillGoalOnRequested_1 = require("../handlers/events/delivery/goals/FulfillGoalOnRequested"); const goalExecution_1 = require("../handlers/events/delivery/goals/goalExecution"); const CacheCleanupAutomationEventListener_1 = require("../handlers/events/delivery/goals/k8s/CacheCleanupAutomationEventListener"); const eventSigning_1 = require("../signing/eventSigning"); const goalSigning_1 = require("../signing/goalSigning"); const array_1 = require("../util/misc/array"); const SdmGoalMetricReportingAutomationEventListener_1 = require("../util/SdmGoalMetricReportingAutomationEventListener"); const startupMessage_1 = require("../util/startupMessage"); const defaultSoftwareDeliveryMachineConfiguration_1 = require("./defaultSoftwareDeliveryMachineConfiguration"); const InvokeSdmStartupListenersAutomationEventListener_1 = require("./InvokeSdmStartupListenersAutomationEventListener"); const modes_1 = require("./modes"); /** * Configure and set up a Software Delivery Machine instance with the automation-client framework for standalone * or single goal based execution * @param {(configuration: (Configuration & SoftwareDeliveryMachineOptions)) => SoftwareDeliveryMachine} machineMaker * @param {ConfigureOptions} options * @returns {ConfigurationPostProcessor} */ function configureSdm(machineMaker, options = {}) { return async (config) => { let mergedConfig = config; // Configure the local SDM mergedConfig = await doWithSdmLocal(local => { return local.configureLocal()(mergedConfig); }) || mergedConfig; const defaultSdmConfiguration = defaultSoftwareDeliveryMachineConfiguration_1.defaultSoftwareDeliveryMachineConfiguration(config); mergedConfig = _.merge(defaultSdmConfiguration, mergedConfig); ConfigurationValues_1.validateConfigurationValues(mergedConfig, options); const sdm = await machineMaker(mergedConfig); await doWithSdmLocal(local => sdm.addExtensionPacks(local.LocalLifecycle, local.LocalSdmConfig)); // Configure the job forking ability await configureJobLaunching(mergedConfig, sdm); configureGoalSigning(mergedConfig); configureEventSigning(mergedConfig); await registerMetadata(mergedConfig, sdm); // Register startup message detail _.update(mergedConfig, "logging.banner.contributors", old => !!old ? old : []); mergedConfig.logging.banner.contributors.push(startupMessage_1.sdmStartupMessage(sdm), startupMessage_1.sdmExtensionPackStartupMessage(sdm)); _.update(mergedConfig, "listeners", old => !!old ? old : []); mergedConfig.listeners.push(new InvokeSdmStartupListenersAutomationEventListener_1.InvokeSdmStartupListenersAutomationEventListener(sdm), new SdmGoalMetricReportingAutomationEventListener_1.SdmGoalMetricReportingAutomationEventListener()); return mergedConfig; }; } exports.configureSdm = configureSdm; /** * Configure how this SDM is going to handle goals * @param mergedConfig * @param machine */ async function configureJobLaunching(mergedConfig, machine) { const forked = process.env.ATOMIST_ISOLATED_GOAL === "true"; if (forked) { configureSdmToRunExactlyOneGoal(mergedConfig, machine); } else { // initialize the GoalSchedulers for (const goalScheduler of array_1.toArray(mergedConfig.sdm.goalScheduler || [])) { if (!!goalScheduler.initialize) { await goalScheduler.initialize(mergedConfig); } } _.update(mergedConfig, "commands", old => !!old ? old : []); mergedConfig.commands.push(...machine.commandHandlers); _.update(mergedConfig, "events", old => !!old ? old : []); mergedConfig.events.push(...machine.eventHandlers); _.update(mergedConfig, "ingesters", old => !!old ? old : []); mergedConfig.ingesters.push(...machine.ingesters); } } /** * Configure SDM to run only one goal * @param mergedConfig * @param sdm */ function configureSdmToRunExactlyOneGoal(mergedConfig, sdm) { if (process.env.ATOMIST_JOB_NAME) { mergedConfig.name = process.env.ATOMIST_REGISTRATION_NAME; } else { mergedConfig.name = `${mergedConfig.name}-${process.env.ATOMIST_GOAL_ID || string_1.guid()}`; } // Force ephemeral policy and no handlers or ingesters mergedConfig.policy = "ephemeral"; mergedConfig.commands = []; mergedConfig.events = [ () => new FulfillGoalOnRequested_1.FulfillGoalOnRequested(sdm.goalFulfillmentMapper, [...sdm.goalExecutionListeners]) ]; mergedConfig.ingesters = []; mergedConfig.ws.enabled = false; mergedConfig.cluster.enabled = false; mergedConfig.listeners.push(new goalExecution_1.GoalExecutionAutomationEventListener(sdm), new CacheCleanupAutomationEventListener_1.CacheCleanupAutomationEventListener(sdm)); mergedConfig.requestProcessorFactory = (automations, cfg, listeners) => new goalExecution_1.GoalExecutionRequestProcessor(automations, cfg, listeners); } /** * Configure SDM to sign and verify goals * @param mergedConfig */ function configureGoalSigning(mergedConfig) { if (!!mergedConfig.sdm.goalSigning && mergedConfig.sdm.goalSigning.enabled === true) { _.update(mergedConfig, "graphql.listeners", old => !!old ? old : []); mergedConfig.graphql.listeners.push(new goalSigning_1.GoalSigningAutomationEventListener(mergedConfig.sdm.goalSigning)); } } /** * Configure SDM to sign and verify events * @param mergedConfig */ function configureEventSigning(mergedConfig) { var _a, _b; if (((_b = (_a = mergedConfig.sdm) === null || _a === void 0 ? void 0 : _a.eventSigning) === null || _b === void 0 ? void 0 : _b.enabled) === true) { _.update(mergedConfig, "graphql.listeners", old => !!old ? old : []); mergedConfig.graphql.listeners.push(new eventSigning_1.EventSigningAutomationEventListener(mergedConfig.sdm.eventSigning)); mergedConfig.events = eventSigning_1.wrapEventHandlersToVerifySignature(mergedConfig.events || [], mergedConfig.sdm.eventSigning); } } async function registerMetadata(config, machine) { // tslint:disable-next-line:no-implicit-dependencies const sdmPj = require("@atomist/sdm/package.json"); config.metadata = Object.assign(Object.assign({}, config.metadata), { "atomist.sdm": `${sdmPj.name}:${sdmPj.version}`, "atomist.sdm.name": machine.name, "atomist.sdm.extension-packs": machine.extensionPacks.map(ex => `${ex.name}:${ex.version}`).join(", ") }); config.sdm.name = machine.name; await doWithSdmLocal(() => { // tslint:disable-next-line:no-implicit-dependencies const sdmLocalPj = require("@atomist/sdm-local/package.json"); config.metadata["atomist.sdm-local"] = `${sdmLocalPj.name}:${sdmLocalPj.version}`; }); } /** * Perform the given operation with the sdm-local module if it's available. * If it isn't, silently continue without error. * @param {(sdmLocal: any) => any} callback * @return {any} */ async function doWithSdmLocal(callback) { if (modes_1.isInLocalMode() || modes_1.isGitHubAction()) { // tslint:disable-next-line:no-implicit-dependencies const local = attemptToRequire("@atomist/sdm-local", !process.env.ATOMIST_NPM_LOCAL_LINK); if (local) { return callback(local); } else { logger_1.logger.warn("Skipping local mode configuration because 'ATOMIST_NPM_LOCAL_LINK' was defined, " + "but '@atomist/sdm-local' could not be loaded"); return undefined; } } return undefined; } /** * Attempt to NPM require module * @param module * @param failOnError */ function attemptToRequire(module, failOnError) { try { return require(module); } catch (err) { if (failOnError) { throw new Error(`Unable to load '${module}'. Please install with 'npm install ${module}'.`); } else { return undefined; } } } //# sourceMappingURL=configureSdm.js.map