@flowfuse/driver-kubernetes 2.21.3-e342621-202509150738.0 → 2.22.1-468ab35-202510010835.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/.github/workflows/release-publish.yml +1 -1
- package/CHANGELOG.md +9 -0
- package/kubernetes.js +66 -23
- package/package.json +1 -1
|
@@ -13,6 +13,6 @@ jobs:
|
|
|
13
13
|
with:
|
|
14
14
|
node-version: 18
|
|
15
15
|
- run: npm ci
|
|
16
|
-
- uses: JS-DevTools/npm-publish@
|
|
16
|
+
- uses: JS-DevTools/npm-publish@7f8fe47b3bea1be0c3aec2b717c5ec1f3e03410b # v4.1.1
|
|
17
17
|
with:
|
|
18
18
|
token: ${{ secrets.NPM_PUBLISH_TOKEN }}
|
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,12 @@
|
|
|
1
|
+
#### 2.22.0: Release
|
|
2
|
+
|
|
3
|
+
- Bump JS-DevTools/npm-publish from 4.0.0 to 4.0.1 (#236)
|
|
4
|
+
- Increase http timeout for forge polling nr-launcher (#235)
|
|
5
|
+
- Bump JS-DevTools/npm-publish from 3.1.1 to 4.0.0 (#234)
|
|
6
|
+
- Bump tar-fs from 3.1.0 to 3.1.1 (#238) @app/dependabot
|
|
7
|
+
- Force 24 hour time out to be a string (#237) @hardillb
|
|
8
|
+
- Add team broker mqtt agent support (#232) @hardillb
|
|
9
|
+
|
|
1
10
|
#### 2.21.2: Release
|
|
2
11
|
|
|
3
12
|
- Bump actions/setup-node from 4.4.0 to 5.0.0 (#230)
|
package/kubernetes.js
CHANGED
|
@@ -202,6 +202,13 @@ const createDeployment = async (project, options) => {
|
|
|
202
202
|
localPod.spec.containers[0].resources.limits.cpu = `${stack.cpu * 10}m`
|
|
203
203
|
}
|
|
204
204
|
|
|
205
|
+
if (this._app.config.driver.options?.projectLabels) {
|
|
206
|
+
localPod.spec.labels = {
|
|
207
|
+
...localPod.spec.labels,
|
|
208
|
+
...this._app.config.driver.options.projectLabels
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
|
|
205
212
|
const ha = await project.getSetting('ha')
|
|
206
213
|
if (ha?.replicas > 1) {
|
|
207
214
|
localDeployment.spec.replicas = ha.replicas
|
|
@@ -225,6 +232,9 @@ const createService = async (project, options) => {
|
|
|
225
232
|
throw new Error('Service type must be either NodePort or ClusterIP')
|
|
226
233
|
}
|
|
227
234
|
localService.spec.type = serviceType
|
|
235
|
+
if (this._app.config.driver.options?.projectLabels) {
|
|
236
|
+
localService.metadata.labels = this._app.config.driver.options.projectLabels
|
|
237
|
+
}
|
|
228
238
|
return localService
|
|
229
239
|
}
|
|
230
240
|
|
|
@@ -264,6 +274,10 @@ const createIngress = async (project, options) => {
|
|
|
264
274
|
localIngress.metadata.annotations[key] = mustache(localIngress.metadata.annotations[key], exposedData)
|
|
265
275
|
})
|
|
266
276
|
|
|
277
|
+
if (this._app.config.driver.options?.projectLabels) {
|
|
278
|
+
localIngress.metadata.labels = this._app.config.driver.options.projectLabels
|
|
279
|
+
}
|
|
280
|
+
|
|
267
281
|
localIngress.metadata.name = project.safeName
|
|
268
282
|
localIngress.spec.rules[0].host = url.host
|
|
269
283
|
localIngress.spec.rules[0].http.paths[0].backend.service.name = `${prefix}${project.safeName}`
|
|
@@ -312,6 +326,10 @@ const createCustomIngress = async (project, hostname, options) => {
|
|
|
312
326
|
customIngress.spec.ingressClassName = `${this._customHostname.ingressClass}`
|
|
313
327
|
}
|
|
314
328
|
|
|
329
|
+
if (this._app.config.driver.options?.projectLabels) {
|
|
330
|
+
customIngress.metadata.labels = this._app.config.driver.options.projectLabels
|
|
331
|
+
}
|
|
332
|
+
|
|
315
333
|
return customIngress
|
|
316
334
|
}
|
|
317
335
|
|
|
@@ -337,6 +355,12 @@ const createPersistentVolumeClaim = async (project, options) => {
|
|
|
337
355
|
'ff-project-id': project.id,
|
|
338
356
|
'ff-project-name': project.safeName
|
|
339
357
|
}
|
|
358
|
+
if (this._app.config.driver.options?.projectLabels) {
|
|
359
|
+
pvc.metadata.labels = {
|
|
360
|
+
...pvc.metadata.labels,
|
|
361
|
+
...this._app.config.driver.options.projectLabels
|
|
362
|
+
}
|
|
363
|
+
}
|
|
340
364
|
console.log(`PVC: ${JSON.stringify(pvc, null, 2)}`)
|
|
341
365
|
return pvc
|
|
342
366
|
}
|
|
@@ -521,7 +545,8 @@ const getStaticFileUrl = async (instance, filePath) => {
|
|
|
521
545
|
}
|
|
522
546
|
|
|
523
547
|
const createMQTTTopicAgent = async (broker) => {
|
|
524
|
-
|
|
548
|
+
const agent = broker.constructor.name === 'TeamBrokerAgent'
|
|
549
|
+
this._app.log.info(`[k8s] Starting MQTT Schema agent ${agent ? 'team-broker' : broker.hashid} for ${broker.Team.hashid}`)
|
|
525
550
|
const localPod = JSON.parse(JSON.stringify(mqttSchemaAgentPodTemplate))
|
|
526
551
|
const localService = JSON.parse(JSON.stringify(mqttSchemaAgentServiceTemplate))
|
|
527
552
|
|
|
@@ -530,25 +555,39 @@ const createMQTTTopicAgent = async (broker) => {
|
|
|
530
555
|
const { token } = await broker.refreshAuthTokens()
|
|
531
556
|
localPod.spec.containers[0].env.push({ name: 'FORGE_TEAM_TOKEN', value: token })
|
|
532
557
|
localPod.spec.containers[0].env.push({ name: 'FORGE_URL', value: this._app.config.api_url })
|
|
533
|
-
localPod.spec.containers[0].env.push({ name: 'FORGE_BROKER_ID', value: broker.hashid })
|
|
558
|
+
localPod.spec.containers[0].env.push({ name: 'FORGE_BROKER_ID', value: agent ? 'team-broker' : broker.hashid })
|
|
534
559
|
localPod.spec.containers[0].env.push({ name: 'FORGE_TEAM_ID', value: broker.Team.hashid })
|
|
560
|
+
if (agent) {
|
|
561
|
+
// env vars must be strings not numbers
|
|
562
|
+
localPod.spec.containers[0].env.push({ name: 'FORGE_TIMEOUT', value: '24' })
|
|
563
|
+
}
|
|
535
564
|
|
|
536
565
|
if (this._app.config.driver.options.projectSelector) {
|
|
537
566
|
localPod.spec.nodeSelector = this._app.config.driver.options.projectSelector
|
|
538
567
|
}
|
|
539
568
|
|
|
540
|
-
localPod.metadata.name = `mqtt-schema-agent-${broker.Team.hashid.toLowerCase()}-${broker.hashid.toLowerCase()}`
|
|
569
|
+
localPod.metadata.name = `mqtt-schema-agent-${broker.Team.hashid.toLowerCase()}-${agent ? 'team-broker' : broker.hashid.toLowerCase()}`
|
|
541
570
|
localPod.metadata.labels = {
|
|
542
571
|
name: `mqtt-schema-agent-${broker.Team.hashid.toLowerCase()}-${broker.hashid.toLowerCase()}`,
|
|
543
572
|
team: broker.Team.hashid,
|
|
544
|
-
broker: broker.hashid
|
|
573
|
+
broker: agent ? 'team-broker' : broker.hashid
|
|
545
574
|
}
|
|
546
|
-
localService.metadata.name = `mqtt-schema-agent-${broker.Team.hashid.toLowerCase()}-${broker.hashid.toLowerCase()}`
|
|
575
|
+
localService.metadata.name = `mqtt-schema-agent-${broker.Team.hashid.toLowerCase()}-${agent ? 'team-broker' : broker.hashid.toLowerCase()}`
|
|
547
576
|
localService.metadata.labels = {
|
|
548
577
|
team: broker.Team.hashid,
|
|
549
|
-
broker: broker.hashid
|
|
578
|
+
broker: agent ? 'team-broker' : broker.hashid
|
|
579
|
+
}
|
|
580
|
+
if (this._app.config.driver.options?.projectLabels) {
|
|
581
|
+
localPod.spec.labels = {
|
|
582
|
+
...localPod.spec.labels,
|
|
583
|
+
...this._app.config.driver.options.projectLabels
|
|
584
|
+
}
|
|
585
|
+
localService.metadata.labels = {
|
|
586
|
+
...localService.metadata.labels,
|
|
587
|
+
...this._app.config.driver.options.projectLabels
|
|
588
|
+
}
|
|
550
589
|
}
|
|
551
|
-
localService.spec.selector.name = `mqtt-schema-agent-${broker.Team.hashid.toLowerCase()}-${broker.hashid.toLowerCase()}`
|
|
590
|
+
localService.spec.selector.name = `mqtt-schema-agent-${broker.Team.hashid.toLowerCase()}-${agent ? 'team-broker' : broker.hashid.toLowerCase()}`
|
|
552
591
|
|
|
553
592
|
// TODO remove registry entry
|
|
554
593
|
localPod.spec.containers[0].image = this._app.config.driver.options?.mqttSchemaContainer || `${this._app.config.driver.options.registry ? this._app.config.driver.options.registry + '/' : ''}flowfuse/mqtt-schema-agent`
|
|
@@ -560,7 +599,7 @@ const createMQTTTopicAgent = async (broker) => {
|
|
|
560
599
|
await this._k8sApi.createNamespacedPod({ namespace, body: localPod })
|
|
561
600
|
await this._k8sApi.createNamespacedService({ namespace, body: localService })
|
|
562
601
|
} catch (err) {
|
|
563
|
-
this._app.log.error(`[k8s] Problem creating MQTT Agent ${broker.hashid} in ${namespace} - ${err.toString()} ${err.stack}`)
|
|
602
|
+
this._app.log.error(`[k8s] Problem creating MQTT Agent ${agent ? 'team-broker' : broker.hashid} in ${namespace} - ${err.toString()} ${err.stack}`)
|
|
564
603
|
}
|
|
565
604
|
}
|
|
566
605
|
|
|
@@ -699,15 +738,16 @@ module.exports = {
|
|
|
699
738
|
|
|
700
739
|
// Check restarting MQTT-Schema-Agent
|
|
701
740
|
brokers.forEach(async (broker) => {
|
|
741
|
+
const agent = broker.constructor.name === 'TeamBrokerAgent'
|
|
702
742
|
if (broker.Team && broker.state === 'running') {
|
|
703
743
|
try {
|
|
704
|
-
this._app.log.info(`[k8s] Testing MQTT Agent ${broker.hashid} in ${namespace} pod exists`)
|
|
705
|
-
this._app.log.debug(`mqtt-schema-agent-${broker.Team.hashid.toLowerCase()}-${broker.hashid.toLowerCase()}`)
|
|
706
|
-
await this._k8sApi.readNamespacedPodStatus({ name: `mqtt-schema-agent-${broker.Team.hashid.toLowerCase()}-${broker.hashid.toLowerCase()}`, namespace })
|
|
707
|
-
this._app.log.info(`[k8s] MQTT Agent pod ${broker.hashid} in ${namespace} found`)
|
|
744
|
+
this._app.log.info(`[k8s] Testing MQTT Agent ${agent ? 'team-broker' : broker.hashid} in ${namespace} pod exists`)
|
|
745
|
+
this._app.log.debug(`mqtt-schema-agent-${broker.Team.hashid.toLowerCase()}-${agent ? 'team-broker' : broker.hashid.toLowerCase()}`)
|
|
746
|
+
await this._k8sApi.readNamespacedPodStatus({ name: `mqtt-schema-agent-${broker.Team.hashid.toLowerCase()}-${agent ? 'team-broker' : broker.hashid.toLowerCase()}`, namespace })
|
|
747
|
+
this._app.log.info(`[k8s] MQTT Agent pod ${agent ? 'team-broker' : broker.hashid} in ${namespace} found`)
|
|
708
748
|
} catch (err) {
|
|
709
|
-
this._app.log.debug(`[k8s] MQTT Agent ${broker.hashid} - failed ${err.toString()}`)
|
|
710
|
-
this._app.log.debug(`[k8s] MQTT Agent ${broker.hashid} - recreating pod`)
|
|
749
|
+
this._app.log.debug(`[k8s] MQTT Agent ${agent ? 'team-broker' : broker.hashid} - failed ${err.toString()}`)
|
|
750
|
+
this._app.log.debug(`[k8s] MQTT Agent ${agent ? 'team-broker' : broker.hashid} - recreating pod`)
|
|
711
751
|
await createMQTTTopicAgent(broker)
|
|
712
752
|
}
|
|
713
753
|
}
|
|
@@ -1142,7 +1182,7 @@ module.exports = {
|
|
|
1142
1182
|
const addresses = await getEndpoints(project)
|
|
1143
1183
|
const logRequests = []
|
|
1144
1184
|
for (const address in addresses) {
|
|
1145
|
-
logRequests.push(got.get(`http://${addresses[address]}:2880/flowforge/logs`, { timeout: { request:
|
|
1185
|
+
logRequests.push(got.get(`http://${addresses[address]}:2880/flowforge/logs`, { timeout: { request: 2000 } }).json())
|
|
1146
1186
|
}
|
|
1147
1187
|
const results = await Promise.all(logRequests)
|
|
1148
1188
|
const combinedResults = results.flat(1)
|
|
@@ -1150,7 +1190,7 @@ module.exports = {
|
|
|
1150
1190
|
return combinedResults
|
|
1151
1191
|
} else {
|
|
1152
1192
|
const prefix = project.safeName.match(/^[0-9]/) ? 'srv-' : ''
|
|
1153
|
-
const result = await got.get(`http://${prefix}${project.safeName}.${this._namespace}:2880/flowforge/logs`, { timeout: { request:
|
|
1193
|
+
const result = await got.get(`http://${prefix}${project.safeName}.${this._namespace}:2880/flowforge/logs`, { timeout: { request: 2000 } }).json()
|
|
1154
1194
|
return result
|
|
1155
1195
|
}
|
|
1156
1196
|
},
|
|
@@ -1280,31 +1320,34 @@ module.exports = {
|
|
|
1280
1320
|
createMQTTTopicAgent(broker)
|
|
1281
1321
|
},
|
|
1282
1322
|
stopBrokerAgent: async (broker) => {
|
|
1323
|
+
const agent = broker.constructor.name === 'TeamBrokerAgent'
|
|
1283
1324
|
try {
|
|
1284
|
-
await this._k8sApi.deleteNamespacedService({ name: `mqtt-schema-agent-${broker.Team.hashid.toLowerCase()}-${broker.hashid.toLowerCase()}`, namespace: this._namespace })
|
|
1285
|
-
await this._k8sApi.deleteNamespacedPod({ name: `mqtt-schema-agent-${broker.Team.hashid.toLowerCase()}-${broker.hashid.toLowerCase()}`, namespace: this._namespace })
|
|
1325
|
+
await this._k8sApi.deleteNamespacedService({ name: `mqtt-schema-agent-${broker.Team.hashid.toLowerCase()}-${agent ? 'team-broker' : broker.hashid.toLowerCase()}`, namespace: this._namespace })
|
|
1326
|
+
await this._k8sApi.deleteNamespacedPod({ name: `mqtt-schema-agent-${broker.Team.hashid.toLowerCase()}-${agent ? 'team-broker' : broker.hashid.toLowerCase()}`, namespace: this._namespace })
|
|
1286
1327
|
} catch (err) {
|
|
1287
|
-
this._app.log.error(`[k8s] Error deleting MQTT Agent ${broker.hashid}: ${err.toString()} ${err.code}`)
|
|
1328
|
+
this._app.log.error(`[k8s] Error deleting MQTT Agent ${agent ? 'team-broker' : broker.hashid}: ${err.toString()} ${err.code}`)
|
|
1288
1329
|
}
|
|
1289
1330
|
},
|
|
1290
1331
|
getBrokerAgentState: async (broker) => {
|
|
1332
|
+
const agent = broker.constructor.name === 'TeamBrokerAgent'
|
|
1291
1333
|
try {
|
|
1292
|
-
const status = await got.get(`http://mqtt-schema-agent-${broker.Team.hashid.toLowerCase()}-${broker.hashid.toLowerCase()}.${this._namespace}:3500/api/v1/status`, { timeout: { request: 1000 } }).json()
|
|
1334
|
+
const status = await got.get(`http://mqtt-schema-agent-${broker.Team.hashid.toLowerCase()}-${agent ? 'team-broker' : broker.hashid.toLowerCase()}.${this._namespace}:3500/api/v1/status`, { timeout: { request: 1000 } }).json()
|
|
1293
1335
|
return status
|
|
1294
1336
|
} catch (err) {
|
|
1295
1337
|
return { error: 'error_getting_status', message: err.toString() }
|
|
1296
1338
|
}
|
|
1297
1339
|
},
|
|
1298
1340
|
sendBrokerAgentCommand: async (broker, command) => {
|
|
1341
|
+
const agent = broker.constructor.name === 'TeamBrokerAgent'
|
|
1299
1342
|
if (command === 'start' || command === 'restart') {
|
|
1300
1343
|
try {
|
|
1301
|
-
await got.post(`http://mqtt-schema-agent-${broker.Team.hashid.toLowerCase()}-${broker.hashid.toLowerCase()}.${this._namespace}:3500/api/v1/commands/start`, { timeout: { request: 1000 } })
|
|
1344
|
+
await got.post(`http://mqtt-schema-agent-${broker.Team.hashid.toLowerCase()}-${agent ? 'team-broker' : broker.hashid.toLowerCase()}.${this._namespace}:3500/api/v1/commands/start`, { timeout: { request: 1000 } })
|
|
1302
1345
|
} catch (err) {
|
|
1303
1346
|
|
|
1304
1347
|
}
|
|
1305
1348
|
} else if (command === 'stop') {
|
|
1306
1349
|
try {
|
|
1307
|
-
await got.post(`http://mqtt-schema-agent-${broker.Team.hashid.toLowerCase()}-${broker.hashid.toLowerCase()}.${this._namespace}:3500/api/v1/commands/stop`, { timeout: { request: 1000 } })
|
|
1350
|
+
await got.post(`http://mqtt-schema-agent-${broker.Team.hashid.toLowerCase()}-${agent ? 'team-broker' : broker.hashid.toLowerCase()}.${this._namespace}:3500/api/v1/commands/stop`, { timeout: { request: 1000 } })
|
|
1308
1351
|
} catch (err) {
|
|
1309
1352
|
|
|
1310
1353
|
}
|
|
@@ -1333,7 +1376,7 @@ module.exports = {
|
|
|
1333
1376
|
}
|
|
1334
1377
|
} else {
|
|
1335
1378
|
const prefix = project.safeName.match(/^[0-9]/) ? 'srv-' : ''
|
|
1336
|
-
const result = await got.get(`http://${prefix}${project.safeName}.${this._namespace}:2880/flowforge/resources`, { timeout: { request:
|
|
1379
|
+
const result = await got.get(`http://${prefix}${project.safeName}.${this._namespace}:2880/flowforge/resources`, { timeout: { request: 2000 } }).json()
|
|
1337
1380
|
if (Array.isArray(result)) {
|
|
1338
1381
|
return {
|
|
1339
1382
|
meta: {},
|