Skip to content

Commit

Permalink
feat: restore jobs (#227)
Browse files Browse the repository at this point in the history
* feat: backup/restore

* fix(restore-container): from env-vars

* fix: add dummy file for tests

* feat: add restore db

* fix: run restore job in prod

* fix(ci): variable db restore options

* fix: restore: disable db atm

* Update .gitlab-ci.yml

* fix: plop

* Update .gitlab-ci.yml

* Update .gitlab-ci.yml

Co-authored-by: Lionel <lionel.breduillieard@beta.gouv.fr>
  • Loading branch information
Julien Bouquillon and lionelB committed Dec 16, 2020
1 parent e018458 commit 88824f3
Show file tree
Hide file tree
Showing 19 changed files with 4,476 additions and 1 deletion.
27 changes: 27 additions & 0 deletions .gitlab-ci.yml
Expand Up @@ -2,6 +2,9 @@ include:
- project: SocialGouv/gitlab-ci-yml
file: /autodevops_simple_app.yml
ref: v16.2.0
- project: SocialGouv/gitlab-ci-yml
file: /base_deploy_kosko_stage.yml
ref: v20.1.1
#
- /targets/alert-cli/.gitlab-ci.yml
- /targets/ingester/.gitlab-ci.yml
Expand Down Expand Up @@ -98,3 +101,27 @@ Deploy app (dev):
Deploy app (prod):
only:
- never

#

# todo: restrict to branches ?
Restore container:
stage: Deploy
only:
- branches
extends:
- .base_deploy_kosko_stage
environment:
name: prod2
variables:
# storage copy
SOURCE_CONTAINER: "cdtn"
SOURCE_SERVER: "dev"
DESTINATION_CONTAINER: "cdtn-dev"
DESTINATION_SERVER: "dev"
# db restore
# BACKUP_DB_NAME: "db_${CI_COMMIR_SHORT_SHA}"
# BACKUP_DB_OWNER: "user_${CI_COMMIR_SHORT_SHA}"
# BACKUP_DB_FILE: "hasura_prod_db.psql.gz"
# kosko options
KOSKO_GENERATE_ARGS: --env prod restore
6 changes: 6 additions & 0 deletions .k8s/__tests__/__snapshots__/kosko generate --env dev.ts.snap
@@ -0,0 +1,6 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`kosko generate --dev 1`] = `
"42
"
`;
@@ -0,0 +1,6 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`kosko generate --preprod 1`] = `
"42
"
`;
107 changes: 107 additions & 0 deletions .k8s/__tests__/__snapshots__/kosko generate --env prod restore.ts.snap
@@ -0,0 +1,107 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`kosko generate --prod restore 1`] = `
"metadata:
name: restore-container-8843083e
namespace: cdtn-admin-secret
spec:
backoffLimit: 0
template:
metadata: {}
spec:
containers:
- command:
- sh
- '-c'
- >+
[ ! -z $SOURCE_CONTAINER ] || (echo \\"No SOURCE_CONTAINER\\"; exit 1)
[ ! -z $SOURCE_ACCOUNT_NAME ] || (echo \\"No SOURCE_ACCOUNT_NAME\\";
exit 1)
[ ! -z $SOURCE_ACCOUNT_KEY ] || (echo \\"No SOURCE_ACCOUNT_KEY\\";
exit 1)
[ ! -z $DESTINATION_CONTAINER ] || (echo \\"No
DESTINATION_CONTAINER\\"; exit 1)
[ ! -z $DESTINATION_ACCOUNT_NAME ] || (echo \\"No
DESTINATION_ACCOUNT_NAME\\"; exit 1)
[ ! -z $DESTINATION_ACCOUNT_KEY ] || (echo \\"No
DESTINATION_ACCOUNT_KEY\\"; exit 1)
echo \\"starting restore container $SOURCE_CONTAINER into
$DESTINATION_CONTAINER\\"
# copy container
az storage copy -r --source-account-name
\\"$SOURCE_ACCOUNT_NAME\\" --source-account-key
\\"$SOURCE_ACCOUNT_KEY\\" --source-container \\"$SOURCE_CONTAINER\\"
--account-name \\"$DESTINATION_ACCOUNT_NAME\\" --account-key
\\"$DESTINATION_ACCOUNT_KEY\\" --destination-container
\\"$DESTINATION_CONTAINER\\"
# get original permission
PUBLIC_ACCESS=\`az storage container show-permission
--account-name \\"$SOURCE_ACCOUNT_NAME\\" --account-key
\\"$SOURCE_ACCOUNT_KEY\\" --name $SOURCE_CONTAINER | jq -r
\\".publicAccess\\"\`
# set original permission
az storage container set-permission --name
$DESTINATION_CONTAINER --account-name
\\"$DESTINATION_ACCOUNT_NAME\\" --account-key
\\"$DESTINATION_ACCOUNT_KEY\\" --public-access $PUBLIC_ACCESS
env:
- name: SOURCE_ACCOUNT_NAME
valueFrom:
secretKeyRef:
name: azure-cdtnadminprod-volume
key: azurestorageaccountname
- name: SOURCE_ACCOUNT_KEY
valueFrom:
secretKeyRef:
name: azure-cdtnadminprod-volume
key: azurestorageaccountkey
- name: DESTINATION_ACCOUNT_NAME
valueFrom:
secretKeyRef:
name: azure-cdtnadmindev-volume
key: azurestorageaccountname
- name: DESTINATION_ACCOUNT_KEY
valueFrom:
secretKeyRef:
name: azure-cdtnadmindev-volume
key: azurestorageaccountkey
- name: SOURCE_CONTAINER
value: source-container
- name: DESTINATION_CONTAINER
value: destination-container
envFrom: []
image: 'mcr.microsoft.com/azure-cli:2.15.1'
imagePullPolicy: IfNotPresent
name: restore-db
resources:
limits:
cpu: 300m
memory: 512Mi
requests:
cpu: 50m
memory: 64Mi
restartPolicy: Never
apiVersion: batch/v1
kind: Job
"
`;
@@ -0,0 +1,6 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`kosko generate --prod 1`] = `
"42
"
`;
15 changes: 15 additions & 0 deletions .k8s/__tests__/kosko generate --env dev.ts
@@ -0,0 +1,15 @@
//

