Skip to content

Commit 2aaebf3

Browse files
Commands for Event Broker Services
1 parent 451ed95 commit 2aaebf3

File tree

10 files changed

+458
-1
lines changed

10 files changed

+458
-1
lines changed
Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
import {Command, Flags} from '@oclif/core'
2+
import {table} from 'table'
3+
4+
import {EventBrokerCreateApiResponse, EventBrokerCreateDetail} from '../../../types/broker.js'
5+
import {camelCaseToTitleCase} from '../../../util/internal.js'
6+
import {ScConnection} from '../../../util/sc-connection.js'
7+
8+
export default class MissionctrlBrokerCreate extends Command {
9+
static override args = {}
10+
static override description = `Create an event broker service. You must provide a unique name and select a service class and datacenter. You can optionally define other properties for the event broker service.
11+
12+
Your token must have one of the permissions listed in the Token Permissions.
13+
14+
Token Permissions: [ \`services:post\` ]`
15+
static override examples = ['<%= config.bin %> <%= command.id %> --datacenter-id=MyDatacenterId --name=MyBrokerName --service-class-id=DEVELOPER']
16+
static override flags = {
17+
'datacenter-id': Flags.string({
18+
char: 'd',
19+
description: 'The identifier of the datacenter.',
20+
required: true,
21+
}),
22+
'env-name': Flags.string({
23+
char: 'e',
24+
description:
25+
'The name of the environment environment where you want to create the service. If no name is provided, the service will be created in the default environment.',
26+
}),
27+
locked: Flags.boolean({
28+
char: 'l',
29+
default: false,
30+
description:
31+
'Indicates if you can delete the event broker service after creating it. The default value is false.',
32+
}),
33+
'max-spool-usage': Flags.string({
34+
char: 's',
35+
description:
36+
'The message spool size, in gigabytes (GB). A default message spool size is provided if this is not specified.',
37+
}),
38+
'msg-vpn-name': Flags.string({
39+
char: 'm',
40+
description: 'The message VPN name. A default message VPN name is provided when this is not specified.',
41+
}),
42+
name: Flags.string({char: 'n', description: 'Name of the event broker service to create.', required: true}),
43+
'service-class-id': Flags.string({
44+
char: 'c',
45+
description: 'Supported service classes.',
46+
required: true,
47+
}),
48+
version: Flags.string({
49+
char: 'v',
50+
description: 'The event broker version. A default version is provided when this is not specified.',
51+
}),
52+
}
53+
54+
public async run(): Promise<void> {
55+
const {flags} = await this.parse(MissionctrlBrokerCreate)
56+
57+
const datacenterId = flags['datacenter-id'] ?? ''
58+
let envName = flags['env-name'] ?? ''
59+
const locked = flags.locked ?? false
60+
// const maxSpoolUsage = flags['max-spool-usage'] ?? ''
61+
// const msgVpnName = flags['msg-vpn-name'] ?? ''
62+
const name = flags.name ?? ''
63+
const redundancyGroupSslEnabled = false // This flag is not defined yet, but it is used in the API body
64+
const serviceClassId = flags['service-class-id'] ?? 'DEVELOPER'
65+
// const version = flags.version ?? ''
66+
67+
const conn = new ScConnection()
68+
69+
// API url
70+
const apiUrl: string = `/missionControl/eventBrokerServices`
71+
72+
// If envName is provided, retrieve the environment ID
73+
if (envName) {
74+
const envApiUrl = `/platform/environments?name=${envName}`
75+
const envResp = await conn.get<{data: {id: string}[]}>(envApiUrl)
76+
if( envResp.data.length > 1) {
77+
this.error(`Multiple environments found with: ${name}. Exactly one environment must match the provided name.`)
78+
} else {
79+
envName = envResp.data[0]?.id
80+
}
81+
}
82+
83+
// API body
84+
const body: Record<string, unknown> = {
85+
datacenterId,
86+
envName,
87+
// eventBrokerVersion: version,
88+
locked,
89+
// maxSpoolUsage,
90+
// msgVpnName,
91+
name,
92+
redundancyGroupSslEnabled,
93+
serviceClassId,
94+
}
95+
96+
// API call
97+
const resp = await conn.post<EventBrokerCreateApiResponse>(apiUrl, body)
98+
// Display results
99+
this.log('Event broker service created successfully.')
100+
this.print(resp.data)
101+
}
102+
103+
private print(broker: EventBrokerCreateDetail): void {
104+
this.log()
105+
const tableRows = [
106+
['Key', 'Value'],
107+
...Object.entries(broker).map(([key, value]) => [camelCaseToTitleCase(key), value]),
108+
]
109+
110+
// Table config
111+
const config = {
112+
columns: {
113+
1: {width: 50, wrapWord: true},
114+
},
115+
drawHorizontalLine(lineIndex: number, rowCount: number) {
116+
return lineIndex === 0 || lineIndex === 1 || lineIndex === rowCount
117+
},
118+
}
119+
this.log(table(tableRows, config))
120+
}
121+
}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
import {Command, Flags} from '@oclif/core'
2+
3+
import {EventBrokerListApiResponse} from '../../../types/broker.js'
4+
import {ScConnection} from '../../../util/sc-connection.js'
5+
6+
export default class MissionctrlBrokerDelete extends Command {
7+
static override args = {}
8+
static override description = `Delete a service using its unique identifier.
9+
10+
Your token must have one of the permissions listed in the Token Permissions.
11+
12+
Token Permissions: [ \`services:delete\` **or** \`services:delete:self\` **or** \`mission_control:access\` ]`
13+
static override examples = [
14+
'<%= config.bin %> <%= command.id %> --broker-id=MyBrokerId',
15+
'<%= config.bin %> <%= command.id %> --name=MyBrokerName',
16+
]
17+
static override flags = {
18+
// flag for getting environment by id (-e, --env-id)
19+
'broker-id': Flags.string({
20+
char: 'e',
21+
description: 'Id of the event broker service.',
22+
exactlyOne: ['broker-id', 'name'],
23+
}),
24+
// flag for getting environment by name (-n, --name=VALUE)
25+
name: Flags.string({
26+
char: 'n',
27+
description: 'Name of the event broker service.',
28+
exactlyOne: ['broker-id', 'name'],
29+
}),
30+
}
31+
32+
public async run(): Promise<void> {
33+
const {flags} = await this.parse(MissionctrlBrokerDelete)
34+
35+
const name = flags.name ?? ''
36+
const brokerId = flags['broker-id'] ?? ''
37+
38+
const conn = new ScConnection()
39+
40+
// API url
41+
let apiUrl: string = `/missionControl/eventBrokerServices`
42+
let brokerIdToDelete: string | undefined = brokerId
43+
44+
// If broker name was provided, get the broker matching provided name and delete. If more than one broker matches, an error will be thrown.
45+
// If broker id was provided, delete broker with that id
46+
if (name) {
47+
// API call to get broker by name
48+
const getBrokersApiUrl = `${apiUrl}?customAttributes=name=="${name}"`
49+
const resp = await conn.get<EventBrokerListApiResponse>(getBrokersApiUrl)
50+
if (resp.data.length > 1) {
51+
this.error(
52+
`Multiple event broker services found with: ${name}. Exactly one broker must match the provided name.`,
53+
)
54+
} else {
55+
brokerIdToDelete = resp.data[0]?.id
56+
}
57+
}
58+
59+
// API call to delete environment by id
60+
apiUrl += `/${brokerIdToDelete}`
61+
await conn.delete<string>(apiUrl)
62+
this.log(`Event broker service with id '${brokerIdToDelete}' has been deleted successfully.`)
63+
}
64+
}
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
import {Command, Flags} from '@oclif/core'
2+
import {table} from 'table'
3+
4+
import {EventBrokerListApiResponse, EventBrokerServiceDetail} from '../../../types/broker.js'
5+
import {camelCaseToTitleCase} from '../../../util/internal.js'
6+
import {ScConnection} from '../../../util/sc-connection.js'
7+
8+
export default class MissionctrlBrokerDisplay extends Command {
9+
static override args = {}
10+
static override description = `Get the details of an event broker service using its identifier or name.
11+
12+
Use either the Event Broker's ID (--broker-id) or name of the Event Broker (--name).
13+
14+
Token Permissions: [ \`mission_control:access\` **or** \`services:get\` **or** \`services:get:self\` **or** \`services:view\` **or** \`services:view:self\` ]`
15+
static override examples = ['<%= config.bin %> <%= command.id %>']
16+
static override flags = {
17+
'broker-id': Flags.string({
18+
char: 'b',
19+
description: 'Id of the event broker service.',
20+
exactlyOne: ['broker-id', 'name'],
21+
}),
22+
name: Flags.string({
23+
char: 'n',
24+
description: 'Name of the event broker service.',
25+
exactlyOne: ['broker-id', 'name'],
26+
}),
27+
}
28+
29+
public async run(): Promise<void> {
30+
const {flags} = await this.parse(MissionctrlBrokerDisplay)
31+
32+
const name = flags.name ?? ''
33+
const brokerId = flags['broker-id'] ?? ''
34+
35+
const conn = new ScConnection()
36+
37+
// API url
38+
let apiUrl: string = `/missionControl/eventBrokerServices`
39+
40+
// If broker name provided, get all brokers matching provided name
41+
// If broker id provided, get broker with that id
42+
if (brokerId) {
43+
// API call to get broker by id
44+
apiUrl += `/${brokerId}`
45+
const resp = await conn.get<EventBrokerServiceDetail>(apiUrl)
46+
this.print(resp)
47+
} else if (name) {
48+
// API call to get broker by name
49+
apiUrl += `?customAttributes=name=="${name}"`
50+
const resp = await conn.get<EventBrokerListApiResponse>(apiUrl)
51+
for (const broker of resp.data) {
52+
this.print(broker)
53+
}
54+
} else {
55+
this.error('Either --broker-id or --name must be provided.')
56+
}
57+
}
58+
59+
private print(broker: EventBrokerServiceDetail): void {
60+
this.log()
61+
const tableRows = [
62+
['Key', 'Value'],
63+
...Object.entries(broker).map(([key, value]) => [camelCaseToTitleCase(key), value]),
64+
]
65+
66+
// Table config
67+
const config = {
68+
columns: {
69+
1: {width: 50, wrapWord: true},
70+
},
71+
drawHorizontalLine(lineIndex: number, rowCount: number) {
72+
return lineIndex === 0 || lineIndex === 1 || lineIndex === rowCount
73+
},
74+
}
75+
this.log(table(tableRows, config))
76+
}
77+
}
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
import {Command, Flags} from '@oclif/core'
2+
import {table} from 'table'
3+
4+
import {EventBrokerListApiResponse, EventBrokerServiceDetail} from '../../../types/broker.js'
5+
import {ScConnection} from '../../../util/sc-connection.js'
6+
7+
export default class MissionctrlBrokerList extends Command {
8+
static override args = {}
9+
static override description = `Get a listing of event broker services.
10+
11+
Your token must have one of the permissions listed in the Token Permissions.
12+
13+
Token Permissions: [ \`mission_control:access\` **or** \`services:get\` **or** \`services:get:self\` **or** \`services:view\` **or** \`services:view:self\` ]`
14+
static override examples = ['<%= config.bin %> <%= command.id %> --name=MyBrokerName --pageNumber=1 --pageSize=10 --sort=name:asc']
15+
static override flags = {
16+
// flag with a value (-n, --name=VALUE)
17+
name: Flags.string({char: 'n', description: 'Name of the event broker service to match on.'}),
18+
// pageNumber (--pageNumber=VALUE)
19+
pageNumber: Flags.integer({description: 'The page number to get. Defaults to 1'}),
20+
// pageSize (--pageSize=VALUE)
21+
pageSize: Flags.integer({
22+
description: 'The number of event broker services to return per page. Defaults to 100',
23+
max: 100,
24+
min: 1,
25+
}),
26+
// sort (--sort=VALUE)
27+
sort: Flags.string({
28+
description: `Sort the returned event broker services by attribute.
29+
30+
You can use the following value formats for the sort order:
31+
32+
* attributes-names
33+
* attributes-names:sort-order`,
34+
}),
35+
}
36+
37+
public async run(): Promise<void> {
38+
const {flags} = await this.parse(MissionctrlBrokerList)
39+
40+
const conn = new ScConnection()
41+
42+
const pageSize = flags.pageSize ?? 10
43+
const pageNumber = flags.pageNumber ?? 1
44+
45+
// API url
46+
let apiUrl: string = `/missionControl/eventBrokerServices?pageSize=${pageSize}&pageNumber=${pageNumber}`
47+
if (flags.sort) {
48+
apiUrl += `&sort=${flags.sort}`
49+
}
50+
51+
if (flags.name) {
52+
apiUrl += `&customAttributes=name=="${flags.name}"`
53+
}
54+
55+
// API call
56+
const resp = await conn.get<EventBrokerListApiResponse>(apiUrl)
57+
58+
// Array to output as table
59+
const brokerArray = [
60+
['Name', 'Id', 'Type', 'Version', 'Owned By', 'Datacenter Id', 'Service Class Id'],
61+
...resp.data.map((item: EventBrokerServiceDetail) => [
62+
item.name,
63+
item.id,
64+
item.type,
65+
item.eventBrokerServiceVersion,
66+
item.ownedBy,
67+
item.datacenterId,
68+
item.serviceClassId,
69+
]),
70+
]
71+
// Display results as a table
72+
this.log()
73+
this.log(table(brokerArray))
74+
}
75+
}

0 commit comments

Comments
 (0)