@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.
Files changed (175) hide show
  1. package/bin/catladder-gitlab.js +1 -1
  2. package/dist/build/base/createBuildJob.d.ts +2 -2
  3. package/dist/build/base/getBuildInfo.d.ts +1 -1
  4. package/dist/build/docker.d.ts +44 -6
  5. package/dist/build/docker.js +45 -19
  6. package/dist/build/index.d.ts +6 -5
  7. package/dist/build/node/buildJob.d.ts +2 -2
  8. package/dist/build/node/cache.d.ts +2 -2
  9. package/dist/build/node/index.d.ts +1 -1
  10. package/dist/build/node/meteor.d.ts +1 -1
  11. package/dist/build/node/meteor.js +6 -0
  12. package/dist/build/node/testJob.d.ts +2 -2
  13. package/dist/build/node/testJob.js +3 -0
  14. package/dist/build/node/yarn.d.ts +1 -1
  15. package/dist/build/node/yarn.js +13 -1
  16. package/dist/build/types.d.ts +10 -0
  17. package/dist/bundles/catladder-gitlab/index.js +32457 -0
  18. package/dist/catladder-gitlab.js +1 -2
  19. package/dist/config/configruedEnvs.d.ts +1 -1
  20. package/dist/config/readConfig.d.ts +1 -1
  21. package/dist/constants.js +1 -1
  22. package/dist/context/getEnvConfig.d.ts +9 -0
  23. package/dist/context/getEnvConfig.js +26 -0
  24. package/dist/context/getEnvType.d.ts +4 -0
  25. package/dist/context/getEnvType.js +18 -0
  26. package/dist/context/getEnvironment.d.ts +3 -0
  27. package/dist/context/getEnvironment.js +187 -0
  28. package/dist/context/getEnvironmentContext.d.ts +4 -0
  29. package/dist/context/getEnvironmentContext.js +36 -0
  30. package/dist/context/getEnvironmentVariables.d.ts +10 -0
  31. package/dist/context/getEnvironmentVariables.js +322 -0
  32. package/dist/context/getLabels.d.ts +8 -0
  33. package/dist/context/getLabels.js +49 -0
  34. package/dist/context/index.d.ts +5 -6
  35. package/dist/context/index.js +176 -181
  36. package/dist/context/resolveReferences.d.ts +1 -3
  37. package/dist/context/resolveReferences.js +275 -26
  38. package/dist/context/resolveReferences.test.js +332 -81
  39. package/dist/defaults/index.d.ts +1 -1
  40. package/dist/deploy/base.d.ts +4 -2
  41. package/dist/deploy/base.js +37 -17
  42. package/dist/deploy/cloudRun/deployJob.d.ts +3 -0
  43. package/dist/deploy/cloudRun/deployJob.js +139 -0
  44. package/dist/deploy/cloudRun/index.d.ts +9 -0
  45. package/dist/deploy/cloudRun/index.js +56 -0
  46. package/dist/deploy/cloudRun/utils/gcloudServiceAccountLoginCommands.d.ts +2 -0
  47. package/dist/deploy/cloudRun/utils/gcloudServiceAccountLoginCommands.js +14 -0
  48. package/dist/deploy/cloudSql/index.d.ts +8 -0
  49. package/dist/deploy/cloudSql/index.js +30 -0
  50. package/dist/deploy/custom/deployJob.d.ts +2 -2
  51. package/dist/deploy/custom/deployJob.js +4 -1
  52. package/dist/deploy/custom/index.d.ts +2 -1
  53. package/dist/deploy/custom/index.js +15 -18
  54. package/dist/deploy/dockerTag/deployJob.d.ts +3 -0
  55. package/dist/deploy/dockerTag/deployJob.js +33 -0
  56. package/dist/deploy/dockerTag/index.d.ts +2 -0
  57. package/dist/deploy/dockerTag/index.js +19 -0
  58. package/dist/deploy/index.d.ts +12 -8
  59. package/dist/deploy/index.js +27 -14
  60. package/dist/deploy/kubernetes/additionalSecretKeys.d.ts +4 -0
  61. package/dist/deploy/kubernetes/additionalSecretKeys.js +33 -0
  62. package/dist/deploy/kubernetes/cloudsql.d.ts +1 -1
  63. package/dist/deploy/kubernetes/deployJob.d.ts +2 -2
  64. package/dist/deploy/kubernetes/deployJob.js +13 -66
  65. package/dist/deploy/kubernetes/index.d.ts +2 -1
  66. package/dist/deploy/kubernetes/index.js +45 -16
  67. package/dist/deploy/kubernetes/kubeEnv.d.ts +10 -0
  68. package/dist/deploy/kubernetes/kubeEnv.js +90 -0
  69. package/dist/deploy/kubernetes/kubeValues.d.ts +90 -0
  70. package/dist/deploy/kubernetes/kubeValues.js +96 -0
  71. package/dist/deploy/kubernetes/mongodb.d.ts +18 -5
  72. package/dist/deploy/kubernetes/mongodb.js +118 -8
  73. package/dist/deploy/kubernetes/processSecretsAsFiles.d.ts +21 -21
  74. package/dist/deploy/types/base.d.ts +15 -0
  75. package/dist/deploy/types/base.js +3 -0
  76. package/dist/deploy/types/custom.d.ts +27 -0
  77. package/dist/deploy/types/custom.js +3 -0
  78. package/dist/deploy/types/dockerTag.d.ts +10 -0
  79. package/dist/deploy/types/dockerTag.js +3 -0
  80. package/dist/deploy/types/googleCloudRun.d.ts +39 -0
  81. package/dist/deploy/types/googleCloudRun.js +3 -0
  82. package/dist/deploy/types/index.d.ts +24 -0
  83. package/dist/deploy/types/index.js +41 -0
  84. package/dist/deploy/{types.d.ts → types/kubernetes.d.ts} +128 -36
  85. package/dist/deploy/types/kubernetes.js +3 -0
  86. package/dist/deploy/utils.d.ts +2 -2
  87. package/dist/deploy/utils.js +4 -0
  88. package/dist/pipeline/createChildPipeline.d.ts +2 -2
  89. package/dist/pipeline/createChildPipeline.js +3 -3
  90. package/dist/pipeline/createJobs.d.ts +2 -2
  91. package/dist/pipeline/createJobs.js +63 -25
  92. package/dist/pipeline/gitlab/makeGitlabJob.d.ts +3 -2
  93. package/dist/pipeline/gitlab/makeGitlabJob.js +2 -1
  94. package/dist/pipeline/packageManager.d.ts +1 -1
  95. package/dist/rules/index.d.ts +1 -1
  96. package/dist/runner/index.d.ts +2 -3
  97. package/dist/tsconfig.tsbuildinfo +1 -1
  98. package/dist/types/config.d.ts +7 -6
  99. package/dist/types/config.js +1 -1
  100. package/dist/types/context.d.ts +10 -2
  101. package/dist/types/environmentContext.d.ts +22 -0
  102. package/dist/types/environmentContext.js +3 -0
  103. package/dist/types/gitlab-types.d.ts +1 -1
  104. package/dist/types/jobs.d.ts +8 -3
  105. package/dist/types/jobs.js +1 -1
  106. package/dist/types/pipeline.d.ts +1 -1
  107. package/package.json +15 -11
  108. package/scripts/bundle +2 -0
  109. package/src/build/base/createBuildJob.ts +3 -2
  110. package/src/build/base/getBuildInfo.ts +1 -1
  111. package/src/build/docker.ts +47 -29
  112. package/src/build/index.ts +8 -5
  113. package/src/build/node/buildJob.ts +2 -2
  114. package/src/build/node/cache.ts +2 -2
  115. package/src/build/node/index.ts +1 -1
  116. package/src/build/node/meteor.ts +8 -2
  117. package/src/build/node/testJob.ts +4 -2
  118. package/src/build/node/yarn.ts +21 -10
  119. package/src/build/tests/storybook.test.ts +1 -1
  120. package/src/build/types.ts +13 -1
  121. package/src/catladder-gitlab.ts +4 -2
  122. package/src/config/configruedEnvs.test.ts +2 -2
  123. package/src/config/configruedEnvs.ts +5 -4
  124. package/src/config/readConfig.ts +1 -1
  125. package/src/context/getEnvConfig.ts +21 -0
  126. package/src/context/getEnvType.ts +17 -0
  127. package/src/context/getEnvironment.ts +40 -0
  128. package/src/context/getEnvironmentContext.ts +57 -0
  129. package/src/context/getEnvironmentVariables.ts +152 -0
  130. package/src/context/getLabels.ts +20 -0
  131. package/src/context/index.ts +25 -191
  132. package/src/context/resolveReferences.test.ts +15 -15
  133. package/src/context/resolveReferences.ts +37 -30
  134. package/src/defaults/index.ts +1 -1
  135. package/src/deploy/base.ts +43 -19
  136. package/src/deploy/cloudRun/deployJob.ts +104 -0
  137. package/src/deploy/cloudRun/index.ts +48 -0
  138. package/src/deploy/cloudRun/utils/gcloudServiceAccountLoginCommands.ts +14 -0
  139. package/src/deploy/cloudSql/index.ts +16 -0
  140. package/src/deploy/custom/deployJob.ts +10 -3
  141. package/src/deploy/custom/index.ts +9 -1
  142. package/src/deploy/dockerTag/deployJob.ts +31 -0
  143. package/src/deploy/dockerTag/index.ts +9 -0
  144. package/src/deploy/index.ts +26 -17
  145. package/src/deploy/kubernetes/additionalSecretKeys.ts +23 -0
  146. package/src/deploy/kubernetes/cloudsql.ts +2 -1
  147. package/src/deploy/kubernetes/deployJob.ts +19 -77
  148. package/src/deploy/kubernetes/index.ts +42 -1
  149. package/src/deploy/kubernetes/kubeEnv.ts +48 -0
  150. package/src/deploy/kubernetes/kubeValues.ts +82 -0
  151. package/src/deploy/kubernetes/mongodb.ts +104 -7
  152. package/src/deploy/kubernetes/processSecretsAsFiles.ts +1 -1
  153. package/src/deploy/types/base.ts +17 -0
  154. package/src/deploy/types/custom.ts +24 -0
  155. package/src/deploy/types/dockerTag.ts +12 -0
  156. package/src/deploy/types/googleCloudRun.ts +79 -0
  157. package/src/deploy/types/index.ts +28 -0
  158. package/src/deploy/types/kubernetes.ts +281 -0
  159. package/src/deploy/utils.ts +6 -2
  160. package/src/pipeline/createChildPipeline.test.ts +1 -1
  161. package/src/pipeline/createChildPipeline.ts +4 -4
  162. package/src/pipeline/createJobs.ts +32 -21
  163. package/src/pipeline/gitlab/makeGitlabJob.ts +3 -2
  164. package/src/pipeline/packageManager.ts +1 -1
  165. package/src/rules/index.ts +1 -1
  166. package/src/runner/index.ts +2 -1
  167. package/src/types/config.ts +8 -6
  168. package/src/types/context.ts +14 -2
  169. package/src/types/environmentContext.ts +26 -0
  170. package/src/types/gitlab-types.ts +1 -1
  171. package/src/types/jobs.ts +9 -2
  172. package/src/types/pipeline.ts +1 -1
  173. package/tsconfig.json +2 -0
  174. package/dist/deploy/types.js +0 -16
  175. 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
