@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.
@@ -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
+ }
@@ -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('deploy-template')
104
+ .command('deployTemplate <site>')
110
105
  .description('Deploy an application for a specific site')
111
- .action(async () => {
112
- const deployTag = await getDeployTag();
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
@@ -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
+ };
@@ -266,7 +266,7 @@ export async function writeAndPushDeployConfig(
266
266
  * @param {string} site - The site name.
267
267
  */
268
268
 
269
- export async function getDeployTag() {
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 getDefaultDeploySite(deployTag) {
278
- const env = deployTag.includes('alpha') ? 'dev' : 'qa';
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', env, site);
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 deployAppWithTag(application, env, site, deployTag) {
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, env, site);
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
- terraform init \
40
- -input=false \
41
- -reconfigure \
42
- -backend=true \
43
- -backend-config=./env/${CURRENT_ENVIRONMENT}/us-west-2/backend.tfvars \
44
- -backend-config="key=us-west-2/${PROJECT}/${SITE_NAME}/${CURRENT_ENVIRONMENT}/terraform.tfstate"
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
-