@heroku-cli/heroku-connect-plugin 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.md +206 -0
- package/README.md +93 -0
- package/commands/connect/db-set.js +69 -0
- package/commands/connect/diagnose.js +108 -0
- package/commands/connect/export.js +35 -0
- package/commands/connect/import.js +30 -0
- package/commands/connect/info.js +55 -0
- package/commands/connect/mapping-delete.js +33 -0
- package/commands/connect/mapping-diagnose.js +33 -0
- package/commands/connect/mapping-reload.js +31 -0
- package/commands/connect/mapping-state.js +26 -0
- package/commands/connect/mapping-write-errors.js +34 -0
- package/commands/connect/pause.js +24 -0
- package/commands/connect/recover.js +25 -0
- package/commands/connect/resume.js +24 -0
- package/commands/connect/sf-auth.js +75 -0
- package/commands/connect/state.js +34 -0
- package/commands/connect/write-errors.js +27 -0
- package/commands/connect-events/db-set.js +68 -0
- package/commands/connect-events/info.js +57 -0
- package/commands/connect-events/pause.js +24 -0
- package/commands/connect-events/recover.js +25 -0
- package/commands/connect-events/resume.js +24 -0
- package/commands/connect-events/sf-auth.js +75 -0
- package/commands/connect-events/state.js +34 -0
- package/commands/connect-events/stream-create.js +32 -0
- package/commands/connect-events/stream-delete.js +33 -0
- package/commands/connect-events/stream-state.js +26 -0
- package/index.js +50 -0
- package/lib/clients/connect.js +29 -0
- package/lib/clients/discovery.js +32 -0
- package/lib/connect/api.js +181 -0
- package/package.json +42 -0
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
const api = require('../../lib/connect/api.js')
|
|
3
|
+
const cli = require('@heroku/heroku-cli-util')
|
|
4
|
+
const co = require('co')
|
|
5
|
+
|
|
6
|
+
module.exports = {
|
|
7
|
+
topic: 'connect:mapping',
|
|
8
|
+
command: 'reload',
|
|
9
|
+
description: "Reload a mapping's data from Salesforce",
|
|
10
|
+
help: "Reload a mapping's data from Salesforce",
|
|
11
|
+
args: [
|
|
12
|
+
{ name: 'mapping' }
|
|
13
|
+
],
|
|
14
|
+
flags: [
|
|
15
|
+
{ name: 'resource', description: 'specific connection resource name', hasValue: true }
|
|
16
|
+
],
|
|
17
|
+
needsApp: true,
|
|
18
|
+
needsAuth: true,
|
|
19
|
+
run: cli.command(co.wrap(function * (context, heroku) {
|
|
20
|
+
yield cli.action(`initiating reload of ${context.args.mapping}`, co(function * () {
|
|
21
|
+
const connection = yield api.withConnection(context, heroku)
|
|
22
|
+
context.region = connection.region_url
|
|
23
|
+
const mapping = yield api.withMapping(connection, context.args.mapping)
|
|
24
|
+
|
|
25
|
+
const response = yield api.request(context, 'POST', '/api/v3/mappings/' + mapping.id + '/actions/reload')
|
|
26
|
+
if (response.status !== 202) {
|
|
27
|
+
throw new Error(response.data.message || 'unknown error')
|
|
28
|
+
}
|
|
29
|
+
}))
|
|
30
|
+
}))
|
|
31
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
const api = require('../../lib/connect/api.js')
|
|
3
|
+
const cli = require('@heroku/heroku-cli-util')
|
|
4
|
+
const co = require('co')
|
|
5
|
+
|
|
6
|
+
module.exports = {
|
|
7
|
+
topic: 'connect:mapping',
|
|
8
|
+
command: 'state',
|
|
9
|
+
description: 'return a mapping state',
|
|
10
|
+
help: 'return a mapping state',
|
|
11
|
+
args: [
|
|
12
|
+
{ name: 'mapping' }
|
|
13
|
+
],
|
|
14
|
+
flags: [
|
|
15
|
+
{ name: 'resource', description: 'specific connection resource name', hasValue: true }
|
|
16
|
+
],
|
|
17
|
+
needsApp: true,
|
|
18
|
+
needsAuth: true,
|
|
19
|
+
run: cli.command(co.wrap(function * (context, heroku) {
|
|
20
|
+
const connection = yield api.withConnection(context, heroku)
|
|
21
|
+
context.region = connection.region_url
|
|
22
|
+
const mapping = yield api.withMapping(connection, context.args.mapping)
|
|
23
|
+
|
|
24
|
+
cli.log(mapping.state)
|
|
25
|
+
}))
|
|
26
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
const api = require('../../lib/connect/api.js')
|
|
3
|
+
const cli = require('@heroku/heroku-cli-util')
|
|
4
|
+
|
|
5
|
+
module.exports = {
|
|
6
|
+
topic: 'connect:mapping',
|
|
7
|
+
command: 'write-errors',
|
|
8
|
+
description: 'Display the last 24 hours of write errors on this mapping',
|
|
9
|
+
examples: [
|
|
10
|
+
'$ heroku connect:mapping:write-errors -a myapp --resource herokuconnect-twisted-123 Account'
|
|
11
|
+
],
|
|
12
|
+
args: [
|
|
13
|
+
{
|
|
14
|
+
name: 'name',
|
|
15
|
+
optional: false,
|
|
16
|
+
description: 'Name of the mapping to retrieve errors for'
|
|
17
|
+
}
|
|
18
|
+
],
|
|
19
|
+
flags: [
|
|
20
|
+
{
|
|
21
|
+
name: 'resource',
|
|
22
|
+
description: 'specific connection resource name',
|
|
23
|
+
hasValue: true
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
name: 'json',
|
|
27
|
+
description: 'print errors as styled JSON',
|
|
28
|
+
hasValue: false
|
|
29
|
+
}
|
|
30
|
+
],
|
|
31
|
+
needsApp: true,
|
|
32
|
+
needsAuth: true,
|
|
33
|
+
run: cli.command(api.getWriteErrors)
|
|
34
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
const api = require('../../lib/connect/api.js')
|
|
3
|
+
const cli = require('@heroku/heroku-cli-util')
|
|
4
|
+
const co = require('co')
|
|
5
|
+
|
|
6
|
+
module.exports = {
|
|
7
|
+
topic: 'connect',
|
|
8
|
+
command: 'pause',
|
|
9
|
+
description: 'Pause a connection',
|
|
10
|
+
help: 'Pauses an active connection',
|
|
11
|
+
flags: [
|
|
12
|
+
{ name: 'resource', description: 'specific connection resource name', hasValue: true }
|
|
13
|
+
],
|
|
14
|
+
needsApp: true,
|
|
15
|
+
needsAuth: true,
|
|
16
|
+
run: cli.command(co.wrap(function * (context, heroku) {
|
|
17
|
+
yield cli.action('pausing connection', co(function * () {
|
|
18
|
+
const connection = yield api.withConnection(context, heroku)
|
|
19
|
+
context.region = connection.region_url
|
|
20
|
+
const url = '/api/v3/connections/' + connection.id + '/actions/pause'
|
|
21
|
+
yield api.request(context, 'POST', url)
|
|
22
|
+
}))
|
|
23
|
+
}))
|
|
24
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
const api = require('../../lib/connect/api.js')
|
|
3
|
+
const cli = require('@heroku/heroku-cli-util')
|
|
4
|
+
const co = require('co')
|
|
5
|
+
|
|
6
|
+
module.exports = {
|
|
7
|
+
topic: 'connect',
|
|
8
|
+
command: 'recover',
|
|
9
|
+
aliases: ['connect:restart'],
|
|
10
|
+
description: 'Recover a connection',
|
|
11
|
+
help: 'Clears errors and attempts to resume sync operations',
|
|
12
|
+
flags: [
|
|
13
|
+
{ name: 'resource', description: 'specific connection resource name', hasValue: true }
|
|
14
|
+
],
|
|
15
|
+
needsApp: true,
|
|
16
|
+
needsAuth: true,
|
|
17
|
+
run: cli.command(co.wrap(function * (context, heroku) {
|
|
18
|
+
yield cli.action('recovering connection', co(function * () {
|
|
19
|
+
const connection = yield api.withConnection(context, heroku)
|
|
20
|
+
context.region = connection.region_url
|
|
21
|
+
const url = '/api/v3/connections/' + connection.id + '/actions/restart'
|
|
22
|
+
yield api.request(context, 'POST', url)
|
|
23
|
+
}))
|
|
24
|
+
}))
|
|
25
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
const api = require('../../lib/connect/api.js')
|
|
3
|
+
const cli = require('@heroku/heroku-cli-util')
|
|
4
|
+
const co = require('co')
|
|
5
|
+
|
|
6
|
+
module.exports = {
|
|
7
|
+
topic: 'connect',
|
|
8
|
+
command: 'resume',
|
|
9
|
+
description: 'Resume a connection',
|
|
10
|
+
help: 'Resumes a paused connection',
|
|
11
|
+
flags: [
|
|
12
|
+
{ name: 'resource', description: 'specific connection resource name', hasValue: true }
|
|
13
|
+
],
|
|
14
|
+
needsApp: true,
|
|
15
|
+
needsAuth: true,
|
|
16
|
+
run: cli.command(co.wrap(function * (context, heroku) {
|
|
17
|
+
cli.action('resuming connection', co(function * () {
|
|
18
|
+
const connection = yield api.withConnection(context, heroku)
|
|
19
|
+
context.region = connection.region_url
|
|
20
|
+
const url = '/api/v3/connections/' + connection.id + '/actions/resume'
|
|
21
|
+
yield api.request(context, 'POST', url)
|
|
22
|
+
}))
|
|
23
|
+
}))
|
|
24
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
const api = require('../../lib/connect/api.js')
|
|
3
|
+
const cli = require('@heroku/heroku-cli-util')
|
|
4
|
+
const co = require('co')
|
|
5
|
+
const http = require('http')
|
|
6
|
+
|
|
7
|
+
const LOCAL_PORT = 18000
|
|
8
|
+
|
|
9
|
+
function callbackServer () {
|
|
10
|
+
return new Promise(function (resolve, reject) {
|
|
11
|
+
// Create a local server that can receive the user after authoriztion is complete
|
|
12
|
+
http.createServer(function (request, response) {
|
|
13
|
+
// Notify the user that the the authorization is complete
|
|
14
|
+
response.writeHead(200, { 'Content-Type': 'text/html' })
|
|
15
|
+
const res = '<html><body><h3>Authorization complete</h3><p>You may close this window and return to the terminal to continue.</p></body></html>'
|
|
16
|
+
response.end(res)
|
|
17
|
+
|
|
18
|
+
// Shut down the server so the command can exit
|
|
19
|
+
request.connection.destroy()
|
|
20
|
+
this.close()
|
|
21
|
+
|
|
22
|
+
// Return control to the main command
|
|
23
|
+
resolve()
|
|
24
|
+
}).listen(LOCAL_PORT)
|
|
25
|
+
})
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function * run (context, heroku) {
|
|
29
|
+
let redir
|
|
30
|
+
yield cli.action('fetching authorizing URL', co(function * () {
|
|
31
|
+
const connection = yield api.withConnection(context, heroku)
|
|
32
|
+
context.region = connection.region_url
|
|
33
|
+
|
|
34
|
+
const url = `/api/v3/connections/${connection.id}/authorize_url`
|
|
35
|
+
const args = {
|
|
36
|
+
environment: 'production',
|
|
37
|
+
// Redirect to the local server created in callbackServer(), so the CLI
|
|
38
|
+
// can respond immediately after successful authorization
|
|
39
|
+
next: `http://localhost:${LOCAL_PORT}`
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
if (context.flags.environment) {
|
|
43
|
+
args.environment = context.flags.environment
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
if (context.flags.environment === 'custom' && context.flags.domain) {
|
|
47
|
+
args.domain = context.flags.domain
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const response = yield api.request(context, 'POST', url, args)
|
|
51
|
+
redir = response.data.redirect
|
|
52
|
+
|
|
53
|
+
yield cli.open(redir)
|
|
54
|
+
}))
|
|
55
|
+
|
|
56
|
+
cli.log("\nIf your browser doesn't open, please copy the following URL to proceed:\n" + redir + '\n')
|
|
57
|
+
|
|
58
|
+
yield cli.action('waiting for authorization', callbackServer())
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
module.exports = {
|
|
62
|
+
topic: 'connect',
|
|
63
|
+
command: 'sf:auth',
|
|
64
|
+
description: 'Authorize access to Salesforce for your connection',
|
|
65
|
+
help: 'Opens a browser to authorize a connection to a Salesforce Org',
|
|
66
|
+
flags: [
|
|
67
|
+
{ name: 'callback', char: 'c', description: 'final callback URL', hasValue: true },
|
|
68
|
+
{ name: 'environment', char: 'e', description: '"production", "sandbox", or "custom" [defaults to "production"]', hasValue: true },
|
|
69
|
+
{ name: 'domain', char: 'd', description: 'specify a custom login domain (if using a "custom" environment)', hasValue: true },
|
|
70
|
+
{ name: 'resource', description: 'specific connection resource name', hasValue: true }
|
|
71
|
+
],
|
|
72
|
+
needsApp: true,
|
|
73
|
+
needsAuth: true,
|
|
74
|
+
run: cli.command(co.wrap(run))
|
|
75
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
const api = require('../../lib/connect/api.js')
|
|
3
|
+
const cli = require('@heroku/heroku-cli-util')
|
|
4
|
+
const co = require('co')
|
|
5
|
+
|
|
6
|
+
function * run (context, heroku) {
|
|
7
|
+
const connections = yield api.withUserConnections(context, context.app, context.flags, heroku)
|
|
8
|
+
|
|
9
|
+
if (context.flags.json) {
|
|
10
|
+
cli.styledJSON(connections)
|
|
11
|
+
} else {
|
|
12
|
+
cli.table(connections, {
|
|
13
|
+
columns: [
|
|
14
|
+
{ key: 'db_key', label: 'Database' },
|
|
15
|
+
{ key: 'schema_name', label: 'Schema' },
|
|
16
|
+
{ key: 'state', label: 'State' }
|
|
17
|
+
]
|
|
18
|
+
})
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
module.exports = {
|
|
23
|
+
topic: 'connect',
|
|
24
|
+
command: 'state',
|
|
25
|
+
description: 'return the connection(s) state',
|
|
26
|
+
help: 'returns the state key of the selected connections',
|
|
27
|
+
flags: [
|
|
28
|
+
{ name: 'resource', description: 'specific connection resource name', hasValue: true },
|
|
29
|
+
{ name: 'json', description: 'print output as json', hasValue: false }
|
|
30
|
+
],
|
|
31
|
+
needsApp: true,
|
|
32
|
+
needsAuth: true,
|
|
33
|
+
run: cli.command(co.wrap(run))
|
|
34
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
const api = require('../../lib/connect/api.js')
|
|
3
|
+
const cli = require('@heroku/heroku-cli-util')
|
|
4
|
+
|
|
5
|
+
module.exports = {
|
|
6
|
+
topic: 'connect',
|
|
7
|
+
command: 'write-errors',
|
|
8
|
+
description: 'Display the last 24 hours of write errors on this connection',
|
|
9
|
+
examples: [
|
|
10
|
+
'$ heroku connect:write-errors -a myapp --resource herokuconnect-twisted-123'
|
|
11
|
+
],
|
|
12
|
+
flags: [
|
|
13
|
+
{
|
|
14
|
+
name: 'resource',
|
|
15
|
+
description: 'specific connection resource name',
|
|
16
|
+
hasValue: true
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
name: 'json',
|
|
20
|
+
description: 'print errors as styled JSON',
|
|
21
|
+
hasValue: false
|
|
22
|
+
}
|
|
23
|
+
],
|
|
24
|
+
needsApp: true,
|
|
25
|
+
needsAuth: true,
|
|
26
|
+
run: cli.command(api.getWriteErrors)
|
|
27
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
const api = require('../../lib/connect/api.js')
|
|
3
|
+
const cli = require('@heroku/heroku-cli-util')
|
|
4
|
+
const co = require('co')
|
|
5
|
+
const inquirer = require('inquirer')
|
|
6
|
+
|
|
7
|
+
const fetchKeys = co.wrap(function * (appName, context) {
|
|
8
|
+
const url = `/api/v3/apps/${appName}`
|
|
9
|
+
const response = yield api.request(context, 'GET', url)
|
|
10
|
+
const keys = []// new Array(response.json.db_keys.length);
|
|
11
|
+
response.data.db_keys.forEach(function (key) {
|
|
12
|
+
keys.push({
|
|
13
|
+
name: `${key.name} (${key.addon.plan})`,
|
|
14
|
+
value: key.name
|
|
15
|
+
})
|
|
16
|
+
})
|
|
17
|
+
return yield Promise.resolve(keys)
|
|
18
|
+
})
|
|
19
|
+
|
|
20
|
+
module.exports = {
|
|
21
|
+
topic: 'connect-events',
|
|
22
|
+
command: 'db:set',
|
|
23
|
+
description: 'Set database parameters',
|
|
24
|
+
help: "Set a connection's database config var and schema name",
|
|
25
|
+
flags: [
|
|
26
|
+
{ name: 'resource', description: 'specific connection resource name', hasValue: true },
|
|
27
|
+
{ name: 'db', description: 'Database config var name', hasValue: true },
|
|
28
|
+
{ name: 'schema', description: 'Database schema name', hasValue: true }
|
|
29
|
+
],
|
|
30
|
+
needsApp: true,
|
|
31
|
+
needsAuth: true,
|
|
32
|
+
run: cli.command(co.wrap(function * (context, heroku) {
|
|
33
|
+
const data = {
|
|
34
|
+
db_key: context.flags.db,
|
|
35
|
+
schema_name: context.flags.schema
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const connection = yield api.withConnection(context, heroku, api.ADDON_TYPE_EVENTS)
|
|
39
|
+
context.region = connection.region_url
|
|
40
|
+
|
|
41
|
+
inquirer.prompt([
|
|
42
|
+
{
|
|
43
|
+
name: 'db_key',
|
|
44
|
+
type: 'list',
|
|
45
|
+
message: "Select the config var that points to the database you'd like to use",
|
|
46
|
+
choices: yield fetchKeys(connection.app_name, context),
|
|
47
|
+
when: !context.flags.db
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
name: 'schema_name',
|
|
51
|
+
message: "Enter a schema name you'd like to use for the conneted data",
|
|
52
|
+
default: context.flags.schema || 'salesforce',
|
|
53
|
+
when: !context.flags.schema
|
|
54
|
+
}
|
|
55
|
+
]).then(co.wrap(function * (answers) {
|
|
56
|
+
for (const key in answers) {
|
|
57
|
+
data[key] = answers[key]
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
yield cli.action('setting database parameters', co(function * () {
|
|
61
|
+
const url = `/api/v3/kafka-connections/${connection.id}`
|
|
62
|
+
yield api.request(context, 'PUT', url, data)
|
|
63
|
+
}))
|
|
64
|
+
|
|
65
|
+
cli.styledHash(data)
|
|
66
|
+
}))
|
|
67
|
+
}))
|
|
68
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
const api = require('../../lib/connect/api.js')
|
|
3
|
+
const cli = require('@heroku/heroku-cli-util')
|
|
4
|
+
const co = require('co')
|
|
5
|
+
|
|
6
|
+
module.exports = {
|
|
7
|
+
topic: 'connect-events',
|
|
8
|
+
command: 'info',
|
|
9
|
+
default: false,
|
|
10
|
+
description: 'display connection information',
|
|
11
|
+
help: 'display connection information',
|
|
12
|
+
flags: [
|
|
13
|
+
{ name: 'resource', description: 'specific connection resource name', hasValue: true },
|
|
14
|
+
{ name: 'check-for-new', char: 'c', description: 'check for access to any new connections', hasValue: false }
|
|
15
|
+
],
|
|
16
|
+
needsApp: true,
|
|
17
|
+
needsAuth: true,
|
|
18
|
+
run: cli.command(co.wrap(function * (context, heroku) {
|
|
19
|
+
let connections
|
|
20
|
+
|
|
21
|
+
if (context.flags['check-for-new']) {
|
|
22
|
+
connections = yield api.requestAppAccess(context, context.app, context.flags, true, heroku, api.ADDON_TYPE_EVENTS)
|
|
23
|
+
} else {
|
|
24
|
+
connections = yield api.withUserConnections(context, context.app, context.flags, true, heroku, api.ADDON_TYPE_EVENTS)
|
|
25
|
+
if (connections.length === 0) {
|
|
26
|
+
connections = yield api.requestAppAcess(context, context.app, context.flags, true, heroku, api.ADDON_TYPE_EVENTS)
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
if (connections.length === 0) {
|
|
31
|
+
const instanceName = process.env.CONNECT_ADDON === 'connectqa' ? 'platformeventsqa' : 'herokuconnect'
|
|
32
|
+
cli.error('No connection found. You may need to use addons:open to make it accessible to the CLI.')
|
|
33
|
+
cli.error('')
|
|
34
|
+
cli.error('For Example:')
|
|
35
|
+
cli.error(`heroku addons:open ${instanceName} -a ${context.app}`)
|
|
36
|
+
} else {
|
|
37
|
+
connections = yield api.withStreams(context, connections)
|
|
38
|
+
connections.forEach(function (connection) {
|
|
39
|
+
cli.styledHeader(`Connection [${connection.id}] / ${connection.resource_name} (${connection.state})`)
|
|
40
|
+
cli.log()
|
|
41
|
+
if (connection.streams.length > 0) {
|
|
42
|
+
cli.table(
|
|
43
|
+
connection.streams, {
|
|
44
|
+
columns: [
|
|
45
|
+
{ key: 'object_name', label: 'Object Name' },
|
|
46
|
+
{ key: 'state', label: 'State' }
|
|
47
|
+
]
|
|
48
|
+
}
|
|
49
|
+
)
|
|
50
|
+
} else {
|
|
51
|
+
cli.log('No streams')
|
|
52
|
+
}
|
|
53
|
+
cli.log()
|
|
54
|
+
})
|
|
55
|
+
}
|
|
56
|
+
}))
|
|
57
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
const api = require('../../lib/connect/api.js')
|
|
3
|
+
const cli = require('@heroku/heroku-cli-util')
|
|
4
|
+
const co = require('co')
|
|
5
|
+
|
|
6
|
+
module.exports = {
|
|
7
|
+
topic: 'connect-events',
|
|
8
|
+
command: 'pause',
|
|
9
|
+
description: 'Pause a connection',
|
|
10
|
+
help: 'Pauses an active connection',
|
|
11
|
+
flags: [
|
|
12
|
+
{ name: 'resource', description: 'specific connection resource name', hasValue: true }
|
|
13
|
+
],
|
|
14
|
+
needsApp: true,
|
|
15
|
+
needsAuth: true,
|
|
16
|
+
run: cli.command(co.wrap(function * (context, heroku) {
|
|
17
|
+
yield cli.action('pausing connection', co(function * () {
|
|
18
|
+
const connection = yield api.withConnection(context, heroku, api.ADDON_TYPE_EVENTS)
|
|
19
|
+
context.region = connection.region_url
|
|
20
|
+
const url = `/api/v3/kafka-connections/${connection.id}/actions/pause`
|
|
21
|
+
yield api.request(context, 'POST', url)
|
|
22
|
+
}))
|
|
23
|
+
}))
|
|
24
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
const api = require('../../lib/connect/api.js')
|
|
3
|
+
const cli = require('@heroku/heroku-cli-util')
|
|
4
|
+
const co = require('co')
|
|
5
|
+
|
|
6
|
+
module.exports = {
|
|
7
|
+
topic: 'connect-events',
|
|
8
|
+
command: 'recover',
|
|
9
|
+
aliases: ['connect:restart'],
|
|
10
|
+
description: 'Recover a connection',
|
|
11
|
+
help: 'Clears errors and attempts to resume sync operations',
|
|
12
|
+
flags: [
|
|
13
|
+
{ name: 'resource', description: 'specific connection resource name', hasValue: true }
|
|
14
|
+
],
|
|
15
|
+
needsApp: true,
|
|
16
|
+
needsAuth: true,
|
|
17
|
+
run: cli.command(co.wrap(function * (context, heroku) {
|
|
18
|
+
yield cli.action('recovering connection', co(function * () {
|
|
19
|
+
const connection = yield api.withConnection(context, heroku, api.ADDON_TYPE_EVENTS)
|
|
20
|
+
context.region = connection.region_url
|
|
21
|
+
const url = `/api/v3/kafka-connections/${connection.id}/actions/recover`
|
|
22
|
+
yield api.request(context, 'POST', url)
|
|
23
|
+
}))
|
|
24
|
+
}))
|
|
25
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
const api = require('../../lib/connect/api.js')
|
|
3
|
+
const cli = require('@heroku/heroku-cli-util')
|
|
4
|
+
const co = require('co')
|
|
5
|
+
|
|
6
|
+
module.exports = {
|
|
7
|
+
topic: 'connect-events',
|
|
8
|
+
command: 'resume',
|
|
9
|
+
description: 'Resume a connection',
|
|
10
|
+
help: 'Resumes a paused connection',
|
|
11
|
+
flags: [
|
|
12
|
+
{ name: 'resource', description: 'specific connection resource name', hasValue: true }
|
|
13
|
+
],
|
|
14
|
+
needsApp: true,
|
|
15
|
+
needsAuth: true,
|
|
16
|
+
run: cli.command(co.wrap(function * (context, heroku) {
|
|
17
|
+
cli.action('resuming connection', co(function * () {
|
|
18
|
+
const connection = yield api.withConnection(context, heroku, api.ADDON_TYPE_EVENTS)
|
|
19
|
+
context.region = connection.region_url
|
|
20
|
+
const url = `/api/v3/kafka-connections/${connection.id}/actions/resume`
|
|
21
|
+
yield api.request(context, 'POST', url)
|
|
22
|
+
}))
|
|
23
|
+
}))
|
|
24
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
const api = require('../../lib/connect/api.js')
|
|
3
|
+
const cli = require('@heroku/heroku-cli-util')
|
|
4
|
+
const co = require('co')
|
|
5
|
+
const http = require('http')
|
|
6
|
+
|
|
7
|
+
const LOCAL_PORT = 18000
|
|
8
|
+
|
|
9
|
+
function callbackServer () {
|
|
10
|
+
return new Promise(function (resolve, reject) {
|
|
11
|
+
// Create a local server that can receive the user after authoriztion is complete
|
|
12
|
+
http.createServer(function (request, response) {
|
|
13
|
+
// Notify the user that the the authorization is complete
|
|
14
|
+
response.writeHead(200, { 'Content-Type': 'text/html' })
|
|
15
|
+
const res = '<html><body><h3>Authorization complete</h3><p>You may close this window and return to the terminal to continue.</p></body></html>'
|
|
16
|
+
response.end(res)
|
|
17
|
+
|
|
18
|
+
// Shut down the server so the command can exit
|
|
19
|
+
request.connection.destroy()
|
|
20
|
+
this.close()
|
|
21
|
+
|
|
22
|
+
// Return control to the main command
|
|
23
|
+
resolve()
|
|
24
|
+
}).listen(LOCAL_PORT)
|
|
25
|
+
})
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function * run (context, heroku) {
|
|
29
|
+
let redir
|
|
30
|
+
yield cli.action('fetching authorizing URL', co(function * () {
|
|
31
|
+
const connection = yield api.withConnection(context, heroku, api.ADDON_TYPE_EVENTS)
|
|
32
|
+
context.region = connection.region_url
|
|
33
|
+
|
|
34
|
+
const url = `/api/v3/kafka-connections/${connection.id}/authorize_url`
|
|
35
|
+
const args = {
|
|
36
|
+
environment: 'production',
|
|
37
|
+
// Redirect to the local server created in callbackServer(), so the CLI
|
|
38
|
+
// can respond immediately after successful authorization
|
|
39
|
+
next: `http://localhost:${LOCAL_PORT}`
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
if (context.flags.environment) {
|
|
43
|
+
args.environment = context.flags.environment
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
if (context.flags.environment === 'custom' && context.flags.domain) {
|
|
47
|
+
args.domain = context.flags.domain
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const response = yield api.request(context, 'POST', url, args)
|
|
51
|
+
redir = response.data.redirect
|
|
52
|
+
|
|
53
|
+
yield cli.open(redir)
|
|
54
|
+
}))
|
|
55
|
+
|
|
56
|
+
cli.log("\nIf your browser doesn't open, please copy the following URL to proceed:\n" + redir + '\n')
|
|
57
|
+
|
|
58
|
+
yield cli.action('waiting for authorization', callbackServer())
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
module.exports = {
|
|
62
|
+
topic: 'connect-events',
|
|
63
|
+
command: 'sf:auth',
|
|
64
|
+
description: 'Authorize access to Salesforce for your connection',
|
|
65
|
+
help: 'Opens a browser to authorize a connection to a Salesforce Org',
|
|
66
|
+
flags: [
|
|
67
|
+
{ name: 'callback', char: 'c', description: 'final callback URL', hasValue: true },
|
|
68
|
+
{ name: 'environment', char: 'e', description: '"production", "sandbox", or "custom" [defaults to "production"]', hasValue: true },
|
|
69
|
+
{ name: 'domain', char: 'd', description: 'specify a custom login domain (if using a "custom" environment)', hasValue: true },
|
|
70
|
+
{ name: 'resource', description: 'specific connection resource name', hasValue: true }
|
|
71
|
+
],
|
|
72
|
+
needsApp: true,
|
|
73
|
+
needsAuth: true,
|
|
74
|
+
run: cli.command(co.wrap(run))
|
|
75
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
const api = require('../../lib/connect/api.js')
|
|
3
|
+
const cli = require('@heroku/heroku-cli-util')
|
|
4
|
+
const co = require('co')
|
|
5
|
+
|
|
6
|
+
function * run (context, heroku) {
|
|
7
|
+
const connections = yield api.withUserConnections(context, context.app, context.flags, heroku, true, api.ADDON_TYPE_EVENTS)
|
|
8
|
+
|
|
9
|
+
if (context.flags.json) {
|
|
10
|
+
cli.styledJSON(connections)
|
|
11
|
+
} else {
|
|
12
|
+
cli.table(connections, {
|
|
13
|
+
columns: [
|
|
14
|
+
{ key: 'db_key', label: 'Kafka' },
|
|
15
|
+
{ key: 'schema_name', label: 'Schema' },
|
|
16
|
+
{ key: 'state', label: 'State' }
|
|
17
|
+
]
|
|
18
|
+
})
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
module.exports = {
|
|
23
|
+
topic: 'connect-events',
|
|
24
|
+
command: 'state',
|
|
25
|
+
description: 'return the connection(s) state',
|
|
26
|
+
help: 'returns the state key of the selected connections',
|
|
27
|
+
flags: [
|
|
28
|
+
{ name: 'resource', description: 'specific connection resource name', hasValue: true },
|
|
29
|
+
{ name: 'json', description: 'print output as json', hasValue: false }
|
|
30
|
+
],
|
|
31
|
+
needsApp: true,
|
|
32
|
+
needsAuth: true,
|
|
33
|
+
run: cli.command(co.wrap(run))
|
|
34
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
const api = require('../../lib/connect/api.js')
|
|
3
|
+
const cli = require('@heroku/heroku-cli-util')
|
|
4
|
+
const co = require('co')
|
|
5
|
+
|
|
6
|
+
module.exports = {
|
|
7
|
+
topic: 'connect-events:stream',
|
|
8
|
+
command: 'create',
|
|
9
|
+
description: 'Create a stream',
|
|
10
|
+
help: 'Create a stream',
|
|
11
|
+
args: [
|
|
12
|
+
{ name: 'stream' }
|
|
13
|
+
],
|
|
14
|
+
flags: [
|
|
15
|
+
{ name: 'resource', description: 'specific connection resource name', hasValue: true }
|
|
16
|
+
],
|
|
17
|
+
needsApp: true,
|
|
18
|
+
needsAuth: true,
|
|
19
|
+
run: cli.command(co.wrap(function * (context, heroku) {
|
|
20
|
+
yield cli.action('creating stream', co(function * () {
|
|
21
|
+
const connection = yield api.withConnection(context, heroku, api.ADDON_TYPE_EVENTS)
|
|
22
|
+
context.region = connection.region_url
|
|
23
|
+
const response = yield api.request(
|
|
24
|
+
context, 'POST', `/api/v3/kafka-connections/${connection.id}/streams`,
|
|
25
|
+
{ object_name: context.args.stream }
|
|
26
|
+
)
|
|
27
|
+
if (response.status !== 201) {
|
|
28
|
+
throw new Error(response.data.message || 'unknown error')
|
|
29
|
+
}
|
|
30
|
+
}))
|
|
31
|
+
}))
|
|
32
|
+
}
|