@docupace/pipeline 1.0.7-alpha.ervins1.9 → 1.0.7-beta.0
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/package.json +3 -5
- package/src/next/cli.js +1 -40
- package/src/next/config.js +3 -15
- package/src/next/deploy.js +22 -39
- package/src/auth0/cli.js +0 -31
- package/src/auth0/configure.js +0 -622
- package/src/auth0/vault.js +0 -107
- package/src/next/apache.js +0 -36
- package/src/next/connect.js +0 -158
- package/src/next/haproxy.js +0 -50
- package/src/next/vault.js +0 -13
package/package.json
CHANGED
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@docupace/pipeline",
|
|
3
|
-
"version": "1.0.7-
|
|
3
|
+
"version": "1.0.7-beta.0",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"bin": {
|
|
8
8
|
"dp-changeset-cli": "src/changeset/cli.js",
|
|
9
|
-
"dp-next-cli": "src/next/cli.js"
|
|
10
|
-
"dp-auth0-cli": "src/auth0/cli.js"
|
|
9
|
+
"dp-next-cli": "src/next/cli.js"
|
|
11
10
|
},
|
|
12
11
|
"keywords": [
|
|
13
12
|
"bash"
|
|
@@ -16,7 +15,6 @@
|
|
|
16
15
|
"license": "ISC",
|
|
17
16
|
"dependencies": {
|
|
18
17
|
"@changesets/cli": "^2.27.10",
|
|
19
|
-
"auth0-deploy-cli": "^7.24.3",
|
|
20
18
|
"axios": "^1.7.9",
|
|
21
19
|
"commander": "^12.1.0",
|
|
22
20
|
"dotenv": "^16.4.7",
|
|
@@ -24,7 +22,7 @@
|
|
|
24
22
|
"lodash": "^4.17.21",
|
|
25
23
|
"openai": "^4.76.3",
|
|
26
24
|
"zod": "^3.24.1",
|
|
27
|
-
"zx": "^8.
|
|
25
|
+
"zx": "^8.2.4"
|
|
28
26
|
},
|
|
29
27
|
"devDependencies": {
|
|
30
28
|
"@eslint/js": "^9.17.0",
|
package/src/next/cli.js
CHANGED
|
@@ -7,10 +7,6 @@ import { publish } from './publish.js';
|
|
|
7
7
|
import { deployFromSite } from './deploy.js';
|
|
8
8
|
import { deployTemplate } from './deploy.js';
|
|
9
9
|
import { copy } from './copy.js';
|
|
10
|
-
import { vaultAddSiteData } from './vault.js';
|
|
11
|
-
import { addApacheSite } from './apache.js';
|
|
12
|
-
import { haproxySync } from './haproxy.js';
|
|
13
|
-
import { connectClone } from './connect.js';
|
|
14
10
|
import dotenv from 'dotenv';
|
|
15
11
|
|
|
16
12
|
dotenv.config({ path: ['.env.pipeline.local', 'config/.env.pipeline.local'] });
|
|
@@ -21,7 +17,6 @@ const program = new Command();
|
|
|
21
17
|
import { $ } from 'zx';
|
|
22
18
|
import { deployCore } from './jenkins.js';
|
|
23
19
|
import { runPipeline } from './pipline.js';
|
|
24
|
-
|
|
25
20
|
const GIT_SHA = (await $`git log --pretty=format:'%h' -n 1`).stdout.trim();
|
|
26
21
|
|
|
27
22
|
program
|
|
@@ -38,39 +33,6 @@ program
|
|
|
38
33
|
await sonar(GIT_SHA);
|
|
39
34
|
});
|
|
40
35
|
|
|
41
|
-
program
|
|
42
|
-
.command('addApacheSite')
|
|
43
|
-
.description('Add site to apache')
|
|
44
|
-
.action(async () => {
|
|
45
|
-
await addApacheSite();
|
|
46
|
-
});
|
|
47
|
-
|
|
48
|
-
program
|
|
49
|
-
.command('connectClone')
|
|
50
|
-
.description('Clone connect site')
|
|
51
|
-
.action(async () => {
|
|
52
|
-
await connectClone();
|
|
53
|
-
});
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
program
|
|
57
|
-
.command('haproxySync')
|
|
58
|
-
.description('Sync haproxy config')
|
|
59
|
-
.action(async () => {
|
|
60
|
-
await haproxySync();
|
|
61
|
-
});
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
program
|
|
66
|
-
.command('vaultAddSiteData')
|
|
67
|
-
.description('Add m2m auth0 data to vault')
|
|
68
|
-
.requiredOption('-s, --site-name <siteName>', 'Site name')
|
|
69
|
-
.action(async (options) => {
|
|
70
|
-
const { siteName, } = options;
|
|
71
|
-
await vaultAddSiteData(siteName);
|
|
72
|
-
});
|
|
73
|
-
|
|
74
36
|
program
|
|
75
37
|
.command('publish')
|
|
76
38
|
.description('Publish a Docker image')
|
|
@@ -121,8 +83,7 @@ program
|
|
|
121
83
|
});
|
|
122
84
|
});
|
|
123
85
|
|
|
124
|
-
|
|
125
|
-
program
|
|
86
|
+
program
|
|
126
87
|
.command('copy')
|
|
127
88
|
.description('Copy a Docker image between registries')
|
|
128
89
|
.requiredOption('-a, --application <application>', 'Application name')
|
package/src/next/config.js
CHANGED
|
@@ -4,27 +4,23 @@ export const environmentConfig = {
|
|
|
4
4
|
dev: {
|
|
5
5
|
newUrl: (site) => `${site}.dev.dpai.tech`,
|
|
6
6
|
oldUrl: (site) => `https://www.dev.docupaceinc.com/${site}`,
|
|
7
|
-
docupaceHost: () => 'www.dev.docupaceinc.com',
|
|
8
7
|
},
|
|
9
8
|
qa: {
|
|
10
9
|
newUrl: (site) => `${site}.qa.dpai.tech`,
|
|
11
10
|
oldUrl: (site) => `https://www.preprod.docupaceinc.com/${site}`,
|
|
12
|
-
docupaceHost: () => 'www.preprod.docupaceinc.com',
|
|
13
11
|
},
|
|
14
12
|
uat: {
|
|
15
13
|
newUrl: (site) => `${site}.qa.dpai.tech`,
|
|
16
14
|
oldUrl: (site) => `https://www2.paperout.com/${site}_uat`,
|
|
17
|
-
docupaceHost: () => 'www2.paperout.com',
|
|
18
15
|
},
|
|
19
16
|
stage: {
|
|
20
17
|
newUrl: (site) => `${site}.stage.dpai.tech`,
|
|
21
18
|
oldUrl: (site) => `https://www2.paperout.com/${site}_staging`,
|
|
22
|
-
docupaceHost: () => 'www2.paperout.com',
|
|
23
19
|
},
|
|
20
|
+
|
|
24
21
|
prod: {
|
|
25
22
|
newUrl: (site) => `${site}.dpai.tech`,
|
|
26
23
|
oldUrl: (site) => `https://www2.paperout.com/${site}`,
|
|
27
|
-
docupaceHost: () => 'www2.paperout.com',
|
|
28
24
|
},
|
|
29
25
|
};
|
|
30
26
|
|
|
@@ -69,16 +65,8 @@ export const getBitbucketInfo = () => {
|
|
|
69
65
|
|
|
70
66
|
export const getRepUrl = (repoName) => {
|
|
71
67
|
const { username, password, workspace } = getBitbucketInfo();
|
|
72
|
-
|
|
68
|
+
const repoUrl = `https://${username}:${password}@bitbucket.org/${workspace}/${repoName}.git`;
|
|
69
|
+
return repoUrl;
|
|
73
70
|
};
|
|
74
71
|
|
|
75
72
|
export const jfRegistryUrl = 'registry.paperout.com';
|
|
76
|
-
|
|
77
|
-
export const getVaultSecretsConfigs = (site) => {
|
|
78
|
-
return {
|
|
79
|
-
commonSecretsPath: 'secret/data/common/config',
|
|
80
|
-
siteCommonSecretsPath: `secret/data/${site}/common/config`,
|
|
81
|
-
graphqlServerSecretsPath: `secret/data/${site}/graphql-server/config`,
|
|
82
|
-
uiSecretsPath: `secret/data/${site}/ui/config`
|
|
83
|
-
}
|
|
84
|
-
};
|
package/src/next/deploy.js
CHANGED
|
@@ -22,56 +22,27 @@ function getRepoLocalPath(env) {
|
|
|
22
22
|
return { repoPath, repoName };
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
-
function
|
|
26
|
-
const repoName = `${repoSlug}`;
|
|
27
|
-
const repoPath = path.join(process.cwd(), repoName);
|
|
28
|
-
return { repoPath, repoName };
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
function cleanUpRepoPath(repoPath) {
|
|
32
|
-
// Check and handle repo directory
|
|
33
|
-
if (fs.existsSync(repoPath)) {
|
|
34
|
-
console.log(`${repoPath} directory exists. Removing it...`);
|
|
35
|
-
fs.rmSync(repoPath, {
|
|
36
|
-
recursive: true,
|
|
37
|
-
force: true
|
|
38
|
-
});
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
export async function cloneEnvRepository(env) {
|
|
25
|
+
async function cloneEnvRepository(env) {
|
|
43
26
|
const { repoPath, repoName } = getRepoLocalPath(env);
|
|
44
27
|
const repoUrl = getRepUrl(repoName);
|
|
45
28
|
console.log(`Cloning repository: ${repoName}`);
|
|
46
|
-
await $`git clone
|
|
47
|
-
console.log(`Repository cloned to: ${repoPath}`);
|
|
48
|
-
return repoPath;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
export async function cloneRepository(repoSlug) {
|
|
52
|
-
const { repoPath, repoName } = getRepoLocalPathByRepoSlug(repoSlug);
|
|
53
|
-
const repoUrl = getRepUrl(repoName);
|
|
54
|
-
|
|
55
|
-
await cleanUpRepoPath(repoPath)
|
|
56
|
-
|
|
57
|
-
console.log(`Cloning repository: ${repoName}`);
|
|
58
|
-
await $`git clone --depth 1 ${repoUrl}`;
|
|
29
|
+
await $`git clone ${repoUrl}`;
|
|
59
30
|
console.log(`Repository cloned to: ${repoPath}`);
|
|
60
31
|
return repoPath;
|
|
61
32
|
}
|
|
62
33
|
|
|
63
|
-
function getConfigPath(application, env, site) {
|
|
34
|
+
function getConfigPath(application, env, site, name) {
|
|
64
35
|
const { repoPath } = getRepoLocalPath(env);
|
|
65
36
|
const deployConfigFilePath = path.join(
|
|
66
37
|
repoPath,
|
|
67
|
-
`dp/${site}/${application}.
|
|
38
|
+
`dp/${site}/${application}.${name}.yaml`,
|
|
68
39
|
);
|
|
69
40
|
|
|
70
41
|
return { repoPath, deployConfigFilePath };
|
|
71
42
|
}
|
|
72
43
|
|
|
73
|
-
|
|
74
|
-
const { deployConfigFilePath } = getConfigPath(application, env, site);
|
|
44
|
+
async function readDeployConfig(application, env, site, name) {
|
|
45
|
+
const { deployConfigFilePath } = getConfigPath(application, env, site, name);
|
|
75
46
|
|
|
76
47
|
let deployConfig;
|
|
77
48
|
try {
|
|
@@ -92,6 +63,7 @@ export async function cloneAndReadDeployConfig(application, env, site) {
|
|
|
92
63
|
application,
|
|
93
64
|
env,
|
|
94
65
|
site,
|
|
66
|
+
'values',
|
|
95
67
|
);
|
|
96
68
|
|
|
97
69
|
return { repoPath, deployConfigFilePath, deployConfig };
|
|
@@ -147,7 +119,7 @@ export async function pushDeployConfig(repoPath, commitMessage) {
|
|
|
147
119
|
console.log('✅ Cleanup complete.');
|
|
148
120
|
}
|
|
149
121
|
|
|
150
|
-
function writeDeployConfig(
|
|
122
|
+
function writeDeployConfig(deployConfigFilePath, deployConfig) {
|
|
151
123
|
try {
|
|
152
124
|
fs.writeFileSync(deployConfigFilePath, yaml.dump(deployConfig), 'utf8');
|
|
153
125
|
console.log(`✅ Updated YAML file saved at: ${deployConfigFilePath}`);
|
|
@@ -163,7 +135,7 @@ export async function writeAndPushDeployConfig(
|
|
|
163
135
|
deployConfig,
|
|
164
136
|
commitMessage,
|
|
165
137
|
) {
|
|
166
|
-
writeDeployConfig(
|
|
138
|
+
writeDeployConfig(deployConfigFilePath, deployConfig);
|
|
167
139
|
await pushDeployConfig(repoPath, commitMessage);
|
|
168
140
|
}
|
|
169
141
|
|
|
@@ -301,6 +273,7 @@ export async function deployFromSite(
|
|
|
301
273
|
application,
|
|
302
274
|
fromEnv,
|
|
303
275
|
fromSite,
|
|
276
|
+
'values',
|
|
304
277
|
);
|
|
305
278
|
|
|
306
279
|
if (fromEnv !== toEnv) {
|
|
@@ -311,7 +284,7 @@ export async function deployFromSite(
|
|
|
311
284
|
const {
|
|
312
285
|
deployConfig: toDeployConfig,
|
|
313
286
|
deployConfigFilePath: toDeployConfigFilePath,
|
|
314
|
-
} = await readDeployConfig(application, toEnv, toSite);
|
|
287
|
+
} = await readDeployConfig(application, toEnv, toSite, 'values');
|
|
315
288
|
|
|
316
289
|
// Update target configuration using attributes specified in appInfo
|
|
317
290
|
for (const attribute of appDetails.deployAttributes) {
|
|
@@ -324,8 +297,18 @@ export async function deployFromSite(
|
|
|
324
297
|
}
|
|
325
298
|
}
|
|
326
299
|
|
|
300
|
+
const {
|
|
301
|
+
deployConfig: toDeployAppConfig,
|
|
302
|
+
deployConfigFilePath: toDeployAppConfigFilePath,
|
|
303
|
+
} = await readDeployConfig(application, toEnv, toSite, 'app');
|
|
304
|
+
|
|
305
|
+
toDeployAppConfig.revision = fromDeployConfig.image.tag;
|
|
306
|
+
|
|
327
307
|
// Write updated configuration to the target YAML file
|
|
328
|
-
writeDeployConfig(
|
|
308
|
+
writeDeployConfig(toDeployConfigFilePath, toDeployConfig);
|
|
309
|
+
|
|
310
|
+
writeDeployConfig(toDeployAppConfigFilePath, toDeployAppConfig);
|
|
311
|
+
|
|
329
312
|
}
|
|
330
313
|
|
|
331
314
|
// Push all changes if any updates were made
|
package/src/auth0/cli.js
DELETED
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
import { Command } from 'commander';
|
|
4
|
-
import {
|
|
5
|
-
configureFromSite
|
|
6
|
-
} from './configure.js';
|
|
7
|
-
import {
|
|
8
|
-
getVaultSecrets
|
|
9
|
-
} from './vault.js'
|
|
10
|
-
|
|
11
|
-
import dotenv from 'dotenv';
|
|
12
|
-
|
|
13
|
-
dotenv.config({ path: ['.env.pipeline.local', 'config/.env.pipeline.local'] });
|
|
14
|
-
|
|
15
|
-
const program = new Command();
|
|
16
|
-
|
|
17
|
-
program
|
|
18
|
-
.command('configureFromSite <fromSite> <toSite> <env> <deployUI> <deployGraphQLServer> <useNewDomain>')
|
|
19
|
-
.description('Configure the Auth0 tenants in env for the given site')
|
|
20
|
-
.action(async (fromSite, toSite, env, deployUI, deployGraphQLServer, useNewDomain) => {
|
|
21
|
-
await configureFromSite(fromSite, toSite, env, deployUI, deployGraphQLServer, useNewDomain);
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
program
|
|
25
|
-
.command('getVaultSecrets <vaultPath>')
|
|
26
|
-
.description('Get Secrets for Vault PATH')
|
|
27
|
-
.action(async (vaultPath) => {
|
|
28
|
-
await getVaultSecrets(vaultPath);
|
|
29
|
-
});
|
|
30
|
-
|
|
31
|
-
program.parse(process.argv);
|
package/src/auth0/configure.js
DELETED
|
@@ -1,622 +0,0 @@
|
|
|
1
|
-
import fs from 'fs';
|
|
2
|
-
import path from 'path';
|
|
3
|
-
import yaml from 'js-yaml';
|
|
4
|
-
import { $ } from 'zx';
|
|
5
|
-
import axios from 'axios';
|
|
6
|
-
import crypto from 'crypto';
|
|
7
|
-
import { deploy } from 'auth0-deploy-cli';
|
|
8
|
-
|
|
9
|
-
import {
|
|
10
|
-
cloneEnvRepository,
|
|
11
|
-
cloneRepository,
|
|
12
|
-
readDeployConfig,
|
|
13
|
-
pushDeployConfig
|
|
14
|
-
} from '../next/deploy.js';
|
|
15
|
-
|
|
16
|
-
import {
|
|
17
|
-
getVaultSecrets,
|
|
18
|
-
updateVaultSecrets
|
|
19
|
-
} from './vault.js';
|
|
20
|
-
|
|
21
|
-
import {
|
|
22
|
-
getVaultSecretsConfigs,
|
|
23
|
-
environmentConfig
|
|
24
|
-
} from '../next/config.js';
|
|
25
|
-
|
|
26
|
-
async function ensureDirectoryExists(dirPath) {
|
|
27
|
-
try {
|
|
28
|
-
await fs.promises.mkdir(dirPath, { recursive: true });
|
|
29
|
-
console.log(`Directory created or already exists: ${dirPath}`);
|
|
30
|
-
} catch (err) {
|
|
31
|
-
console.error(`Failed to create directory: ${err.message}`);
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
async function addApplicationToApi ({application, auth0Domain, auth0AuthToken, coreApiIdentifier}){
|
|
36
|
-
console.log("Adding application to API authorized applications...");
|
|
37
|
-
|
|
38
|
-
try {
|
|
39
|
-
const auth0Response = await axios.get(`https://${auth0Domain}/api/v2/clients`, {
|
|
40
|
-
headers: {authorization: `Bearer ${auth0AuthToken}`},
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
const appAuth0ClientIdData = auth0Response.data.find(client => client.name === `${application}`);
|
|
44
|
-
const appAuth0ClientId = appAuth0ClientIdData.client_id;
|
|
45
|
-
|
|
46
|
-
await axios.post(
|
|
47
|
-
`https://${auth0Domain}/api/v2/client-grants`,
|
|
48
|
-
{
|
|
49
|
-
client_id: appAuth0ClientId,
|
|
50
|
-
audience: `${coreApiIdentifier}`,
|
|
51
|
-
scope: [],
|
|
52
|
-
},
|
|
53
|
-
{
|
|
54
|
-
headers: {
|
|
55
|
-
Authorization: `Bearer ${auth0AuthToken}`,
|
|
56
|
-
"Content-Type": "application/json",
|
|
57
|
-
},
|
|
58
|
-
}
|
|
59
|
-
);
|
|
60
|
-
console.log(`Application (${appAuth0ClientId}) authorized for API: ${coreApiIdentifier}`);
|
|
61
|
-
} catch (err) {
|
|
62
|
-
console.error(`Failed to add application: ${application}: ${err.message}`);
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
async function initializeAuth0Configuration({
|
|
68
|
-
initConfiguration,
|
|
69
|
-
auth0Domain,
|
|
70
|
-
auth0AuthToken,
|
|
71
|
-
coreApiIdentifier,
|
|
72
|
-
}) {
|
|
73
|
-
if (initConfiguration === "true") {
|
|
74
|
-
try {
|
|
75
|
-
// Create a new resource server in Auth0
|
|
76
|
-
console.log("Creating resource server in Auth0...");
|
|
77
|
-
|
|
78
|
-
const resourceServerResponse = await axios.post(
|
|
79
|
-
`https://${auth0Domain}/api/v2/resource-servers`,
|
|
80
|
-
{
|
|
81
|
-
name: "docupace-core",
|
|
82
|
-
identifier: `${coreApiIdentifier}`,
|
|
83
|
-
token_lifetime: 86400,
|
|
84
|
-
allow_offline_access: false,
|
|
85
|
-
signing_alg: "RS256",
|
|
86
|
-
skip_consent_for_verifiable_first_party_clients: true,
|
|
87
|
-
scopes: [],
|
|
88
|
-
},
|
|
89
|
-
{
|
|
90
|
-
headers: {
|
|
91
|
-
Authorization: `Bearer ${auth0AuthToken}`,
|
|
92
|
-
"Content-Type": "application/json",
|
|
93
|
-
},
|
|
94
|
-
}
|
|
95
|
-
);
|
|
96
|
-
|
|
97
|
-
const apiId = resourceServerResponse.data.id;
|
|
98
|
-
|
|
99
|
-
// Update tenant settings with the default audience
|
|
100
|
-
console.log("Updating tenant settings...");
|
|
101
|
-
await axios.patch(
|
|
102
|
-
`https://${auth0Domain}/api/v2/tenants/settings`,
|
|
103
|
-
{
|
|
104
|
-
default_audience: `${coreApiIdentifier}`,
|
|
105
|
-
},
|
|
106
|
-
{
|
|
107
|
-
headers: {
|
|
108
|
-
Authorization: `Bearer ${auth0AuthToken}`,
|
|
109
|
-
"Content-Type": "application/json",
|
|
110
|
-
},
|
|
111
|
-
}
|
|
112
|
-
);
|
|
113
|
-
console.log("Tenant settings updated successfully.");
|
|
114
|
-
} catch (error) {
|
|
115
|
-
console.error("Error during Auth0 configuration:", error.response?.data || error.message);
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
async function importAuth0Templates(directoryPath, auth0Domain, auth0ClientID, auth0ClientSecret) {
|
|
121
|
-
try {
|
|
122
|
-
const config = {
|
|
123
|
-
input_file: directoryPath,
|
|
124
|
-
config: {
|
|
125
|
-
AUTH0_DOMAIN: auth0Domain,
|
|
126
|
-
AUTH0_CLIENT_ID: auth0ClientID,
|
|
127
|
-
AUTH0_CLIENT_SECRET: auth0ClientSecret,
|
|
128
|
-
},
|
|
129
|
-
debug: true,
|
|
130
|
-
};
|
|
131
|
-
|
|
132
|
-
console.log('Starting Auth0 template import...');
|
|
133
|
-
await deploy(config);
|
|
134
|
-
console.log('Auth0 template import completed successfully!');
|
|
135
|
-
} catch (error) {
|
|
136
|
-
console.error('Error during Auth0 template import:', error.message);
|
|
137
|
-
process.exit(1); // Exit with an error code
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
async function updateJsonFile(filePath, updates) {
|
|
142
|
-
const content = await fs.promises.readFile(filePath, 'utf8');
|
|
143
|
-
const jsonContent = JSON.parse(content);
|
|
144
|
-
const updatedContent = JSON.stringify({...jsonContent, ...updates}, null, 2);
|
|
145
|
-
await fs.promises.writeFile(filePath, updatedContent);
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
async function replaceInFile(filePath, replacements) {
|
|
149
|
-
let content = await fs.promises.readFile(filePath, 'utf8');
|
|
150
|
-
for (const [search, replace] of replacements) {
|
|
151
|
-
content = content.replace(new RegExp(search, 'g'), replace);
|
|
152
|
-
}
|
|
153
|
-
await fs.promises.writeFile(filePath, content);
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
async function templateAuth0(siteUrl, coreApiContext, env, filePaths, deployUI, deployGraphQLServer, commonSecrets) {
|
|
157
|
-
try {
|
|
158
|
-
let uiAllowedCallbacksUrls,
|
|
159
|
-
uiAllowedLogoutUrls;
|
|
160
|
-
let graphqlAllowedCallbacksUrls,
|
|
161
|
-
graphqlAllowedLogoutUrls;
|
|
162
|
-
|
|
163
|
-
// Configure URLs based on environment
|
|
164
|
-
if (env === 'prd') {
|
|
165
|
-
uiAllowedCallbacksUrls = [`https://${siteUrl}/api/auth/callback`];
|
|
166
|
-
uiAllowedLogoutUrls = [`https://${siteUrl}`];
|
|
167
|
-
|
|
168
|
-
graphqlAllowedCallbacksUrls = [`https://${siteUrl}/api/graphql/callback`];
|
|
169
|
-
graphqlAllowedLogoutUrls = [`https://${siteUrl}/api/graphql/`];
|
|
170
|
-
} else {
|
|
171
|
-
uiAllowedCallbacksUrls = [
|
|
172
|
-
`https://${siteUrl}/api/auth/callback`,
|
|
173
|
-
`http://localhost:3000/api/auth/callback`,
|
|
174
|
-
];
|
|
175
|
-
uiAllowedLogoutUrls = [
|
|
176
|
-
`https://${siteUrl}`,
|
|
177
|
-
`http://localhost:3000`,
|
|
178
|
-
];
|
|
179
|
-
|
|
180
|
-
graphqlAllowedCallbacksUrls = [
|
|
181
|
-
`https://${siteUrl}/api/graphql/callback`,
|
|
182
|
-
`http://localhost:4000/api/graphql/callback`,
|
|
183
|
-
];
|
|
184
|
-
graphqlAllowedLogoutUrls = [
|
|
185
|
-
`http://localhost:4000/api/graphql/`,
|
|
186
|
-
`https://${siteUrl}/api/graphql/`,
|
|
187
|
-
];
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
const configureUI = deployUI === 'true';
|
|
191
|
-
if (configureUI) {
|
|
192
|
-
console.log('ui_allowed_callbacks_urls ->', uiAllowedCallbacksUrls);
|
|
193
|
-
console.log('ui_allowed_logout_urls ->', uiAllowedLogoutUrls);
|
|
194
|
-
|
|
195
|
-
await updateJsonFile(filePaths.uiJson, {
|
|
196
|
-
callbacks: uiAllowedCallbacksUrls,
|
|
197
|
-
allowed_logout_urls: uiAllowedLogoutUrls,
|
|
198
|
-
});
|
|
199
|
-
console.log('Updated URLs for main UI...');
|
|
200
|
-
} else {
|
|
201
|
-
await fs.promises.unlink(filePaths.uiJson);
|
|
202
|
-
await updateJsonFile(filePaths.databaseJson, {
|
|
203
|
-
enabled_clients: (content) => content.enabled_clients.filter((client) => client !== 'docupace-ui-main'),
|
|
204
|
-
});
|
|
205
|
-
console.log("Removed 'docupace-ui-main' from enabled_clients in database.json");
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
const configureGraphqlServer = deployGraphQLServer === 'true';
|
|
209
|
-
if (configureGraphqlServer) {
|
|
210
|
-
console.log('graphql_allowed_callbacks_urls ->', graphqlAllowedCallbacksUrls);
|
|
211
|
-
console.log('graphql_allowed_logout_urls ->', graphqlAllowedLogoutUrls);
|
|
212
|
-
|
|
213
|
-
await updateJsonFile(filePaths.graphqlJson, {
|
|
214
|
-
callbacks: graphqlAllowedCallbacksUrls,
|
|
215
|
-
allowed_logout_urls: graphqlAllowedLogoutUrls,
|
|
216
|
-
});
|
|
217
|
-
console.log('Updated URLs for GraphQL server...');
|
|
218
|
-
} else {
|
|
219
|
-
await fs.promises.unlink(filePaths.graphqlJson);
|
|
220
|
-
await updateJsonFile(filePaths.databaseJson, {
|
|
221
|
-
enabled_clients: (content) => content.enabled_clients.filter((client) => client !== 'docupace-graphql'),
|
|
222
|
-
});
|
|
223
|
-
console.log("Removed 'docupace-graphql' from enabled_clients in database.json");
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
// TWILIO configuration
|
|
227
|
-
await replaceInFile(filePaths.twilioJson, [
|
|
228
|
-
['twilioauthtokenplaceholder', commonSecrets.TWILIO_AUTH_TOKEN],
|
|
229
|
-
['twiliosidplaceholder', commonSecrets.TWILIO_SID],
|
|
230
|
-
['twiliofromplaceholder', commonSecrets.TWILIO_FROM_NUMBER],
|
|
231
|
-
]);
|
|
232
|
-
|
|
233
|
-
console.log('TWILIO configuration updated...');
|
|
234
|
-
|
|
235
|
-
// Database configuration
|
|
236
|
-
await replaceInFile(filePaths.databaseLoginJs, [
|
|
237
|
-
['"${docupaceHost}"', `"${siteUrl}"`],
|
|
238
|
-
['"${docupaceContext}"', `"${coreApiContext}"`],
|
|
239
|
-
]);
|
|
240
|
-
|
|
241
|
-
// MFA configuration
|
|
242
|
-
// if (process.env.AUTH0_MFA === 'ENABLE') {
|
|
243
|
-
// console.log('AUTH0 MFA is enabled');
|
|
244
|
-
// await execAsync('rsync -av ./auth0template/templateMFA/ ./auth0template/template/');
|
|
245
|
-
// } else if (process.env.AUTH0_MFA === 'DISABLE') {
|
|
246
|
-
// console.log('AUTH0 MFA is disabled');
|
|
247
|
-
// await execAsync('rsync -av ./auth0template/templateNoMFA/ ./auth0template/template/');
|
|
248
|
-
// }
|
|
249
|
-
|
|
250
|
-
console.log('Template configuration completed.');
|
|
251
|
-
} catch (err) {
|
|
252
|
-
console.error('Error configuring Auth0 templates:', err);
|
|
253
|
-
}
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
async function getAuth0AuthToken(auth0Domain, clientId, clientSecret) {
|
|
257
|
-
try {
|
|
258
|
-
const response = await axios.post(`https://${auth0Domain}/oauth/token`, {
|
|
259
|
-
client_id: clientId,
|
|
260
|
-
client_secret: clientSecret,
|
|
261
|
-
audience: `https://${auth0Domain}/api/v2/`,
|
|
262
|
-
grant_type: 'client_credentials',
|
|
263
|
-
}, {
|
|
264
|
-
headers: {
|
|
265
|
-
'Content-Type': 'application/json',
|
|
266
|
-
},
|
|
267
|
-
});
|
|
268
|
-
|
|
269
|
-
const authToken = response.data.access_token;
|
|
270
|
-
// console.log("Auth0 Auth Token:", authToken);
|
|
271
|
-
return authToken;
|
|
272
|
-
} catch (error) {
|
|
273
|
-
console.error("Error fetching Auth0 token:", error.response ? error.response.data : error.message);
|
|
274
|
-
}
|
|
275
|
-
}
|
|
276
|
-
|
|
277
|
-
async function configureUI(siteHost, coreURL, docupaceHost, site, env, useNewDomain, auth0Domain, auth0ClientId, auth0ClientSecret, auth0Token, vaultSiteSecretsPath, imageTag, repoPath) {
|
|
278
|
-
console.log(`Configuring UI for site: ${site} Host: ${siteHost} in env: ${env}`);
|
|
279
|
-
|
|
280
|
-
try {
|
|
281
|
-
const auth0Response = await axios.get(`https://${auth0Domain}/api/v2/clients`, {
|
|
282
|
-
headers: {authorization: `Bearer ${auth0Token}`},
|
|
283
|
-
});
|
|
284
|
-
|
|
285
|
-
const uiClient = auth0Response.data.find(client => client.name === "docupace-ui-main");
|
|
286
|
-
const uiAuth0ClientId = uiClient.client_id;
|
|
287
|
-
const uiAuth0ClientSecret = uiClient.client_secret;
|
|
288
|
-
|
|
289
|
-
// Generate Auth0 Secret
|
|
290
|
-
const uiAuth0Secret = crypto.randomBytes(48).toString('base64').replace(/[^a-zA-Z0-9]/g, '');
|
|
291
|
-
|
|
292
|
-
// Prepare data payload
|
|
293
|
-
console.log("Preparing Vault UI data payload...");
|
|
294
|
-
const uiSecretData = JSON.stringify({
|
|
295
|
-
data: {
|
|
296
|
-
AUTH0_CLIENT_ID: uiAuth0ClientId,
|
|
297
|
-
AUTH0_CLIENT_SECRET: uiAuth0ClientSecret,
|
|
298
|
-
AUTH0_SECRET: uiAuth0Secret,
|
|
299
|
-
},
|
|
300
|
-
});
|
|
301
|
-
|
|
302
|
-
await updateVaultSecrets(vaultSiteSecretsPath, uiSecretData);
|
|
303
|
-
|
|
304
|
-
// Prepare ui.app.yaml
|
|
305
|
-
const uiAppYaml = `
|
|
306
|
-
repo: docupace-ui-main
|
|
307
|
-
revision: master
|
|
308
|
-
`.trim();
|
|
309
|
-
|
|
310
|
-
// Prepare ui.values.yaml
|
|
311
|
-
const uiValuesYaml = `
|
|
312
|
-
uiMain:
|
|
313
|
-
auth0BaseUrl: https://${siteHost}
|
|
314
|
-
auth0IssuerBaseUrl: https://${auth0Domain}
|
|
315
|
-
auth0ClientId: vault:secret/data/${site}/ui/config#AUTH0_CLIENT_ID
|
|
316
|
-
graphqlClientUrl: https://${siteHost}/api/graphql
|
|
317
|
-
graphqlServerUrl: https://${siteHost}/api/graphql
|
|
318
|
-
connectUrl: https://${siteHost}
|
|
319
|
-
coreUrl: https://${coreURL}
|
|
320
|
-
env:
|
|
321
|
-
AUTH0_CLIENT_SECRET: vault:secret/data/${site}/ui/config#AUTH0_CLIENT_SECRET
|
|
322
|
-
AUTH0_SECRET: vault:secret/data/${site}/ui/config#AUTH0_SECRET
|
|
323
|
-
image:
|
|
324
|
-
repository: registry.paperout.com/docupace-ui-main-dev-docker-local/docupace-ui-main
|
|
325
|
-
tag: ${imageTag}
|
|
326
|
-
imagePullSecrets:
|
|
327
|
-
- name: jf-artifactory
|
|
328
|
-
ingress:
|
|
329
|
-
enabled: true
|
|
330
|
-
className: nginx
|
|
331
|
-
annotations:
|
|
332
|
-
external-dns.alpha.kubernetes.io/hostname: ${siteHost}
|
|
333
|
-
external-dns.alpha.kubernetes.io/zone: public
|
|
334
|
-
cert-manager.io/cluster-issuer: letsencrypt
|
|
335
|
-
nginx.ingress.kubernetes.io/proxy-buffer-size: 128k
|
|
336
|
-
hosts:
|
|
337
|
-
- host: ${siteHost}
|
|
338
|
-
paths:
|
|
339
|
-
- path: /
|
|
340
|
-
pathType: Prefix
|
|
341
|
-
tls:
|
|
342
|
-
- hosts:
|
|
343
|
-
- ${siteHost}
|
|
344
|
-
secretName: dp-next-ui-cert
|
|
345
|
-
externalConnectIngress:
|
|
346
|
-
enabled: ${useNewDomain}
|
|
347
|
-
className: nginx
|
|
348
|
-
annotations:
|
|
349
|
-
cert-manager.io/cluster-issuer: letsencrypt
|
|
350
|
-
external-dns.alpha.kubernetes.io/hostname: ${siteHost}
|
|
351
|
-
external-dns.alpha.kubernetes.io/zone: public
|
|
352
|
-
nginx.ingress.kubernetes.io/backend-protocol: HTTPS
|
|
353
|
-
nginx.ingress.kubernetes.io/configuration-snippet: |
|
|
354
|
-
proxy_set_header Host ${siteHost};
|
|
355
|
-
nginx.ingress.kubernetes.io/proxy-buffer-size: 8k
|
|
356
|
-
hosts:
|
|
357
|
-
- host: ${siteHost}
|
|
358
|
-
paths:
|
|
359
|
-
- path: /core
|
|
360
|
-
- path: /core_b2b
|
|
361
|
-
- path: /core_reports
|
|
362
|
-
- path: /corerealm
|
|
363
|
-
- path: /connect
|
|
364
|
-
- path: /webstart
|
|
365
|
-
- path: /core_ws
|
|
366
|
-
- path: /core_docupload
|
|
367
|
-
- path: /core_ariws
|
|
368
|
-
- path: /core_restws
|
|
369
|
-
- path: /core_webdav
|
|
370
|
-
tls:
|
|
371
|
-
- hosts:
|
|
372
|
-
- ${siteHost}
|
|
373
|
-
secretName: dp-next-ui-cert
|
|
374
|
-
externalConnectService:
|
|
375
|
-
enabled: ${useNewDomain}
|
|
376
|
-
name: external-connect
|
|
377
|
-
domain: ${docupaceHost}
|
|
378
|
-
`.trim();
|
|
379
|
-
|
|
380
|
-
// Write configuration files
|
|
381
|
-
console.log("Writing configuration files...");
|
|
382
|
-
await ensureDirectoryExists(path.resolve(`${repoPath}/dp/${site}`));
|
|
383
|
-
|
|
384
|
-
await fs.writeFile(`${repoPath}/dp/${site}/ui.app.yaml`, uiAppYaml, (err) => {
|
|
385
|
-
if (err) {
|
|
386
|
-
console.error("Failed to write the file:", err);
|
|
387
|
-
} else {
|
|
388
|
-
console.log("File written successfully.");
|
|
389
|
-
}
|
|
390
|
-
});
|
|
391
|
-
|
|
392
|
-
await fs.writeFile(`${repoPath}/dp/${site}/ui.values.yaml`, uiValuesYaml, (err) => {
|
|
393
|
-
if (err) {
|
|
394
|
-
console.error("Failed to write the file:", err);
|
|
395
|
-
} else {
|
|
396
|
-
console.log("File written successfully.");
|
|
397
|
-
}
|
|
398
|
-
});
|
|
399
|
-
console.log("Done!");
|
|
400
|
-
} catch (error) {
|
|
401
|
-
console.error("Error configuring UI:", error);
|
|
402
|
-
}
|
|
403
|
-
}
|
|
404
|
-
|
|
405
|
-
async function configureGraphQLServer(siteHost, coreURL, docupaceHost, site, env, auth0Domain, auth0ClientId, auth0ClientSecret, auth0Token, vaultSiteSecretsPath, imageTag, standardConfigRemoteBranch, repoPath, commonSecrets) {
|
|
406
|
-
console.log(`Configuring GraphQL Server for site: ${site} Host: ${siteHost} in env: ${env}`);
|
|
407
|
-
|
|
408
|
-
try {
|
|
409
|
-
const auth0Response = await axios.get(`https://${auth0Domain}/api/v2/clients`, {
|
|
410
|
-
headers: {authorization: `Bearer ${auth0Token}`},
|
|
411
|
-
});
|
|
412
|
-
|
|
413
|
-
const graphQLServerClient = auth0Response.data.find(client => client.name === "docupace-graphql");
|
|
414
|
-
const graphQLServerClientCredentials = auth0Response.data.find(client => client.name === "docupace-graphql-client-credentials");
|
|
415
|
-
|
|
416
|
-
const graphQLServerAuth0ClientId = graphQLServerClient.client_id;
|
|
417
|
-
const graphQLServerAuth0ClientSecret = graphQLServerClient.client_secret;
|
|
418
|
-
|
|
419
|
-
const graphQLServerCCAuth0ClientId = graphQLServerClientCredentials.client_id;
|
|
420
|
-
const graphQLServerCCAuth0ClientSecret = graphQLServerClientCredentials.client_secret;
|
|
421
|
-
|
|
422
|
-
// Prepare data payload
|
|
423
|
-
console.log("Preparing Vault GraphQL Server data payload...");
|
|
424
|
-
const graphQLServerSecretData = JSON.stringify({
|
|
425
|
-
data: {
|
|
426
|
-
AUTH0_CLIENT_ID: graphQLServerAuth0ClientId,
|
|
427
|
-
AUTH0_CLIENT_SECRET: graphQLServerAuth0ClientSecret,
|
|
428
|
-
AUTH0_CC_CLIENT_ID: graphQLServerCCAuth0ClientId,
|
|
429
|
-
AUTH0_CC_CLIENT_SECRET: graphQLServerCCAuth0ClientSecret,
|
|
430
|
-
CORE_PASSWORD: commonSecrets.CORE_PASSWORD,
|
|
431
|
-
REMOTE_CONFIG_PATH: commonSecrets.REMOTE_CONFIG_PATH,
|
|
432
|
-
STANDARD_CONFIG_REMOTE_PATH: commonSecrets.STANDARD_CONFIG_REMOTE_PATH,
|
|
433
|
-
},
|
|
434
|
-
});
|
|
435
|
-
|
|
436
|
-
await updateVaultSecrets(vaultSiteSecretsPath, graphQLServerSecretData);
|
|
437
|
-
|
|
438
|
-
// Prepare ui.app.yaml
|
|
439
|
-
const graphQLServerAppYaml = `
|
|
440
|
-
repo: docupace-graphql-server
|
|
441
|
-
revision: ${standardConfigRemoteBranch}
|
|
442
|
-
`.trim();
|
|
443
|
-
|
|
444
|
-
// Prepare ui.values.yaml
|
|
445
|
-
const graphQLServerValuesYaml = `
|
|
446
|
-
graphqlServer:
|
|
447
|
-
auth0Domain: https://${auth0Domain}
|
|
448
|
-
auth0ClientId: vault:secret/data/${site}/graphql-server/config#AUTH0_CLIENT_ID
|
|
449
|
-
auth0Audience: ${commonSecrets.CORE_API_IDENTIFIER}
|
|
450
|
-
baseUrl: https://${siteHost}/api/graphql
|
|
451
|
-
coreUrl: https://${coreURL}
|
|
452
|
-
integrationHubUrl: "https://${commonSecrets.INTEGRATION_HUB_URL}"
|
|
453
|
-
standardConfigRemoteBranch: ${standardConfigRemoteBranch}
|
|
454
|
-
apiLevel: "2"
|
|
455
|
-
env:
|
|
456
|
-
AUTH0_CLIENT_SECRET: vault:secret/data/${site}/graphql-server/config#AUTH0_CLIENT_SECRET
|
|
457
|
-
STANDARD_CONFIG_REMOTE_PATH: vault:secret/data/common/config#STANDARD_CONFIG_REMOTE_PATH
|
|
458
|
-
AUTH0_CC_CLIENT_ID: vault:secret/data/${site}/graphql-server/config#AUTH0_CC_CLIENT_ID
|
|
459
|
-
AUTH0_CC_CLIENT_SECRET: vault:secret/data/${site}/graphql-server/config#AUTH0_CC_CLIENT_SECRET
|
|
460
|
-
image:
|
|
461
|
-
repository: registry.paperout.com/docupace-graphql-server-dev-docker-local/docupace-graphql-server
|
|
462
|
-
tag: ${imageTag}
|
|
463
|
-
imagePullSecrets:
|
|
464
|
-
- name: jf-artifactory
|
|
465
|
-
ingress:
|
|
466
|
-
annotations:
|
|
467
|
-
external-dns.alpha.kubernetes.io/hostname: ${siteHost}
|
|
468
|
-
external-dns.alpha.kubernetes.io/zone: public
|
|
469
|
-
cert-manager.io/cluster-issuer: letsencrypt
|
|
470
|
-
nginx.ingress.kubernetes.io/proxy-buffer-size: 128k
|
|
471
|
-
enabled: true
|
|
472
|
-
className: nginx
|
|
473
|
-
hosts:
|
|
474
|
-
- host: ${siteHost}
|
|
475
|
-
paths:
|
|
476
|
-
- path: /api/graphql
|
|
477
|
-
pathType: Prefix
|
|
478
|
-
tls:
|
|
479
|
-
- hosts:
|
|
480
|
-
- ${siteHost}
|
|
481
|
-
secretName: dp-next-ui-cert
|
|
482
|
-
`.trim();
|
|
483
|
-
|
|
484
|
-
// Write configuration files
|
|
485
|
-
console.log("Writing ArgoCD GraphQL Server configuration files...");
|
|
486
|
-
await ensureDirectoryExists(path.resolve(`${repoPath}/dp/${site}`));
|
|
487
|
-
|
|
488
|
-
await fs.writeFile(`${repoPath}/dp/${site}/graphql-server.app.yaml`, graphQLServerAppYaml, (err) => {
|
|
489
|
-
if (err) {
|
|
490
|
-
console.error("Failed to write the file:", err);
|
|
491
|
-
} else {
|
|
492
|
-
console.log("File written successfully.");
|
|
493
|
-
}
|
|
494
|
-
});
|
|
495
|
-
|
|
496
|
-
await fs.writeFile(`${repoPath}/dp/${site}/graphql-server.values.yaml`, graphQLServerValuesYaml, (err) => {
|
|
497
|
-
if (err) {
|
|
498
|
-
console.error("Failed to write the file:", err);
|
|
499
|
-
} else {
|
|
500
|
-
console.log("File written successfully.");
|
|
501
|
-
}
|
|
502
|
-
});
|
|
503
|
-
console.log("Done!");
|
|
504
|
-
} catch (error) {
|
|
505
|
-
console.error("Error configuring GraphQL Server:", error);
|
|
506
|
-
}
|
|
507
|
-
}
|
|
508
|
-
|
|
509
|
-
export async function configureFromSite(fromSite, toSite, env, deployUI, deployGraphQLServer, useNewDomain) {
|
|
510
|
-
console.log(`Configuring Auth0 tenants and ArgoCD apps for site: ${toSite} in env: ${env} from site: ${fromSite}`);
|
|
511
|
-
// Common Secrets
|
|
512
|
-
const commonSecretsPath = getVaultSecretsConfigs(toSite).commonSecretsPath;
|
|
513
|
-
console.log(`commonSecretsPath => ${commonSecretsPath}`)
|
|
514
|
-
const commonSecrets = await getVaultSecrets(commonSecretsPath);
|
|
515
|
-
|
|
516
|
-
// Site Common Secrets
|
|
517
|
-
const siteCommonSecretsPath = getVaultSecretsConfigs(toSite).siteCommonSecretsPath;
|
|
518
|
-
console.log(`siteCommonSecretsPath => ${siteCommonSecretsPath}`)
|
|
519
|
-
const siteCommonSecrets = await getVaultSecrets(siteCommonSecretsPath);
|
|
520
|
-
|
|
521
|
-
const auth0Domain = `docupace-${env}-${toSite}.us.auth0.com`
|
|
522
|
-
const auth0ClientId = siteCommonSecrets.AUTH0_CLIENT_ID;
|
|
523
|
-
const auth0ClientSecret = siteCommonSecrets.AUTH0_CLIENT_SECRET;
|
|
524
|
-
const auth0Token = await getAuth0AuthToken(auth0Domain, auth0ClientId, auth0ClientSecret);
|
|
525
|
-
|
|
526
|
-
// UI app
|
|
527
|
-
const uiSecretsPath = getVaultSecretsConfigs(toSite).uiSecretsPath;
|
|
528
|
-
console.log(`uiSecretsPath => ${uiSecretsPath}`)
|
|
529
|
-
|
|
530
|
-
// GraphQL-Server app
|
|
531
|
-
const graphqlSecretsPath = getVaultSecretsConfigs(toSite).graphqlServerSecretsPath;
|
|
532
|
-
console.log(`graphqlSecretsPath => ${graphqlSecretsPath}`)
|
|
533
|
-
|
|
534
|
-
// Clone repositories
|
|
535
|
-
const repoPath = await cloneEnvRepository(env);
|
|
536
|
-
const templateRepoPath = await cloneRepository('template');
|
|
537
|
-
const auth0RepoPath = await cloneRepository('auth0-site-setup');
|
|
538
|
-
|
|
539
|
-
// Read deploy configs
|
|
540
|
-
const { deployConfig: deployUIConfig } = await readDeployConfig('ui', env, fromSite);
|
|
541
|
-
const uiImageTag = deployUIConfig.image.tag;
|
|
542
|
-
|
|
543
|
-
const { deployConfig: deployGraphQLServerConfig} = await readDeployConfig('graphql-server', env, fromSite);
|
|
544
|
-
const graphqlImageTag = deployGraphQLServerConfig.image.tag;
|
|
545
|
-
const graphqlStandardConfigRemoteBranch = deployGraphQLServerConfig.graphqlServer.standardConfigRemoteBranch;
|
|
546
|
-
|
|
547
|
-
// File paths
|
|
548
|
-
const filePaths = {
|
|
549
|
-
clientJson: './auth0-site-setup/template/clients/docupace-connect.json',
|
|
550
|
-
databaseLoginJs: './auth0-site-setup/template/database-connections/docupace/login.js',
|
|
551
|
-
loginHtml: './auth0-site-setup/template/pages/login.html',
|
|
552
|
-
graphqlJson: './auth0-site-setup/template/clients/docupace-graphql.json',
|
|
553
|
-
uiJson: './auth0-site-setup/template/clients/docupace-ui-main.json',
|
|
554
|
-
databaseJson: './auth0-site-setup/template/database-connections/docupace/database.json',
|
|
555
|
-
twilioJson: './auth0-site-setup/template/guardian/providers/sms-twilio.json',
|
|
556
|
-
};
|
|
557
|
-
|
|
558
|
-
console.log(`Copying Latest UI Image Tag: ${deployUIConfig.image.tag} from site: ${fromSite} to site: ${toSite}`);
|
|
559
|
-
console.log(`Copying Latest GraphQL Server Image Tag: ${deployGraphQLServerConfig.image.tag} from site: ${fromSite} to site: ${toSite}`);
|
|
560
|
-
|
|
561
|
-
// Get latest commit ID from TEMPLATE_DIR
|
|
562
|
-
let shortCommitId;
|
|
563
|
-
try {
|
|
564
|
-
process.chdir(templateRepoPath);
|
|
565
|
-
shortCommitId = (await $`git log --pretty=format:'%h' -n 1`).stdout.trim();
|
|
566
|
-
|
|
567
|
-
if (!shortCommitId) {
|
|
568
|
-
console.error("Error: Latest Template commit ID is empty or not set");
|
|
569
|
-
}
|
|
570
|
-
|
|
571
|
-
console.log(`Latest Template commit ID: ${shortCommitId}`);
|
|
572
|
-
process.chdir('..'); // Return to the parent directory
|
|
573
|
-
} catch (error) {
|
|
574
|
-
console.error("Error retrieving the latest template commit ID:", error.message);
|
|
575
|
-
}
|
|
576
|
-
|
|
577
|
-
const envConfig = environmentConfig[env];
|
|
578
|
-
|
|
579
|
-
let CORE_URL,
|
|
580
|
-
SITE_HOST,
|
|
581
|
-
CORE_API_CONTEXT,
|
|
582
|
-
CONNECT_URL,
|
|
583
|
-
DOCUPACE_HOST;
|
|
584
|
-
if (useNewDomain) {
|
|
585
|
-
const newUrl = envConfig.newUrl(toSite);
|
|
586
|
-
CORE_URL = `${newUrl}/core`;
|
|
587
|
-
SITE_HOST = newUrl;
|
|
588
|
-
CORE_API_CONTEXT = "core";
|
|
589
|
-
CONNECT_URL = `${newUrl}/connect`;
|
|
590
|
-
DOCUPACE_HOST = envConfig.docupaceHost();
|
|
591
|
-
} else {
|
|
592
|
-
const oldUrl = envConfig.oldUrl(toSite);
|
|
593
|
-
CORE_URL = oldUrl;
|
|
594
|
-
SITE_HOST = oldUrl;
|
|
595
|
-
CORE_API_CONTEXT = toSite;
|
|
596
|
-
CONNECT_URL = `${oldUrl}_ui`;
|
|
597
|
-
}
|
|
598
|
-
|
|
599
|
-
await templateAuth0(SITE_HOST, CORE_API_CONTEXT, env, filePaths, deployUI, deployGraphQLServer, commonSecrets);
|
|
600
|
-
await importAuth0Templates('./auth0-site-setup/template', auth0Domain, auth0ClientId, auth0ClientSecret);
|
|
601
|
-
|
|
602
|
-
if (deployUI === 'true') {
|
|
603
|
-
await configureUI(SITE_HOST, CORE_URL, DOCUPACE_HOST, toSite, env, useNewDomain, auth0Domain, auth0ClientId, auth0ClientSecret, auth0Token, uiSecretsPath, uiImageTag, repoPath);
|
|
604
|
-
}
|
|
605
|
-
|
|
606
|
-
await configureGraphQLServer(SITE_HOST, CORE_URL, DOCUPACE_HOST, toSite, env, auth0Domain, auth0ClientId, auth0ClientSecret, auth0Token, graphqlSecretsPath, graphqlImageTag, graphqlStandardConfigRemoteBranch, repoPath, commonSecrets);
|
|
607
|
-
await pushDeployConfig(repoPath, `Config update for ${toSite} from ${fromSite} with UI: ${uiImageTag} and GraphQL: ${graphqlImageTag}`);
|
|
608
|
-
|
|
609
|
-
await initializeAuth0Configuration({
|
|
610
|
-
initConfiguration: "true",
|
|
611
|
-
auth0Domain: auth0Domain,
|
|
612
|
-
auth0AuthToken: auth0Token,
|
|
613
|
-
coreApiIdentifier: commonSecrets.CORE_API_IDENTIFIER,
|
|
614
|
-
});
|
|
615
|
-
|
|
616
|
-
await addApplicationToApi({
|
|
617
|
-
application: 'docupace-graphql-client-credentials',
|
|
618
|
-
auth0Domain: auth0Domain,
|
|
619
|
-
auth0AuthToken: auth0Token,
|
|
620
|
-
coreApiIdentifier: commonSecrets.CORE_API_IDENTIFIER
|
|
621
|
-
})
|
|
622
|
-
}
|
package/src/auth0/vault.js
DELETED
|
@@ -1,107 +0,0 @@
|
|
|
1
|
-
import axios from 'axios';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Fetch secrets from Vault.
|
|
5
|
-
* @param {string} vaultPath - The path in Vault to fetch secrets from.
|
|
6
|
-
* @returns {Promise<Object>} - The secret data as a JSON object.
|
|
7
|
-
*/
|
|
8
|
-
export async function getVaultSecrets(vaultPath) {
|
|
9
|
-
if (!vaultPath) {
|
|
10
|
-
console.error("Error: VAULT_PATH is required.");
|
|
11
|
-
throw new Error("VAULT_PATH is required.");
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
const vaultToken = process.env.VAULT_TOKEN;
|
|
15
|
-
const vaultAddr = process.env.VAULT_ADDR;
|
|
16
|
-
|
|
17
|
-
if (!vaultToken || !vaultAddr) {
|
|
18
|
-
console.error("Error: VAULT_TOKEN and VAULT_ADDR must be set.");
|
|
19
|
-
throw new Error("VAULT_TOKEN and VAULT_ADDR must be set.");
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
try {
|
|
23
|
-
// Disable SSL verification globally by setting environment variable
|
|
24
|
-
if (process.env.VAULT_SKIP_VERIFY === 'true') {
|
|
25
|
-
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
// Fetch the secret from Vault
|
|
29
|
-
const response = await axios.get(`${vaultAddr}/v1/${vaultPath}`, {
|
|
30
|
-
headers: {
|
|
31
|
-
'X-Vault-Token': vaultToken,
|
|
32
|
-
},
|
|
33
|
-
});
|
|
34
|
-
|
|
35
|
-
// Validate the response contains JSON data
|
|
36
|
-
const data = response.data;
|
|
37
|
-
if (data && typeof data === 'object') {
|
|
38
|
-
// console.log(`Secrets fetched successfully from Vault at ${JSON.stringify(data.data.data)})`);
|
|
39
|
-
return data.data.data;
|
|
40
|
-
} else {
|
|
41
|
-
console.error("Error: Invalid JSON received from Vault.");
|
|
42
|
-
throw new Error("Invalid JSON received from Vault.");
|
|
43
|
-
}
|
|
44
|
-
} catch (error) {
|
|
45
|
-
if (error.response) {
|
|
46
|
-
console.error(
|
|
47
|
-
`Error: Failed to connect to Vault server at ${vaultAddr}. Response: ${error.response.status} ${error.response.statusText}`
|
|
48
|
-
);
|
|
49
|
-
} else {
|
|
50
|
-
console.error(`Error: ${error.message}`);
|
|
51
|
-
}
|
|
52
|
-
// throw error;
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
/**
|
|
57
|
-
* Update a secret in Vault.
|
|
58
|
-
* @param {string} vaultPath - The path in Vault where the secret should be updated.
|
|
59
|
-
* @param {Object} secretData - The secret data to be stored (as a JSON object).
|
|
60
|
-
* @returns {Promise<Object>} - The response from Vault as a JSON object.
|
|
61
|
-
*/
|
|
62
|
-
export async function updateVaultSecrets(vaultPath, secretData) {
|
|
63
|
-
if (!vaultPath || !secretData) {
|
|
64
|
-
console.error("Usage: updateVaultSecret(vaultPath, secretData)");
|
|
65
|
-
throw new Error("Both vaultPath and secretData are required.");
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
const vaultToken = process.env.VAULT_TOKEN;
|
|
69
|
-
const vaultAddr = process.env.VAULT_ADDR;
|
|
70
|
-
|
|
71
|
-
if (!vaultToken || !vaultAddr) {
|
|
72
|
-
console.error("Error: VAULT_TOKEN and VAULT_ADDR must be set.");
|
|
73
|
-
throw new Error("VAULT_TOKEN and VAULT_ADDR must be set.");
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
try {
|
|
77
|
-
// Disable SSL verification globally if VAULT_SKIP_VERIFY is set
|
|
78
|
-
if (process.env.VAULT_SKIP_VERIFY === 'true') {
|
|
79
|
-
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
// Make the POST request to update the Vault secret
|
|
83
|
-
const response = await axios.post(
|
|
84
|
-
`${vaultAddr}/v1/${vaultPath}`,
|
|
85
|
-
secretData,
|
|
86
|
-
{
|
|
87
|
-
headers: {
|
|
88
|
-
'X-Vault-Token': vaultToken,
|
|
89
|
-
'Content-Type': 'application/json',
|
|
90
|
-
},
|
|
91
|
-
}
|
|
92
|
-
);
|
|
93
|
-
|
|
94
|
-
// Return the response from Vault
|
|
95
|
-
console.log(response.data);
|
|
96
|
-
return response.data;
|
|
97
|
-
} catch (error) {
|
|
98
|
-
if (error.response) {
|
|
99
|
-
console.error(
|
|
100
|
-
`Error: Failed to update secret at ${vaultPath}. Response: ${error.response.status} ${error.response.statusText}`
|
|
101
|
-
);
|
|
102
|
-
} else {
|
|
103
|
-
console.error(`Error: ${error.message}`);
|
|
104
|
-
}
|
|
105
|
-
// throw error;
|
|
106
|
-
}
|
|
107
|
-
}
|
package/src/next/apache.js
DELETED
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
import { $ } from 'zx';
|
|
2
|
-
|
|
3
|
-
export async function addApacheSite() {
|
|
4
|
-
if (
|
|
5
|
-
!process.env.ENVIRONMENT ||
|
|
6
|
-
(process.env.ENVIRONMENT !== 'dev' && process.env.ENVIRONMENT !== 'qa')
|
|
7
|
-
) {
|
|
8
|
-
log("Error: ENVIRONMENT must be either 'dev' or 'qa'.");
|
|
9
|
-
process.exit(1);
|
|
10
|
-
}
|
|
11
|
-
if (!process.env.SITE) {
|
|
12
|
-
log('Error: SITE cannot be empty.');
|
|
13
|
-
process.exit(1);
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
// Save private key from base64
|
|
17
|
-
const haproxyPrivateKey = process.env.HAPROXY_PRIVATE_KEY;
|
|
18
|
-
if (!haproxyPrivateKey) {
|
|
19
|
-
log('Error: HAPROXY_PRIVATE_KEY not set.');
|
|
20
|
-
process.exit(1);
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
await fs.writeFile('private.key', Buffer.from(haproxyPrivateKey, 'base64'));
|
|
24
|
-
await fs.chmod('private.key', 0o600);
|
|
25
|
-
|
|
26
|
-
const server = `${process.env.ENVIRONMENT}-apalb01a.corp.docupace.com`;
|
|
27
|
-
console.log("Running command");
|
|
28
|
-
const sshCmd = (script) =>
|
|
29
|
-
$`ssh -i private.key -o StrictHostKeyChecking=no root@${server} ${script}`;
|
|
30
|
-
|
|
31
|
-
// The script is run twice in the Bash version
|
|
32
|
-
await sshCmd(`/root/repo/iis-preprod/scripts/addsite/add_core_site.sh ${process.env.ENVIRONMENT} ${process.env.SITE}`);
|
|
33
|
-
//await sshCmd(`/root/repo/iis-preprod/scripts/addsite/add_core_site.sh ${process.env.ENVIRONMENT} ${process.env.SITE}`);
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
|
package/src/next/connect.js
DELETED
|
@@ -1,158 +0,0 @@
|
|
|
1
|
-
import 'zx/globals'; // npm i zx
|
|
2
|
-
import fs from 'fs-extra';
|
|
3
|
-
import path from 'path';
|
|
4
|
-
import axios from 'axios';
|
|
5
|
-
import { $ } from 'zx';
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
import {
|
|
10
|
-
cloneEnvRepository,
|
|
11
|
-
cloneRepository
|
|
12
|
-
} from './deploy.js';
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
import { getVaultSecrets } from '../auth0/vault.js';
|
|
16
|
-
|
|
17
|
-
import {
|
|
18
|
-
getVaultSecretsConfigs,
|
|
19
|
-
environmentConfig
|
|
20
|
-
} from './config.js';
|
|
21
|
-
|
|
22
|
-
process.env.COMMON_VAULT_PATH = process.env.COMMON_VAULT_PATH || 'secret/data/common/config';
|
|
23
|
-
process.env.VAULT_SKIP_VERIFY = process.env.VAULT_SKIP_VERIFY || 'true';
|
|
24
|
-
process.env.CONNECT_DIR = process.env.CONNECT_DIR || 'connect';
|
|
25
|
-
const vaultToken = process.env.VAULT_TOKEN;
|
|
26
|
-
const vaultAddr = process.env.VAULT_ADDR;
|
|
27
|
-
|
|
28
|
-
function log(msg) {
|
|
29
|
-
console.log(`[*] ${msg}`);
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
/* --------------------------------
|
|
33
|
-
* 1. GIT CHECKOUT
|
|
34
|
-
* -------------------------------- */
|
|
35
|
-
async function gitCheckout(repository, destDir, branch = 'master') {
|
|
36
|
-
if (!(await fs.pathExists(destDir))) {
|
|
37
|
-
log(`Directory ${destDir} does not exist. Cloning repository...`);
|
|
38
|
-
} else {
|
|
39
|
-
log(`Directory ${destDir} exists. Removing it...`);
|
|
40
|
-
await fs.remove(destDir);
|
|
41
|
-
log(`Cloning ${destDir} repository...`);
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
const username = process.env.BITBUCKET_USERNAME;
|
|
45
|
-
const password = process.env.BITBUCKET_APP_PASSWORD;
|
|
46
|
-
|
|
47
|
-
// Construct clone command
|
|
48
|
-
const cloneUrl = `https://${username}:${password}@bitbucket.org/dp-cloud/${repository}.git`;
|
|
49
|
-
|
|
50
|
-
log(`Perform cloning`);
|
|
51
|
-
await $`git clone --branch=${branch} --depth 1 ${cloneUrl} ${destDir}`;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
export async function connectClone() {
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
if (!vaultToken || !vaultAddr) {
|
|
63
|
-
console.error("Error: VAULT_TOKEN and VAULT_ADDR must be set.");
|
|
64
|
-
throw new Error("VAULT_TOKEN and VAULT_ADDR must be set.");
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
const site = process.env.BUILD_SITE;
|
|
68
|
-
if (!site) {
|
|
69
|
-
log('Error: BUILD_SITE is not set');
|
|
70
|
-
process.exit(1);
|
|
71
|
-
}
|
|
72
|
-
const siteCommonVaultPath = `secret/data/${site}/common/config`;
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
// 2) getVaultSecrets
|
|
76
|
-
const secretsJson = await getVaultSecrets(siteCommonVaultPath);
|
|
77
|
-
if (!secretsJson.AUTH0_CLIENT_ID) {
|
|
78
|
-
log('Failed to retrieve secret data.');
|
|
79
|
-
process.exit(1);
|
|
80
|
-
}
|
|
81
|
-
const siteCommonSecrets = secretsJson;
|
|
82
|
-
|
|
83
|
-
// 3) Export secrets as environment variables
|
|
84
|
-
process.env.AUTH0_CLIENT_ID = siteCommonSecrets.AUTH0_CLIENT_ID;
|
|
85
|
-
process.env.AUTH0_CLIENT_SECRET = siteCommonSecrets.AUTH0_CLIENT_SECRET;
|
|
86
|
-
|
|
87
|
-
process.env.AUTH0_SUBDOMAIN="docupace-${BUILD_ENVIRONMENT}-${BUILD_SITE}"
|
|
88
|
-
process.env.AUTH0_REGION_DOMAIN="us.auth0.com"
|
|
89
|
-
|
|
90
|
-
log(`BUILD_ENVIRONMENT: ${process.env.BUILD_ENVIRONMENT}`);
|
|
91
|
-
log(`BUILD_SITE: ${process.env.BUILD_SITE}`);
|
|
92
|
-
log(`AUTH0_SUBDOMAIN: ${process.env.AUTH0_SUBDOMAIN}`);
|
|
93
|
-
log(`AUTH0_REGION_DOMAIN: ${process.env.AUTH0_REGION_DOMAIN}`);
|
|
94
|
-
log(`AUTH0_CLIENT_ID: ${process.env.AUTH0_CLIENT_ID}`);
|
|
95
|
-
|
|
96
|
-
process.env.AUTH0_DOMAIN = `${process.env.AUTH0_SUBDOMAIN}.${process.env.AUTH0_REGION_DOMAIN}`;
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
const projectRoot = process.cwd();
|
|
100
|
-
// 4) Clone 'connect-deploy' into CONNECT_DIR
|
|
101
|
-
const test1 = $`pwd ; echo "test"; find ..`;
|
|
102
|
-
log(test1);
|
|
103
|
-
|
|
104
|
-
await gitCheckout('connect-deploy', process.env.CONNECT_DIR);
|
|
105
|
-
|
|
106
|
-
// 5) Create site clone (emulating the dock.sh call)
|
|
107
|
-
const cloneFrom = path.join(projectRoot,process.env.CONNECT_DIR,`${process.env.FROM_BUILD_ENVIRONMENT}/${process.env.FROM_BUILD_SITE}`);
|
|
108
|
-
const cloneTo = path.join(projectRoot,process.env.CONNECT_DIR,`${process.env.BUILD_ENVIRONMENT}/${process.env.BUILD_SITE}`);
|
|
109
|
-
log(`projectRoot: ${projectRoot}`);
|
|
110
|
-
const connectHome = path.join(projectRoot,process.env.CONNECT_DIR);
|
|
111
|
-
$`find .`;
|
|
112
|
-
if (!(await fs.pathExists(cloneFrom))) {
|
|
113
|
-
log('Clone template directory not found:');
|
|
114
|
-
process.exit(1);
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
if (!(await fs.pathExists(cloneTo))) {
|
|
119
|
-
log('New site does not exist. Performing cloning...');
|
|
120
|
-
|
|
121
|
-
process.env.IMAGE_VERSION=$`cd ${cloneFrom} && grep -E '^IMAGE_VERSION=' dock.sh | cut -f2 -d=`
|
|
122
|
-
await $`cd ${cloneTo} && bash dock.sh clone ${process.env.BUILD_ENVIRONMENT} ${process.env.BUILD_SITE} ${process.env.IMAGE_VERSION}`;
|
|
123
|
-
} else {
|
|
124
|
-
log('Site already exists. Continuing Auth0 setup...');
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
await $`cd ${cloneTo} && bash dock.sh getAuth0Metadata`;
|
|
129
|
-
|
|
130
|
-
// 7) Check conf files, print logs
|
|
131
|
-
await $`grep "auth0" ${path.join(cloneTo, 'conf/application.conf')}`;
|
|
132
|
-
await $`ls -all ${path.join(cloneTo, 'conf')}`;
|
|
133
|
-
await $`ls -all ${path.join(cloneTo, 'conf/saml')}`;
|
|
134
|
-
await $`cat ${path.join(cloneTo, 'conf/saml/auth0.xml')}`;
|
|
135
|
-
|
|
136
|
-
// 8) Git add, commit, push
|
|
137
|
-
await $`cd ${cloneTo} && git checkout master && git pull --ff-only`;
|
|
138
|
-
await $`cd ${cloneTo} && git remote -v`;
|
|
139
|
-
await $`cd ${cloneTo} && git branch`;
|
|
140
|
-
await $`cd ${cloneTo} && git status`;
|
|
141
|
-
await $`cd ${cloneTo} && git add . ../sites.sh`;
|
|
142
|
-
await $`cd ${cloneTo} && git status`;
|
|
143
|
-
|
|
144
|
-
const numChanges = (
|
|
145
|
-
await $`cd ${cloneTo} && git diff-index HEAD`
|
|
146
|
-
).stdout.split('\n').filter(Boolean).length;
|
|
147
|
-
|
|
148
|
-
if (numChanges > 0) {
|
|
149
|
-
const jiraTicket = process.env.JIRA_TICKET || 'NO_JIRA';
|
|
150
|
-
const message = `${jiraTicket} usdoc-s-builui job download_auth0_metadata for ${process.env.BUILD_ENVIRONMENT}/${process.env.BUILD_SITE}`;
|
|
151
|
-
log('About to commit changes to git');
|
|
152
|
-
await $`cd ${cloneTo} && git commit -m ${message}`;
|
|
153
|
-
await $`cd ${cloneTo} && git push -u origin master`;
|
|
154
|
-
} else {
|
|
155
|
-
log('No changes have been made. The site likely already has the correct configuration.');
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
|
package/src/next/haproxy.js
DELETED
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
import { $ } from 'zx';
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
export async function haproxySync() {
|
|
5
|
-
const repoPath = '/root/repo/docupace-ansible';
|
|
6
|
-
const inventory = path.join(repoPath, 'inventories/preprod/inventory');
|
|
7
|
-
|
|
8
|
-
// Create haproxy.sh
|
|
9
|
-
const scriptContent = `
|
|
10
|
-
#!/bin/bash
|
|
11
|
-
|
|
12
|
-
[[ ! -f ${inventory} ]] && ( echo "Alert: no inventory file: ${inventory}" ; exit 1 )
|
|
13
|
-
cd ${repoPath}
|
|
14
|
-
pwd
|
|
15
|
-
git stash
|
|
16
|
-
git pull origin master
|
|
17
|
-
git checkout master
|
|
18
|
-
git submodule update --remote
|
|
19
|
-
git submodule foreach --recursive git checkout master
|
|
20
|
-
git submodule foreach --recursive git pull origin master
|
|
21
|
-
|
|
22
|
-
ansible-playbook -i inventories/preprod/inventory haproxy.yml -e "cluster=preprod"
|
|
23
|
-
|
|
24
|
-
echo "proceeding"
|
|
25
|
-
echo "committing changes"
|
|
26
|
-
git add preprod-haproxy.cfg
|
|
27
|
-
git commit -m "Sync haproxy"
|
|
28
|
-
git push origin master
|
|
29
|
-
`;
|
|
30
|
-
|
|
31
|
-
await fs.writeFile('haproxy.sh', scriptContent);
|
|
32
|
-
|
|
33
|
-
// Private key
|
|
34
|
-
const haproxyPrivateKey = process.env.HAPROXY_PRIVATE_KEY;
|
|
35
|
-
if (!haproxyPrivateKey) {
|
|
36
|
-
log('Error: HAPROXY_PRIVATE_KEY not set.');
|
|
37
|
-
process.exit(1);
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
await fs.writeFile('private.key', Buffer.from(haproxyPrivateKey, 'base64'));
|
|
41
|
-
await fs.chmod('private.key', 0o600);
|
|
42
|
-
|
|
43
|
-
await $`cat private.key`; // Just to mimic the script's behavior
|
|
44
|
-
|
|
45
|
-
// Copy script to remote
|
|
46
|
-
await $`scp -i private.key -o StrictHostKeyChecking=no haproxy.sh root@10.10.28.198:/tmp/haproxy.sh`;
|
|
47
|
-
|
|
48
|
-
// Execute script on remote
|
|
49
|
-
await $`ssh -i private.key -o StrictHostKeyChecking=no root@10.10.28.198 "bash /tmp/haproxy.sh"`;
|
|
50
|
-
}
|
package/src/next/vault.js
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { $ } from 'zx';
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
export async function vaultAddSiteData(SITE) {
|
|
5
|
-
const AUTH0_CLIENT_ID = `${process.env.AUTH0_CLIENT_ID}`;
|
|
6
|
-
const AUTH0_CLIENT_SECRET = `${process.env.AUTH0_CLIENT_SECRET}`;
|
|
7
|
-
await $`export VAULT_SKIP_VERIFY=true`;
|
|
8
|
-
await $`vault kv put secret/dp-${SITE}/common/config AUTH0_CLIENT_ID="${AUTH0_CLIENT_ID}" AUTH0_CLIENT_SECRET="${AUTH0_CLIENT_SECRET}"`
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|