@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.
@@ -13,6 +13,6 @@ jobs:
13
13
  with:
14
14
  node-version: 18
15
15
  - run: npm ci
16
- - uses: JS-DevTools/npm-publish@d9dc932de083f0e6de6a50f0d1097a7142c3751b # v4.0.0
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
- this._app.log.info(`[k8s] Starting MQTT Schema agent ${broker.hashid} for ${broker.Team.hashid}`)
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: 1000 } }).json())
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: 1000 } }).json()
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: 1000 } }).json()
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: {},
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flowfuse/driver-kubernetes",
3
- "version": "2.21.3-e342621-202509150738.0",
3
+ "version": "2.22.1-468ab35-202510010835.0",
4
4
  "description": "Kubernetes driver for FlowFuse",
5
5
  "main": "kubernetes.js",
6
6
  "scripts": {