@catladder/pipeline 0.0.0-node16-ddfae617 → 0.0.0-refactor-env-context-9e652b63
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/catladder-gitlab.js +1 -1
- package/dist/build/base/createBuildJob.d.ts +2 -2
- package/dist/build/base/getBuildInfo.d.ts +1 -1
- package/dist/build/docker.d.ts +44 -6
- package/dist/build/docker.js +45 -19
- package/dist/build/index.d.ts +6 -5
- package/dist/build/node/buildJob.d.ts +2 -2
- package/dist/build/node/cache.d.ts +2 -2
- package/dist/build/node/index.d.ts +1 -1
- package/dist/build/node/meteor.d.ts +1 -1
- package/dist/build/node/meteor.js +6 -0
- package/dist/build/node/testJob.d.ts +2 -2
- package/dist/build/node/testJob.js +3 -0
- package/dist/build/node/yarn.d.ts +1 -1
- package/dist/build/node/yarn.js +13 -1
- package/dist/build/types.d.ts +10 -0
- package/dist/bundles/catladder-gitlab/index.js +32457 -0
- package/dist/catladder-gitlab.js +1 -2
- package/dist/config/configruedEnvs.d.ts +1 -1
- package/dist/config/readConfig.d.ts +1 -1
- package/dist/constants.js +1 -1
- package/dist/context/getEnvConfig.d.ts +9 -0
- package/dist/context/getEnvConfig.js +26 -0
- package/dist/context/getEnvType.d.ts +4 -0
- package/dist/context/getEnvType.js +18 -0
- package/dist/context/getEnvironment.d.ts +3 -0
- package/dist/context/getEnvironment.js +187 -0
- package/dist/context/getEnvironmentContext.d.ts +4 -0
- package/dist/context/getEnvironmentContext.js +36 -0
- package/dist/context/getEnvironmentVariables.d.ts +10 -0
- package/dist/context/getEnvironmentVariables.js +322 -0
- package/dist/context/getLabels.d.ts +8 -0
- package/dist/context/getLabels.js +49 -0
- package/dist/context/index.d.ts +5 -6
- package/dist/context/index.js +176 -181
- package/dist/context/resolveReferences.d.ts +1 -3
- package/dist/context/resolveReferences.js +275 -26
- package/dist/context/resolveReferences.test.js +332 -81
- package/dist/defaults/index.d.ts +1 -1
- package/dist/deploy/base.d.ts +4 -2
- package/dist/deploy/base.js +37 -17
- package/dist/deploy/cloudRun/deployJob.d.ts +3 -0
- package/dist/deploy/cloudRun/deployJob.js +139 -0
- package/dist/deploy/cloudRun/index.d.ts +9 -0
- package/dist/deploy/cloudRun/index.js +56 -0
- package/dist/deploy/cloudRun/utils/gcloudServiceAccountLoginCommands.d.ts +2 -0
- package/dist/deploy/cloudRun/utils/gcloudServiceAccountLoginCommands.js +14 -0
- package/dist/deploy/cloudSql/index.d.ts +8 -0
- package/dist/deploy/cloudSql/index.js +30 -0
- package/dist/deploy/custom/deployJob.d.ts +2 -2
- package/dist/deploy/custom/deployJob.js +4 -1
- package/dist/deploy/custom/index.d.ts +2 -1
- package/dist/deploy/custom/index.js +15 -18
- package/dist/deploy/dockerTag/deployJob.d.ts +3 -0
- package/dist/deploy/dockerTag/deployJob.js +33 -0
- package/dist/deploy/dockerTag/index.d.ts +2 -0
- package/dist/deploy/dockerTag/index.js +19 -0
- package/dist/deploy/index.d.ts +12 -8
- package/dist/deploy/index.js +27 -14
- package/dist/deploy/kubernetes/additionalSecretKeys.d.ts +4 -0
- package/dist/deploy/kubernetes/additionalSecretKeys.js +33 -0
- package/dist/deploy/kubernetes/cloudsql.d.ts +1 -1
- package/dist/deploy/kubernetes/deployJob.d.ts +2 -2
- package/dist/deploy/kubernetes/deployJob.js +13 -66
- package/dist/deploy/kubernetes/index.d.ts +2 -1
- package/dist/deploy/kubernetes/index.js +45 -16
- package/dist/deploy/kubernetes/kubeEnv.d.ts +10 -0
- package/dist/deploy/kubernetes/kubeEnv.js +90 -0
- package/dist/deploy/kubernetes/kubeValues.d.ts +90 -0
- package/dist/deploy/kubernetes/kubeValues.js +96 -0
- package/dist/deploy/kubernetes/mongodb.d.ts +18 -5
- package/dist/deploy/kubernetes/mongodb.js +118 -8
- package/dist/deploy/kubernetes/processSecretsAsFiles.d.ts +21 -21
- package/dist/deploy/types/base.d.ts +15 -0
- package/dist/deploy/types/base.js +3 -0
- package/dist/deploy/types/custom.d.ts +27 -0
- package/dist/deploy/types/custom.js +3 -0
- package/dist/deploy/types/dockerTag.d.ts +10 -0
- package/dist/deploy/types/dockerTag.js +3 -0
- package/dist/deploy/types/googleCloudRun.d.ts +39 -0
- package/dist/deploy/types/googleCloudRun.js +3 -0
- package/dist/deploy/types/index.d.ts +24 -0
- package/dist/deploy/types/index.js +41 -0
- package/dist/deploy/{types.d.ts → types/kubernetes.d.ts} +128 -36
- package/dist/deploy/types/kubernetes.js +3 -0
- package/dist/deploy/utils.d.ts +2 -2
- package/dist/deploy/utils.js +4 -0
- package/dist/pipeline/createChildPipeline.d.ts +2 -2
- package/dist/pipeline/createChildPipeline.js +3 -3
- package/dist/pipeline/createJobs.d.ts +2 -2
- package/dist/pipeline/createJobs.js +63 -25
- package/dist/pipeline/gitlab/makeGitlabJob.d.ts +3 -2
- package/dist/pipeline/gitlab/makeGitlabJob.js +2 -1
- package/dist/pipeline/packageManager.d.ts +1 -1
- package/dist/rules/index.d.ts +1 -1
- package/dist/runner/index.d.ts +2 -3
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/types/config.d.ts +7 -6
- package/dist/types/config.js +1 -1
- package/dist/types/context.d.ts +10 -2
- package/dist/types/environmentContext.d.ts +22 -0
- package/dist/types/environmentContext.js +3 -0
- package/dist/types/gitlab-types.d.ts +1 -1
- package/dist/types/jobs.d.ts +8 -3
- package/dist/types/jobs.js +1 -1
- package/dist/types/pipeline.d.ts +1 -1
- package/package.json +15 -11
- package/scripts/bundle +2 -0
- package/src/build/base/createBuildJob.ts +3 -2
- package/src/build/base/getBuildInfo.ts +1 -1
- package/src/build/docker.ts +47 -29
- package/src/build/index.ts +8 -5
- package/src/build/node/buildJob.ts +2 -2
- package/src/build/node/cache.ts +2 -2
- package/src/build/node/index.ts +1 -1
- package/src/build/node/meteor.ts +8 -2
- package/src/build/node/testJob.ts +4 -2
- package/src/build/node/yarn.ts +21 -10
- package/src/build/tests/storybook.test.ts +1 -1
- package/src/build/types.ts +13 -1
- package/src/catladder-gitlab.ts +4 -2
- package/src/config/configruedEnvs.test.ts +2 -2
- package/src/config/configruedEnvs.ts +5 -4
- package/src/config/readConfig.ts +1 -1
- package/src/context/getEnvConfig.ts +21 -0
- package/src/context/getEnvType.ts +17 -0
- package/src/context/getEnvironment.ts +40 -0
- package/src/context/getEnvironmentContext.ts +57 -0
- package/src/context/getEnvironmentVariables.ts +152 -0
- package/src/context/getLabels.ts +20 -0
- package/src/context/index.ts +25 -191
- package/src/context/resolveReferences.test.ts +15 -15
- package/src/context/resolveReferences.ts +37 -30
- package/src/defaults/index.ts +1 -1
- package/src/deploy/base.ts +43 -19
- package/src/deploy/cloudRun/deployJob.ts +104 -0
- package/src/deploy/cloudRun/index.ts +48 -0
- package/src/deploy/cloudRun/utils/gcloudServiceAccountLoginCommands.ts +14 -0
- package/src/deploy/cloudSql/index.ts +16 -0
- package/src/deploy/custom/deployJob.ts +10 -3
- package/src/deploy/custom/index.ts +9 -1
- package/src/deploy/dockerTag/deployJob.ts +31 -0
- package/src/deploy/dockerTag/index.ts +9 -0
- package/src/deploy/index.ts +26 -17
- package/src/deploy/kubernetes/additionalSecretKeys.ts +23 -0
- package/src/deploy/kubernetes/cloudsql.ts +2 -1
- package/src/deploy/kubernetes/deployJob.ts +19 -77
- package/src/deploy/kubernetes/index.ts +42 -1
- package/src/deploy/kubernetes/kubeEnv.ts +48 -0
- package/src/deploy/kubernetes/kubeValues.ts +82 -0
- package/src/deploy/kubernetes/mongodb.ts +104 -7
- package/src/deploy/kubernetes/processSecretsAsFiles.ts +1 -1
- package/src/deploy/types/base.ts +17 -0
- package/src/deploy/types/custom.ts +24 -0
- package/src/deploy/types/dockerTag.ts +12 -0
- package/src/deploy/types/googleCloudRun.ts +79 -0
- package/src/deploy/types/index.ts +28 -0
- package/src/deploy/types/kubernetes.ts +281 -0
- package/src/deploy/utils.ts +6 -2
- package/src/pipeline/createChildPipeline.test.ts +1 -1
- package/src/pipeline/createChildPipeline.ts +4 -4
- package/src/pipeline/createJobs.ts +32 -21
- package/src/pipeline/gitlab/makeGitlabJob.ts +3 -2
- package/src/pipeline/packageManager.ts +1 -1
- package/src/rules/index.ts +1 -1
- package/src/runner/index.ts +2 -1
- package/src/types/config.ts +8 -6
- package/src/types/context.ts +14 -2
- package/src/types/environmentContext.ts +26 -0
- package/src/types/gitlab-types.ts +1 -1
- package/src/types/jobs.ts +9 -2
- package/src/types/pipeline.ts +1 -1
- package/tsconfig.json +2 -0
- package/dist/deploy/types.js +0 -16
- package/src/deploy/types.ts +0 -189
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import type { DeployTypeDefinition } from "..";
|
|
2
|
+
import { getSecretVarName } from "../../context";
|
|
3
|
+
import { createGoogleCloudRunDeployJobs } from "./deployJob";
|
|
4
|
+
|
|
5
|
+
export const GCLOUD_DEPLOY_CREDENTIALS_KEY = "GCLOUD_DEPLOY_credentialsKey";
|
|
6
|
+
|
|
7
|
+
export const GCLOUD_RUN_CANONICAL_HOST_SUFFIX =
|
|
8
|
+
"GCLOUD_RUN_canonicalHostSuffix";
|
|
9
|
+
|
|
10
|
+
export const GCLOUD_RUN_DEPLOY_TYPE: DeployTypeDefinition<"google-cloudrun"> = {
|
|
11
|
+
jobs: createGoogleCloudRunDeployJobs,
|
|
12
|
+
defaults: () => ({}),
|
|
13
|
+
additionalSecretKeys: () => [GCLOUD_DEPLOY_CREDENTIALS_KEY],
|
|
14
|
+
getAdditionalEnvVars: ({ fullName, env, componentName }) => {
|
|
15
|
+
const HOST_CANONICAL =
|
|
16
|
+
fullName.toLowerCase() +
|
|
17
|
+
"-" +
|
|
18
|
+
process.env[
|
|
19
|
+
getSecretVarName(env, componentName, GCLOUD_RUN_CANONICAL_HOST_SUFFIX)
|
|
20
|
+
];
|
|
21
|
+
|
|
22
|
+
return {
|
|
23
|
+
HOST_CANONICAL,
|
|
24
|
+
};
|
|
25
|
+
},
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
export const GCLOUD_RUN_JOB_DEPLOY_TYPE: DeployTypeDefinition<"google-cloudrun-job"> =
|
|
29
|
+
{
|
|
30
|
+
jobs: createGoogleCloudRunDeployJobs,
|
|
31
|
+
defaults: () => ({}),
|
|
32
|
+
additionalSecretKeys: () => [GCLOUD_DEPLOY_CREDENTIALS_KEY],
|
|
33
|
+
getAdditionalEnvVars: ({ deployConfigRaw, fullName }) => {
|
|
34
|
+
if (!deployConfigRaw) {
|
|
35
|
+
return {};
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const jobName = fullName.toLowerCase();
|
|
39
|
+
const CLOUD_RUN_JOB_TRIGGER_URL = `https://${deployConfigRaw.region}-run.googleapis.com/apis/run.googleapis.com/v1/namespaces/${deployConfigRaw.projectId}/jobs/${jobName}:run`;
|
|
40
|
+
|
|
41
|
+
return { CLOUD_RUN_JOB_TRIGGER_URL };
|
|
42
|
+
},
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
export const GCLOUD_RUN_DEPLOY_TYPES = {
|
|
46
|
+
"google-cloudrun": GCLOUD_RUN_DEPLOY_TYPE,
|
|
47
|
+
"google-cloudrun-job": GCLOUD_RUN_JOB_DEPLOY_TYPE,
|
|
48
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { GCLOUD_DEPLOY_CREDENTIALS_KEY } from "..";
|
|
2
|
+
import { getSecretVarNameForContext } from "../../../context";
|
|
3
|
+
import type { Context } from "../../../types";
|
|
4
|
+
|
|
5
|
+
export const gcloudServiceAccountLoginCommands = (context: Context) => {
|
|
6
|
+
return [
|
|
7
|
+
`echo $${getSecretVarNameForContext(
|
|
8
|
+
context,
|
|
9
|
+
GCLOUD_DEPLOY_CREDENTIALS_KEY
|
|
10
|
+
)} > ./____keyfile.json
|
|
11
|
+
`,
|
|
12
|
+
`gcloud auth activate-service-account --key-file="./____keyfile.json"`,
|
|
13
|
+
];
|
|
14
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { Context } from "../../types";
|
|
2
|
+
import { isOfDeployType } from "../types";
|
|
3
|
+
|
|
4
|
+
export const hasCloudSQL = (context: Context) => {
|
|
5
|
+
if (isOfDeployType(context.componentConfig.deploy, "kubernetes")) {
|
|
6
|
+
return context.componentConfig.deploy.values?.cloudsql?.enabled;
|
|
7
|
+
}
|
|
8
|
+
return false;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export const getCloudSQLConfig = (context: Context) => {
|
|
12
|
+
if (isOfDeployType(context.componentConfig.deploy, "kubernetes")) {
|
|
13
|
+
return context.componentConfig.deploy.values?.cloudsql;
|
|
14
|
+
}
|
|
15
|
+
throw new Error("cannot get cloud sql config");
|
|
16
|
+
};
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { merge } from "lodash";
|
|
2
|
-
|
|
3
|
-
import {
|
|
2
|
+
|
|
3
|
+
import { getYarnInstall } from "../../build/node/yarn";
|
|
4
|
+
import type { Context } from "../../types/context";
|
|
5
|
+
import type { CatladderJob } from "../../types/jobs";
|
|
4
6
|
import { getBaseDeploymentJob } from "../base";
|
|
5
7
|
import { isOfDeployType } from "../types";
|
|
6
8
|
|
|
@@ -15,9 +17,14 @@ export const createCustomDeployJobs = (context: Context): CatladderJob[] => {
|
|
|
15
17
|
}
|
|
16
18
|
const baseDeploymentJob = getBaseDeploymentJob(context);
|
|
17
19
|
|
|
20
|
+
const yarnInstall = getYarnInstall(context);
|
|
18
21
|
return [
|
|
19
22
|
merge({}, baseDeploymentJob, {
|
|
20
|
-
script: [
|
|
23
|
+
script: [
|
|
24
|
+
`cd ${context.componentConfig.dir}`,
|
|
25
|
+
...(deployConfig.requiresYarnInstall ? yarnInstall : []),
|
|
26
|
+
...deployConfig.script,
|
|
27
|
+
],
|
|
21
28
|
}),
|
|
22
29
|
];
|
|
23
30
|
};
|
|
@@ -1 +1,9 @@
|
|
|
1
|
-
|
|
1
|
+
import type { DeployTypeDefinition } from "..";
|
|
2
|
+
import { createCustomDeployJobs } from "./deployJob";
|
|
3
|
+
|
|
4
|
+
export const CUSTOM_DEPLOY_TYPE: DeployTypeDefinition<"custom"> = {
|
|
5
|
+
jobs: createCustomDeployJobs,
|
|
6
|
+
defaults: () => ({}),
|
|
7
|
+
additionalSecretKeys: () => [],
|
|
8
|
+
getAdditionalEnvVars: () => ({}),
|
|
9
|
+
};
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { merge } from "lodash";
|
|
2
|
+
import { getDockerJobBaseProps, gitlabDockerLogin } from "../../build/docker";
|
|
3
|
+
|
|
4
|
+
import type { Context } from "../../types/context";
|
|
5
|
+
import type { CatladderJob } from "../../types/jobs";
|
|
6
|
+
import { getBaseDeploymentJob } from "../base";
|
|
7
|
+
import { isOfDeployType } from "../types";
|
|
8
|
+
|
|
9
|
+
export const createDockerTagDeployJobs = (context: Context): CatladderJob[] => {
|
|
10
|
+
const deployConfig = context.componentConfig.deploy;
|
|
11
|
+
if (deployConfig === false) {
|
|
12
|
+
return [];
|
|
13
|
+
}
|
|
14
|
+
if (!isOfDeployType(deployConfig, "dockerTag")) {
|
|
15
|
+
// should not happen
|
|
16
|
+
throw new Error("deploy config is not dockerTag");
|
|
17
|
+
}
|
|
18
|
+
const baseDeploymentJob = getBaseDeploymentJob(context);
|
|
19
|
+
const tag = deployConfig.tag;
|
|
20
|
+
return [
|
|
21
|
+
merge({}, baseDeploymentJob, getDockerJobBaseProps(context), {
|
|
22
|
+
script: [
|
|
23
|
+
gitlabDockerLogin,
|
|
24
|
+
`docker pull $DOCKER_IMAGE:$DOCKER_IMAGE_TAG`,
|
|
25
|
+
`docker tag $DOCKER_IMAGE:$DOCKER_IMAGE_TAG $DOCKER_IMAGE:${tag}`,
|
|
26
|
+
`docker push $DOCKER_IMAGE:${tag}`,
|
|
27
|
+
`echo "pushed as $DOCKER_IMAGE:${tag}"`,
|
|
28
|
+
],
|
|
29
|
+
}),
|
|
30
|
+
];
|
|
31
|
+
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { DeployTypeDefinition } from "..";
|
|
2
|
+
import { createDockerTagDeployJobs } from "./deployJob";
|
|
3
|
+
|
|
4
|
+
export const DOCKER_TAG_DEPLOY_TYPE: DeployTypeDefinition<"dockerTag"> = {
|
|
5
|
+
jobs: createDockerTagDeployJobs,
|
|
6
|
+
defaults: () => ({}),
|
|
7
|
+
additionalSecretKeys: () => [],
|
|
8
|
+
getAdditionalEnvVars: () => ({}),
|
|
9
|
+
};
|
package/src/deploy/index.ts
CHANGED
|
@@ -1,25 +1,34 @@
|
|
|
1
|
-
import { Context } from "../types/context";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
1
|
+
import type { Context } from "../types/context";
|
|
2
|
+
import type { EnvironmentContext } from "../types/environmentContext";
|
|
3
|
+
import type { CatladderJob } from "../types/jobs";
|
|
4
|
+
import { GCLOUD_RUN_DEPLOY_TYPES } from "./cloudRun";
|
|
5
|
+
import { CUSTOM_DEPLOY_TYPE } from "./custom";
|
|
6
|
+
import { DOCKER_TAG_DEPLOY_TYPE } from "./dockerTag";
|
|
7
|
+
import { KUBERNETES_DEPLOY_TYPE } from "./kubernetes";
|
|
8
|
+
import type { DeployConfigGeneric, DeployConfigType } from "./types";
|
|
9
|
+
export * from "./cloudRun";
|
|
10
|
+
export * from "./cloudSql";
|
|
6
11
|
export * from "./kubernetes";
|
|
7
12
|
export * from "./types";
|
|
8
13
|
export * from "./utils";
|
|
14
|
+
|
|
15
|
+
export type DeployTypeDefinition<T extends DeployConfigType> = {
|
|
16
|
+
jobs: (context: Context) => CatladderJob[];
|
|
17
|
+
defaults: (
|
|
18
|
+
envVarContext: EnvironmentContext<any, T>
|
|
19
|
+
) => Partial<DeployConfigGeneric<T>>;
|
|
20
|
+
additionalSecretKeys: (envVarContext: EnvironmentContext<any, T>) => string[];
|
|
21
|
+
getAdditionalEnvVars: (
|
|
22
|
+
envVarContext: EnvironmentContext<any, T>
|
|
23
|
+
) => Record<string, string | undefined | null>;
|
|
24
|
+
};
|
|
9
25
|
export type DeployTypes = {
|
|
10
|
-
[
|
|
11
|
-
jobs: (context: Context) => CatladderJob[];
|
|
12
|
-
defaults: () => Partial<Extract<DeployConfig, { type: type }>>;
|
|
13
|
-
};
|
|
26
|
+
[T in DeployConfigType]: DeployTypeDefinition<T>;
|
|
14
27
|
};
|
|
15
28
|
|
|
16
29
|
export const DEPLOY_TYPES: DeployTypes = {
|
|
17
|
-
kubernetes:
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
custom: {
|
|
22
|
-
jobs: createCustomDeployJobs,
|
|
23
|
-
defaults: () => ({}),
|
|
24
|
-
},
|
|
30
|
+
kubernetes: KUBERNETES_DEPLOY_TYPE,
|
|
31
|
+
custom: CUSTOM_DEPLOY_TYPE,
|
|
32
|
+
dockerTag: DOCKER_TAG_DEPLOY_TYPE,
|
|
33
|
+
...GCLOUD_RUN_DEPLOY_TYPES,
|
|
25
34
|
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { EnvironmentContext } from "../../types/environmentContext";
|
|
2
|
+
|
|
3
|
+
export const additionalKubernetesSecretKeys = ({
|
|
4
|
+
deployConfigRaw,
|
|
5
|
+
}: EnvironmentContext<any, "kubernetes">) => {
|
|
6
|
+
if (!deployConfigRaw) {
|
|
7
|
+
return [];
|
|
8
|
+
}
|
|
9
|
+
const keys = [];
|
|
10
|
+
if (deployConfigRaw.values?.mongodb?.enabled) {
|
|
11
|
+
keys.push("MONGODB_ROOT_PASSWORD");
|
|
12
|
+
if (deployConfigRaw.values.mongodb.architecture === "replicaset") {
|
|
13
|
+
keys.push("MONGODB_REPLICASET_KEY");
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
if (deployConfigRaw.values?.cloudsql?.enabled) {
|
|
18
|
+
keys.push("POSTGRESQL_PASSWORD");
|
|
19
|
+
keys.push("cloudsqlProxyCredentials");
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
return keys;
|
|
23
|
+
};
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
import { dump } from "js-yaml";
|
|
2
2
|
import { merge } from "lodash";
|
|
3
|
-
import { DeployConfigKubernetesValues } from "..";
|
|
4
3
|
import { getSecretVarNameForContext } from "../..";
|
|
5
4
|
import { getRunnerImage } from "../../runner";
|
|
6
|
-
import { Context } from "../../types/context";
|
|
7
|
-
import { CatladderJob } from "../../types/jobs";
|
|
8
|
-
import {
|
|
9
|
-
|
|
5
|
+
import type { Context } from "../../types/context";
|
|
6
|
+
import type { CatladderJob } from "../../types/jobs";
|
|
7
|
+
import {
|
|
8
|
+
getBaseDeploymentJob,
|
|
9
|
+
getBaseDeploymentStopJob,
|
|
10
|
+
getBaseRollbackJob,
|
|
11
|
+
} from "../base";
|
|
10
12
|
import { isOfDeployType } from "../types";
|
|
11
|
-
import {
|
|
12
|
-
import { createMongodbBaseConfig } from "./mongodb";
|
|
13
|
-
import { processSecretsAsFiles } from "./processSecretsAsFiles";
|
|
13
|
+
import { createKubeValues } from "./kubeValues";
|
|
14
14
|
|
|
15
15
|
export const createKubernetesDeployJobs = (
|
|
16
16
|
context: Context
|
|
@@ -24,71 +24,7 @@ export const createKubernetesDeployJobs = (
|
|
|
24
24
|
throw new Error("deploy config is not kubernetes");
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
const
|
|
28
|
-
/**
|
|
29
|
-
* separate by secrets and public.
|
|
30
|
-
* we evalulate the actual values later, but want to store the secrets in kubernetes secrets
|
|
31
|
-
*/
|
|
32
|
-
const env = Object.entries(allEnvVars).reduce<{
|
|
33
|
-
secret: Record<string, string>;
|
|
34
|
-
public: Record<string, string>;
|
|
35
|
-
}>(
|
|
36
|
-
(acc, [key, value]) => {
|
|
37
|
-
if (String(value)?.startsWith("$CL_")) {
|
|
38
|
-
acc.secret = {
|
|
39
|
-
...acc.secret,
|
|
40
|
-
[key]: value,
|
|
41
|
-
};
|
|
42
|
-
return acc;
|
|
43
|
-
}
|
|
44
|
-
acc.public = {
|
|
45
|
-
...acc.public,
|
|
46
|
-
[key]: value,
|
|
47
|
-
};
|
|
48
|
-
return acc;
|
|
49
|
-
},
|
|
50
|
-
{
|
|
51
|
-
secret: {},
|
|
52
|
-
public: {},
|
|
53
|
-
}
|
|
54
|
-
);
|
|
55
|
-
|
|
56
|
-
const defaultAppConfig: DeployConfigKubernetesValues["application"] = {
|
|
57
|
-
host: context.environment.host,
|
|
58
|
-
command: context.componentConfig.build.startCommand,
|
|
59
|
-
livenessProbe: {
|
|
60
|
-
httpGet: {
|
|
61
|
-
path: deployConfig.values?.application?.healthRoute ?? "__health",
|
|
62
|
-
},
|
|
63
|
-
},
|
|
64
|
-
readinessProbe: {
|
|
65
|
-
httpGet: {
|
|
66
|
-
path: deployConfig.values?.application?.healthRoute ?? "__health",
|
|
67
|
-
},
|
|
68
|
-
},
|
|
69
|
-
startupProbe: {
|
|
70
|
-
httpGet: {
|
|
71
|
-
path: deployConfig.values?.application?.healthRoute ?? "__health",
|
|
72
|
-
},
|
|
73
|
-
},
|
|
74
|
-
};
|
|
75
|
-
|
|
76
|
-
const defaultKubeValues = {
|
|
77
|
-
application: defaultAppConfig,
|
|
78
|
-
|
|
79
|
-
env: env,
|
|
80
|
-
...(deployConfig.values?.cloudsql?.enabled
|
|
81
|
-
? createCloudsqlBaseConfig(context)
|
|
82
|
-
: {}),
|
|
83
|
-
...(deployConfig.values?.mongodb?.enabled
|
|
84
|
-
? createMongodbBaseConfig(context)
|
|
85
|
-
: {}),
|
|
86
|
-
};
|
|
87
|
-
|
|
88
|
-
const kubeValues = processSecretsAsFiles(
|
|
89
|
-
mergeWithMergingArrays(defaultKubeValues, deployConfig.values)
|
|
90
|
-
);
|
|
91
|
-
|
|
27
|
+
const kubeValues = createKubeValues(context);
|
|
92
28
|
const kubernetesEnvironment = {
|
|
93
29
|
namespace: context.environment.envVars.KUBE_NAMESPACE,
|
|
94
30
|
};
|
|
@@ -96,8 +32,9 @@ export const createKubernetesDeployJobs = (
|
|
|
96
32
|
image: getRunnerImage("kubernetes"),
|
|
97
33
|
variables: {
|
|
98
34
|
...context.environment.envVars,
|
|
35
|
+
RELEASE_NAME: context.environment.fullName,
|
|
99
36
|
HELM_EXPERIMENTAL_OCI: "1",
|
|
100
|
-
|
|
37
|
+
KUBE_DOCKER_IMAGE_PULL_SECRET: `gitlab-registry-${context.componentName}`,
|
|
101
38
|
KUBE_VALUES: dump(kubeValues, {
|
|
102
39
|
lineWidth: -1,
|
|
103
40
|
quotingType: "'",
|
|
@@ -110,14 +47,12 @@ export const createKubernetesDeployJobs = (
|
|
|
110
47
|
].join(" "),
|
|
111
48
|
COMPONENT_NAME: context.componentName,
|
|
112
49
|
BUILD_ID: context.commitInfo?.buildId,
|
|
113
|
-
// TODO: unify with docker build stage
|
|
114
|
-
IMAGE_NAME: context.environment.shortName + "/" + context.componentName,
|
|
115
|
-
IMAGE_TAG: "$CI_COMMIT_SHA",
|
|
116
50
|
},
|
|
117
51
|
};
|
|
118
52
|
|
|
119
53
|
const baseDeploymentJob = getBaseDeploymentJob(context);
|
|
120
54
|
const baseStopJob = getBaseDeploymentStopJob(context);
|
|
55
|
+
const baseRollbackJob = getBaseRollbackJob(context);
|
|
121
56
|
const clusterName = `kube-${context.environment.fullName}`;
|
|
122
57
|
const connectContext = [
|
|
123
58
|
`kubectl config set-cluster "${clusterName}" --server="$${getSecretVarNameForContext(
|
|
@@ -152,5 +87,12 @@ export const createKubernetesDeployJobs = (
|
|
|
152
87
|
kubernetes: kubernetesEnvironment,
|
|
153
88
|
},
|
|
154
89
|
}),
|
|
90
|
+
|
|
91
|
+
merge({}, baseRollbackJob, shared, {
|
|
92
|
+
script: [...connectContext, "kubernetesRollback"],
|
|
93
|
+
environment: {
|
|
94
|
+
kubernetes: kubernetesEnvironment,
|
|
95
|
+
},
|
|
96
|
+
}),
|
|
155
97
|
];
|
|
156
98
|
};
|
|
@@ -1 +1,42 @@
|
|
|
1
|
-
|
|
1
|
+
import slugify from "slugify";
|
|
2
|
+
import type { DeployTypeDefinition } from "..";
|
|
3
|
+
import { getKubernetesNamespace } from "..";
|
|
4
|
+
import { additionalKubernetesSecretKeys } from "./additionalSecretKeys";
|
|
5
|
+
import { createKubernetesDeployJobs } from "./deployJob";
|
|
6
|
+
|
|
7
|
+
export const KUBERNETES_DEPLOY_TYPE: DeployTypeDefinition<"kubernetes"> = {
|
|
8
|
+
jobs: createKubernetesDeployJobs,
|
|
9
|
+
defaults: () => ({}),
|
|
10
|
+
additionalSecretKeys: additionalKubernetesSecretKeys,
|
|
11
|
+
getAdditionalEnvVars: ({
|
|
12
|
+
componentName,
|
|
13
|
+
fullConfig,
|
|
14
|
+
deployConfigRaw,
|
|
15
|
+
env,
|
|
16
|
+
envType,
|
|
17
|
+
commitInfo,
|
|
18
|
+
}) => {
|
|
19
|
+
const KUBE_APP_NAME_PREFIX =
|
|
20
|
+
envType === "review" && commitInfo ? `${commitInfo.reviewSlug}-` : "";
|
|
21
|
+
const KUBE_APP_NAME = `${KUBE_APP_NAME_PREFIX}${componentName}`;
|
|
22
|
+
const KUBE_NAMESPACE = getKubernetesNamespace(fullConfig, env);
|
|
23
|
+
const componentSlug = slugify(componentName);
|
|
24
|
+
const envInUrl =
|
|
25
|
+
envType === "review" && commitInfo
|
|
26
|
+
? `${commitInfo.reviewSlug}.${env}`
|
|
27
|
+
: env;
|
|
28
|
+
|
|
29
|
+
const domainCanonical =
|
|
30
|
+
(deployConfigRaw && deployConfigRaw.cluster?.domainCanonical) || // for convenience, we allow clusters to define a canonical domain, because a cluster has a fixed ip and you will usually have a domain pointing to that cluster
|
|
31
|
+
fullConfig.domainCanonical ||
|
|
32
|
+
"panter.cloud";
|
|
33
|
+
const HOST_CANONICAL = `${componentSlug}.${envInUrl}.${fullConfig.appName}.${fullConfig.customerName}.${domainCanonical}`; // default for kubernetes and rest
|
|
34
|
+
|
|
35
|
+
return {
|
|
36
|
+
KUBE_NAMESPACE,
|
|
37
|
+
KUBE_APP_NAME,
|
|
38
|
+
KUBE_APP_NAME_PREFIX,
|
|
39
|
+
HOST_CANONICAL,
|
|
40
|
+
};
|
|
41
|
+
},
|
|
42
|
+
};
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import type { Context } from "../../types";
|
|
2
|
+
import { isOfDeployType } from "../types";
|
|
3
|
+
|
|
4
|
+
const shouldGoIntoSecrets = (key: string, value: string) => {
|
|
5
|
+
if (String(value)?.includes("$CL_")) {
|
|
6
|
+
return true;
|
|
7
|
+
}
|
|
8
|
+
return false;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* separate by secrets and public.
|
|
13
|
+
* we evalulate the actual values later, but want to store the secrets in kubernetes secrets
|
|
14
|
+
*/
|
|
15
|
+
export const createKubeEnv = (context: Context) => {
|
|
16
|
+
if (!isOfDeployType(context.componentConfig.deploy, "kubernetes")) {
|
|
17
|
+
// should not happen
|
|
18
|
+
throw new Error("deploy config is not kubernetes");
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const allEnvVars = context.environment.envVars;
|
|
22
|
+
|
|
23
|
+
const env = Object.entries(allEnvVars).reduce<{
|
|
24
|
+
secret: Record<string, string>;
|
|
25
|
+
public: Record<string, string>;
|
|
26
|
+
}>(
|
|
27
|
+
(acc, [key, value]) => {
|
|
28
|
+
if (shouldGoIntoSecrets(key, value)) {
|
|
29
|
+
acc.secret = {
|
|
30
|
+
...acc.secret,
|
|
31
|
+
[key]: value,
|
|
32
|
+
};
|
|
33
|
+
return acc;
|
|
34
|
+
}
|
|
35
|
+
acc.public = {
|
|
36
|
+
...acc.public,
|
|
37
|
+
[key]: value,
|
|
38
|
+
};
|
|
39
|
+
return acc;
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
secret: {},
|
|
43
|
+
public: {},
|
|
44
|
+
}
|
|
45
|
+
);
|
|
46
|
+
|
|
47
|
+
return env;
|
|
48
|
+
};
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { merge } from "lodash";
|
|
2
|
+
|
|
3
|
+
import type { Context } from "../../types/context";
|
|
4
|
+
import { mergeWithMergingArrays } from "../../utils";
|
|
5
|
+
import { hasCloudSQL } from "../cloudSql";
|
|
6
|
+
import type { DeployConfigKubernetesValues } from "../types";
|
|
7
|
+
import { isOfDeployType } from "../types";
|
|
8
|
+
import { createCloudsqlBaseConfig } from "./cloudsql";
|
|
9
|
+
import { createKubeEnv } from "./kubeEnv";
|
|
10
|
+
import { createMongodbBaseConfig } from "./mongodb";
|
|
11
|
+
import { processSecretsAsFiles } from "./processSecretsAsFiles";
|
|
12
|
+
|
|
13
|
+
const createAppConfig = (
|
|
14
|
+
context: Context,
|
|
15
|
+
application: DeployConfigKubernetesValues["application"]
|
|
16
|
+
): DeployConfigKubernetesValues["application"] => {
|
|
17
|
+
if (application === false) {
|
|
18
|
+
return {
|
|
19
|
+
enabled: false,
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
return mergeWithMergingArrays(
|
|
24
|
+
{
|
|
25
|
+
host: context.environment.host,
|
|
26
|
+
command: context.componentConfig.build.startCommand,
|
|
27
|
+
livenessProbe: {
|
|
28
|
+
httpGet: {
|
|
29
|
+
path: application?.healthRoute ?? "__health",
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
readinessProbe: {
|
|
33
|
+
httpGet: {
|
|
34
|
+
path: application?.healthRoute ?? "__health",
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
startupProbe: {
|
|
38
|
+
httpGet: {
|
|
39
|
+
path: application?.healthRoute ?? "__health",
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
}, // default
|
|
43
|
+
application // merge rest in
|
|
44
|
+
);
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
export const createKubeValues = (context: Context) => {
|
|
48
|
+
const deployConfig = context.componentConfig.deploy;
|
|
49
|
+
if (deployConfig === false) {
|
|
50
|
+
return [];
|
|
51
|
+
}
|
|
52
|
+
if (!isOfDeployType(deployConfig, "kubernetes")) {
|
|
53
|
+
// should not happen
|
|
54
|
+
throw new Error("deploy config is not kubernetes");
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const { values } = deployConfig;
|
|
58
|
+
|
|
59
|
+
// we remove the application config because it can be just the value `false` which is a convenience feature, but not supported in the helm chart
|
|
60
|
+
// we only merge the rest of the values in
|
|
61
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
62
|
+
const { application, ...rest } = values ?? {};
|
|
63
|
+
|
|
64
|
+
const env = createKubeEnv(context);
|
|
65
|
+
|
|
66
|
+
const defaultKubeValues = merge(
|
|
67
|
+
{
|
|
68
|
+
env,
|
|
69
|
+
application: createAppConfig(context, application),
|
|
70
|
+
},
|
|
71
|
+
hasCloudSQL(context) ? createCloudsqlBaseConfig(context) : {},
|
|
72
|
+
deployConfig.values?.mongodb?.enabled
|
|
73
|
+
? createMongodbBaseConfig(context)
|
|
74
|
+
: {}
|
|
75
|
+
);
|
|
76
|
+
|
|
77
|
+
const kubeValues = processSecretsAsFiles(
|
|
78
|
+
mergeWithMergingArrays(defaultKubeValues, rest)
|
|
79
|
+
);
|
|
80
|
+
|
|
81
|
+
return kubeValues;
|
|
82
|
+
};
|
|
@@ -1,17 +1,114 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { range } from "lodash";
|
|
2
|
+
import type { Context } from "../..";
|
|
3
|
+
import { getSecretVarNameForContext, isOfDeployType } from "../..";
|
|
2
4
|
|
|
5
|
+
const getCredentialString = (context: Context) =>
|
|
6
|
+
`root:$${getSecretVarNameForContext(context, "MONGODB_ROOT_PASSWORD")}@`;
|
|
7
|
+
const getMongodbHost = (context: Context, name: string) => {
|
|
8
|
+
const namespace = context.environment.envVars.KUBE_NAMESPACE;
|
|
9
|
+
return `${name}.${namespace}.svc.cluster.local:27017`;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
const getMongodbStandaloneHost = (context: Context) => {
|
|
13
|
+
const fullAppname = context.environment.envVars.KUBE_APP_NAME;
|
|
14
|
+
return getMongodbHost(context, `${fullAppname}-mongodb`);
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
const getMongodbReplicasetHost = (context: Context, index: number) => {
|
|
18
|
+
const fullAppname = context.environment.envVars.KUBE_APP_NAME;
|
|
19
|
+
return getMongodbHost(
|
|
20
|
+
context,
|
|
21
|
+
`${fullAppname}-mongodb-${index}.${fullAppname}-mongodb-headless`
|
|
22
|
+
);
|
|
23
|
+
};
|
|
24
|
+
const createMongodbUrl = (context: Context, dbName: string) => {
|
|
25
|
+
if (!isOfDeployType(context.componentConfig.deploy, "kubernetes")) {
|
|
26
|
+
throw new Error("can only createMongodbUrl on supported deploys");
|
|
27
|
+
}
|
|
28
|
+
const mongodbConfig = context.componentConfig.deploy.values?.mongodb;
|
|
29
|
+
|
|
30
|
+
let queryParams: string | undefined = undefined;
|
|
31
|
+
|
|
32
|
+
let hosts = "";
|
|
33
|
+
if (mongodbConfig?.architecture === "replicaset") {
|
|
34
|
+
hosts = range(0, mongodbConfig?.replicaCount ?? 2)
|
|
35
|
+
.map((i) => getMongodbReplicasetHost(context, i))
|
|
36
|
+
.join(",");
|
|
37
|
+
|
|
38
|
+
queryParams = "replicaSet=rs0&authSource=admin";
|
|
39
|
+
} else {
|
|
40
|
+
hosts = getMongodbStandaloneHost(context);
|
|
41
|
+
queryParams = "authSource=admin";
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
return `mongodb://${getCredentialString(context)}${hosts}/${dbName}${
|
|
45
|
+
queryParams ? `?${queryParams}` : ""
|
|
46
|
+
}`;
|
|
47
|
+
};
|
|
48
|
+
const createMongoBackupDefaultConfig = (context: Context) => {
|
|
49
|
+
if (!isOfDeployType(context.componentConfig.deploy, "kubernetes")) {
|
|
50
|
+
throw new Error("can only create mongodb base config on supported deploys");
|
|
51
|
+
}
|
|
52
|
+
const mongodbConfig = context.componentConfig.deploy.values?.mongodb;
|
|
53
|
+
const fullAppName = context.environment.envVars.KUBE_APP_NAME;
|
|
54
|
+
const backupEnabled = ["prod", "stage"].includes(context.environment.envType);
|
|
55
|
+
|
|
56
|
+
let hostToBackup: string;
|
|
57
|
+
let pvcToBackup: string;
|
|
58
|
+
|
|
59
|
+
if (mongodbConfig?.architecture === "replicaset") {
|
|
60
|
+
// bit quirky, we need to specify the host and its volume
|
|
61
|
+
// on replicaset its probably best to not use the first one, whcih usually starts as master, so we take the second (last one would also be ok)
|
|
62
|
+
const backupHostIndex =
|
|
63
|
+
mongodbConfig?.architecture === "replicaset" &&
|
|
64
|
+
mongodbConfig.replicaCount &&
|
|
65
|
+
mongodbConfig.replicaCount > 1
|
|
66
|
+
? 1
|
|
67
|
+
: 0;
|
|
68
|
+
|
|
69
|
+
hostToBackup = getMongodbReplicasetHost(context, backupHostIndex);
|
|
70
|
+
pvcToBackup = `datadir-${fullAppName}-mongodb-${backupHostIndex}`;
|
|
71
|
+
} else {
|
|
72
|
+
hostToBackup = getMongodbStandaloneHost(context);
|
|
73
|
+
pvcToBackup = `${fullAppName}-mongodb`;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
return {
|
|
77
|
+
enabled: backupEnabled,
|
|
78
|
+
hostToBackup,
|
|
79
|
+
pvcToBackup,
|
|
80
|
+
image: "mrelite/kubectlmongoshell:v1.0",
|
|
81
|
+
schedule: "0 4 * * *",
|
|
82
|
+
volumeSnapshotClass: "snapshotclass",
|
|
83
|
+
};
|
|
84
|
+
};
|
|
3
85
|
export const createMongodbBaseConfig = (context: Context) => {
|
|
86
|
+
if (!isOfDeployType(context.componentConfig.deploy, "kubernetes")) {
|
|
87
|
+
throw new Error("can only create mongodb base config on supported deploys");
|
|
88
|
+
}
|
|
89
|
+
const mongodbConfig = context.componentConfig.deploy.values?.mongodb;
|
|
90
|
+
|
|
4
91
|
return {
|
|
5
92
|
mongodb: {
|
|
6
93
|
enabled: true,
|
|
7
|
-
|
|
8
|
-
enabled:
|
|
94
|
+
auth: {
|
|
95
|
+
enabled: true,
|
|
96
|
+
rootPassword:
|
|
97
|
+
"$" + getSecretVarNameForContext(context, "MONGODB_ROOT_PASSWORD"),
|
|
98
|
+
replicaSetKey:
|
|
99
|
+
"$" + getSecretVarNameForContext(context, "MONGODB_REPLICASET_KEY"),
|
|
100
|
+
},
|
|
101
|
+
persistence: {
|
|
102
|
+
storageClass: "standard-rwo",
|
|
9
103
|
},
|
|
104
|
+
backup: createMongoBackupDefaultConfig(context),
|
|
10
105
|
},
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
106
|
+
env: {
|
|
107
|
+
secret: {
|
|
108
|
+
MONGO_URL: createMongodbUrl(context, mongodbConfig?.dbName ?? "app"),
|
|
109
|
+
...(mongodbConfig?.architecture === "replicaset"
|
|
110
|
+
? { MONGO_OPLOG_URL: createMongodbUrl(context, "local") } // oplog only works with replicasets
|
|
111
|
+
: {}),
|
|
15
112
|
},
|
|
16
113
|
},
|
|
17
114
|
};
|