@flowfuse/driver-kubernetes 2.4.1-c425d12-202406041337.0 → 2.5.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 +7 -0
- package/README.md +10 -0
- package/kubernetes.js +160 -34
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
#### 2.5.0: Release
|
|
2
|
+
|
|
3
|
+
- Custom Hostname support (#151) @hardillb
|
|
4
|
+
- Bump actions/setup-node from 1 to 4 (#159) @app/dependabot
|
|
5
|
+
- Bump actions/checkout from 1 to 4 (#158) @app/dependabot
|
|
6
|
+
- Enable dependabot for github actions (#154) @ppawlowski
|
|
7
|
+
|
|
1
8
|
#### 2.4.0: Release
|
|
2
9
|
|
|
3
10
|
- Revert "Add support for user set health check interval" (#152) @Steve-Mcl
|
package/README.md
CHANGED
|
@@ -21,6 +21,11 @@ driver:
|
|
|
21
21
|
k8sDelay: 1000
|
|
22
22
|
k8sRetries: 10
|
|
23
23
|
logPassthrough: true
|
|
24
|
+
customHostname:
|
|
25
|
+
enabled: true
|
|
26
|
+
cnameTarget: custom-loadbalancer.example.com
|
|
27
|
+
certManagerIssuer: lets-encrypt
|
|
28
|
+
ingressClass: custom-nginx
|
|
24
29
|
```
|
|
25
30
|
|
|
26
31
|
- `registry` is the Docker Registry to load Stack Containers from
|
|
@@ -34,6 +39,11 @@ AWS EKS specific annotation for ALB Ingress. or `openshift` to allow running on
|
|
|
34
39
|
- `k8sRetries` how many times to retry actions against the K8s API
|
|
35
40
|
- `k8sDelay` how long to wait (in ms) between retries to the K8s API
|
|
36
41
|
- `logPassthrough` Have Node-RED logs printed in JSON format to container stdout (default false)
|
|
42
|
+
- `customHostname` Settings linked to allowing instances to have a second hostname
|
|
43
|
+
- `customHostname.enabled` (default false)
|
|
44
|
+
- `customHostname.cnameTarget` The hostname users should configure their DNS entries to point at. Required. (default not set)
|
|
45
|
+
- `customHostname.certManagerIssuer` Name of the Cluster issuer to use to create HTTPS certs for the custom hostname (default not set)
|
|
46
|
+
- `customHostname.ingressClass` Name of the IngressClass to use to expose the custom hostname (default not set)
|
|
37
47
|
|
|
38
48
|
Expects to pick up K8s credentials from the environment
|
|
39
49
|
|
package/kubernetes.js
CHANGED
|
@@ -131,6 +131,36 @@ const ingressTemplate = {
|
|
|
131
131
|
}
|
|
132
132
|
}
|
|
133
133
|
|
|
134
|
+
const customIngressTemplate = {
|
|
135
|
+
apiVersion: 'networking.k8s.io/v1',
|
|
136
|
+
kind: 'Ingress',
|
|
137
|
+
metadata: {
|
|
138
|
+
annotations: {}
|
|
139
|
+
},
|
|
140
|
+
spec: {
|
|
141
|
+
rules: [
|
|
142
|
+
{
|
|
143
|
+
http: {
|
|
144
|
+
paths: [
|
|
145
|
+
{
|
|
146
|
+
pathType: 'Prefix',
|
|
147
|
+
path: '/',
|
|
148
|
+
backend: {
|
|
149
|
+
service: {
|
|
150
|
+
port: { number: 1880 }
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
]
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
],
|
|
158
|
+
tls: [
|
|
159
|
+
|
|
160
|
+
]
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
134
164
|
const createDeployment = async (project, options) => {
|
|
135
165
|
const stack = project.ProjectStack.properties
|
|
136
166
|
|
|
@@ -340,6 +370,50 @@ const createIngress = async (project, options) => {
|
|
|
340
370
|
return localIngress
|
|
341
371
|
}
|
|
342
372
|
|
|
373
|
+
const createCustomIngress = async (project, hostname, options) => {
|
|
374
|
+
const prefix = project.safeName.match(/^[0-9]/) ? 'srv-' : ''
|
|
375
|
+
const url = new URL(project.url)
|
|
376
|
+
url.host = hostname
|
|
377
|
+
|
|
378
|
+
// exposedData available for annotation replacements
|
|
379
|
+
const exposedData = {
|
|
380
|
+
serviceName: `${prefix}${project.safeName}`,
|
|
381
|
+
instanceURL: url.href,
|
|
382
|
+
instanceHost: url.host,
|
|
383
|
+
instanceProtocol: url.protocol
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
this._app.log.info('K8S DRIVER: start custom hostname ingress template')
|
|
387
|
+
const customIngress = JSON.parse(JSON.stringify(customIngressTemplate))
|
|
388
|
+
|
|
389
|
+
customIngress.metadata.name = `${project.safeName}-custom`
|
|
390
|
+
customIngress.spec.rules[0].host = hostname
|
|
391
|
+
customIngress.spec.rules[0].http.paths[0].backend.service.name = `${prefix}${project.safeName}`
|
|
392
|
+
|
|
393
|
+
if (this._customHostname?.certManagerIssuer) {
|
|
394
|
+
customIngress.metadata.annotations['cert-manager.io/cluster-issuer'] = this._customHostname.certManagerIssuer
|
|
395
|
+
customIngress.spec.tls = [
|
|
396
|
+
{
|
|
397
|
+
hosts: [
|
|
398
|
+
hostname
|
|
399
|
+
],
|
|
400
|
+
secretName: `${project.safeName}-custom`
|
|
401
|
+
}
|
|
402
|
+
]
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
// process annotations with potential replacements
|
|
406
|
+
Object.keys(customIngress.metadata.annotations).forEach((key) => {
|
|
407
|
+
customIngress.metadata.annotations[key] = mustache(customIngress.metadata.annotations[key], exposedData)
|
|
408
|
+
})
|
|
409
|
+
|
|
410
|
+
if (this._customHostname?.ingressClass) {
|
|
411
|
+
customIngress.spec.ingressClassName = `${this._customHostname.ingressClass}`
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
return customIngress
|
|
415
|
+
}
|
|
416
|
+
|
|
343
417
|
const createProject = async (project, options) => {
|
|
344
418
|
const namespace = this._app.config.driver.options.projectNamespace || 'flowforge'
|
|
345
419
|
|
|
@@ -352,7 +426,7 @@ const createProject = async (project, options) => {
|
|
|
352
426
|
} catch (err) {
|
|
353
427
|
if (err.statusCode === 409) {
|
|
354
428
|
// If deployment exists, perform an upgrade
|
|
355
|
-
this._app.log.warn(`[k8s] Deployment for
|
|
429
|
+
this._app.log.warn(`[k8s] Deployment for instance ${project.id} already exists. Upgrading deployment`)
|
|
356
430
|
const result = await this._k8sAppApi.readNamespacedDeployment(project.safeName, namespace)
|
|
357
431
|
|
|
358
432
|
const existingDeployment = result.body
|
|
@@ -363,7 +437,7 @@ const createProject = async (project, options) => {
|
|
|
363
437
|
}
|
|
364
438
|
} else {
|
|
365
439
|
// Log other errors and rethrow them for additional higher-level handling
|
|
366
|
-
this._app.log.error(`[k8s] Unexpected error creating deployment for
|
|
440
|
+
this._app.log.error(`[k8s] Unexpected error creating deployment for instance ${project.id}.`)
|
|
367
441
|
this._app.log.error(`[k8s] deployment ${JSON.stringify(localDeployment, undefined, 2)}`)
|
|
368
442
|
this._app.log.error(err)
|
|
369
443
|
// rethrow the error so the wrapper knows this hasn't worked
|
|
@@ -383,7 +457,7 @@ const createProject = async (project, options) => {
|
|
|
383
457
|
counter++
|
|
384
458
|
if (counter > this._k8sRetries) {
|
|
385
459
|
clearInterval(pollInterval)
|
|
386
|
-
this._app.log.error(`[k8s]
|
|
460
|
+
this._app.log.error(`[k8s] Instance ${project.id} - timeout waiting for Deployment`)
|
|
387
461
|
reject(new Error('Timed out to creating Deployment'))
|
|
388
462
|
}
|
|
389
463
|
}
|
|
@@ -394,10 +468,10 @@ const createProject = async (project, options) => {
|
|
|
394
468
|
await this._k8sApi.createNamespacedService(namespace, localService)
|
|
395
469
|
} catch (err) {
|
|
396
470
|
if (err.statusCode === 409) {
|
|
397
|
-
this._app.log.warn(`[k8s] Service for
|
|
471
|
+
this._app.log.warn(`[k8s] Service for instance ${project.id} already exists, proceeding...`)
|
|
398
472
|
} else {
|
|
399
473
|
if (project.state !== 'suspended') {
|
|
400
|
-
this._app.log.error(`[k8s]
|
|
474
|
+
this._app.log.error(`[k8s] Instance ${project.id} - error creating service: ${err.toString()}`)
|
|
401
475
|
throw err
|
|
402
476
|
}
|
|
403
477
|
}
|
|
@@ -415,7 +489,7 @@ const createProject = async (project, options) => {
|
|
|
415
489
|
counter++
|
|
416
490
|
if (counter > this._k8sRetries) {
|
|
417
491
|
clearInterval(pollInterval)
|
|
418
|
-
this._app.log.error(`[k8s]
|
|
492
|
+
this._app.log.error(`[k8s] Instance ${project.id} - timeout waiting for Service`)
|
|
419
493
|
reject(new Error('Timed out to creating Service'))
|
|
420
494
|
}
|
|
421
495
|
}
|
|
@@ -426,14 +500,32 @@ const createProject = async (project, options) => {
|
|
|
426
500
|
await this._k8sNetApi.createNamespacedIngress(namespace, localIngress)
|
|
427
501
|
} catch (err) {
|
|
428
502
|
if (err.statusCode === 409) {
|
|
429
|
-
this._app.log.warn(`[k8s] Ingress for
|
|
503
|
+
this._app.log.warn(`[k8s] Ingress for instance ${project.id} already exists, proceeding...`)
|
|
430
504
|
} else {
|
|
431
505
|
if (project.state !== 'suspended') {
|
|
432
|
-
this._app.log.error(`[k8s]
|
|
506
|
+
this._app.log.error(`[k8s] Instance ${project.id} - error creating ingress: ${err.toString()}`)
|
|
433
507
|
throw err
|
|
434
508
|
}
|
|
435
509
|
}
|
|
436
510
|
}
|
|
511
|
+
if (this._customHostname?.enabled) {
|
|
512
|
+
const customHostname = await project.getSetting('customHostname')
|
|
513
|
+
if (customHostname) {
|
|
514
|
+
const customHostnameIngress = await createCustomIngress(project, customHostname, options)
|
|
515
|
+
try {
|
|
516
|
+
await this._k8sNetApi.createNamespacedIngress(namespace, customHostnameIngress)
|
|
517
|
+
} catch (err) {
|
|
518
|
+
if (err.statusCode === 409) {
|
|
519
|
+
this._app.log.warn(`[k8s] Custom Hostname Ingress for instance ${project.id} already exists, proceeding...`)
|
|
520
|
+
} else {
|
|
521
|
+
if (project.state !== 'suspended') {
|
|
522
|
+
this._app.log.error(`[k8s] Instance ${project.id} - error creating custom hostname ingress: ${err.toString()}`)
|
|
523
|
+
throw err
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
}
|
|
437
529
|
|
|
438
530
|
await new Promise((resolve, reject) => {
|
|
439
531
|
let counter = 0
|
|
@@ -446,7 +538,7 @@ const createProject = async (project, options) => {
|
|
|
446
538
|
counter++
|
|
447
539
|
if (counter > this._k8sRetries) {
|
|
448
540
|
clearInterval(pollInterval)
|
|
449
|
-
this._app.log.error(`[k8s]
|
|
541
|
+
this._app.log.error(`[k8s] Instance ${project.id} - timeout waiting for Ingress`)
|
|
450
542
|
reject(new Error('Timed out to creating Ingress'))
|
|
451
543
|
}
|
|
452
544
|
}
|
|
@@ -479,11 +571,11 @@ const getEndpoints = async (project) => {
|
|
|
479
571
|
|
|
480
572
|
module.exports = {
|
|
481
573
|
/**
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
574
|
+
* Initialises this driver
|
|
575
|
+
* @param {string} app - the Vue application
|
|
576
|
+
* @param {object} options - A set of configuration options for the driver
|
|
577
|
+
* @return {forge.containers.ProjectArguments}
|
|
578
|
+
*/
|
|
487
579
|
init: async (app, options) => {
|
|
488
580
|
this._app = app
|
|
489
581
|
this._projects = {}
|
|
@@ -495,6 +587,10 @@ module.exports = {
|
|
|
495
587
|
this._certManagerIssuer = this._app.config.driver.options?.certManagerIssuer
|
|
496
588
|
this._logPassthrough = this._app.config.driver.options?.logPassthrough || false
|
|
497
589
|
this._cloudProvider = this._app.config.driver.options?.cloudProvider
|
|
590
|
+
if (this._app.config.driver.options?.customHostname?.enabled) {
|
|
591
|
+
this._app.log.info('[k8s] Enabling Custom Hostname Support')
|
|
592
|
+
this._customHostname = this._app.config.driver.options?.customHostname
|
|
593
|
+
}
|
|
498
594
|
|
|
499
595
|
const kc = new k8s.KubeConfig()
|
|
500
596
|
|
|
@@ -570,7 +666,7 @@ module.exports = {
|
|
|
570
666
|
this._app.log.info(`[k8s] deployment ${project.id} in ${namespace} found`)
|
|
571
667
|
} catch (err) {
|
|
572
668
|
this._app.log.error(`[k8s] Error while reading namespaced deployment for project '${project.safeName}' ${project.id}. Error msg=${err.message}, stack=${err.stack}`)
|
|
573
|
-
this._app.log.info(`[k8s]
|
|
669
|
+
this._app.log.info(`[k8s] Instance ${project.id} - recreating deployment`)
|
|
574
670
|
const fullProject = await this._app.db.models.Project.byId(project.id)
|
|
575
671
|
await createProject(fullProject, options)
|
|
576
672
|
}
|
|
@@ -581,13 +677,13 @@ module.exports = {
|
|
|
581
677
|
await this._k8sApi.readNamespacedPodStatus(project.safeName, namespace)
|
|
582
678
|
this._app.log.info(`[k8s] pod ${project.id} in ${namespace} found`)
|
|
583
679
|
} catch (err) {
|
|
584
|
-
this._app.log.debug(`[k8s]
|
|
680
|
+
this._app.log.debug(`[k8s] Instance ${project.id} - recreating deployment`)
|
|
585
681
|
const fullProject = await this._app.db.models.Project.byId(project.id)
|
|
586
682
|
await createProject(fullProject, options)
|
|
587
683
|
}
|
|
588
684
|
}
|
|
589
685
|
} catch (err) {
|
|
590
|
-
this._app.log.error(`[k8s]
|
|
686
|
+
this._app.log.error(`[k8s] Instance ${project.id} - error resuming project: ${err.stack}`)
|
|
591
687
|
}
|
|
592
688
|
})
|
|
593
689
|
}, 1000)
|
|
@@ -652,14 +748,30 @@ module.exports = {
|
|
|
652
748
|
try {
|
|
653
749
|
await this._k8sNetApi.deleteNamespacedIngress(project.safeName, this._namespace)
|
|
654
750
|
} catch (err) {
|
|
655
|
-
this._app.log.error(`[k8s]
|
|
751
|
+
this._app.log.error(`[k8s] Instance ${project.id} - error deleting ingress: ${err.toString()}`)
|
|
656
752
|
}
|
|
657
753
|
|
|
658
754
|
if (this._certManagerIssuer) {
|
|
659
755
|
try {
|
|
660
756
|
await this._k8sApi.deleteNamespacedSecret(project.safeName, this._namespace)
|
|
661
757
|
} catch (err) {
|
|
662
|
-
this._app.log.error(`[k8s]
|
|
758
|
+
this._app.log.error(`[k8s] Instance ${project.id} - error deleting tls secret: ${err.toString()}`)
|
|
759
|
+
}
|
|
760
|
+
}
|
|
761
|
+
|
|
762
|
+
if (this._customHostname?.enabled) {
|
|
763
|
+
try {
|
|
764
|
+
await this._k8sNetApi.deleteNamespacedIngress(`${project.safeName}-custom`, this._namespace)
|
|
765
|
+
} catch (err) {
|
|
766
|
+
this._app.log.error(`[k8s] Instance ${project.id} - error deleting custom ingress: ${err.toString()}`)
|
|
767
|
+
}
|
|
768
|
+
|
|
769
|
+
if (this._customHostname?.certManagerIssuer) {
|
|
770
|
+
try {
|
|
771
|
+
await this._k8sApi.deleteNamespacedSecret(`${project.safeName}-custom`, this._namespace)
|
|
772
|
+
} catch (err) {
|
|
773
|
+
this._app.log.error(`[k8s] Instance ${project.id} - error deleting custom tls secret: ${err.toString()}`)
|
|
774
|
+
}
|
|
663
775
|
}
|
|
664
776
|
}
|
|
665
777
|
|
|
@@ -679,20 +791,20 @@ module.exports = {
|
|
|
679
791
|
counter++
|
|
680
792
|
if (counter > this._k8sRetries) {
|
|
681
793
|
clearInterval(pollInterval)
|
|
682
|
-
this._app.log.error(`[k8s]
|
|
794
|
+
this._app.log.error(`[k8s] Instance ${project.id} - timed out deleting ingress`)
|
|
683
795
|
reject(new Error('Timed out to deleting Ingress'))
|
|
684
796
|
}
|
|
685
797
|
}, this._k8sDelay)
|
|
686
798
|
})
|
|
687
799
|
} catch (err) {
|
|
688
|
-
this._app.log.error(`[k8s]
|
|
800
|
+
this._app.log.error(`[k8s] Instance ${project.id} - Ingress was not deleted: ${err.toString()}`)
|
|
689
801
|
}
|
|
690
802
|
|
|
691
803
|
const prefix = project.safeName.match(/^[0-9]/) ? 'srv-' : ''
|
|
692
804
|
try {
|
|
693
805
|
await this._k8sApi.deleteNamespacedService(prefix + project.safeName, this._namespace)
|
|
694
806
|
} catch (err) {
|
|
695
|
-
this._app.log.error(`[k8s]
|
|
807
|
+
this._app.log.error(`[k8s] Instance ${project.id} - error deleting service: ${err.toString()}`)
|
|
696
808
|
}
|
|
697
809
|
|
|
698
810
|
try {
|
|
@@ -708,13 +820,13 @@ module.exports = {
|
|
|
708
820
|
counter++
|
|
709
821
|
if (counter > this._k8sRetries) {
|
|
710
822
|
clearInterval(pollInterval)
|
|
711
|
-
this._app.log.error(`[k8s]
|
|
823
|
+
this._app.log.error(`[k8s] Instance ${project.id} - timed deleting service`)
|
|
712
824
|
reject(new Error('Timed out to deleting Service'))
|
|
713
825
|
}
|
|
714
826
|
}, this._k8sDelay)
|
|
715
827
|
})
|
|
716
828
|
} catch (err) {
|
|
717
|
-
this._app.log.error(`[k8s]
|
|
829
|
+
this._app.log.error(`[k8s] Instance ${project.id} - Service was not deleted: ${err.toString()}`)
|
|
718
830
|
}
|
|
719
831
|
|
|
720
832
|
const currentType = await project.getSetting('k8sType')
|
|
@@ -739,7 +851,7 @@ module.exports = {
|
|
|
739
851
|
counter++
|
|
740
852
|
if (counter > this._k8sRetries) {
|
|
741
853
|
clearInterval(pollInterval)
|
|
742
|
-
this._app.log.error(`[k8s]
|
|
854
|
+
this._app.log.error(`[k8s] Instance ${project.id} - timed deleting ${pod ? 'Pod' : 'Deployment'}`)
|
|
743
855
|
reject(new Error('Timed out to deleting Deployment'))
|
|
744
856
|
}
|
|
745
857
|
} catch (err) {
|
|
@@ -759,13 +871,27 @@ module.exports = {
|
|
|
759
871
|
try {
|
|
760
872
|
await this._k8sNetApi.deleteNamespacedIngress(project.safeName, this._namespace)
|
|
761
873
|
} catch (err) {
|
|
762
|
-
this._app.log.error(`[k8s]
|
|
874
|
+
this._app.log.error(`[k8s] Instance ${project.id} - error deleting ingress: ${err.toString()}`)
|
|
763
875
|
}
|
|
764
876
|
if (this._certManagerIssuer) {
|
|
765
877
|
try {
|
|
766
878
|
await this._k8sApi.deleteNamespacedSecret(project.safeName, this._namespace)
|
|
767
879
|
} catch (err) {
|
|
768
|
-
this._app.log.error(`[k8s]
|
|
880
|
+
this._app.log.error(`[k8s] Instance ${project.id} - error deleting tls secret: ${err.toString()}`)
|
|
881
|
+
}
|
|
882
|
+
}
|
|
883
|
+
if (this._customHostname?.enabled) {
|
|
884
|
+
try {
|
|
885
|
+
await this._k8sNetApi.deleteNamespacedIngress(`${project.safeName}-custom`, this._namespace)
|
|
886
|
+
} catch (err) {
|
|
887
|
+
this._app.log.error(`[k8s] Instance ${project.id} - error deleting custom ingress: ${err.toString()}`)
|
|
888
|
+
}
|
|
889
|
+
if (this._customHostname?.certManagerIssuer) {
|
|
890
|
+
try {
|
|
891
|
+
await this._k8sApi.deleteNamespacedSecret(`${project.safeName}-custom`, this._namespace)
|
|
892
|
+
} catch (err) {
|
|
893
|
+
this._app.log.error(`[k8s] Instance ${project.id} - error deleting custom tls secret: ${err.toString()}`)
|
|
894
|
+
}
|
|
769
895
|
}
|
|
770
896
|
}
|
|
771
897
|
try {
|
|
@@ -775,7 +901,7 @@ module.exports = {
|
|
|
775
901
|
await this._k8sApi.deleteNamespacedService(project.safeName, this._namespace)
|
|
776
902
|
}
|
|
777
903
|
} catch (err) {
|
|
778
|
-
this._app.log.error(`[k8s]
|
|
904
|
+
this._app.log.error(`[k8s] Instance ${project.id} - error deleting service: ${err.toString()}`)
|
|
779
905
|
}
|
|
780
906
|
const currentType = await project.getSetting('k8sType')
|
|
781
907
|
try {
|
|
@@ -789,9 +915,9 @@ module.exports = {
|
|
|
789
915
|
} catch (err) {
|
|
790
916
|
if (project.state !== 'suspended') {
|
|
791
917
|
if (currentType === 'deployment') {
|
|
792
|
-
this._app.log.error(`[k8s]
|
|
918
|
+
this._app.log.error(`[k8s] Instance ${project.id} - error deleting deployment: ${err.toString()}`)
|
|
793
919
|
} else {
|
|
794
|
-
this._app.log.error(`[k8s]
|
|
920
|
+
this._app.log.error(`[k8s] Instance ${project.id} - error deleting pod: ${err.toString()}`)
|
|
795
921
|
}
|
|
796
922
|
}
|
|
797
923
|
}
|
|
@@ -841,7 +967,7 @@ module.exports = {
|
|
|
841
967
|
this._projects[project.id].state = info.state
|
|
842
968
|
return info
|
|
843
969
|
} catch (err) {
|
|
844
|
-
this._app.log.debug(`error getting state from
|
|
970
|
+
this._app.log.debug(`error getting state from instance ${project.id}: ${err}`)
|
|
845
971
|
return {
|
|
846
972
|
id: project.id,
|
|
847
973
|
state: 'starting',
|
|
@@ -874,7 +1000,7 @@ module.exports = {
|
|
|
874
1000
|
this._projects[project.id].state = info.state
|
|
875
1001
|
return info
|
|
876
1002
|
} catch (err) {
|
|
877
|
-
this._app.log.debug(`error getting state from
|
|
1003
|
+
this._app.log.debug(`error getting state from instance ${project.id}: ${err}`)
|
|
878
1004
|
return {
|
|
879
1005
|
id: project.id,
|
|
880
1006
|
state: 'starting',
|
|
@@ -891,7 +1017,7 @@ module.exports = {
|
|
|
891
1017
|
}
|
|
892
1018
|
}
|
|
893
1019
|
} catch (err) {
|
|
894
|
-
this._app.log.debug(`error getting pod status for
|
|
1020
|
+
this._app.log.debug(`error getting pod status for instance ${project.id}: ${err}`)
|
|
895
1021
|
return {
|
|
896
1022
|
id: project?.id,
|
|
897
1023
|
error: err,
|
|
@@ -1013,7 +1139,7 @@ module.exports = {
|
|
|
1013
1139
|
* @return {forge.Status}
|
|
1014
1140
|
*/
|
|
1015
1141
|
revokeUserToken: async (project, token) => { // logout:nodered(step-3)
|
|
1016
|
-
this._app.log.debug(`[k8s]
|
|
1142
|
+
this._app.log.debug(`[k8s] Instance ${project.id} - logging out node-red instance`)
|
|
1017
1143
|
const endpoints = await getEndpoints(project)
|
|
1018
1144
|
const commands = []
|
|
1019
1145
|
for (const address in endpoints) {
|