@docupace/pipeline 1.0.33-matttest.3 → 1.0.34
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 -2
- package/src/auth0/alias.js +36 -39
- package/src/auth0/cli.js +48 -15
- package/src/auth0/configure.js +316 -450
- package/src/auth0/export.js +43 -0
- package/src/auth0/metadata.js +132 -0
- package/src/auth0/vault.js +3 -3
- package/src/next/cli.js +4 -29
- package/src/next/config.js +9 -0
- package/src/next/deploy.js +8 -16
- package/terraform/init.sh +21 -9
- package/terraform/plan.sh +12 -5
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { getVaultSecrets } from './vault.js';
|
|
2
|
+
import { getVaultSecretsConfigs } from '../next/config.js';
|
|
3
|
+
import { dump } from 'auth0-deploy-cli';
|
|
4
|
+
|
|
5
|
+
export async function exportConf(site, env) {
|
|
6
|
+
try {
|
|
7
|
+
console.log(
|
|
8
|
+
`Exporting Auth0 configuration for site: ${site} and env: ${env}`,
|
|
9
|
+
);
|
|
10
|
+
|
|
11
|
+
const siteCommonSecretsPath =
|
|
12
|
+
getVaultSecretsConfigs(site).siteCommonSecretsPath;
|
|
13
|
+
console.log(`siteCommonSecretsPath => ${siteCommonSecretsPath}`);
|
|
14
|
+
const siteCommonSecrets = await getVaultSecrets(siteCommonSecretsPath);
|
|
15
|
+
|
|
16
|
+
const auth0Domain = `docupace-${env}-${site}.us.auth0.com`;
|
|
17
|
+
const auth0ClientId = siteCommonSecrets.AUTH0_CLIENT_ID;
|
|
18
|
+
const auth0ClientSecret = siteCommonSecrets.AUTH0_CLIENT_SECRET;
|
|
19
|
+
|
|
20
|
+
const config = {
|
|
21
|
+
config: {
|
|
22
|
+
AUTH0_DOMAIN: auth0Domain,
|
|
23
|
+
AUTH0_CLIENT_ID: auth0ClientId,
|
|
24
|
+
AUTH0_CLIENT_SECRET: auth0ClientSecret,
|
|
25
|
+
},
|
|
26
|
+
format: 'directory',
|
|
27
|
+
output_folder: `./auth0-${site}-export`,
|
|
28
|
+
export_ids: false,
|
|
29
|
+
env: false,
|
|
30
|
+
debug: true,
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
console.log(`Starting Auth0 ${site} configuration export...`);
|
|
34
|
+
await dump(config);
|
|
35
|
+
console.log(`Auth0 ${site} configuration export completed successfully!`);
|
|
36
|
+
} catch (error) {
|
|
37
|
+
console.error(
|
|
38
|
+
`Error during Auth0 ${site} configuration export:`,
|
|
39
|
+
error.message,
|
|
40
|
+
);
|
|
41
|
+
process.exit(1);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import fs from 'fs-extra';
|
|
2
|
+
import axios from 'axios';
|
|
3
|
+
import path from 'path';
|
|
4
|
+
import { cloneRepository } from '../next/deploy.js';
|
|
5
|
+
import { getAuth0AuthToken } from './configure.js';
|
|
6
|
+
import { getVaultSecrets } from './vault.js';
|
|
7
|
+
import { getVaultSecretsConfigs } from '../next/config.js';
|
|
8
|
+
import { pushDeployConfig } from '../next/deploy.js';
|
|
9
|
+
|
|
10
|
+
export async function getAuth0Metadata(site, env) {
|
|
11
|
+
try {
|
|
12
|
+
const connectDeployRepoPath = await cloneRepository('connect-deploy');
|
|
13
|
+
|
|
14
|
+
if (env === 'qa') {
|
|
15
|
+
console.log(
|
|
16
|
+
`The environment is: (${env}), but connect-deploy has preprod instead`,
|
|
17
|
+
);
|
|
18
|
+
process.chdir(`${connectDeployRepoPath}/envs/preprod/${site}`);
|
|
19
|
+
} else {
|
|
20
|
+
process.chdir(`${connectDeployRepoPath}/envs/${env}/${site}`);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const configPath = path.join('conf', 'application.conf');
|
|
24
|
+
const appConf = await fs.readFile(configPath, 'utf-8');
|
|
25
|
+
const connectContext = appConf.match(
|
|
26
|
+
/application\.context\s*=\s*"(.*?)"/,
|
|
27
|
+
)?.[1];
|
|
28
|
+
|
|
29
|
+
if (!connectContext) {
|
|
30
|
+
console.error('connectContext not found in application.conf. Exiting...');
|
|
31
|
+
process.exit(1);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const siteHost = appConf.match(
|
|
35
|
+
/docupace\.baseUrlClient\s*=\s*"?https?:\/\/([^/]+)"?/,
|
|
36
|
+
)?.[1];
|
|
37
|
+
|
|
38
|
+
if (!siteHost) {
|
|
39
|
+
console.error('siteHost not found in application.conf. Exiting...');
|
|
40
|
+
process.exit(1);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const connectEndpoint = `https://${siteHost}${connectContext}`;
|
|
44
|
+
console.log('CONNECT_ENDPOINT:', connectEndpoint);
|
|
45
|
+
|
|
46
|
+
console.log('Requesting token from Auth0...');
|
|
47
|
+
const siteCommonSecretsPath =
|
|
48
|
+
getVaultSecretsConfigs(site).siteCommonSecretsPath;
|
|
49
|
+
console.log(`siteCommonSecretsPath => ${siteCommonSecretsPath}`);
|
|
50
|
+
const siteCommonSecrets = await getVaultSecrets(siteCommonSecretsPath);
|
|
51
|
+
const auth0Domain = `docupace-${env}-${site}.us.auth0.com`;
|
|
52
|
+
const auth0ClientId = siteCommonSecrets.AUTH0_CLIENT_ID;
|
|
53
|
+
const auth0ClientSecret = siteCommonSecrets.AUTH0_CLIENT_SECRET;
|
|
54
|
+
const auth0Token = await getAuth0AuthToken(
|
|
55
|
+
auth0Domain,
|
|
56
|
+
auth0ClientId,
|
|
57
|
+
auth0ClientSecret,
|
|
58
|
+
);
|
|
59
|
+
|
|
60
|
+
const auth0Response = await axios.get(
|
|
61
|
+
`https://${auth0Domain}/api/v2/clients`,
|
|
62
|
+
{
|
|
63
|
+
headers: { authorization: `Bearer ${auth0Token}` },
|
|
64
|
+
},
|
|
65
|
+
);
|
|
66
|
+
|
|
67
|
+
const connectClient = auth0Response.data.find(
|
|
68
|
+
(client) => client.name === 'docupace-connect',
|
|
69
|
+
);
|
|
70
|
+
|
|
71
|
+
if (!connectClient) {
|
|
72
|
+
console.error('Client "docupace-connect" not found.');
|
|
73
|
+
process.exit(1);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const clientId = connectClient.client_id;
|
|
77
|
+
console.log('Found client_id:', clientId);
|
|
78
|
+
|
|
79
|
+
const metadataRes = await axios.get(
|
|
80
|
+
`https://${auth0Domain}/samlp/metadata/${clientId}`,
|
|
81
|
+
{
|
|
82
|
+
responseType: 'text',
|
|
83
|
+
},
|
|
84
|
+
);
|
|
85
|
+
|
|
86
|
+
const metadata = metadataRes.data;
|
|
87
|
+
|
|
88
|
+
if (metadata.length < 2000) {
|
|
89
|
+
console.error(
|
|
90
|
+
'Downloaded metadata looks incorrect (too small). Exiting...',
|
|
91
|
+
);
|
|
92
|
+
process.exit(1);
|
|
93
|
+
}
|
|
94
|
+
await fs.ensureDir('conf/saml');
|
|
95
|
+
await fs.writeFile('conf/saml/auth0.xml', metadata);
|
|
96
|
+
console.log('SAML metadata written to conf/saml/auth0.xml');
|
|
97
|
+
|
|
98
|
+
let newConfig = appConf;
|
|
99
|
+
|
|
100
|
+
if (/useSAML\s*=/.test(appConf)) {
|
|
101
|
+
newConfig = newConfig.replace(/useSAML\s*=.*/, 'useSAML=true');
|
|
102
|
+
} else {
|
|
103
|
+
newConfig += '\nuseSAML=true';
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
const replacements = {
|
|
107
|
+
'saml.clients.auth0.idpMetadataPath': '${samlEnvPath}"/auth0.xml"',
|
|
108
|
+
'saml.clients.auth0.spEntityId': `"${connectEndpoint}"`,
|
|
109
|
+
'saml.clients.auth0.redirectFormInput': '"RelayState"',
|
|
110
|
+
'saml.clients.auth0.idpLoginUrl': `"https://${auth0Domain}/v2/logout?client_id=${clientId}&returnTo=${connectEndpoint}"`,
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
for (const [key, value] of Object.entries(replacements)) {
|
|
114
|
+
const pattern = new RegExp(`${key}\\s*=.*`, 'g');
|
|
115
|
+
if (pattern.test(newConfig)) {
|
|
116
|
+
newConfig = newConfig.replace(pattern, `${key}=${value}`);
|
|
117
|
+
} else {
|
|
118
|
+
newConfig += `\n${key}=${value}`;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
await fs.writeFile(configPath, newConfig);
|
|
123
|
+
console.log('The application.conf has been updated.');
|
|
124
|
+
await pushDeployConfig(
|
|
125
|
+
connectDeployRepoPath,
|
|
126
|
+
`Auth0 SAML metadata update for site: (${site}) in env: (${env})`,
|
|
127
|
+
);
|
|
128
|
+
} catch (error) {
|
|
129
|
+
console.error('Error:', error.message);
|
|
130
|
+
process.exit(1);
|
|
131
|
+
}
|
|
132
|
+
}
|
package/src/auth0/vault.js
CHANGED
|
@@ -44,7 +44,7 @@ export async function getVaultSecrets(vaultPath) {
|
|
|
44
44
|
} catch (error) {
|
|
45
45
|
if (error.response) {
|
|
46
46
|
console.error(
|
|
47
|
-
`Error: Failed to connect to Vault server at ${vaultAddr}. Response: ${error.response.status} ${error.response.statusText}
|
|
47
|
+
`Error: Failed to connect to Vault server at ${vaultAddr}. Response: ${error.response.status} ${error.response.statusText}`,
|
|
48
48
|
);
|
|
49
49
|
} else {
|
|
50
50
|
console.error(`Error: ${error.message}`);
|
|
@@ -88,7 +88,7 @@ export async function updateVaultSecrets(vaultPath, secretData) {
|
|
|
88
88
|
'X-Vault-Token': vaultToken,
|
|
89
89
|
'Content-Type': 'application/json',
|
|
90
90
|
},
|
|
91
|
-
}
|
|
91
|
+
},
|
|
92
92
|
);
|
|
93
93
|
|
|
94
94
|
// Return the response from Vault
|
|
@@ -97,7 +97,7 @@ export async function updateVaultSecrets(vaultPath, secretData) {
|
|
|
97
97
|
} catch (error) {
|
|
98
98
|
if (error.response) {
|
|
99
99
|
console.error(
|
|
100
|
-
`Error: Failed to update secret at ${vaultPath}. Response: ${error.response.status} ${error.response.statusText}
|
|
100
|
+
`Error: Failed to update secret at ${vaultPath}. Response: ${error.response.status} ${error.response.statusText}`,
|
|
101
101
|
);
|
|
102
102
|
} else {
|
|
103
103
|
console.error(`Error: ${error.message}`);
|
package/src/next/cli.js
CHANGED
|
@@ -4,12 +4,7 @@ import { Command } from 'commander';
|
|
|
4
4
|
import { pull } from './pull.js';
|
|
5
5
|
import { sonar } from './sonar.js';
|
|
6
6
|
import { publish } from './publish.js';
|
|
7
|
-
import {
|
|
8
|
-
deployAppWithTag,
|
|
9
|
-
deployFromSite,
|
|
10
|
-
getDefaultDeploySite,
|
|
11
|
-
getDeployTag,
|
|
12
|
-
} from './deploy.js';
|
|
7
|
+
import { deployFromSite } from './deploy.js';
|
|
13
8
|
import { deployTemplate } from './deploy.js';
|
|
14
9
|
import { copy } from './copy.js';
|
|
15
10
|
import { vaultAddSiteData } from './vault.js';
|
|
@@ -106,30 +101,10 @@ program
|
|
|
106
101
|
});
|
|
107
102
|
|
|
108
103
|
program
|
|
109
|
-
.command('
|
|
104
|
+
.command('deployTemplate <site>')
|
|
110
105
|
.description('Deploy an application for a specific site')
|
|
111
|
-
.action(async () => {
|
|
112
|
-
|
|
113
|
-
const { env, site } = await getDefaultDeploySite(deployTag);
|
|
114
|
-
await deployTemplate(env, site, deployTag);
|
|
115
|
-
});
|
|
116
|
-
|
|
117
|
-
program
|
|
118
|
-
.command('deployTemplate')
|
|
119
|
-
.description('Deploy an application for a specific site')
|
|
120
|
-
.action(async () => {
|
|
121
|
-
const deployTag = await getDeployTag();
|
|
122
|
-
const { env, site } = await getDefaultDeploySite(deployTag);
|
|
123
|
-
await deployTemplate(env, site, deployTag);
|
|
124
|
-
});
|
|
125
|
-
|
|
126
|
-
program
|
|
127
|
-
.command('deploy-app <application>')
|
|
128
|
-
.description('Deploy an application for a specific site')
|
|
129
|
-
.action(async (application) => {
|
|
130
|
-
const deployTag = await getDeployTag();
|
|
131
|
-
const { env, site } = await getDefaultDeploySite(deployTag);
|
|
132
|
-
await deployAppWithTag(application, env, site, deployTag);
|
|
106
|
+
.action(async (site) => {
|
|
107
|
+
await deployTemplate(site);
|
|
133
108
|
});
|
|
134
109
|
|
|
135
110
|
program
|
package/src/next/config.js
CHANGED
|
@@ -80,5 +80,14 @@ export const getVaultSecretsConfigs = (site) => {
|
|
|
80
80
|
siteCommonSecretsPath: `secret/data/${site}/common/config`,
|
|
81
81
|
graphqlServerSecretsPath: `secret/data/${site}/graphql-server/config`,
|
|
82
82
|
uiSecretsPath: `secret/data/${site}/ui/config`,
|
|
83
|
+
awsSecretsPath: `secret/data/${site}/aws/config`,
|
|
83
84
|
};
|
|
84
85
|
};
|
|
86
|
+
|
|
87
|
+
export const coreSiteEnvMap = {
|
|
88
|
+
dev: 'dev',
|
|
89
|
+
qa: 'preprod',
|
|
90
|
+
stg: 'staging',
|
|
91
|
+
uat: 'uat',
|
|
92
|
+
prd: 'prod',
|
|
93
|
+
};
|
package/src/next/deploy.js
CHANGED
|
@@ -266,7 +266,7 @@ export async function writeAndPushDeployConfig(
|
|
|
266
266
|
* @param {string} site - The site name.
|
|
267
267
|
*/
|
|
268
268
|
|
|
269
|
-
|
|
269
|
+
async function getDeployTag() {
|
|
270
270
|
const gitTag = (
|
|
271
271
|
await $`git tag --points-at HEAD | grep '^v' | head -n 1`
|
|
272
272
|
).stdout.trim();
|
|
@@ -274,17 +274,12 @@ export async function getDeployTag() {
|
|
|
274
274
|
return deployTag;
|
|
275
275
|
}
|
|
276
276
|
|
|
277
|
-
export async function
|
|
278
|
-
const
|
|
279
|
-
const site = env === 'dev' ? 'financialdev' : 'qa';
|
|
280
|
-
return { env, site };
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
export async function deployTemplate(env, site, deployTag) {
|
|
277
|
+
export async function deployTemplate(site) {
|
|
278
|
+
const deployTag = await getDeployTag();
|
|
284
279
|
console.log(`Deploying standard template for site: ${site}`);
|
|
285
280
|
console.log(`Using deployment tag: ${deployTag}`);
|
|
286
281
|
const { repoPath, deployConfigFilePath, deployConfig } =
|
|
287
|
-
await cloneAndReadDeployConfig('graphql-server',
|
|
282
|
+
await cloneAndReadDeployConfig('graphql-server', 'dev', site);
|
|
288
283
|
|
|
289
284
|
deployConfig.graphqlServer.standardConfigRemoteBranch = deployTag;
|
|
290
285
|
|
|
@@ -297,17 +292,14 @@ export async function deployTemplate(env, site, deployTag) {
|
|
|
297
292
|
console.log('Deployment completed successfully.');
|
|
298
293
|
}
|
|
299
294
|
|
|
300
|
-
export async function
|
|
295
|
+
export async function deploy(application, site) {
|
|
296
|
+
const deployTag = getDeployTag();
|
|
297
|
+
|
|
301
298
|
console.log(`Deploying application: ${application} for site: ${site}`);
|
|
302
299
|
console.log(`Using deployment tag: ${deployTag}`);
|
|
303
300
|
|
|
304
|
-
if (env !== 'dev') {
|
|
305
|
-
const appDetails = appInfo[application];
|
|
306
|
-
await copy2(appDetails.repositoryName, 'dev', env, deployTag);
|
|
307
|
-
}
|
|
308
|
-
|
|
309
301
|
const { repoPath, deployConfigFilePath, deployConfig } =
|
|
310
|
-
await cloneAndReadDeployConfig(application,
|
|
302
|
+
await cloneAndReadDeployConfig(application, 'dev', site);
|
|
311
303
|
const updatedConfigData = setTag(deployConfig, deployTag);
|
|
312
304
|
await writeAndPushDeployConfig(
|
|
313
305
|
repoPath,
|
package/terraform/init.sh
CHANGED
|
@@ -33,16 +33,28 @@ echo "$atlassian_workspace_runner_ssh_key" | base64 -d > ~/.ssh/id_ed25519
|
|
|
33
33
|
chmod 600 ~/.ssh/id_ed25519
|
|
34
34
|
ssh-keyscan bitbucket.org > ~/.ssh/known_hosts
|
|
35
35
|
|
|
36
|
-
|
|
36
|
+
info () {
|
|
37
|
+
echo "PROJECT => $PROJECT"
|
|
38
|
+
echo "CURRENT_ENVIRONMENT => $CURRENT_ENVIRONMENT"
|
|
39
|
+
echo "SITE_NAME => $SITE_NAME"
|
|
40
|
+
}
|
|
37
41
|
|
|
38
42
|
if [[ "$PROJECT" == "s3" ]]; then
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
43
|
+
info
|
|
44
|
+
terraform init \
|
|
45
|
+
-input=false \
|
|
46
|
+
-reconfigure \
|
|
47
|
+
-backend=true \
|
|
48
|
+
-backend-config=./env/${CURRENT_ENVIRONMENT}/us-west-2/backend.tfvars \
|
|
49
|
+
-backend-config="key=us-west-2/${PROJECT}/${SITE_NAME}/${CURRENT_ENVIRONMENT}/terraform.tfstate"
|
|
50
|
+
elif [[ "$PROJECT" == "idp" ]]; then
|
|
51
|
+
info
|
|
52
|
+
terraform init \
|
|
53
|
+
-input=false \
|
|
54
|
+
-reconfigure \
|
|
55
|
+
-backend=true \
|
|
56
|
+
-backend-config=./env/${CURRENT_ENVIRONMENT}/us-west-2/backend.tfvars \
|
|
57
|
+
-backend-config="key=us-west-2/${PROJECT}/${SITE_NAME}/${CURRENT_ENVIRONMENT}/terraform.tfstate"
|
|
46
58
|
else
|
|
47
59
|
terraform init -backend-config=./env/${CURRENT_ENVIRONMENT}/us-west-2/backend.tfvars --reconfigure
|
|
48
|
-
fi
|
|
60
|
+
fi
|
package/terraform/plan.sh
CHANGED
|
@@ -44,11 +44,18 @@ elif [[ "$PROJECT" == "s3" ]];then
|
|
|
44
44
|
-var="site=${SITE_NAME}" \
|
|
45
45
|
-var="env=${CURRENT_ENVIRONMENT}" \
|
|
46
46
|
-out .tfplan
|
|
47
|
+
elif [[ "$PROJECT" == "idp" ]];then
|
|
48
|
+
terraform plan -var-file="./env/${CURRENT_ENVIRONMENT}/us-west-2/terraform.tfvars" \
|
|
49
|
+
-var="site=${SITE_NAME}" \
|
|
50
|
+
-var="env=${CURRENT_ENVIRONMENT}" \
|
|
51
|
+
-var="docupace_domain=${DOCUPACE_DOMAIN}" \
|
|
52
|
+
-var="docupace_next_domain=${DOCUPACE_NEXT_DOMAIN}" \
|
|
53
|
+
-var="old_page_design=${USE_OLD_PAGE_DESIGN}" \
|
|
54
|
+
-var="use_new_domain=${USE_NEW_DOMAIN}" \
|
|
55
|
+
-var="configure_autologin=${CONFIGURE_AUTOLOGIN}" \
|
|
56
|
+
-var="configure_ui_main=${CONFIGURE_UI_MAIN}" \
|
|
57
|
+
-var="enable_mfa=${ENABLE_MFA}" \
|
|
58
|
+
-out .tfplan
|
|
47
59
|
else
|
|
48
60
|
terraform plan -var-file="./env/${CURRENT_ENVIRONMENT}/us-west-2/terraform.tfvars" -out .tfplan
|
|
49
61
|
fi
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|