import { getEnvManifests } from "@socialgouv/kosko-charts/testing";
import { project } from "@socialgouv/kosko-charts/testing/fake/gitlab-ci.env";

jest.setTimeout(1000 * 60);
test("kosko generate --dev", async () => {
expect(
await getEnvManifests("dev", "", {
...project("cdtn-admin").dev,
KUBE_NAMESPACE: "foo-XYZ-master-dev2",
RANCHER_PROJECT_ID: "c-bar:p-foo",
})
).toMatchSnapshot();
});
15 changes: 15 additions & 0 deletions .k8s/__tests__/kosko generate --env preprod.ts
@@ -0,0 +1,15 @@
//

import { getEnvManifests } from "@socialgouv/kosko-charts/testing";
import { project } from "@socialgouv/kosko-charts/testing/fake/gitlab-ci.env";

jest.setTimeout(1000 * 60);
test("kosko generate --preprod", async () => {
expect(
await getEnvManifests("preprod", "", {
...project("cdtn-admin").preprod,
KUBE_NAMESPACE: "foo-XYZ-preprod-dev2",
RANCHER_PROJECT_ID: "c-bar:p-foo",
})
).toMatchSnapshot();
});
20 changes: 20 additions & 0 deletions .k8s/__tests__/kosko generate --env prod restore.ts
@@ -0,0 +1,20 @@
//

import { getEnvManifests } from "@socialgouv/kosko-charts/testing";
import { project } from "@socialgouv/kosko-charts/testing/fake/gitlab-ci.env";

jest.setTimeout(1000 * 60);
test("kosko generate --prod restore", async () => {
process.env.SOURCE_CONTAINER = "source-container";
process.env.SOURCE_SERVER = "prod";
process.env.DESTINATION_CONTAINER = "destination-container";
process.env.DESTINATION_SERVER = "dev";
process.env.BACKUP_DB_OWNER = "some-owner";
process.env.BACKUP_DB_NAME = "some-database";
process.env.BACKUP_DB_FILE = "some-backup.sql.gz";
expect(
await getEnvManifests("prod", "restore", {
...project("cdtn-admin").prod,
})
).toMatchSnapshot();
});
13 changes: 13 additions & 0 deletions .k8s/__tests__/kosko generate --env prod.ts
@@ -0,0 +1,13 @@
//

import { getEnvManifests } from "@socialgouv/kosko-charts/testing";
import { project } from "@socialgouv/kosko-charts/testing/fake/gitlab-ci.env";

jest.setTimeout(1000 * 60);
test("kosko generate --prod", async () => {
expect(
await getEnvManifests("prod", "", {
...project("cdtn-admin").prod,
})
).toMatchSnapshot();
});
2 changes: 2 additions & 0 deletions .k8s/components/index.ts
@@ -0,0 +1,2 @@
//dummy
export default [42];
31 changes: 31 additions & 0 deletions .k8s/components/restore/container.ts
@@ -0,0 +1,31 @@
import env from "@kosko/env";
import { ok } from "assert";

import { EnvVar } from "kubernetes-models/v1/EnvVar";
import { restoreContainerJob } from "@socialgouv/kosko-charts/components/azure-storage/restore-container.job";

ok(process.env.SOURCE_CONTAINER);
ok(process.env.DESTINATION_CONTAINER);
ok(process.env.SOURCE_SERVER === "prod" || process.env.SOURCE_SERVER === "dev");
ok(
process.env.DESTINATION_SERVER === "prod" ||
process.env.DESTINATION_SERVER === "dev"
);

