@catladder/cli
Version:
Panter cli tool for cloud CI/CD and DevOps
148 lines (147 loc) • 6.09 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.getCreateScheduleScript = exports.getDeleteSchedulesScript = void 0;
const bash_1 = require("../../../../bash");
const utils_1 = require("../../../../utils");
const cloudRunExecutionUrl_1 = require("../../utils/cloudRunExecutionUrl");
const createArgsString_1 = require("../../utils/createArgsString");
const jobName_1 = require("../../utils/jobName");
const cloudRunJobs_1 = require("../cloudRunJobs");
const common_1 = require("../common");
const getDeleteSchedulesScript = context => {
const deployConfig = (0, common_1.getCloudRunDeployConfig)(context);
const schedules = getSchedules(context);
const argsString = (0, createArgsString_1.createArgsString)({
project: deployConfig.projectId,
location: deployConfig.region
});
return schedules.map(({
fullName
}) => {
return [`${(0, common_1.gcloudSchedulerCmd)()} jobs delete ${fullName} ${argsString}`];
}).flat();
};
exports.getDeleteSchedulesScript = getDeleteSchedulesScript;
const getCreateScheduleScript = context => {
const schedules = getSchedules(context);
const {
region: location,
projectId: project
} = (0, common_1.getCloudRunDeployConfig)(context);
return schedules.map(({
fullName,
config
}, jobIndex) => {
var _a;
// `headers` is pulled out of the shared args because the flag name differs
// between create (`--headers`) and update (`--update-headers`).
const {
uri,
headers,
...args
} = getSchedulerArgs(config, context);
const argsString = (0, createArgsString_1.createArgsString)({
project,
location,
uri: `"$current_job_uri"`,
...args,
schedule: `"${config.schedule}"`,
"max-retry-attempts": (_a = config.maxRetryAttempts) !== null && _a !== void 0 ? _a : 0
});
const headersValue = headers ? `"${(0, bash_1.bashEscape)(headers)}"` : undefined;
const createHeadersArg = headersValue ? ` --headers=${headersValue}` : "";
const updateHeadersArg = headersValue ? ` --update-headers=${headersValue}` : "";
return [jobIndex === 0 ? `exist_scheduler_names="$(\n ${(0, common_1.gcloudSchedulerCmd)()} jobs list --filter='httpTarget.uri ~ ${context.env}.*${context.name}' --format='value(name)' --limit=999 --location='${location}' --project='${project}'\n)"` : null, `current_job_uri="${uri}"`, `current_scheduler_name="${fullName}"`, `if echo "$exist_scheduler_names" | grep -Fx "$current_scheduler_name" >/dev/null; then`, ` ${(0, common_1.gcloudSchedulerCmd)()} jobs update http "$current_scheduler_name" ${argsString}${updateHeadersArg}`, `else`, ` ${(0, common_1.gcloudSchedulerCmd)()} jobs create http "$current_scheduler_name" ${argsString}${createHeadersArg}`, `fi`].filter(utils_1.notNil).join("\n");
});
};
exports.getCreateScheduleScript = getCreateScheduleScript;
const getSchedulerArgs = (scheduler, context) => {
var _a, _b;
if (scheduler.type === "job") {
const {
projectId,
region
} = (0, common_1.getCloudRunDeployConfig)(context);
const body = scheduler.args !== undefined ? {
overrides: {
containerOverrides: [((_a = scheduler.args) === null || _a === void 0 ? void 0 : _a.length) > 0 ? {
args: scheduler.args
} : {
args: [],
clearArgs: true // not sure why this is neeeded, but it is
}]
}
} : null;
return {
uri: (0, cloudRunExecutionUrl_1.getCloudRunJobExecuteUrl)(scheduler.job, {
appFullName: context.environment.fullName,
projectId,
region
}),
"message-body": body ? '"' + (0, bash_1.bashEscape)(JSON.stringify(body)) + '"' : undefined,
"http-method": "POST",
"oauth-service-account-email": `"$GCLOUD_PROJECT_NUMBER-compute@developer.gserviceaccount.com"`
};
}
if (scheduler.type === "http") {
// default the Content-Type to application/json when a body is sent and the
// user didn't set one explicitly. Otherwise Cloud Scheduler falls back to
// application/octet-stream, which is rarely what's intended.
const hasContentType = Object.keys((_b = scheduler.headers) !== null && _b !== void 0 ? _b : {}).some(k => k.toLowerCase() === "content-type");
const headers = scheduler.body && !hasContentType ? {
"Content-Type": "application/json",
...scheduler.headers
} : scheduler.headers;
return {
uri: scheduler.url,
"message-body": scheduler.body ? '"' + (0, bash_1.bashEscape)(scheduler.body) + '"' : undefined,
"http-method": scheduler.method,
headers: headers ? Object.entries(headers).map(([k, v]) => `${k}=${v}`).join(",") : undefined,
"oidc-service-account-email": `"$GCLOUD_PROJECT_NUMBER-compute@developer.gserviceaccount.com"`
};
}
throw new Error(`Unknown scheduler type: ${scheduler.type}`);
};
const getSchedules = context => {
const legacyScheduleJobs = getLegacyJobSchedules(context);
const schedules = getScheduledExecutes(context);
return Object.entries({
...legacyScheduleJobs,
...schedules
}).map(([name, config]) => ({
name,
fullName: (0, jobName_1.getFullSchedulerName)(context, name),
config
}));
};
const getLegacyJobSchedules = context => {
const jobsWithNames = (0, cloudRunJobs_1.getCloudRunJobsWithNames)(context);
return Object.fromEntries(jobsWithNames.filter(entry => entry.job.when === "schedule").map(({
job: {
maxRetryAttempts,
schedule
},
jobName
}) => {
const schedulerName = jobName.concat("-scheduler");
return [schedulerName, {
type: "job",
job: jobName,
maxRetryAttempts,
schedule,
when: "schedule"
}];
}));
};
const getScheduledExecutes = context => {
var _a;
const deployConfig = (0, common_1.getCloudRunDeployConfig)(context);
return Object.fromEntries(Object.entries((_a = deployConfig.execute) !== null && _a !== void 0 ? _a : {}).flatMap(([key, value]) => {
if (!value || value.when !== "schedule") {
return [];
}
return [[key, value]];
}));
};