heroku 9.0.0-alpha.3 → 9.0.0-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.
Files changed (36) hide show
  1. package/lib/commands/addons/create.d.ts +1 -0
  2. package/lib/commands/addons/create.js +13 -1
  3. package/lib/commands/apps/info.js +7 -7
  4. package/lib/commands/ci/config/get.js +2 -2
  5. package/lib/commands/ci/config/index.d.ts +1 -0
  6. package/lib/commands/ci/config/index.js +3 -2
  7. package/lib/commands/ci/config/set.d.ts +1 -1
  8. package/lib/commands/ci/config/set.js +1 -1
  9. package/lib/commands/ci/config/unset.d.ts +0 -1
  10. package/lib/commands/ci/config/unset.js +2 -3
  11. package/lib/commands/container/pull.js +3 -0
  12. package/lib/commands/container/push.js +3 -1
  13. package/lib/commands/container/release.js +3 -1
  14. package/lib/commands/container/rm.js +3 -0
  15. package/lib/commands/container/run.js +3 -0
  16. package/lib/commands/spaces/transfer.js +2 -2
  17. package/lib/commands/spaces/trusted-ips/remove.d.ts +1 -1
  18. package/lib/commands/spaces/trusted-ips/remove.js +1 -1
  19. package/lib/commands/spaces/vpn/config.js +1 -1
  20. package/lib/commands/spaces/vpn/connect.js +5 -2
  21. package/lib/commands/spaces/vpn/destroy.js +4 -1
  22. package/lib/commands/spaces/vpn/info.js +1 -1
  23. package/lib/commands/spaces/vpn/update.js +5 -2
  24. package/lib/commands/spaces/vpn/wait.d.ts +4 -1
  25. package/lib/commands/spaces/vpn/wait.js +20 -3
  26. package/lib/lib/container/helpers.d.ts +8 -0
  27. package/lib/lib/container/helpers.js +26 -0
  28. package/lib/lib/git/git.js +3 -3
  29. package/oclif.manifest.json +37 -196
  30. package/package.json +4 -8
  31. package/lib/commands/spaces/outbound-rules/add.d.ts +0 -15
  32. package/lib/commands/spaces/outbound-rules/add.js +0 -81
  33. package/lib/commands/spaces/outbound-rules/index.d.ts +0 -15
  34. package/lib/commands/spaces/outbound-rules/index.js +0 -49
  35. package/lib/commands/spaces/outbound-rules/remove.d.ts +0 -17
  36. package/lib/commands/spaces/outbound-rules/remove.js +0 -53