const manifests = restoreContainerJob({
env: [
new EnvVar({
name: "SOURCE_CONTAINER",
value: process.env.SOURCE_CONTAINER,
}),
new EnvVar({
name: "DESTINATION_CONTAINER",
value: process.env.DESTINATION_CONTAINER,
}),
],
project: "cdtn-admin",
from: process.env.SOURCE_SERVER,
to: process.env.DESTINATION_SERVER,
});

export default manifests;
29 changes: 29 additions & 0 deletions .k8s/components/restore/db.ts
@@ -0,0 +1,29 @@
import env from "@kosko/env";
import { ok } from "assert";

import { EnvVar } from "kubernetes-models/v1/EnvVar";
import { restoreDbJob } from "@socialgouv/kosko-charts/components/azure-pg/restore-db.job";

ok(process.env.BACKUP_DB_NAME);
ok(process.env.BACKUP_DB_OWNER);
ok(process.env.BACKUP_DB_FILE);

const manifests = restoreDbJob({
project: "cdtn-admin",
env: [
new EnvVar({
name: "PGDATABASE",
value: process.env.BACKUP_DB_NAME,
}),
new EnvVar({
name: "OWNER",
value: process.env.BACKUP_DB_OWNER,
}),
new EnvVar({
name: "FILE",
value: process.env.BACKUP_DB_FILE,
}),
],
});

export default manifests;
4 changes: 4 additions & 0 deletions .k8s/components/restore/index.ts
@@ -0,0 +1,4 @@
import containerJob from "./container";
import dbJob from "./db";

export default [containerJob /*, dbJob*/];
13 changes: 13 additions & 0 deletions .k8s/environments/.gitlab-ci.env
@@ -0,0 +1,13 @@
CI_COMMIT_REF_NAME=cdtn-admin-branch
CI_ENVIRONMENT_NAME=cdtn-admin-branch-dev2
CI_ENVIRONMENT_SLUG=cdtn-admin-branch-42
CI_ENVIRONMENT_URL=https://cdtn-admin-branch-dev2-sample-next-app.dev2.fabrique.social.gouv.fr
CI_PROJECT_NAME=cdtn-admin
CI_PROJECT_PATH_SLUG=socialgouv-cdtn-admin
CI_REGISTRY_IMAGE=registry.gitlab.factory.social.gouv.fr/socialgouv/cdtn-admin
CI_REPOSITORY_URL=git@github.com:SocialGouv/cdtn-admin.git
KUBE_INGRESS_BASE_DOMAIN=dev2.fabrique.social.gouv.fr
KUBE_NAMESPACE=cdtn-admin-24-branch-42
RANCHER_PROJECT_ID=c-kk8xm:p-4fxg8
CI_COMMIT_SHA=8843083edb7f873cad1d1420731a60773594ffae
CI_COMMIT_SHORT_SHA=8843083e
8 changes: 8 additions & 0 deletions .k8s/kosko.toml
@@ -0,0 +1,8 @@

# dont include restore jobs on deploys
components = ["!restore", "*"]
require = ["ts-node/register"]

# dont include underscores-prefix components
[environments.prod]
components = ["!(_*)"]
38 changes: 38 additions & 0 deletions .k8s/package.json
@@ -0,0 +1,38 @@
{
"babel": {
"plugins": [
[
"@babel/plugin-transform-modules-commonjs"
]
]
},
"dependencies": {
"@kosko/env": "^1.0.1",
"@kubernetes-models/sealed-secrets": "^1.0.1",
"@socialgouv/kosko-charts": "^4.1.0",
"@types/node": "^14.14.13",
"kosko": "^1.0.1",
"kubernetes-models": "^1.0.1",
"ts-node": "^9.1.1",
"typescript": "^4.1.3"
},
"devDependencies": {
"@babel/core": "^7.12.10",
"@babel/plugin-transform-modules-commonjs": "^7.12.1",
"@types/jest": "^26.0.18",
"dotenv": "^8.2.0",
"jest": "^26.6.3"
},
"license": "Apache-2.0",
"scripts": {
"generate": "kosko generate",
"generate:dev": "kosko generate --env dev",
"generate:preprod": "kosko generate --env preprod",
"generate:prod": "kosko generate --env prod",
"gitlab": "DOTENV_CONFIG_PATH=./environments/.gitlab-ci.env kosko generate --require dotenv/config",
"gitlab:dev": "yarn --silent gitlab --env dev",
"gitlab:preprod": "yarn --silent gitlab --env preprod",
"gitlab:prod": "yarn --silent gitlab --env prod",
"test": "jest"
}
}
11 changes: 11 additions & 0 deletions .k8s/tsconfig.json
@@ -0,0 +1,11 @@
{
"compilerOptions": {
"baseUrl": ".",
"esModuleInterop": true,
"module": "commonjs",
"moduleResolution": "node",
"strict": true,
"target": "es2015",
"types": ["node", "jest"]
}
}

0 comments on commit 88824f3

Please sign in to comment.