- import { Context } from "../../types/context";
3
- import { CatladderJob } from "../../types/jobs";
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: [`cd ${context.componentConfig.dir}`, ...deployConfig.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
- export * from "./deployJob";
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
+ };
@@ -1,25 +1,34 @@
1
- import { Context } from "../types/context";
2
- import { CatladderJob } from "../types/jobs";
3
- import { createCustomDeployJobs } from "./custom";
4
- import { createKubernetesDeployJobs } from "./kubernetes";
5
- import { DeployConfig } from "./types";
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
- [type in DeployConfig["type"]]: {
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
- jobs: createKubernetesDeployJobs,
19
- defaults: () => ({}),
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,4 +1,5 @@
1
- import { Context, getSecretVarNameForContext } from "../..";
1
+ import type { Context} from "../..";
2
+ import { getSecretVarNameForContext } from "../..";
2
3
 
3
4
  export const createCloudsqlBaseConfig = (context: Context) => {
4
5
  return {
@@ -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 { mergeWithMergingArrays } from "../../utils";
9
- import { getBaseDeploymentJob, getBaseDeploymentStopJob } from "../base";
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 { createCloudsqlBaseConfig } from "./cloudsql";
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 allEnvVars = context.environment.envVars;
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
- IMAGE_PULL_SECRET: `gitlab-registry-${context.componentName}`,
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
- export * from "./deployJob";
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 { Context } from "../..";
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
- backup: {
8
- enabled: ["prod", "stage"].includes(context.environment.envType),
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
- "mongodb-replicaset": {
12
- replicas: 1,
13
- persistentVolume: {
14
- storageClass: "standard",
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
  };