@@ -2,6 +2,7 @@ import { Command } from '@heroku-cli/command';
2
2
  export default class Create extends Command {
3
3
  static topic: string;
4
4
  static description: string;
5
+ static example: string;
5
6
  static strict: boolean;
6
7
  static hiddenAliases: string[];
7
8
  static flags: {
@@ -6,6 +6,7 @@ const command_1 = require("@heroku-cli/command");
6
6
  const core_1 = require("@oclif/core");
7
7
  const notify_1 = require("../../lib/notify");
8
8
  const create_addon_1 = require("../../lib/addons/create_addon");
9
+ const tsheredoc_1 = require("tsheredoc");
9
10
  function parseConfig(args) {
10
11
  const config = {};
11
12
  while (args.length > 0) {
@@ -68,7 +69,18 @@ class Create extends command_1.Command {
68
69
  }
69
70
  exports.default = Create;
70
71
  Create.topic = 'addons';
71
- Create.description = 'create a new add-on resource';
72
+ Create.description = (0, tsheredoc_1.default) `
73
+ Create a new add-on resource.
74
+
75
+ In order to add additional config items, please place them at the end of the command after a double-dash (--).
76
+ `;
77
+ Create.example = (0, tsheredoc_1.default) `
78
+ Create an add-on resource:
79
+ $heroku addons:create heroku-redis --app my-app
80
+
81
+ Create an add-on resource with additional config items:
82
+ $heroku addons:create heroku-postgresql:standard-0 --app my-app -- --fork DATABASE
83
+ `;
72
84
  Create.strict = false;
73
85
  Create.hiddenAliases = ['addons:add'];
74
86
  Create.flags = {
@@ -4,7 +4,7 @@ const core_1 = require("@oclif/core");
4
4
  const command_1 = require("@heroku-cli/command");
5
5
  const util = require("util");
6
6
  const _ = require("lodash");
7
- const filesize = require('filesize');
7
+ const filesize_1 = require("filesize");
8
8
  const { countBy, snakeCase } = _;
9
9
  function formatDate(date) {
10
10
  return date.toISOString();
@@ -49,7 +49,7 @@ function print(info, addons, collaborators, extended) {
49
49
  if (info.app.cron_next_run)
50
50
  data['Cron Next Run'] = formatDate(new Date(info.app.cron_next_run));
51
51
  if (info.app.database_size)
52
- data['Database Size'] = filesize(info.app.database_size, { round: 0 });
52
+ data['Database Size'] = (0, filesize_1.filesize)(info.app.database_size, { standard: 'jedec', round: 0 });
53
53
  if (info.app.create_status !== 'complete')
54
54
  data['Create Status'] = info.app.create_status;
55
55
  if (info.app.space)
@@ -61,8 +61,8 @@ function print(info, addons, collaborators, extended) {
61
61
  data['Auto Cert Mgmt'] = info.app.acm;
62
62
  data['Git URL'] = info.app.git_url;
63
63
  data['Web URL'] = info.app.web_url;
64
- data['Repo Size'] = filesize(info.app.repo_size, { round: 0 });
65
- data['Slug Size'] = filesize(info.app.slug_size, { round: 0 });
64
+ data['Repo Size'] = (0, filesize_1.filesize)(info.app.repo_size, { standard: 'jedec', round: 0 });
65
+ data['Slug Size'] = (0, filesize_1.filesize)(info.app.slug_size, { standard: 'jedec', round: 0 });
66
66
  data.Owner = info.app.owner.email;
67
67
  data.Region = info.app.region.name;
68
68
  data.Dynos = countBy(info.dynos, 'type');
@@ -107,15 +107,15 @@ class AppsInfo extends command_1.Command {
107
107
  if (info.app.cron_next_run)
108
108
  print('cron_next_run', formatDate(new Date(info.app.cron_next_run)));
109
109
  if (info.app.database_size)
110
- print('database_size', filesize(info.app.database_size, { round: 0 }));
110
+ print('database_size', (0, filesize_1.filesize)(info.app.database_size, { standard: 'jedec', round: 0 }));
111
111
  if (info.app.create_status !== 'complete')
112
112
  print('create_status', info.app.create_status);
113
113
  if (info.pipeline_coupling)
114
114
  print('pipeline', `${info.pipeline_coupling.pipeline.name}:${info.pipeline_coupling.stage}`);
115
115
  print('git_url', info.app.git_url);
116
116
  print('web_url', info.app.web_url);
117
- print('repo_size', filesize(info.app.repo_size, { round: 0 }));
118
- print('slug_size', filesize(info.app.slug_size, { round: 0 }));
117
+ print('repo_size', (0, filesize_1.filesize)(info.app.repo_size, { standard: 'jedec', round: 0 }));
118
+ print('slug_size', (0, filesize_1.filesize)(info.app.slug_size, { standard: 'jedec', round: 0 }));
119
119
  print('owner', info.app.owner.email);
120
120
  print('region', info.app.region.name);
121
121
  print('dynos', util.inspect(countBy(info.dynos, 'type')));
@@ -28,9 +28,9 @@ CiConfigGet.examples = [
28
28
  ];
29
29
  CiConfigGet.flags = {
30
30
  help: command_1.flags.help({ char: 'h' }),
31
- app: command_1.flags.app({ required: false }),
31
+ app: command_1.flags.app(),
32
32
  remote: command_1.flags.remote(),
33
- pipeline: command_1.flags.pipeline({ required: false }),
33
+ pipeline: command_1.flags.pipeline({ exactlyOne: ['pipeline', 'app'] }),
34
34
  shell: command_1.flags.boolean({ char: 's', description: 'output config var in shell format' }),
35
35
  };
36
36
  CiConfigGet.args = {
@@ -4,6 +4,7 @@ export default class CiConfig extends Command {
4
4
  static examples: string[];
5
5
  static flags: {
6
6
  app: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
7
+ remote: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
7
8
  shell: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
8
9
  json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
9
10
  pipeline: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
@@ -36,8 +36,9 @@ CiConfig.examples = [
36
36
  `,
37
37
  ];
38
38
  CiConfig.flags = {
39
- app: command_1.flags.string({ char: 'a', description: 'app name' }),
39
+ app: command_1.flags.app(),
40
+ remote: command_1.flags.remote(),
40
41
  shell: command_1.flags.boolean({ char: 's', description: 'output config vars in shell format' }),
41
42
  json: command_1.flags.boolean({ description: 'output config vars in json format' }),
42
- pipeline: command_1.flags.pipeline(),
43
+ pipeline: command_1.flags.pipeline({ exactlyOne: ['pipeline', 'app'] }),
43
44
  };
@@ -6,7 +6,7 @@ export default class CiConfigSet extends Command {
6
6
  static flags: {
7
7
  app: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
8
8
  remote: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
9
- pipeline: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
9
+ pipeline: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
10
10
  };
11
11
  static strict: boolean;
12
12
  run(): Promise<void>;
@@ -44,6 +44,6 @@ CiConfigSet.examples = [
44
44
  CiConfigSet.flags = {
45
45
  app: command_1.flags.app(),
46
46
  remote: command_1.flags.remote(),
47
- pipeline: command_1.flags.pipeline({ required: true }),
47
+ pipeline: command_1.flags.pipeline({ exactlyOne: ['pipeline', 'app'] }),
48
48
  };
49
49
  CiConfigSet.strict = false;
@@ -5,7 +5,6 @@ export default class CiConfigUnset extends Command {
5
5
  static examples: string[];
6
6
  static strict: boolean;
7
7
  static flags: {
8
- help: import("@oclif/core/lib/interfaces").BooleanFlag<void>;
9
8
  app: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
10
9
  remote: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
11
10
  pipeline: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
@@ -29,8 +29,7 @@ CiConfigUnset.examples = [
29
29
  ];
30
30
  CiConfigUnset.strict = false;
31
31
  CiConfigUnset.flags = {
32
- help: command_1.flags.help({ char: 'h' }),
33
- app: command_1.flags.app({ required: false }),
32
+ app: command_1.flags.app(),
34
33
  remote: command_1.flags.remote(),
35
- pipeline: command_1.flags.pipeline({ required: false }),
34
+ pipeline: command_1.flags.pipeline({ exactlyOne: ['pipeline', 'app'] }),
36
35
  };
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const command_1 = require("@heroku-cli/command");
4
4
  const core_1 = require("@oclif/core");
5
5
  const DockerHelper = require("../../lib/container/docker_helper");
6
+ const helpers_1 = require("../../lib/container/helpers");
6
7
  const debug_1 = require("../../lib/container/debug");
7
8
  const color_1 = require("@heroku-cli/color");
8
9
  class Pull extends command_1.Command {
@@ -12,6 +13,8 @@ class Pull extends command_1.Command {
12
13
  if (argv.length === 0) {
13
14
  this.error(`Error: Requires one or more process types\n${Pull.example}`);
14
15
  }
16
+ const { body: appBody } = await this.heroku.get(`/apps/${app}`);
17
+ (0, helpers_1.ensureContainerStack)(appBody, 'pull');
15
18
  const herokuHost = process.env.HEROKU_HOST || 'heroku.com';
16
19
  const registry = `registry.${herokuHost}`;
17
20
  if (verbose) {
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const command_1 = require("@heroku-cli/command");
4
4
  const core_1 = require("@oclif/core");
5
5
  const DockerHelper = require("../../lib/container/docker_helper");
6
+ const helpers_1 = require("../../lib/container/helpers");
6
7
  const debug_1 = require("../../lib/container/debug");
7
8
  async function selectJobs(jobs, processTypes, recursive) {
8
9
  let filteredJobs = {};
@@ -37,7 +38,8 @@ class Push extends command_1.Command {
37
38
  if (processTypes.length > 1 && !recursive) {
38
39
  core_1.ux.error('Requires exactly one target process type, or --recursive option', { exit: 1 });
39
40
  }
40
- await this.heroku.get(`/apps/${app}`);
41
+ const { body: appBody } = await this.heroku.get(`/apps/${app}`);
42
+ (0, helpers_1.ensureContainerStack)(appBody, 'push');
41
43
  const herokuHost = process.env.HEROKU_HOST || 'heroku.com';
42
44
  const registry = `registry.${herokuHost}`;
43
45
  const dockerfiles = DockerHelper.getDockerfiles(process.cwd(), recursive);
@@ -5,6 +5,7 @@ const command_1 = require("@heroku-cli/command");
5
5
  const core_1 = require("@oclif/core");
6
6
  const debug_1 = require("../../lib/container/debug");
7
7
  const streamer_1 = require("../../lib/container/streamer");
8
+ const helpers_1 = require("../../lib/container/helpers");
8
9
  class ContainerRelease extends command_1.Command {
9
10
  async run() {
10
11
  const { flags, argv } = await this.parse(ContainerRelease);
@@ -15,7 +16,8 @@ class ContainerRelease extends command_1.Command {
15
16
  if (verbose) {
16
17
  debug_1.debug.enabled = true;
17
18
  }
18
- await this.heroku.get(`/apps/${app}`);
19
+ const { body: appBody } = await this.heroku.get(`/apps/${app}`);
20
+ (0, helpers_1.ensureContainerStack)(appBody, 'release');
19
21
  const herokuHost = process.env.HEROKU_HOST || 'heroku.com';
20
22
  const updateData = [];
21
23
  for (const process of argv) {
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const command_1 = require("@heroku-cli/command");
4
4
  const core_1 = require("@oclif/core");
5
5
  const color_1 = require("@heroku-cli/color");
6
+ const helpers_1 = require("../../lib/container/helpers");
6
7
  class Rm extends command_1.Command {
7
8
  async run() {
8
9
  const { argv, flags } = await this.parse(Rm);
@@ -10,6 +11,8 @@ class Rm extends command_1.Command {
10
11
  if (argv.length === 0) {
11
12
  this.error(`Error: Requires one or more process types\n${Rm.example}`);
12
13
  }
14
+ const { body: appBody } = await this.heroku.get(`/apps/${app}`);
15
+ (0, helpers_1.ensureContainerStack)(appBody, 'rm');
13
16
  for (const process of argv) {
14
17
  core_1.ux.action.start(`Removing container ${process} for ${color_1.default.app(app)}`);
15
18
  await this.heroku.patch(`/apps/${app}/formation/${process}`, {
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const command_1 = require("@heroku-cli/command");
4
4
  const core_1 = require("@oclif/core");
5
5
  const DockerHelper = require("../../lib/container/docker_helper");
6
+ const helpers_1 = require("../../lib/container/helpers");
6
7
  const debug_1 = require("../../lib/container/debug");
7
8
  const color_1 = require("@heroku-cli/color");
8
9
  class Run extends command_1.Command {
@@ -15,6 +16,8 @@ class Run extends command_1.Command {
15
16
  if (verbose) {
16
17
  debug_1.debug.enabled = true;
17
18
  }
19
+ const { body: appBody } = await this.heroku.get(`/apps/${app}`);
20
+ (0, helpers_1.ensureContainerStack)(appBody, 'run');
18
21
  const processType = argv.shift();
19
22
  const command = argv.join(' ');
20
23
  const herokuHost = process.env.HEROKU_HOST || 'heroku.com';
@@ -30,6 +30,6 @@ Transfer.examples = [(0, tsheredoc_1.default)(`
30
30
  Transferring space-name to team-name... done
31
31
  `)];
32
32
  Transfer.flags = {
33
- space: command_1.flags.string({ required: true, description: 'name of space' }),
34
- team: command_1.flags.string({ required: true, description: 'desired owner of space' }),
33
+ space: command_1.flags.string({ required: true, char: 's', description: 'name of space' }),
34
+ team: command_1.flags.string({ required: true, char: 't', description: 'desired owner of space' }),
35
35
  };
@@ -5,7 +5,7 @@ export default class Remove extends Command {
5
5
  static description: string;
6
6
  static examples: string[];
7
7
  static flags: {
8
- space: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
8
+ space: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
9
9
  confirm: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
10
10
  };
11
11
  static args: {
@@ -36,7 +36,7 @@ Remove.examples = [(0, tsheredoc_1.default)(`
36
36
  Removed 192.168.2.0/24 from trusted IP ranges on my-space
37
37
  `)];
38
38
  Remove.flags = {
39
- space: command_1.flags.string({ optional: false, description: 'space to remove rule from' }),
39
+ space: command_1.flags.string({ required: true, char: 's', description: 'space to remove rule from' }),
40
40
  confirm: command_1.flags.string({ description: 'set to space name to bypass confirm prompt' }),
41
41
  };
42
42
  Remove.args = {
@@ -31,7 +31,7 @@ Config.description = (0, tsheredoc_1.default)(`
31
31
  - The VPN Gateway must use the IKE Version shown and the Pre-shared Keys as the authentication method
32
32
  `);
33
33
  Config.example = (0, tsheredoc_1.default)(`
34
- $ heroku spaces:vpn:config --space my-space vpn-connection-name
34
+ $ heroku spaces:vpn:config vpn-connection-name --space my-space
35
35
  === vpn-connection-name VPN Tunnels
36
36
  VPN Tunnel Customer Gateway VPN Gateway Pre-shared Key Routable Subnets IKE Version
37
37
  ────────── ──────────────── ────────────── ────────────── ──────────────── ───────────
@@ -31,7 +31,7 @@ Connect.description = (0, tsheredoc_1.default) `
31
31
  The connection is established over the public Internet but all traffic is encrypted using IPSec.
32
32
  `;
33
33
  Connect.examples = [(0, tsheredoc_1.default) `
34
- $ heroku spaces:vpn:connect --name office --ip 35.161.69.30 --cidrs 172.16.0.0/16,10.0.0.0/24 --space my-space
34
+ $ heroku spaces:vpn:connect vpn-connection-name --ip 35.161.69.30 --cidrs 172.16.0.0/16,10.0.0.0/24 --space my-space
35
35
  Creating VPN Connection in space my-space... done
36
36
  ▸ Use spaces:vpn:wait to track allocation.
37
37
  `];
@@ -41,5 +41,8 @@ Connect.flags = {
41
41
  space: command_1.flags.string({ char: 's', description: 'space name', required: true }),
42
42
  };
43
43
  Connect.args = {
44
- name: core_1.Args.string({ required: true }),
44
+ name: core_1.Args.string({
45
+ required: true,
46
+ description: 'name or id of the VPN connection to create',
47
+ }),
45
48
  };
@@ -31,5 +31,8 @@ Destroy.flags = {
31
31
  confirm: command_1.flags.string({ description: 'set to VPN connection name to bypass confirm prompt', hidden: true }),
32
32
  };
33
33
  Destroy.args = {
34
- name: core_1.Args.string({ description: 'name of the VPN connection to destroy', required: true }),
34
+ name: core_1.Args.string({
35
+ required: true,
36
+ description: 'name or id of the VPN connection to destroy',
37
+ }),
35
38
  };
@@ -52,7 +52,7 @@ exports.default = Info;
52
52
  Info.topic = 'spaces';
53
53
  Info.description = 'display the information for VPN';
54
54
  Info.example = (0, tsheredoc_1.default)(`
55
- $ heroku spaces:vpn:info --space my-space vpn-connection-name
55
+ $ heroku spaces:vpn:info vpn-connection-name --space my-space
56
56
  === vpn-connection-name VPN Tunnel Info
57
57
  Name: vpn-connection-name
58
58
  ID: 123456789012
@@ -28,9 +28,12 @@ Update.flags = {
28
28
  space: command_1.flags.string({ char: 's', description: 'space name', required: true }),
29
29
  };
30
30
  Update.example = (0, tsheredoc_1.default) `
31
- $ heroku spaces:vpn:update office --space my-space --cidrs 172.16.0.0/16,10.0.0.0/24
31
+ $ heroku spaces:vpn:update vpn-connection-name --space my-space --cidrs 172.16.0.0/16,10.0.0.0/24
32
32
  Updating VPN Connection in space my-space... done
33
33
  `;
34
34
  Update.args = {
35
- name: core_1.Args.string({ required: true }),
35
+ name: core_1.Args.string({
36
+ required: true,
37
+ description: 'name or id of the VPN connection to update',
38
+ }),
36
39
  };
@@ -2,12 +2,15 @@ import { Command } from '@heroku-cli/command';
2
2
  export default class Wait extends Command {
3
3
  static topic: string;
4
4
  static description: string;
5
+ static examples: string[];
5
6
  static flags: {
6
7
  space: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
7
- name: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
8
8
  json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
9
9
  interval: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
10
10
  timeout: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
11
11
  };
12
+ static args: {
13
+ name: import("@oclif/core/lib/interfaces/parser").Arg<string, Record<string, unknown>>;
14
+ };
12
15
  run(): Promise<void>;
13
16
  }
@@ -4,13 +4,15 @@ const color_1 = require("@heroku-cli/color");
4
4
  const command_1 = require("@heroku-cli/command");
5
5
  const core_1 = require("@oclif/core");
6
6
  const vpn_connections_1 = require("../../../lib/spaces/vpn-connections");
7
+ const tsheredoc_1 = require("tsheredoc");
7
8
  const wait = (ms) => new Promise(resolve => {
8
9
  setTimeout(resolve, ms);
9
10
  });
10
11
  class Wait extends command_1.Command {
11
12
  async run() {
12
- const { flags } = await this.parse(Wait);
13
- const { name, space, json } = flags;
13
+ const { flags, args } = await this.parse(Wait);
14
+ const { space, json } = flags;
15
+ const { name } = args;
14
16
  const interval = (flags.interval ? Number.parseInt(flags.interval, 10) : 10) * 1000;
15
17
  const timeout = (flags.timeout ? Number.parseInt(flags.timeout, 10) : 20 * 60) * 1000;
16
18
  const deadline = new Date(Date.now() + timeout);
@@ -44,10 +46,25 @@ class Wait extends command_1.Command {
44
46
  exports.default = Wait;
45
47
  Wait.topic = 'spaces';
46
48
  Wait.description = 'wait for VPN Connection to be created';
49
+ Wait.examples = [(0, tsheredoc_1.default) `
50
+ $ heroku spaces:vpn:wait vpn-connection-name --space my-space
51
+ Waiting for VPN Connection vpn-connection-name to allocate... done
52
+ === my-space VPN Tunnels
53
+
54
+ VPN Tunnel Customer Gateway VPN Gateway Pre-shared Key Routable Subnets IKE Version
55
+ ────────── ──────────────── ────────────── ────────────── ──────────────── ───────────
56
+ Tunnel 1 104.196.121.200 35.171.237.136 abcdef12345 10.0.0.0/16 1
57
+ Tunnel 2 104.196.121.200 52.44.7.216 fedcba54321 10.0.0.0/16 1
58
+ `];
47
59
  Wait.flags = {
48
60
  space: command_1.flags.string({ char: 's', description: 'space the vpn connection belongs to', required: true }),
49
- name: command_1.flags.string({ char: 'n', description: 'name or id of the vpn connection to wait for', required: true }),
50
61
  json: command_1.flags.boolean({ description: 'output in json format' }),
51
62
  interval: command_1.flags.string({ char: 'i', description: 'seconds to wait between poll intervals' }),
52
63
  timeout: command_1.flags.string({ char: 't', description: 'maximum number of seconds to wait' }),
53
64
  };
65
+ Wait.args = {
66
+ name: core_1.Args.string({
67
+ description: 'name or id of the VPN connection you are waiting on for allocation.',
68
+ required: true,
69
+ }),
70
+ };
@@ -0,0 +1,8 @@
1
+ import * as Heroku from '@heroku-cli/schema';
2
+ /**
3
+ * Ensure that the given app is a container app.
4
+ * @param app {Heroku.App} heroku app
5
+ * @param cmd {String} command name
6
+ * @returns {null} null
7
+ */
8
+ export declare function ensureContainerStack(app: Heroku.App, cmd: string): void;
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ensureContainerStack = void 0;
4
+ const color_1 = require("@heroku-cli/color");
5
+ const core_1 = require("@oclif/core");
6
+ const stackLabelMap = {
7
+ cnb: 'Cloud Native Buildpack',
8
+ };
9
+ /**
10
+ * Ensure that the given app is a container app.
11
+ * @param app {Heroku.App} heroku app
12
+ * @param cmd {String} command name
13
+ * @returns {null} null
14
+ */
15
+ function ensureContainerStack(app, cmd) {
16
+ var _a, _b, _c;
17
+ if (((_a = app.stack) === null || _a === void 0 ? void 0 : _a.name) !== 'container') {
18
+ const appLabel = (((_b = app.stack) === null || _b === void 0 ? void 0 : _b.name) && stackLabelMap[app.stack.name]) || ((_c = app.stack) === null || _c === void 0 ? void 0 : _c.name);
19
+ let message = 'This command is for Docker apps only.';
20
+ if (['push', 'release'].includes(cmd)) {
21
+ message += ` Run ${color_1.default.cyan('git push heroku main')} to deploy your ${color_1.default.cyan(app.name)} ${color_1.default.cyan(appLabel)} app instead.`;
22
+ }
23
+ core_1.ux.error(message, { exit: 1 });
24
+ }
25
+ }
26
+ exports.ensureContainerStack = ensureContainerStack;
@@ -44,11 +44,11 @@ class Git {
44
44
  return `https://${command_1.vars.httpGitHost}/${app}.git`;
45
45
  }
46
46
  async remoteUrl(name) {
47
+ var _a, _b, _c;
47
48
  const remotes = await this.exec(['remote', '-v']);
48
- return remotes.split('\n')
49
+ return (_c = (_b = (_a = remotes.split('\n')
49
50
  .map(r => r.split('\t'))
50
- .find(r => r[0] === name)[1]
51
- .split(' ')[0];
51
+ .find(r => r[0] === name)) === null || _a === void 0 ? void 0 : _a[1]) === null || _b === void 0 ? void 0 : _b.split(' ')[0]) !== null && _c !== void 0 ? _c : '';
52
52
  }
53
53
  url(app) {
54
54
  return this.httpGitUrl(app);
@@ -561,7 +561,8 @@
561
561
  "required": true
562
562
  }
563
563
  },
564
- "description": "create a new add-on resource",
564
+ "description": "Create a new add-on resource.\n\nIn order to add additional config items, please place them at the end of the command after a double-dash (--).\n",
565
+ "examples": "Create an add-on resource:\n$heroku addons:create heroku-redis --app my-app\n\nCreate an add-on resource with additional config items:\n$heroku addons:create heroku-postgresql:standard-0 --app my-app -- --fork DATABASE\n",
565
566
  "flags": {
566
567
  "name": {
567
568
  "description": "name for the add-on resource",
@@ -618,6 +619,7 @@
618
619
  "pluginType": "core",
619
620
  "strict": false,
620
621
  "topic": "addons",
622
+ "example": "Create an add-on resource:\n$heroku addons:create heroku-redis --app my-app\n\nCreate an add-on resource with additional config items:\n$heroku addons:create heroku-postgresql:standard-0 --app my-app -- --fork DATABASE\n",
621
623
  "isESM": false,
622
624
  "relativePath": [
623
625
  "lib",
@@ -9657,6 +9659,7 @@
9657
9659
  ],
9658
9660
  "flags": {
9659
9661
  "space": {
9662
+ "char": "s",
9660
9663
  "description": "name of space",
9661
9664
  "name": "space",
9662
9665
  "required": true,
@@ -9665,6 +9668,7 @@
9665
9668
  "type": "option"
9666
9669
  },
9667
9670
  "team": {
9671
+ "char": "t",
9668
9672
  "description": "desired owner of space",
9669
9673
  "name": "team",
9670
9674
  "required": true,
@@ -10610,7 +10614,6 @@
10610
10614
  "char": "a",
10611
10615
  "description": "app to run command against",
10612
10616
  "name": "app",
10613
- "required": false,
10614
10617
  "hasDynamicHelp": false,
10615
10618
  "multiple": false,
10616
10619
  "type": "option"
@@ -10627,7 +10630,6 @@
10627
10630
  "char": "p",
10628
10631
  "description": "name of pipeline",
10629
10632
  "name": "pipeline",
10630
- "required": false,
10631
10633
  "hasDynamicHelp": false,
10632
10634
  "multiple": false,
10633
10635
  "type": "option"
@@ -10667,12 +10669,20 @@
10667
10669
  "flags": {
10668
10670
  "app": {
10669
10671
  "char": "a",
10670
- "description": "app name",
10672
+ "description": "app to run command against",
10671
10673
  "name": "app",
10672
10674
  "hasDynamicHelp": false,
10673
10675
  "multiple": false,
10674
10676
  "type": "option"
10675
10677
  },
10678
+ "remote": {
10679
+ "char": "r",
10680
+ "description": "git remote of app to use",
10681
+ "name": "remote",
10682
+ "hasDynamicHelp": false,
10683
+ "multiple": false,
10684
+ "type": "option"
10685
+ },
10676
10686
  "shell": {
10677
10687
  "char": "s",
10678
10688
  "description": "output config vars in shell format",
@@ -10739,7 +10749,6 @@
10739
10749
  "char": "p",
10740
10750
  "description": "name of pipeline",
10741
10751
  "name": "pipeline",
10742
- "required": true,
10743
10752
  "hasDynamicHelp": false,
10744
10753
  "multiple": false,
10745
10754
  "type": "option"
@@ -10770,18 +10779,10 @@
10770
10779
  "$ heroku ci:config:unset RAILS_ENV"
10771
10780
  ],
10772
10781
  "flags": {
10773
- "help": {
10774
- "char": "h",
10775
- "description": "Show CLI help.",
10776
- "name": "help",
10777
- "allowNo": false,
10778
- "type": "boolean"
10779
- },
10780
10782
  "app": {
10781
10783
  "char": "a",
10782
10784
  "description": "app to run command against",
10783
10785
  "name": "app",
10784
- "required": false,
10785
10786
  "hasDynamicHelp": false,
10786
10787
  "multiple": false,
10787
10788
  "type": "option"
@@ -10798,7 +10799,6 @@
10798
10799
  "char": "p",
10799
10800
  "description": "name of pipeline",
10800
10801
  "name": "pipeline",
10801
- "required": false,
10802
10802
  "hasDynamicHelp": false,
10803
10803
  "multiple": false,
10804
10804
  "type": "option"
@@ -12574,169 +12574,6 @@
12574
12574
  "set.js"
12575
12575
  ]
12576
12576
  },
12577
- "spaces:outbound-rules:add": {
12578
- "aliases": [
12579
- "outbound-rules:add"
12580
- ],
12581
- "args": {},
12582
- "description": "Add outbound rules to a Private Space\n\nThe destination flag uses CIDR notation.\n\nICMP Rules\nThe ICMP protocol has types, not ports, but the underlying systems treat them as the same. For this reason,\nwhen you want to allow ICMP traffic you will use the --port flag to specify the ICMP types you want to\nallow. ICMP types are numbered, 0-255.\n",
12583
- "examples": [
12584
- "$ heroku outbound-rules:add --space my-space --dest 192.168.2.0/24 --protocol tcp --port 80\nAdding rule to the Outbound Rules of my-space... done\n",
12585
- "# with port range:\n$ heroku outbound-rules:add --space my-space --dest 192.168.2.0/24 --protocol tcp --port 80-100\nAdding rule to the Outbound Rules of my-space... done\n",
12586
- "# opening up everything\n$ heroku outbound-rules:add --space my-space --dest 0.0.0.0/0 --protocol any --port any\nAdding rule to the Outbound Rules of my-space... done\n"
12587
- ],
12588
- "flags": {
12589
- "space": {
12590
- "char": "s",
12591
- "description": "space to add rule to",
12592
- "name": "space",
12593
- "required": true,
12594
- "hasDynamicHelp": false,
12595
- "multiple": false,
12596
- "type": "option"
12597
- },
12598
- "dest": {
12599
- "description": "target CIDR block dynos are allowed to communicate with",
12600
- "name": "dest",
12601
- "required": true,
12602
- "hasDynamicHelp": false,
12603
- "multiple": false,
12604
- "type": "option"
12605
- },
12606
- "protocol": {
12607
- "description": "the protocol dynos are allowed to use when communicating with hosts in destination CIDR block.",
12608
- "name": "protocol",
12609
- "required": true,
12610
- "hasDynamicHelp": false,
12611
- "multiple": false,
12612
- "options": [
12613
- "tcp",
12614
- "udp",
12615
- "icmp",
12616
- "0-255",
12617
- "any"
12618
- ],
12619
- "type": "option"
12620
- },
12621
- "port": {
12622
- "description": "the port dynos are allowed to use when communicating with hosts in destination CIDR block. Accepts a range in `<lowest port>-<highest port>` format. 0 is the minimum. The maximum port allowed is 65535, except for ICMP with a maximum of 255.",
12623
- "name": "port",
12624
- "hasDynamicHelp": false,
12625
- "multiple": false,
12626
- "type": "option"
12627
- }
12628
- },
12629
- "hasDynamicHelp": false,
12630
- "hidden": true,
12631
- "hiddenAliases": [],
12632
- "id": "spaces:outbound-rules:add",
12633
- "pluginAlias": "heroku",
12634
- "pluginName": "heroku",
12635
- "pluginType": "core",
12636
- "strict": true,
12637
- "topic": "spaces",
12638
- "isESM": false,
12639
- "relativePath": [
12640
- "lib",
12641
- "commands",
12642
- "spaces",
12643
- "outbound-rules",
12644
- "add.js"
12645
- ]
12646
- },
12647
- "spaces:outbound-rules": {
12648
- "aliases": [
12649
- "outbound-rules"
12650
- ],
12651
- "args": {
12652
- "space": {
12653
- "hidden": true,
12654
- "name": "space"
12655
- }
12656
- },
12657
- "description": "list Outbound Rules for a space\nOutbound Rules are only available on Private Spaces.\n\nNewly created spaces will have an \"Allow All\" rule set by default\nallowing all egress dyno traffic outside of the space. You can\nremove this default rule to completely stop your private dynos from\ntalking to the world.\n\nYou can add specific rules that only allow your dyno to communicate with trusted hosts.\n",
12658
- "flags": {
12659
- "space": {
12660
- "char": "s",
12661
- "description": "space to get outbound rules from",
12662
- "name": "space",
12663
- "hasDynamicHelp": false,
12664
- "multiple": false,
12665
- "type": "option"
12666
- },
12667
- "json": {
12668
- "description": "output in json format",
12669
- "name": "json",
12670
- "allowNo": false,
12671
- "type": "boolean"
12672
- }
12673
- },
12674
- "hasDynamicHelp": false,
12675
- "hidden": true,
12676
- "hiddenAliases": [],
12677
- "id": "spaces:outbound-rules",
12678
- "pluginAlias": "heroku",
12679
- "pluginName": "heroku",
12680
- "pluginType": "core",
12681
- "strict": true,
12682
- "topic": "spaces",
12683
- "isESM": false,
12684
- "relativePath": [
12685
- "lib",
12686
- "commands",
12687
- "spaces",
12688
- "outbound-rules",
12689
- "index.js"
12690
- ]
12691
- },
12692
- "spaces:outbound-rules:remove": {
12693
- "aliases": [
12694
- "outbound-rules:remove"
12695
- ],
12696
- "args": {
12697
- "ruleNumber": {
12698
- "name": "ruleNumber",
12699
- "required": true
12700
- }
12701
- },
12702
- "description": "Remove a Rules from the list of Outbound Rules",
12703
- "examples": [
12704
- "$ heroku outbound-rules:remove --space my-space 4\n Removed 192.168.2.0/24 from trusted IP ranges on my-space\n"
12705
- ],
12706
- "flags": {
12707
- "space": {
12708
- "description": "space to remove rule from",
12709
- "name": "space",
12710
- "hasDynamicHelp": false,
12711
- "multiple": false,
12712
- "type": "option"
12713
- },
12714
- "confirm": {
12715
- "description": "set to space name to bypass confirm prompt",
12716
- "name": "confirm",
12717
- "hasDynamicHelp": false,
12718
- "multiple": false,
12719
- "type": "option"
12720
- }
12721
- },
12722
- "hasDynamicHelp": false,
12723
- "hidden": true,
12724
- "hiddenAliases": [],
12725
- "id": "spaces:outbound-rules:remove",
12726
- "pluginAlias": "heroku",
12727
- "pluginName": "heroku",
12728
- "pluginType": "core",
12729
- "strict": true,
12730
- "topic": "spaces",
12731
- "isESM": false,
12732
- "relativePath": [
12733
- "lib",
12734
- "commands",
12735
- "spaces",
12736
- "outbound-rules",
12737
- "remove.js"
12738
- ]
12739
- },
12740
12577
  "spaces:peerings:accept": {
12741
12578
  "aliases": [],
12742
12579
  "args": {
@@ -13038,8 +12875,10 @@
13038
12875
  ],
13039
12876
  "flags": {
13040
12877
  "space": {
12878
+ "char": "s",
13041
12879
  "description": "space to remove rule from",
13042
12880
  "name": "space",
12881
+ "required": true,
13043
12882
  "hasDynamicHelp": false,
13044
12883
  "multiple": false,
13045
12884
  "type": "option"
@@ -13081,7 +12920,7 @@
13081
12920
  }
13082
12921
  },
13083
12922
  "description": "display the configuration information for VPN\n\nYou will use the information provided by this command to establish a Private Space VPN Connection.\n\n- You must configure your VPN Gateway to use both Tunnels provided by Heroku\n- The VPN Gateway values are the IP addresses of the Private Space Tunnels\n- The Customer Gateway value is the Public IP of your VPN Gateway\n- The VPN Gateway must use the IKE Version shown and the Pre-shared Keys as the authentication method\n",
13084
- "examples": "$ heroku spaces:vpn:config --space my-space vpn-connection-name\n=== vpn-connection-name VPN Tunnels\n VPN Tunnel Customer Gateway VPN Gateway Pre-shared Key Routable Subnets IKE Version\n ────────── ──────────────── ────────────── ────────────── ──────────────── ───────────\n Tunnel 1 104.196.121.200 35.171.237.136 abcdef12345 10.0.0.0/16 1\n Tunnel 2 104.196.121.200 52.44.7.216 fedcba54321 10.0.0.0/16 1\n",
12923
+ "examples": "$ heroku spaces:vpn:config vpn-connection-name --space my-space\n=== vpn-connection-name VPN Tunnels\n VPN Tunnel Customer Gateway VPN Gateway Pre-shared Key Routable Subnets IKE Version\n ────────── ──────────────── ────────────── ────────────── ──────────────── ───────────\n Tunnel 1 104.196.121.200 35.171.237.136 abcdef12345 10.0.0.0/16 1\n Tunnel 2 104.196.121.200 52.44.7.216 fedcba54321 10.0.0.0/16 1\n",
13085
12924
  "flags": {
13086
12925
  "space": {
13087
12926
  "char": "s",
@@ -13107,7 +12946,7 @@
13107
12946
  "pluginType": "core",
13108
12947
  "strict": true,
13109
12948
  "topic": "spaces",
13110
- "example": "$ heroku spaces:vpn:config --space my-space vpn-connection-name\n=== vpn-connection-name VPN Tunnels\n VPN Tunnel Customer Gateway VPN Gateway Pre-shared Key Routable Subnets IKE Version\n ────────── ──────────────── ────────────── ────────────── ──────────────── ───────────\n Tunnel 1 104.196.121.200 35.171.237.136 abcdef12345 10.0.0.0/16 1\n Tunnel 2 104.196.121.200 52.44.7.216 fedcba54321 10.0.0.0/16 1\n",
12949
+ "example": "$ heroku spaces:vpn:config vpn-connection-name --space my-space\n=== vpn-connection-name VPN Tunnels\n VPN Tunnel Customer Gateway VPN Gateway Pre-shared Key Routable Subnets IKE Version\n ────────── ──────────────── ────────────── ────────────── ──────────────── ───────────\n Tunnel 1 104.196.121.200 35.171.237.136 abcdef12345 10.0.0.0/16 1\n Tunnel 2 104.196.121.200 52.44.7.216 fedcba54321 10.0.0.0/16 1\n",
13111
12950
  "isESM": false,
13112
12951
  "relativePath": [
13113
12952
  "lib",
@@ -13121,13 +12960,14 @@
13121
12960
  "aliases": [],
13122
12961
  "args": {
13123
12962
  "name": {
12963
+ "description": "name or id of the VPN connection to create",
13124
12964
  "name": "name",
13125
12965
  "required": true
13126
12966
  }
13127
12967
  },
13128
12968
  "description": "create VPN\nPrivate Spaces can be connected to another private network via an IPSec VPN connection allowing dynos to connect to hosts on your private networks and vice versa.\nThe connection is established over the public Internet but all traffic is encrypted using IPSec.\n",
13129
12969
  "examples": [
13130
- "$ heroku spaces:vpn:connect --name office --ip 35.161.69.30 --cidrs 172.16.0.0/16,10.0.0.0/24 --space my-space\nCreating VPN Connection in space my-space... done\n▸ Use spaces:vpn:wait to track allocation.\n"
12970
+ "$ heroku spaces:vpn:connect vpn-connection-name --ip 35.161.69.30 --cidrs 172.16.0.0/16,10.0.0.0/24 --space my-space\nCreating VPN Connection in space my-space... done\n▸ Use spaces:vpn:wait to track allocation.\n"
13131
12971
  ],
13132
12972
  "flags": {
13133
12973
  "ip": {
@@ -13219,7 +13059,7 @@
13219
13059
  "aliases": [],
13220
13060
  "args": {
13221
13061
  "name": {
13222
- "description": "name of the VPN connection to destroy",
13062
+ "description": "name or id of the VPN connection to destroy",
13223
13063
  "name": "name",
13224
13064
  "required": true
13225
13065
  }
@@ -13274,7 +13114,7 @@
13274
13114
  }
13275
13115
  },
13276
13116
  "description": "display the information for VPN",
13277
- "examples": "$ heroku spaces:vpn:info --space my-space vpn-connection-name\n=== vpn-connection-name VPN Tunnel Info\nName: vpn-connection-name\nID: 123456789012\nPublic IP: 35.161.69.30\nRoutable CIDRs: 172.16.0.0/16\nStatus: failed\nStatus Message: supplied CIDR block already in use\n=== my-space Tunnel Info\n VPN Tunnel IP Address Status Last Changed Details\n ────────── ───────────── ────── ──────────────────── ─────────────\n Tunnel 1 52.44.146.197 UP 2016-10-25T22:09:05Z status message\n Tunnel 2 52.44.146.197 UP 2016-10-25T22:09:05Z status message\n",
13117
+ "examples": "$ heroku spaces:vpn:info vpn-connection-name --space my-space\n=== vpn-connection-name VPN Tunnel Info\nName: vpn-connection-name\nID: 123456789012\nPublic IP: 35.161.69.30\nRoutable CIDRs: 172.16.0.0/16\nStatus: failed\nStatus Message: supplied CIDR block already in use\n=== my-space Tunnel Info\n VPN Tunnel IP Address Status Last Changed Details\n ────────── ───────────── ────── ──────────────────── ─────────────\n Tunnel 1 52.44.146.197 UP 2016-10-25T22:09:05Z status message\n Tunnel 2 52.44.146.197 UP 2016-10-25T22:09:05Z status message\n",
13278
13118
  "flags": {
13279
13119
  "space": {
13280
13120
  "char": "s",
@@ -13300,7 +13140,7 @@
13300
13140
  "pluginType": "core",
13301
13141
  "strict": true,
13302
13142
  "topic": "spaces",
13303
- "example": "$ heroku spaces:vpn:info --space my-space vpn-connection-name\n=== vpn-connection-name VPN Tunnel Info\nName: vpn-connection-name\nID: 123456789012\nPublic IP: 35.161.69.30\nRoutable CIDRs: 172.16.0.0/16\nStatus: failed\nStatus Message: supplied CIDR block already in use\n=== my-space Tunnel Info\n VPN Tunnel IP Address Status Last Changed Details\n ────────── ───────────── ────── ──────────────────── ─────────────\n Tunnel 1 52.44.146.197 UP 2016-10-25T22:09:05Z status message\n Tunnel 2 52.44.146.197 UP 2016-10-25T22:09:05Z status message\n",
13143
+ "example": "$ heroku spaces:vpn:info vpn-connection-name --space my-space\n=== vpn-connection-name VPN Tunnel Info\nName: vpn-connection-name\nID: 123456789012\nPublic IP: 35.161.69.30\nRoutable CIDRs: 172.16.0.0/16\nStatus: failed\nStatus Message: supplied CIDR block already in use\n=== my-space Tunnel Info\n VPN Tunnel IP Address Status Last Changed Details\n ────────── ───────────── ────── ──────────────────── ─────────────\n Tunnel 1 52.44.146.197 UP 2016-10-25T22:09:05Z status message\n Tunnel 2 52.44.146.197 UP 2016-10-25T22:09:05Z status message\n",
13304
13144
  "isESM": false,
13305
13145
  "relativePath": [
13306
13146
  "lib",
@@ -13314,12 +13154,13 @@
13314
13154
  "aliases": [],
13315
13155
  "args": {
13316
13156
  "name": {
13157
+ "description": "name or id of the VPN connection to update",
13317
13158
  "name": "name",
13318
13159
  "required": true
13319
13160
  }
13320
13161
  },
13321
13162
  "description": "update VPN\nPrivate Spaces can be connected to another private network via an IPSec VPN connection allowing dynos to connect to hosts on your private networks and vice versa.\nThe connection is established over the public Internet but all traffic is encrypted using IPSec.\n",
13322
- "examples": "$ heroku spaces:vpn:update office --space my-space --cidrs 172.16.0.0/16,10.0.0.0/24\nUpdating VPN Connection in space my-space... done\n",
13163
+ "examples": "$ heroku spaces:vpn:update vpn-connection-name --space my-space --cidrs 172.16.0.0/16,10.0.0.0/24\nUpdating VPN Connection in space my-space... done\n",
13323
13164
  "flags": {
13324
13165
  "cidrs": {
13325
13166
  "char": "c",
@@ -13348,7 +13189,7 @@
13348
13189
  "pluginType": "core",
13349
13190
  "strict": true,
13350
13191
  "topic": "spaces",
13351
- "example": "$ heroku spaces:vpn:update office --space my-space --cidrs 172.16.0.0/16,10.0.0.0/24\nUpdating VPN Connection in space my-space... done\n",
13192
+ "example": "$ heroku spaces:vpn:update vpn-connection-name --space my-space --cidrs 172.16.0.0/16,10.0.0.0/24\nUpdating VPN Connection in space my-space... done\n",
13352
13193
  "isESM": false,
13353
13194
  "relativePath": [
13354
13195
  "lib",
@@ -13360,8 +13201,17 @@
13360
13201
  },
13361
13202
  "spaces:vpn:wait": {
13362
13203
  "aliases": [],
13363
- "args": {},
13204
+ "args": {
13205
+ "name": {
13206
+ "description": "name or id of the VPN connection you are waiting on for allocation.",
13207
+ "name": "name",
13208
+ "required": true
13209
+ }
13210
+ },
13364
13211
  "description": "wait for VPN Connection to be created",
13212
+ "examples": [
13213
+ " $ heroku spaces:vpn:wait vpn-connection-name --space my-space\n Waiting for VPN Connection vpn-connection-name to allocate... done\n === my-space VPN Tunnels\n\nVPN Tunnel Customer Gateway VPN Gateway Pre-shared Key Routable Subnets IKE Version\n────────── ──────────────── ────────────── ────────────── ──────────────── ───────────\nTunnel 1 104.196.121.200 35.171.237.136 abcdef12345 10.0.0.0/16 1\nTunnel 2 104.196.121.200 52.44.7.216 fedcba54321 10.0.0.0/16 1\n"
13214
+ ],
13365
13215
  "flags": {
13366
13216
  "space": {
13367
13217
  "char": "s",
@@ -13372,15 +13222,6 @@
13372
13222
  "multiple": false,
13373
13223
  "type": "option"
13374
13224
  },
13375
- "name": {
13376
- "char": "n",
13377
- "description": "name or id of the vpn connection to wait for",
13378
- "name": "name",
13379
- "required": true,
13380
- "hasDynamicHelp": false,
13381
- "multiple": false,
13382
- "type": "option"
13383
- },
13384
13225
  "json": {
13385
13226
  "description": "output in json format",
13386
13227
  "name": "json",
@@ -13922,5 +13763,5 @@
13922
13763
  ]
13923
13764
  }
13924
13765
  },
13925
- "version": "9.0.0-alpha.3"
13766
+ "version": "9.0.0-beta.0"
13926
13767
  }
package/package.json CHANGED
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "name": "heroku",
3
3
  "description": "CLI to interact with Heroku",
4
- "version": "9.0.0-alpha.3",
4
+ "version": "9.0.0-beta.0",
5
5
  "author": "Jeff Dickey @jdxcode",
6
6
  "bin": "./bin/run",
7
7
  "bugs": "https://github.com/heroku/cli/issues",
8
8
  "dependencies": {
9
9
  "@heroku-cli/color": "2.0.1",
10
- "@heroku-cli/command": "^11.0.0",
10
+ "@heroku-cli/command": "^11.1.2",
11
11
  "@heroku-cli/notifications": "^1.2.4",
12
12
  "@heroku-cli/plugin-ps": "^8.1.7",
13
13
  "@heroku-cli/plugin-ps-exec": "^2.4.0",
@@ -43,7 +43,7 @@
43
43
  "debug": "4.3.4",
44
44
  "edit-string": "^1.1.6",
45
45
  "execa": "5.1.1",
46
- "filesize": "^4.0.0",
46
+ "filesize": "^10.1.2",
47
47
  "foreman": "^3.0.1",
48
48
  "fs-extra": "7.0.1",
49
49
  "github-url-to-object": "^4.0.4",
@@ -272,10 +272,6 @@
272
272
  "orgs": {
273
273
  "description": "manage organizations"
274
274
  },
275
- "outbound-rules": {
276
- "description": "space outbound IP rules",
277
- "hidden": true
278
- },
279
275
  "pg": {
280
276
  "description": "manage postgresql databases"
281
277
  },
@@ -391,5 +387,5 @@
391
387
  "version": "oclif readme --multi && git add README.md ../../docs"
392
388
  },
393
389
  "types": "lib/index.d.ts",
394
- "gitHead": "80a96b32a9083b3f9282d96f9b621af7080cd16d"
390
+ "gitHead": "db0a509cf875e88463ea55754ab863c8331068a2"
395
391
  }
@@ -1,15 +0,0 @@
1
- import { Command } from '@heroku-cli/command';
2
- export default class Add extends Command {
3
- static topic: string;
4
- static aliases: string[];
5
- static description: string;
6
- static examples: string[];
7
- static hidden: boolean;
8
- static flags: {
9
- space: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
10
- dest: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
11
- protocol: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
12
- port: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
13
- };
14
- run(): Promise<void>;
15
- }
@@ -1,81 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const command_1 = require("@heroku-cli/command");
4
- const color_1 = require("@heroku-cli/color");
5
- const core_1 = require("@oclif/core");
6
- const tsheredoc_1 = require("tsheredoc");
7
- const outbound_rules_1 = require("../../../lib/spaces/outbound-rules");
8
- const completions_1 = require("@heroku-cli/command/lib/completions");
9
- const completions_2 = require("../../../lib/autocomplete/completions");
10
- class Add extends command_1.Command {
11
- async run() {
12
- const { flags } = await this.parse(Add);
13
- const { space, dest, protocol, port } = flags;
14
- const { body: ruleset } = await this.heroku.get(`/spaces/${space}/outbound-ruleset`, {
15
- headers: { Accept: 'application/vnd.heroku+json; version=3.dogwood' },
16
- });
17
- ruleset.rules = ruleset.rules || [];
18
- const ports = (0, outbound_rules_1.parsePorts)(protocol, port);
19
- ruleset.rules.push({
20
- target: dest, from_port: ports[0], to_port: ports[1] || ports[0], protocol: protocol,
21
- });
22
- core_1.ux.action.start(`Adding rule to the Outbound Rules of ${color_1.default.cyan.bold(space)}`);
23
- await this.heroku.put(`/spaces/${space}/outbound-ruleset`, {
24
- headers: { Accept: 'application/vnd.heroku+json; version=3.dogwood' },
25
- body: ruleset,
26
- });
27
- core_1.ux.action.stop();
28
- core_1.ux.warn('Modifying the Outbound Rules may break Add-ons for Apps in this Private Space');
29
- }
30
- }
31
- exports.default = Add;
32
- Add.topic = 'spaces';
33
- Add.aliases = ['outbound-rules:add'];
34
- Add.description = (0, tsheredoc_1.default)(`
35
- Add outbound rules to a Private Space
36
-
37
- The destination flag uses CIDR notation.
38
-
39
- ICMP Rules
40
- The ICMP protocol has types, not ports, but the underlying systems treat them as the same. For this reason,
41
- when you want to allow ICMP traffic you will use the --port flag to specify the ICMP types you want to
42
- allow. ICMP types are numbered, 0-255.
43
- `);
44
- Add.examples = [
45
- (0, tsheredoc_1.default)(`
46
- $ heroku outbound-rules:add --space my-space --dest 192.168.2.0/24 --protocol tcp --port 80
47
- Adding rule to the Outbound Rules of my-space... done
48
- `),
49
- (0, tsheredoc_1.default)(`
50
- # with port range:
51
- $ heroku outbound-rules:add --space my-space --dest 192.168.2.0/24 --protocol tcp --port 80-100
52
- Adding rule to the Outbound Rules of my-space... done
53
- `),
54
- (0, tsheredoc_1.default)(`
55
- # opening up everything
56
- $ heroku outbound-rules:add --space my-space --dest 0.0.0.0/0 --protocol any --port any
57
- Adding rule to the Outbound Rules of my-space... done
58
- `),
59
- ];
60
- Add.hidden = true;
61
- Add.flags = {
62
- space: command_1.flags.string({
63
- char: 's',
64
- description: 'space to add rule to',
65
- required: true,
66
- completion: completions_1.SpaceCompletion,
67
- }),
68
- dest: command_1.flags.string({
69
- description: 'target CIDR block dynos are allowed to communicate with',
70
- required: true,
71
- }),
72
- protocol: command_1.flags.string({
73
- description: 'the protocol dynos are allowed to use when communicating with hosts in destination CIDR block.',
74
- completion: completions_2.ProtocolCompletion,
75
- options: ['tcp', 'udp', 'icmp', '0-255', 'any'],
76
- required: true,
77
- }),
78
- port: command_1.flags.string({
79
- description: 'the port dynos are allowed to use when communicating with hosts in destination CIDR block. Accepts a range in `<lowest port>-<highest port>` format. 0 is the minimum. The maximum port allowed is 65535, except for ICMP with a maximum of 255.',
80
- }),
81
- };
@@ -1,15 +0,0 @@
1
- import { Command } from '@heroku-cli/command';
2
- export default class Index extends Command {
3
- static topic: string;
4
- static aliases: string[];
5
- static description: string;
6
- static hidden: boolean;
7
- static flags: {
8
- space: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
9
- json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
10
- };
11
- static args: {
12
- space: import("@oclif/core/lib/interfaces/parser").Arg<string | undefined, Record<string, unknown>>;
13
- };
14
- run(): Promise<void>;
15
- }
@@ -1,49 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const command_1 = require("@heroku-cli/command");
4
- const core_1 = require("@oclif/core");
5
- const tsheredoc_1 = require("tsheredoc");
6
- const outbound_rules_1 = require("../../../lib/spaces/outbound-rules");
7
- const completions_1 = require("@heroku-cli/command/lib/completions");
8
- class Index extends command_1.Command {
9
- async run() {
10
- const { flags, args } = await this.parse(Index);
11
- const spaceName = flags.space || args.space;
12
- if (!spaceName) {
13
- core_1.ux.error((0, tsheredoc_1.default)(`
14
- Error: Missing 1 required arg:
15
- space
16
- See more help with --help
17
- `));
18
- }
19
- const { body: ruleset } = await this.heroku.get(`/spaces/${spaceName}/outbound-ruleset`, {
20
- headers: { Accept: 'application/vnd.heroku+json; version=3.dogwood' },
21
- });
22
- if (flags.json)
23
- (0, outbound_rules_1.displayRulesAsJSON)(ruleset);
24
- else
25
- (0, outbound_rules_1.displayRules)(spaceName, ruleset);
26
- }
27
- }
28
- exports.default = Index;
29
- Index.topic = 'spaces';
30
- Index.aliases = ['outbound-rules'];
31
- Index.description = (0, tsheredoc_1.default)(`
32
- list Outbound Rules for a space
33
- Outbound Rules are only available on Private Spaces.
34
-
35
- Newly created spaces will have an "Allow All" rule set by default
36
- allowing all egress dyno traffic outside of the space. You can
37
- remove this default rule to completely stop your private dynos from
38
- talking to the world.
39
-
40
- You can add specific rules that only allow your dyno to communicate with trusted hosts.
41
- `);
42
- Index.hidden = true;
43
- Index.flags = {
44
- space: command_1.flags.string({ char: 's', description: 'space to get outbound rules from', completion: completions_1.SpaceCompletion }),
45
- json: command_1.flags.boolean({ description: 'output in json format' }),
46
- };
47
- Index.args = {
48
- space: core_1.Args.string({ hidden: true }),
49
- };
@@ -1,17 +0,0 @@
1
- import { Command } from '@heroku-cli/command';
2
- export default class Remove extends Command {
3
- static topic: string;
4
- static aliases: string[];
5
- static description: string;
6
- static examples: string[];
7
- static hidden: boolean;
8
- static flags: {
9
- space: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
10
- confirm: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
11
- };
12
- static args: {
13
- ruleNumber: import("@oclif/core/lib/interfaces/parser").Arg<string, Record<string, unknown>>;
14
- };
15
- private clientOptions;
16
- run(): Promise<void>;
17
- }
@@ -1,53 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const color_1 = require("@heroku-cli/color");
4
- const command_1 = require("@heroku-cli/command");
5
- const core_1 = require("@oclif/core");
6
- const tsheredoc_1 = require("tsheredoc");
7
- const confirmCommand_1 = require("../../../lib/confirmCommand");
8
- class Remove extends command_1.Command {
9
- constructor() {
10
- super(...arguments);
11
- this.clientOptions = {
12
- headers: { Accept: 'application/vnd.heroku+json; version=3.dogwood' },
13
- };
14
- }
15
- async run() {
16
- var _a;
17
- const { flags, args } = await this.parse(Remove);
18
- const space = flags.space;
19
- if (!space)
20
- throw new Error('Space name required.');
21
- const { body: ruleset } = await this.heroku.get(`/spaces/${space}/outbound-ruleset`, this.clientOptions);
22
- if (!((_a = ruleset.rules) === null || _a === void 0 ? void 0 : _a.length)) {
23
- throw new Error('No Outbound Rules configured. Nothing to do.');
24
- }
25
- const deleted = ruleset.rules.splice(Number.parseInt(args.ruleNumber, 10) - 1, 1)[0];
26
- await (0, confirmCommand_1.default)(space, flags.confirm, (0, tsheredoc_1.default)(`
27
- Destructive Action
28
- This will remove:
29
- Destination: ${deleted.target}, From Port: ${deleted.from_port}, To Port: ${deleted.to_port}, Protocol ${deleted.protocol}
30
- from the Outbound Rules on ${color_1.default.cyan.bold(space)}
31
- `));
32
- const opts = Object.assign(Object.assign({}, this.clientOptions), { body: ruleset });
33
- await this.heroku.put(`/spaces/${space}/outbound-ruleset`, opts);
34
- core_1.ux.log(`Removed Rule ${color_1.default.cyan.bold(args.ruleNumber)} from Outbound Rules on ${color_1.default.cyan.bold(space)}`);
35
- core_1.ux.warn('It may take a few moments for the changes to take effect.');
36
- }
37
- }
38
- exports.default = Remove;
39
- Remove.topic = 'spaces';
40
- Remove.aliases = ['outbound-rules:remove'];
41
- Remove.description = 'Remove a Rules from the list of Outbound Rules';
42
- Remove.examples = [(0, tsheredoc_1.default)(`
43
- $ heroku outbound-rules:remove --space my-space 4
44
- Removed 192.168.2.0/24 from trusted IP ranges on my-space
45
- `)];
46
- Remove.hidden = true;
47
- Remove.flags = {
48
- space: command_1.flags.string({ optional: false, description: 'space to remove rule from' }),
49
- confirm: command_1.flags.string({ description: 'set to space name to bypass confirm prompt' }),
50
- };
51
- Remove.args = {
52
- ruleNumber: core_1.Args.string({ required: true }),
53
- };