@govuk-pay/cli 0.0.35 → 0.0.37

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@govuk-pay/cli",
3
- "version": "0.0.35",
3
+ "version": "0.0.37",
4
4
  "description": "GOV.UK Pay Command Line Interface",
5
5
  "bin": {
6
6
  "pay": "bin/cli.js",
@@ -4,7 +4,7 @@ exports.handler = exports.builder = exports.desc = exports.command = void 0;
4
4
  const node_child_process_1 = require("node:child_process");
5
5
  const totp_generator_1 = require("totp-generator");
6
6
  const standardContent_1 = require("../../../core/standardContent");
7
- exports.command = 'opt <key>';
7
+ exports.command = 'otp <key>';
8
8
  exports.desc = 'Create otp code';
9
9
  const builder = (yargs) => {
10
10
  return yargs.positional('key', {
@@ -22,7 +22,8 @@ const FORMAT = {
22
22
  yellow: '\x1b[33m',
23
23
  reset: '\x1b[0m',
24
24
  ul: '\x1b[4m',
25
- ulstop: '\x1b[24m'
25
+ ulstop: '\x1b[24m',
26
+ bel: '\u0007'
26
27
  };
27
28
  exports.command = 'tunnel <environment> <application>';
28
29
  exports.desc = 'Open a tunnel to an app database in a given environment';
@@ -66,6 +67,15 @@ async function tunnelHandler(argv) {
66
67
  const environment = argv.environment;
67
68
  const application = argv.application;
68
69
  console.log(`Opening a database tunnel to ${environment} ${application}`);
70
+ let maximumDuration = 90;
71
+ if (process.env.MAXIMUM_DURATION !== undefined) {
72
+ maximumDuration = parseInt(process.env.MAXIMUM_DURATION);
73
+ if (isNaN(maximumDuration)) {
74
+ maximumDuration = 90;
75
+ console.log(`${FORMAT.yellow}MAXIMUM_DURATION should be a whole number of minutes, e.g. MAXIMUM_DURATION=60. Defaulting to ${maximumDuration}.${FORMAT.reset}`);
76
+ }
77
+ }
78
+ const warnTime = maximumDuration * 0.75;
69
79
  ec2 = new client_ec2_1.EC2Client();
70
80
  ecs = new client_ecs_1.ECSClient();
71
81
  ssm = new client_ssm_1.SSMClient();
@@ -74,10 +84,19 @@ async function tunnelHandler(argv) {
74
84
  printWarningToUser();
75
85
  const dbAccessType = await readInputForReadOrWriteDBAccess();
76
86
  const database = await getDatabaseDetails(environment, application);
77
- bastionTask = await startBastion(environment);
87
+ bastionTask = await startBastion(environment, maximumDuration);
88
+ console.log(`${FORMAT.bel}${FORMAT.yellow}The bastion service will terminate in ${maximumDuration} minutes.${FORMAT.reset}`);
89
+ const warnTimeout = setTimeout(() => {
90
+ console.log(`${FORMAT.bel}${FORMAT.yellow}The bastion service will terminate in ${maximumDuration - warnTime} minutes.${FORMAT.reset}`);
91
+ }, warnTime * 60 * 1000);
92
+ const exitTimeout = setTimeout(() => {
93
+ console.log(`${FORMAT.bel}${FORMAT.yellow}The bastion service will now terminate, your tunnel may stop unexpectedly.${FORMAT.reset}`);
94
+ }, maximumDuration * 60 * 1000);
78
95
  openTunnel(bastionTask, database, environment);
79
96
  await printHowToTunnelText(application, environment, database.EngineVersion, dbAccessType);
80
97
  await waitForExit();
98
+ clearTimeout(warnTimeout);
99
+ clearTimeout(exitTimeout);
81
100
  await shutdown(environment, bastionTask);
82
101
  }
83
102
  catch (error) {
@@ -117,10 +136,10 @@ async function waitForExit() {
117
136
  });
118
137
  });
119
138
  }
120
- async function startBastion(environment) {
139
+ async function startBastion(environment, maximumDuration) {
121
140
  const subnetIds = await getBastionSubNets(environment);
122
141
  const securityGroupIds = await getBastionSecurityGroups(environment);
123
- let bastionTask = await launchBastionTask(environment, subnetIds, securityGroupIds);
142
+ let bastionTask = await launchBastionTask(environment, subnetIds, securityGroupIds, maximumDuration);
124
143
  bastionTask = await waitForBastionToBeReady(bastionTask, environment);
125
144
  return bastionTask;
126
145
  }
@@ -156,12 +175,29 @@ async function getBastionSecurityGroups(environment) {
156
175
  .filter(s => s.GroupId !== undefined)
157
176
  .map((securityGroup) => securityGroup.GroupId);
158
177
  }
159
- async function launchBastionTask(environment, subnetIds, securityGroupIds) {
178
+ async function launchBastionTask(environment, subnetIds, securityGroupIds, maximumDuration) {
179
+ let taskDefinition = `${environment}-bastion`;
180
+ if (process.env.BASTION_TASK_DEF_NAME != null && process.env.BASTION_TASK_DEF_NAME.length > 0) {
181
+ taskDefinition = process.env.BASTION_TASK_DEF_NAME;
182
+ }
160
183
  const runTaskCommand = new client_ecs_1.RunTaskCommand({
161
184
  cluster: `${environment}-fargate`,
162
- taskDefinition: `${environment}-bastion`,
185
+ taskDefinition,
163
186
  launchType: 'FARGATE',
164
187
  enableExecuteCommand: true,
188
+ overrides: {
189
+ containerOverrides: [
190
+ {
191
+ name: `${environment}-bastion`,
192
+ environment: [
193
+ {
194
+ name: 'MAXIMUM_DURATION',
195
+ value: `${maximumDuration}m`
196
+ }
197
+ ]
198
+ }
199
+ ]
200
+ },
165
201
  networkConfiguration: {
166
202
  awsvpcConfiguration: {
167
203
  subnets: subnetIds,
@@ -430,5 +466,5 @@ function printError(error) {
430
466
  console.error(`${FORMAT.red}${error}${FORMAT.reset}`);
431
467
  }
432
468
  function printGreen(message) {
433
- console.error(`${FORMAT.green}${message}${FORMAT.reset}`);
469
+ console.log(`${FORMAT.green}${message}${FORMAT.reset}`);
434
470
  }