@dishantlangayan/sc-plugin-broker 0.1.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.txt +202 -0
- package/README.md +268 -0
- package/bin/dev.cmd +3 -0
- package/bin/dev.js +5 -0
- package/bin/run.cmd +3 -0
- package/bin/run.js +5 -0
- package/dist/commands/broker/login/basic.d.ts +54 -0
- package/dist/commands/broker/login/basic.js +293 -0
- package/dist/commands/broker/login/cloud.d.ts +56 -0
- package/dist/commands/broker/login/cloud.js +333 -0
- package/dist/commands/broker/login/list.d.ts +10 -0
- package/dist/commands/broker/login/list.js +36 -0
- package/dist/commands/broker/logout.d.ts +15 -0
- package/dist/commands/broker/logout.js +111 -0
- package/dist/commands/broker/queue/create.d.ts +28 -0
- package/dist/commands/broker/queue/create.js +116 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/lib/broker-utils.d.ts +25 -0
- package/dist/lib/broker-utils.js +62 -0
- package/dist/types/cloud-api.d.ts +102 -0
- package/dist/types/cloud-api.js +5 -0
- package/dist/types/msgvpn-queue.d.ts +49 -0
- package/dist/types/msgvpn-queue.js +4 -0
- package/oclif.manifest.json +475 -0
- package/package.json +75 -0
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { renderTable, ScCommand } from '@dishantlangayan/sc-cli-core';
|
|
2
|
+
export default class BrokerLoginList extends ScCommand {
|
|
3
|
+
static args = {};
|
|
4
|
+
static description = `List all authenticated brokers.
|
|
5
|
+
|
|
6
|
+
Displays brokers you have logged into, including their authentication type, SEMP endpoints, and which one is set as default.`;
|
|
7
|
+
static examples = [
|
|
8
|
+
'<%= config.bin %> <%= command.id %>',
|
|
9
|
+
];
|
|
10
|
+
static flags = {};
|
|
11
|
+
async run() {
|
|
12
|
+
const brokerAuthManager = await this.getBrokerAuthManager();
|
|
13
|
+
// Get all authenticated brokers
|
|
14
|
+
const allBrokers = await brokerAuthManager.getAllBrokers();
|
|
15
|
+
// Handle case when no brokers exist
|
|
16
|
+
if (allBrokers.length === 0) {
|
|
17
|
+
this.log("No brokers found. Run 'sc broker:login:basic' to authenticate.");
|
|
18
|
+
return { data: [] };
|
|
19
|
+
}
|
|
20
|
+
// Create table array (first row is headers, rest are data rows)
|
|
21
|
+
const brokerArray = [
|
|
22
|
+
['Broker Name', 'Auth Type', 'SEMP Endpoint', 'SEMP Port', 'Is Default'],
|
|
23
|
+
...allBrokers.map((broker) => [
|
|
24
|
+
broker.name,
|
|
25
|
+
String(broker.authType),
|
|
26
|
+
broker.sempEndpoint,
|
|
27
|
+
broker.sempPort.toString(),
|
|
28
|
+
broker.isDefault ? 'Yes' : '',
|
|
29
|
+
]),
|
|
30
|
+
];
|
|
31
|
+
// Display results as a table
|
|
32
|
+
this.log(renderTable(brokerArray));
|
|
33
|
+
// Return raw data for --json flag support
|
|
34
|
+
return { data: allBrokers };
|
|
35
|
+
}
|
|
36
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { ScCommand } from '@dishantlangayan/sc-cli-core';
|
|
2
|
+
export default class BrokerLogout extends ScCommand<typeof BrokerLogout> {
|
|
3
|
+
static args: {};
|
|
4
|
+
static description: string;
|
|
5
|
+
static examples: string[];
|
|
6
|
+
static flags: {
|
|
7
|
+
all: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
8
|
+
'broker-name': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
9
|
+
'no-prompt': import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
10
|
+
};
|
|
11
|
+
run(): Promise<{
|
|
12
|
+
count: number;
|
|
13
|
+
loggedOut: string[];
|
|
14
|
+
}>;
|
|
15
|
+
}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { ScCommand } from '@dishantlangayan/sc-cli-core';
|
|
2
|
+
import { checkbox, confirm } from '@inquirer/prompts';
|
|
3
|
+
import { Flags } from '@oclif/core';
|
|
4
|
+
export default class BrokerLogout extends ScCommand {
|
|
5
|
+
static args = {};
|
|
6
|
+
static description = `Logout from authenticated brokers.
|
|
7
|
+
|
|
8
|
+
Removes locally stored broker credentials.
|
|
9
|
+
Interactive mode allows selection with arrow keys and spacebar.`;
|
|
10
|
+
static examples = [
|
|
11
|
+
'<%= config.bin %> <%= command.id %>',
|
|
12
|
+
'<%= config.bin %> <%= command.id %> --broker-name=dev-broker',
|
|
13
|
+
'<%= config.bin %> <%= command.id %> --all',
|
|
14
|
+
'<%= config.bin %> <%= command.id %> --broker-name=prod --no-prompt',
|
|
15
|
+
];
|
|
16
|
+
static flags = {
|
|
17
|
+
all: Flags.boolean({
|
|
18
|
+
char: 'a',
|
|
19
|
+
default: false,
|
|
20
|
+
description: 'Logout from all brokers',
|
|
21
|
+
exclusive: ['broker-name'],
|
|
22
|
+
}),
|
|
23
|
+
'broker-name': Flags.string({
|
|
24
|
+
char: 'b',
|
|
25
|
+
description: 'Broker name to logout from',
|
|
26
|
+
exclusive: ['all'],
|
|
27
|
+
}),
|
|
28
|
+
'no-prompt': Flags.boolean({
|
|
29
|
+
default: false,
|
|
30
|
+
description: 'Skip confirmation prompt and assume Yes',
|
|
31
|
+
}),
|
|
32
|
+
};
|
|
33
|
+
async run() {
|
|
34
|
+
const { flags } = await this.parse(BrokerLogout);
|
|
35
|
+
const brokerName = flags['broker-name'];
|
|
36
|
+
// Get BrokerAuthManager instance
|
|
37
|
+
const brokerAuthManager = await this.getBrokerAuthManager();
|
|
38
|
+
// Get all authenticated brokers
|
|
39
|
+
const allBrokers = await brokerAuthManager.getAllBrokers();
|
|
40
|
+
// Handle case when no brokers exist
|
|
41
|
+
if (allBrokers.length === 0) {
|
|
42
|
+
this.log("No brokers found. Run 'sc broker:login:basic' to authenticate.");
|
|
43
|
+
return { count: 0, loggedOut: [] };
|
|
44
|
+
}
|
|
45
|
+
// Determine which brokers to logout
|
|
46
|
+
let brokerNamesToLogout = [];
|
|
47
|
+
if (flags.all) {
|
|
48
|
+
// Logout from all brokers
|
|
49
|
+
brokerNamesToLogout = allBrokers.map((broker) => broker.name);
|
|
50
|
+
}
|
|
51
|
+
else if (brokerName) {
|
|
52
|
+
// Logout from specific broker
|
|
53
|
+
const broker = allBrokers.find((b) => b.name === brokerName);
|
|
54
|
+
if (!broker) {
|
|
55
|
+
this.error(`Broker '${brokerName}' not found. Run 'sc broker:login:list' to see available brokers.`, { exit: 2 });
|
|
56
|
+
}
|
|
57
|
+
brokerNamesToLogout = [broker.name];
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
// Interactive mode: let user select brokers
|
|
61
|
+
try {
|
|
62
|
+
brokerNamesToLogout = await checkbox({
|
|
63
|
+
choices: allBrokers.map((broker) => ({
|
|
64
|
+
name: broker.isDefault ? `${broker.name} (default)` : broker.name,
|
|
65
|
+
value: broker.name,
|
|
66
|
+
})),
|
|
67
|
+
message: 'Select brokers to logout from:',
|
|
68
|
+
required: true,
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
catch {
|
|
72
|
+
// User cancelled the selection (Ctrl+C)
|
|
73
|
+
this.log('Logout cancelled.');
|
|
74
|
+
return { count: 0, loggedOut: [] };
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
// Confirm logout unless --no-prompt flag is set
|
|
78
|
+
if (!flags['no-prompt']) {
|
|
79
|
+
const count = brokerNamesToLogout.length;
|
|
80
|
+
const brokerWord = count === 1 ? 'broker' : 'brokers';
|
|
81
|
+
try {
|
|
82
|
+
const shouldProceed = await confirm({
|
|
83
|
+
default: true,
|
|
84
|
+
message: `Are you sure you want to logout from ${count} ${brokerWord}?`,
|
|
85
|
+
});
|
|
86
|
+
if (!shouldProceed) {
|
|
87
|
+
this.log('Logout cancelled.');
|
|
88
|
+
return { count: 0, loggedOut: [] };
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
catch {
|
|
92
|
+
// User cancelled the confirmation (Ctrl+C)
|
|
93
|
+
this.log('Logout cancelled.');
|
|
94
|
+
return { count: 0, loggedOut: [] };
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
// Logout from selected brokers (remove all in parallel)
|
|
98
|
+
await Promise.all(brokerNamesToLogout.map((name) => brokerAuthManager.removeBroker(name)));
|
|
99
|
+
// Display success messages
|
|
100
|
+
for (const name of brokerNamesToLogout) {
|
|
101
|
+
const broker = allBrokers.find((b) => b.name === name);
|
|
102
|
+
const displayName = broker?.isDefault ? `${name} (default)` : name;
|
|
103
|
+
this.log(`Successfully logged out from: ${displayName}`);
|
|
104
|
+
}
|
|
105
|
+
// Return result for --json support
|
|
106
|
+
return {
|
|
107
|
+
count: brokerNamesToLogout.length,
|
|
108
|
+
loggedOut: brokerNamesToLogout,
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { ScCommand } from '@dishantlangayan/sc-cli-core';
|
|
2
|
+
import { MsgVpnQueueCreateResponse } from '../../../types/msgvpn-queue.js';
|
|
3
|
+
export default class BrokerQueueCreate extends ScCommand<typeof BrokerQueueCreate> {
|
|
4
|
+
static args: {};
|
|
5
|
+
static description: string;
|
|
6
|
+
static examples: string[];
|
|
7
|
+
static flags: {
|
|
8
|
+
'access-type': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
9
|
+
'broker-id': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
10
|
+
'broker-name': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
11
|
+
'dead-msg-queue': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
12
|
+
'egress-enabled': import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
13
|
+
'ingress-enabled': import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
14
|
+
'max-msg-spool-usage': import("@oclif/core/interfaces").OptionFlag<number | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
15
|
+
'max-redelivery-count': import("@oclif/core/interfaces").OptionFlag<number | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
16
|
+
'max-ttl': import("@oclif/core/interfaces").OptionFlag<number | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
17
|
+
'msg-vpn-name': import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
18
|
+
owner: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
19
|
+
permission: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
20
|
+
'queue-name': import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
21
|
+
'respect-ttl-enabled': import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
22
|
+
};
|
|
23
|
+
run(): Promise<MsgVpnQueueCreateResponse>;
|
|
24
|
+
/**
|
|
25
|
+
* Builds the queue creation request body from command flags
|
|
26
|
+
*/
|
|
27
|
+
private buildQueueRequest;
|
|
28
|
+
}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { printObjectAsKeyValueTable, ScCommand } from '@dishantlangayan/sc-cli-core';
|
|
2
|
+
import { Flags } from '@oclif/core';
|
|
3
|
+
import { resolveBrokerConnection } from '../../../lib/broker-utils.js';
|
|
4
|
+
export default class BrokerQueueCreate extends ScCommand {
|
|
5
|
+
static args = {};
|
|
6
|
+
static description = `Create a Queue on a Solace Event Broker.
|
|
7
|
+
|
|
8
|
+
Any attribute missing from the request will be set to its default value. The creation of instances of this object are synchronized to HA mates and replication sites via config-sync.`;
|
|
9
|
+
static examples = [
|
|
10
|
+
'<%= config.bin %> <%= command.id %> --broker-name=dev-broker --queue-name=myQueue --msg-vpn-name=default',
|
|
11
|
+
'<%= config.bin %> <%= command.id %> --broker-id=dev-broker --queue-name=myQueue --msg-vpn-name=default --access-type=non-exclusive',
|
|
12
|
+
'<%= config.bin %> <%= command.id %> --broker-name=dev-broker --queue-name=myQueue --msg-vpn-name=default --owner=user1 --permission=consume',
|
|
13
|
+
'<%= config.bin %> <%= command.id %> --broker-name=dev-broker --queue-name=myQueue --msg-vpn-name=default --max-msg-spool-usage=1024 --egress-enabled --ingress-enabled',
|
|
14
|
+
'<%= config.bin %> <%= command.id %> --broker-name=dev-broker --queue-name=myQueue --msg-vpn-name=default --dead-msg-queue=#DEAD_MSG_QUEUE --max-redelivery-count=3',
|
|
15
|
+
];
|
|
16
|
+
static flags = {
|
|
17
|
+
'access-type': Flags.string({
|
|
18
|
+
char: 'a',
|
|
19
|
+
description: 'The access type for the queue.',
|
|
20
|
+
options: ['exclusive', 'non-exclusive'],
|
|
21
|
+
}),
|
|
22
|
+
'broker-id': Flags.string({
|
|
23
|
+
char: 'b',
|
|
24
|
+
description: 'Stored broker identifier.',
|
|
25
|
+
exactlyOne: ['broker-id', 'broker-name'],
|
|
26
|
+
}),
|
|
27
|
+
'broker-name': Flags.string({
|
|
28
|
+
char: 'n',
|
|
29
|
+
description: 'Stored broker name.',
|
|
30
|
+
exactlyOne: ['broker-id', 'broker-name'],
|
|
31
|
+
}),
|
|
32
|
+
'dead-msg-queue': Flags.string({
|
|
33
|
+
description: 'The name of the Dead Message Queue.',
|
|
34
|
+
}),
|
|
35
|
+
'egress-enabled': Flags.boolean({
|
|
36
|
+
allowNo: true,
|
|
37
|
+
description: 'Enable or disable egress (message consumption) from the queue.',
|
|
38
|
+
}),
|
|
39
|
+
'ingress-enabled': Flags.boolean({
|
|
40
|
+
allowNo: true,
|
|
41
|
+
description: 'Enable or disable ingress (message reception) to the queue.',
|
|
42
|
+
}),
|
|
43
|
+
'max-msg-spool-usage': Flags.integer({
|
|
44
|
+
char: 's',
|
|
45
|
+
description: 'The maximum message spool usage allowed by the queue, in megabytes (MB).',
|
|
46
|
+
min: 0,
|
|
47
|
+
}),
|
|
48
|
+
'max-redelivery-count': Flags.integer({
|
|
49
|
+
description: 'The maximum number of times a message will be redelivered before it is discarded or moved to the DMQ.',
|
|
50
|
+
min: 0,
|
|
51
|
+
}),
|
|
52
|
+
'max-ttl': Flags.integer({
|
|
53
|
+
description: 'The maximum time in seconds a message can stay in the queue when respect-ttl-enabled is true.',
|
|
54
|
+
min: 0,
|
|
55
|
+
}),
|
|
56
|
+
'msg-vpn-name': Flags.string({
|
|
57
|
+
char: 'v',
|
|
58
|
+
description: 'The name of the Message VPN.',
|
|
59
|
+
required: true,
|
|
60
|
+
}),
|
|
61
|
+
owner: Flags.string({
|
|
62
|
+
char: 'o',
|
|
63
|
+
description: 'The client username that owns the queue and has permission equivalent to delete.',
|
|
64
|
+
}),
|
|
65
|
+
permission: Flags.string({
|
|
66
|
+
char: 'p',
|
|
67
|
+
default: 'consume',
|
|
68
|
+
description: 'The permission level for all consumers of the queue, excluding the owner.',
|
|
69
|
+
options: ['consume', 'delete', 'modify-topic', 'no-access', 'read-only'],
|
|
70
|
+
}),
|
|
71
|
+
'queue-name': Flags.string({
|
|
72
|
+
char: 'q',
|
|
73
|
+
description: 'The name of the queue to create.',
|
|
74
|
+
required: true,
|
|
75
|
+
}),
|
|
76
|
+
'respect-ttl-enabled': Flags.boolean({
|
|
77
|
+
allowNo: true,
|
|
78
|
+
description: 'Enable or disable the respecting of the time-to-live (TTL) for messages.',
|
|
79
|
+
}),
|
|
80
|
+
};
|
|
81
|
+
async run() {
|
|
82
|
+
const { flags } = await this.parse(BrokerQueueCreate);
|
|
83
|
+
// Resolve broker identifier (broker-id OR broker-name are aliases)
|
|
84
|
+
const brokerIdentifier = flags['broker-id'] ?? flags['broker-name'] ?? '';
|
|
85
|
+
// Create SEMP connection using stored credentials
|
|
86
|
+
const sempConn = await resolveBrokerConnection(this, brokerIdentifier);
|
|
87
|
+
// Build queue creation request body
|
|
88
|
+
const queueBody = this.buildQueueRequest(flags);
|
|
89
|
+
// Make SEMP Config API call to create the queue
|
|
90
|
+
const endpoint = `/SEMP/v2/config/msgVpns/${flags['msg-vpn-name']}/queues`;
|
|
91
|
+
const sempResp = await sempConn.post(endpoint, queueBody);
|
|
92
|
+
// Display results
|
|
93
|
+
this.log(printObjectAsKeyValueTable(sempResp.data));
|
|
94
|
+
return sempResp;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Builds the queue creation request body from command flags
|
|
98
|
+
*/
|
|
99
|
+
buildQueueRequest(flags) {
|
|
100
|
+
return {
|
|
101
|
+
queueName: flags['queue-name'],
|
|
102
|
+
...(flags['access-type'] && { accessType: flags['access-type'] }),
|
|
103
|
+
...(flags['dead-msg-queue'] && { deadMsgQueue: flags['dead-msg-queue'] }),
|
|
104
|
+
...(flags['egress-enabled'] !== undefined && { egressEnabled: flags['egress-enabled'] }),
|
|
105
|
+
...(flags['ingress-enabled'] !== undefined && { ingressEnabled: flags['ingress-enabled'] }),
|
|
106
|
+
...(flags['max-msg-spool-usage'] !== undefined && { maxMsgSpoolUsage: flags['max-msg-spool-usage'] }),
|
|
107
|
+
...(flags['max-redelivery-count'] !== undefined && { maxRedeliveryCount: flags['max-redelivery-count'] }),
|
|
108
|
+
...(flags['max-ttl'] !== undefined && { maxTtl: flags['max-ttl'] }),
|
|
109
|
+
...(flags.owner && { owner: flags.owner }),
|
|
110
|
+
...(flags.permission && {
|
|
111
|
+
permission: flags.permission,
|
|
112
|
+
}),
|
|
113
|
+
...(flags['respect-ttl-enabled'] !== undefined && { respectTtlEnabled: flags['respect-ttl-enabled'] }),
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { run } from '@oclif/core';
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { run } from '@oclif/core';
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { ScCommand, ScConnection } from '@dishantlangayan/sc-cli-core';
|
|
2
|
+
import { Command } from '@oclif/core';
|
|
3
|
+
/**
|
|
4
|
+
* Resolves broker and creates authenticated SEMP connection
|
|
5
|
+
*
|
|
6
|
+
* This utility function handles the common pattern of resolving which broker
|
|
7
|
+
* to use for SEMP API calls. It validates the broker identifier exists in
|
|
8
|
+
* stored credentials and creates an authenticated connection.
|
|
9
|
+
*
|
|
10
|
+
* @param command - The ScCommand instance (for error handling and BrokerAuthManager access)
|
|
11
|
+
* @param brokerIdentifier - Broker ID or name from --broker-id or --broker-name flag
|
|
12
|
+
* @param timeout - Optional timeout override in milliseconds
|
|
13
|
+
* @returns Configured ScConnection instance ready for SEMP API calls
|
|
14
|
+
* @throws Will call command.error() with user-friendly messages for various error scenarios
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```typescript
|
|
18
|
+
* // In a command's run() method:
|
|
19
|
+
* const {flags} = await this.parse(MyCommand)
|
|
20
|
+
* const brokerIdentifier = flags['broker-id'] ?? flags['broker-name'] ?? ''
|
|
21
|
+
* const sempConn = await resolveBrokerConnection(this, brokerIdentifier)
|
|
22
|
+
* const resp = await sempConn.get('/SEMP/v2/config/msgVpns')
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
export declare function resolveBrokerConnection(command: ScCommand<typeof Command>, brokerIdentifier: string, timeout?: number): Promise<ScConnection>;
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { BrokerAuthError, BrokerAuthErrorCode } from '@dishantlangayan/sc-cli-core';
|
|
2
|
+
/**
|
|
3
|
+
* Resolves broker and creates authenticated SEMP connection
|
|
4
|
+
*
|
|
5
|
+
* This utility function handles the common pattern of resolving which broker
|
|
6
|
+
* to use for SEMP API calls. It validates the broker identifier exists in
|
|
7
|
+
* stored credentials and creates an authenticated connection.
|
|
8
|
+
*
|
|
9
|
+
* @param command - The ScCommand instance (for error handling and BrokerAuthManager access)
|
|
10
|
+
* @param brokerIdentifier - Broker ID or name from --broker-id or --broker-name flag
|
|
11
|
+
* @param timeout - Optional timeout override in milliseconds
|
|
12
|
+
* @returns Configured ScConnection instance ready for SEMP API calls
|
|
13
|
+
* @throws Will call command.error() with user-friendly messages for various error scenarios
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```typescript
|
|
17
|
+
* // In a command's run() method:
|
|
18
|
+
* const {flags} = await this.parse(MyCommand)
|
|
19
|
+
* const brokerIdentifier = flags['broker-id'] ?? flags['broker-name'] ?? ''
|
|
20
|
+
* const sempConn = await resolveBrokerConnection(this, brokerIdentifier)
|
|
21
|
+
* const resp = await sempConn.get('/SEMP/v2/config/msgVpns')
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
24
|
+
export async function resolveBrokerConnection(command, brokerIdentifier, timeout) {
|
|
25
|
+
try {
|
|
26
|
+
// Use type assertion to access protected method
|
|
27
|
+
const brokerAuthManager = await command.getBrokerAuthManager();
|
|
28
|
+
// Validate broker exists in stored credentials
|
|
29
|
+
try {
|
|
30
|
+
await brokerAuthManager.getBroker(brokerIdentifier);
|
|
31
|
+
}
|
|
32
|
+
catch (error) {
|
|
33
|
+
if (error instanceof BrokerAuthError && error.code === BrokerAuthErrorCode.BROKER_NOT_FOUND) {
|
|
34
|
+
command.error(`Broker '${brokerIdentifier}' not found. Please run 'broker:login:basic' to store broker credentials first.`, { exit: 2 });
|
|
35
|
+
}
|
|
36
|
+
throw error;
|
|
37
|
+
}
|
|
38
|
+
// Create SEMP connection using stored credentials
|
|
39
|
+
return await brokerAuthManager.createConnection(brokerIdentifier, timeout);
|
|
40
|
+
}
|
|
41
|
+
catch (error) {
|
|
42
|
+
// Handle BrokerAuthManager-specific errors
|
|
43
|
+
if (error instanceof BrokerAuthError) {
|
|
44
|
+
switch (error.code) {
|
|
45
|
+
case BrokerAuthErrorCode.BROKER_NOT_FOUND: {
|
|
46
|
+
command.error(`Broker '${brokerIdentifier}' not found. Please run 'broker:login:basic' to store broker credentials first.`, { exit: 2 });
|
|
47
|
+
break;
|
|
48
|
+
}
|
|
49
|
+
case BrokerAuthErrorCode.INVALID_ACCESS_TOKEN: {
|
|
50
|
+
command.error(`Invalid or expired credentials for broker '${brokerIdentifier}'. Please run 'broker:login:basic' again.`, { exit: 2 });
|
|
51
|
+
break;
|
|
52
|
+
}
|
|
53
|
+
default: {
|
|
54
|
+
command.error(`Broker authentication failed: ${error.message}`, { exit: 2 });
|
|
55
|
+
break;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
// Re-throw unexpected errors
|
|
60
|
+
throw error;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cloud API Type Definitions
|
|
3
|
+
* Based on https://api.solace.dev/cloud/openapi/63dc1facc5b9980042ed3901
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Port configuration for a service connection endpoint
|
|
7
|
+
*/
|
|
8
|
+
export interface Port {
|
|
9
|
+
port: number;
|
|
10
|
+
protocol: string;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Service connection endpoint
|
|
14
|
+
*/
|
|
15
|
+
export interface ServiceConnectionEndpoint {
|
|
16
|
+
accessType?: string;
|
|
17
|
+
creationState?: string;
|
|
18
|
+
description?: string;
|
|
19
|
+
hostNames?: string[];
|
|
20
|
+
id: string;
|
|
21
|
+
k8sServiceId?: string;
|
|
22
|
+
k8sServiceType?: string;
|
|
23
|
+
name: string;
|
|
24
|
+
ports: Port[];
|
|
25
|
+
type?: string;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Mission Control Manager credentials for SEMP access
|
|
29
|
+
*/
|
|
30
|
+
export interface MissionControlManagerCredential {
|
|
31
|
+
password: string;
|
|
32
|
+
token?: string;
|
|
33
|
+
username: string;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Message VPN configuration
|
|
37
|
+
*/
|
|
38
|
+
export interface MsgVpn {
|
|
39
|
+
managementAdminLoginCredential?: MissionControlManagerCredential;
|
|
40
|
+
missionControlManagerLoginCredential: MissionControlManagerCredential;
|
|
41
|
+
msgVpnName: string;
|
|
42
|
+
serviceLoginCredential?: {
|
|
43
|
+
password: string;
|
|
44
|
+
username: string;
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Broker configuration
|
|
49
|
+
*/
|
|
50
|
+
export interface Broker {
|
|
51
|
+
cluster?: {
|
|
52
|
+
name: string;
|
|
53
|
+
password: string;
|
|
54
|
+
primaryRouterName: string;
|
|
55
|
+
remoteAddress: string;
|
|
56
|
+
supportedAuthenticationMode?: string[];
|
|
57
|
+
};
|
|
58
|
+
managementReadOnlyLoginCredential?: MissionControlManagerCredential;
|
|
59
|
+
msgVpns?: MsgVpn[];
|
|
60
|
+
version?: string;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Event Broker Service response from Cloud API
|
|
64
|
+
*/
|
|
65
|
+
export interface EventBrokerService {
|
|
66
|
+
adminState?: string;
|
|
67
|
+
broker?: Broker;
|
|
68
|
+
createdTime?: string;
|
|
69
|
+
creationState?: string;
|
|
70
|
+
datacenterId?: string;
|
|
71
|
+
defaultManagementHostname: string;
|
|
72
|
+
environmentId?: string;
|
|
73
|
+
eventBrokerServiceVersion?: string;
|
|
74
|
+
id: string;
|
|
75
|
+
msgVpnName: string;
|
|
76
|
+
name: string;
|
|
77
|
+
ownedBy?: string;
|
|
78
|
+
serviceClassId?: string;
|
|
79
|
+
serviceConnectionEndpoints?: ServiceConnectionEndpoint[];
|
|
80
|
+
type?: string;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* List services response
|
|
84
|
+
*/
|
|
85
|
+
export interface ListServicesResponse {
|
|
86
|
+
data: EventBrokerService[];
|
|
87
|
+
meta?: {
|
|
88
|
+
pagination?: {
|
|
89
|
+
count: number;
|
|
90
|
+
pageNumber: number;
|
|
91
|
+
pageSize: number;
|
|
92
|
+
totalCount: number;
|
|
93
|
+
totalPages: number;
|
|
94
|
+
};
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Get service details response
|
|
99
|
+
*/
|
|
100
|
+
export interface GetServiceResponse {
|
|
101
|
+
data: EventBrokerService;
|
|
102
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SEMP Config API type definitions for MsgVpnQueue operations
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Request body for creating a queue via SEMP Config API
|
|
6
|
+
*/
|
|
7
|
+
export interface MsgVpnQueueCreateRequest {
|
|
8
|
+
accessType?: 'exclusive' | 'non-exclusive';
|
|
9
|
+
deadMsgQueue?: string;
|
|
10
|
+
egressEnabled?: boolean;
|
|
11
|
+
ingressEnabled?: boolean;
|
|
12
|
+
maxMsgSpoolUsage?: number;
|
|
13
|
+
maxRedeliveryCount?: number;
|
|
14
|
+
maxTtl?: number;
|
|
15
|
+
owner?: string;
|
|
16
|
+
permission?: 'consume' | 'delete' | 'modify-topic' | 'no-access' | 'read-only';
|
|
17
|
+
queueName: string;
|
|
18
|
+
respectTtlEnabled?: boolean;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Response from SEMP Config API queue creation
|
|
22
|
+
*/
|
|
23
|
+
export interface MsgVpnQueueCreateResponse {
|
|
24
|
+
data: MsgVpnQueue;
|
|
25
|
+
links?: {
|
|
26
|
+
[key: string]: unknown;
|
|
27
|
+
uri?: string;
|
|
28
|
+
};
|
|
29
|
+
meta: SempMeta;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* MsgVpnQueue object returned by SEMP
|
|
33
|
+
*/
|
|
34
|
+
export interface MsgVpnQueue {
|
|
35
|
+
[key: string]: unknown;
|
|
36
|
+
msgVpnName: string;
|
|
37
|
+
queueName: string;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* SEMP response metadata
|
|
41
|
+
*/
|
|
42
|
+
export interface SempMeta {
|
|
43
|
+
[key: string]: unknown;
|
|
44
|
+
request?: {
|
|
45
|
+
method?: string;
|
|
46
|
+
uri?: string;
|
|
47
|
+
};
|
|
48
|
+
responseCode?: number;
|
|
49
|
+
}
|