@flowfuse/driver-kubernetes 2.5.0 → 2.5.1-8ccd098-202407021403.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/publish.yml +5 -1
- package/README.md +8 -0
- package/kubernetes.js +94 -148
- package/lib/aws-efs.js +54 -0
- package/package.json +2 -1
- package/templates.js +171 -0
|
@@ -10,7 +10,11 @@ on:
|
|
|
10
10
|
|
|
11
11
|
jobs:
|
|
12
12
|
build:
|
|
13
|
-
uses: 'flowfuse/github-actions-workflows/.github/workflows/build_node_package.yml@v0.
|
|
13
|
+
uses: 'flowfuse/github-actions-workflows/.github/workflows/build_node_package.yml@v0.14.0'
|
|
14
|
+
with:
|
|
15
|
+
node: '[
|
|
16
|
+
{"version": "18", "tests": false, "lint": true},
|
|
17
|
+
]'
|
|
14
18
|
|
|
15
19
|
publish:
|
|
16
20
|
needs: build
|
package/README.md
CHANGED
|
@@ -26,6 +26,10 @@ driver:
|
|
|
26
26
|
cnameTarget: custom-loadbalancer.example.com
|
|
27
27
|
certManagerIssuer: lets-encrypt
|
|
28
28
|
ingressClass: custom-nginx
|
|
29
|
+
storage:
|
|
30
|
+
enabled: true
|
|
31
|
+
storageClass: nfs-storage
|
|
32
|
+
size: 5Gi
|
|
29
33
|
```
|
|
30
34
|
|
|
31
35
|
- `registry` is the Docker Registry to load Stack Containers from
|
|
@@ -44,6 +48,10 @@ AWS EKS specific annotation for ALB Ingress. or `openshift` to allow running on
|
|
|
44
48
|
- `customHostname.cnameTarget` The hostname users should configure their DNS entries to point at. Required. (default not set)
|
|
45
49
|
- `customHostname.certManagerIssuer` Name of the Cluster issuer to use to create HTTPS certs for the custom hostname (default not set)
|
|
46
50
|
- `customHostname.ingressClass` Name of the IngressClass to use to expose the custom hostname (default not set)
|
|
51
|
+
- `storage.enabled` Mounts a persistent volume on `/data/storage` (default false)
|
|
52
|
+
- `storage.storageClass` Name of StorageClass to use to allocate the volume (default not set)
|
|
53
|
+
- `storage.storageClassEFSTag` Used instead of `storage.storageClass` when needing to shard across multiple EFS file systems (default not set)
|
|
54
|
+
- `storage.size` Size of the volume to request (default not set)
|
|
47
55
|
|
|
48
56
|
Expects to pick up K8s credentials from the environment
|
|
49
57
|
|
package/kubernetes.js
CHANGED
|
@@ -1,6 +1,15 @@
|
|
|
1
1
|
const got = require('got')
|
|
2
2
|
const k8s = require('@kubernetes/client-node')
|
|
3
3
|
const _ = require('lodash')
|
|
4
|
+
const awsEFS = require('./lib/aws-efs.js')
|
|
5
|
+
|
|
6
|
+
const {
|
|
7
|
+
deploymentTemplate,
|
|
8
|
+
serviceTemplate,
|
|
9
|
+
ingressTemplate,
|
|
10
|
+
customIngressTemplate,
|
|
11
|
+
persistentVolumeClaimTemplate
|
|
12
|
+
} = require('./templates.js')
|
|
4
13
|
|
|
5
14
|
/**
|
|
6
15
|
* Kubernates Container driver
|
|
@@ -14,153 +23,6 @@ const _ = require('lodash')
|
|
|
14
23
|
*
|
|
15
24
|
*/
|
|
16
25
|
|
|
17
|
-
const deploymentTemplate = {
|
|
18
|
-
apiVersion: 'apps/v1',
|
|
19
|
-
kind: 'Deployment',
|
|
20
|
-
metadata: {
|
|
21
|
-
// name: "k8s-client-test-deployment",
|
|
22
|
-
labels: {
|
|
23
|
-
// name: "k8s-client-test-deployment",
|
|
24
|
-
nodered: 'true'
|
|
25
|
-
// app: "k8s-client-test-deployment"
|
|
26
|
-
}
|
|
27
|
-
},
|
|
28
|
-
spec: {
|
|
29
|
-
replicas: 1,
|
|
30
|
-
selector: {
|
|
31
|
-
matchLabels: {
|
|
32
|
-
// app: "k8s-client-test-deployment"
|
|
33
|
-
}
|
|
34
|
-
},
|
|
35
|
-
template: {
|
|
36
|
-
metadata: {
|
|
37
|
-
labels: {
|
|
38
|
-
// name: "k8s-client-test-deployment",
|
|
39
|
-
nodered: 'true'
|
|
40
|
-
// app: "k8s-client-test-deployment"
|
|
41
|
-
}
|
|
42
|
-
},
|
|
43
|
-
spec: {
|
|
44
|
-
securityContext: {
|
|
45
|
-
runAsUser: 1000,
|
|
46
|
-
runAsGroup: 1000,
|
|
47
|
-
fsGroup: 1000
|
|
48
|
-
},
|
|
49
|
-
containers: [
|
|
50
|
-
{
|
|
51
|
-
resources: {
|
|
52
|
-
requests: {
|
|
53
|
-
// 10th of a core
|
|
54
|
-
cpu: '100m',
|
|
55
|
-
memory: '128Mi'
|
|
56
|
-
},
|
|
57
|
-
limits: {
|
|
58
|
-
cpu: '125m',
|
|
59
|
-
memory: '192Mi'
|
|
60
|
-
}
|
|
61
|
-
},
|
|
62
|
-
name: 'node-red',
|
|
63
|
-
// image: "docker-pi.local:5000/bronze-node-red",
|
|
64
|
-
imagePullPolicy: 'Always',
|
|
65
|
-
env: [
|
|
66
|
-
// {name: "APP_NAME", value: "test"},
|
|
67
|
-
{ name: 'TZ', value: 'Europe/London' }
|
|
68
|
-
],
|
|
69
|
-
ports: [
|
|
70
|
-
{ name: 'web', containerPort: 1880, protocol: 'TCP' },
|
|
71
|
-
{ name: 'management', containerPort: 2880, protocol: 'TCP' }
|
|
72
|
-
],
|
|
73
|
-
securityContext: {
|
|
74
|
-
allowPrivilegeEscalation: false
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
]
|
|
78
|
-
},
|
|
79
|
-
enableServiceLinks: false
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
const serviceTemplate = {
|
|
85
|
-
apiVersion: 'v1',
|
|
86
|
-
kind: 'Service',
|
|
87
|
-
metadata: {
|
|
88
|
-
// name: "k8s-client-test-service"
|
|
89
|
-
},
|
|
90
|
-
spec: {
|
|
91
|
-
type: 'ClusterIP',
|
|
92
|
-
selector: {
|
|
93
|
-
// name: "k8s-client-test"
|
|
94
|
-
},
|
|
95
|
-
ports: [
|
|
96
|
-
{ name: 'web', port: 1880, protocol: 'TCP' },
|
|
97
|
-
{ name: 'management', port: 2880, protocol: 'TCP' }
|
|
98
|
-
]
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
const ingressTemplate = {
|
|
103
|
-
apiVersion: 'networking.k8s.io/v1',
|
|
104
|
-
kind: 'Ingress',
|
|
105
|
-
metadata: {
|
|
106
|
-
// name: "k8s-client-test-ingress",
|
|
107
|
-
// namespace: 'flowforge',
|
|
108
|
-
annotations: process.env.INGRESS_ANNOTATIONS ? JSON.parse(process.env.INGRESS_ANNOTATIONS) : {}
|
|
109
|
-
},
|
|
110
|
-
spec: {
|
|
111
|
-
ingressClassName: process.env.INGRESS_CLASS_NAME ? process.env.INGRESS_CLASS_NAME : null,
|
|
112
|
-
rules: [
|
|
113
|
-
{
|
|
114
|
-
// host: "k8s-client-test" + "." + "ubuntu.local",
|
|
115
|
-
http: {
|
|
116
|
-
paths: [
|
|
117
|
-
{
|
|
118
|
-
pathType: 'Prefix',
|
|
119
|
-
path: '/',
|
|
120
|
-
backend: {
|
|
121
|
-
service: {
|
|
122
|
-
// name: 'k8s-client-test-service',
|
|
123
|
-
port: { number: 1880 }
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
]
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
]
|
|
131
|
-
}
|
|
132
|
-
}
|
|
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
|
-
|
|
164
26
|
const createDeployment = async (project, options) => {
|
|
165
27
|
const stack = project.ProjectStack.properties
|
|
166
28
|
|
|
@@ -276,7 +138,7 @@ const createDeployment = async (project, options) => {
|
|
|
276
138
|
})
|
|
277
139
|
}
|
|
278
140
|
|
|
279
|
-
if (this._app.config.driver.options
|
|
141
|
+
if (this._app.config.driver.options?.privateCA) {
|
|
280
142
|
localPod.spec.containers[0].volumeMounts = [
|
|
281
143
|
{
|
|
282
144
|
name: 'cacert',
|
|
@@ -295,6 +157,29 @@ const createDeployment = async (project, options) => {
|
|
|
295
157
|
localPod.spec.containers[0].env.push({ name: 'NODE_EXTRA_CA_CERTS', value: '/usr/local/ssl-certs/chain.pem' })
|
|
296
158
|
}
|
|
297
159
|
|
|
160
|
+
if (this._app.config.driver.options?.storage?.enabled) {
|
|
161
|
+
const volMount = {
|
|
162
|
+
name: 'persistence',
|
|
163
|
+
mountPath: '/data/storage'
|
|
164
|
+
}
|
|
165
|
+
const vol = {
|
|
166
|
+
name: 'persistence',
|
|
167
|
+
persistentVolumeClaim: {
|
|
168
|
+
claimName: `${project.id}-pvc`
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
if (Array.isArray(localPod.spec.containers[0].volumeMounts)) {
|
|
172
|
+
localPod.spec.containers[0].volumeMounts.push(volMount)
|
|
173
|
+
} else {
|
|
174
|
+
localPod.spec.containers[0].volumeMounts = [volMount]
|
|
175
|
+
}
|
|
176
|
+
if (Array.isArray(localPod.spec.volumes)) {
|
|
177
|
+
localPod.spec.volumes.push(vol)
|
|
178
|
+
} else {
|
|
179
|
+
localPod.spec.volumes = [vol]
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
|
|
298
183
|
if (this._app.license.active() && this._cloudProvider === 'openshift') {
|
|
299
184
|
localPod.spec.securityContext = {}
|
|
300
185
|
}
|
|
@@ -414,6 +299,32 @@ const createCustomIngress = async (project, hostname, options) => {
|
|
|
414
299
|
return customIngress
|
|
415
300
|
}
|
|
416
301
|
|
|
302
|
+
const createPersistentVolumeClaim = async (project, options) => {
|
|
303
|
+
const namespace = this._app.config.driver.options?.projectNamespace || 'flowforge'
|
|
304
|
+
const pvc = JSON.parse(JSON.stringify(persistentVolumeClaimTemplate))
|
|
305
|
+
|
|
306
|
+
const drvOptions = this._app.config.driver.options
|
|
307
|
+
|
|
308
|
+
if (drvOptions?.storage?.storageClass) {
|
|
309
|
+
pvc.spec.storageClassName = drvOptions.storage.storageClass
|
|
310
|
+
} else if (drvOptions?.storage?.storageClassEFSTag) {
|
|
311
|
+
pvc.spec.storageClassName = await awsEFS.lookupStorageClass(drvOptions?.storage?.storageClassEFSTag)
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
if (drvOptions?.storage?.size) {
|
|
315
|
+
pvc.spec.resources.requests.storage = drvOptions.storage.size
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
pvc.metadata.namespace = namespace
|
|
319
|
+
pvc.metadata.name = `${project.id}-pvc`
|
|
320
|
+
pvc.metadata.labels = {
|
|
321
|
+
'ff-project-id': project.id,
|
|
322
|
+
'ff-project-name': project.safeName
|
|
323
|
+
}
|
|
324
|
+
console.log(`PVC: ${JSON.stringify(pvc, null, 2)}`)
|
|
325
|
+
return pvc
|
|
326
|
+
}
|
|
327
|
+
|
|
417
328
|
const createProject = async (project, options) => {
|
|
418
329
|
const namespace = this._app.config.driver.options.projectNamespace || 'flowforge'
|
|
419
330
|
|
|
@@ -421,6 +332,24 @@ const createProject = async (project, options) => {
|
|
|
421
332
|
const localService = await createService(project, options)
|
|
422
333
|
const localIngress = await createIngress(project, options)
|
|
423
334
|
|
|
335
|
+
if (this._app.config.driver.options?.storage?.enabled) {
|
|
336
|
+
const localPVC = await createPersistentVolumeClaim(project, options)
|
|
337
|
+
// console.log(JSON.stringify(localPVC, null, 2))
|
|
338
|
+
try {
|
|
339
|
+
await this._k8sApi.createNamespacedPersistentVolumeClaim(namespace, localPVC)
|
|
340
|
+
} catch (err) {
|
|
341
|
+
if (err.statusCode === 409) {
|
|
342
|
+
this._app.log.warn(`[k8s] PVC for instance ${project.id} already exists, proceeding...`)
|
|
343
|
+
} else {
|
|
344
|
+
if (project.state !== 'suspended') {
|
|
345
|
+
this._app.log.error(`[k8s] Instance ${project.id} - error creating PVC: ${err.toString()} ${err.statusCode}`)
|
|
346
|
+
// console.log(err)
|
|
347
|
+
throw err
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
|
|
424
353
|
try {
|
|
425
354
|
await this._k8sAppApi.createNamespacedDeployment(namespace, localDeployment)
|
|
426
355
|
} catch (err) {
|
|
@@ -838,6 +767,15 @@ module.exports = {
|
|
|
838
767
|
await this._k8sApi.deleteNamespacedPod(project.safeName, this._namespace)
|
|
839
768
|
}
|
|
840
769
|
|
|
770
|
+
// We should not delete the PVC when the instance is suspended
|
|
771
|
+
// if (this._app.config.driver.options?.storage?.enabled) {
|
|
772
|
+
// try {
|
|
773
|
+
// await this._k8sApi.deleteNamespacedPersistentVolumeClaim(`${project.safeName}-pvc`, this._namespace)
|
|
774
|
+
// } catch (err) {
|
|
775
|
+
// this._app.log.error(`[k8s] Instance ${project.id} - error deleting PVC: ${err.toString()} ${err.statusCode}`)
|
|
776
|
+
// }
|
|
777
|
+
// }
|
|
778
|
+
|
|
841
779
|
this._projects[project.id].state = 'suspended'
|
|
842
780
|
return new Promise((resolve, reject) => {
|
|
843
781
|
let counter = 0
|
|
@@ -921,6 +859,14 @@ module.exports = {
|
|
|
921
859
|
}
|
|
922
860
|
}
|
|
923
861
|
}
|
|
862
|
+
if (this._app.config.driver.options?.storage?.enabled) {
|
|
863
|
+
try {
|
|
864
|
+
await this._k8sApi.deleteNamespacedPersistentVolumeClaim(`${project.id}-pvc`, this._namespace)
|
|
865
|
+
} catch (err) {
|
|
866
|
+
this._app.log.error(`[k8s] Instance ${project.id} - error deleting PVC: ${err.toString()} ${err.statusCode}`)
|
|
867
|
+
// console.log(err)
|
|
868
|
+
}
|
|
869
|
+
}
|
|
924
870
|
delete this._projects[project.id]
|
|
925
871
|
},
|
|
926
872
|
/**
|
package/lib/aws-efs.js
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
const { EFSClient, DescribeFileSystemsCommand, DescribeAccessPointsCommand } = require("@aws-sdk/client-efs")
|
|
2
|
+
|
|
3
|
+
let client
|
|
4
|
+
|
|
5
|
+
async function lookupStorageClass (tagName) {
|
|
6
|
+
|
|
7
|
+
// console.log(`Looking for ${tagName}`)
|
|
8
|
+
|
|
9
|
+
if (!client) {
|
|
10
|
+
client = new EFSClient()
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const fsCommand = new DescribeFileSystemsCommand()
|
|
14
|
+
const fsList = await client.send(fsCommand)
|
|
15
|
+
// console.log(JSON.stringify(fsList, null, 2))
|
|
16
|
+
|
|
17
|
+
const fileSystems = []
|
|
18
|
+
|
|
19
|
+
for (let i = 0; i<fsList.FileSystems.length; i++) {
|
|
20
|
+
let found = false
|
|
21
|
+
let storageClass = ''
|
|
22
|
+
for (let j = 0; j<fsList.FileSystems[i].Tags.length; j++) {
|
|
23
|
+
const tag = fsList.FileSystems[i].Tags[j]
|
|
24
|
+
if (tag.Key === tagName) {
|
|
25
|
+
found = true
|
|
26
|
+
}
|
|
27
|
+
if (tag.Key === 'storage-class-name') {
|
|
28
|
+
storageClass = tag.Value
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
if (found) {
|
|
32
|
+
// console.log(storageClass)
|
|
33
|
+
const apParams = {
|
|
34
|
+
FileSystemId: fsList.FileSystems[i].FileSystemId
|
|
35
|
+
}
|
|
36
|
+
// console.log(apParams)
|
|
37
|
+
const apListCommand = new DescribeAccessPointsCommand(apParams)
|
|
38
|
+
const apList = await client.send(apListCommand)
|
|
39
|
+
// fileSystems[fsList.FileSystems[i].FileSystemId]
|
|
40
|
+
fileSystems.push({
|
|
41
|
+
apCount: apList.AccessPoints.length,
|
|
42
|
+
storageClass
|
|
43
|
+
})
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
fileSystems.sort((a,b) => a.apCount - b.apCount)
|
|
47
|
+
|
|
48
|
+
return fileSystems[0]?.storageClass
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
module.exports = {
|
|
53
|
+
lookupStorageClass
|
|
54
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@flowfuse/driver-kubernetes",
|
|
3
|
-
"version": "2.5.0",
|
|
3
|
+
"version": "2.5.1-8ccd098-202407021403.0",
|
|
4
4
|
"description": "Kubernetes driver for FlowFuse",
|
|
5
5
|
"main": "kubernetes.js",
|
|
6
6
|
"scripts": {
|
|
@@ -21,6 +21,7 @@
|
|
|
21
21
|
},
|
|
22
22
|
"license": "Apache-2.0",
|
|
23
23
|
"dependencies": {
|
|
24
|
+
"@aws-sdk/client-efs": "^3.600.0",
|
|
24
25
|
"@kubernetes/client-node": "^0.18.1",
|
|
25
26
|
"got": "^11.8.0",
|
|
26
27
|
"lodash": "^4.17.21"
|
package/templates.js
ADDED
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
const deploymentTemplate = {
|
|
2
|
+
apiVersion: 'apps/v1',
|
|
3
|
+
kind: 'Deployment',
|
|
4
|
+
metadata: {
|
|
5
|
+
// name: "k8s-client-test-deployment",
|
|
6
|
+
labels: {
|
|
7
|
+
// name: "k8s-client-test-deployment",
|
|
8
|
+
nodered: 'true'
|
|
9
|
+
// app: "k8s-client-test-deployment"
|
|
10
|
+
}
|
|
11
|
+
},
|
|
12
|
+
spec: {
|
|
13
|
+
replicas: 1,
|
|
14
|
+
selector: {
|
|
15
|
+
matchLabels: {
|
|
16
|
+
// app: "k8s-client-test-deployment"
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
template: {
|
|
20
|
+
metadata: {
|
|
21
|
+
labels: {
|
|
22
|
+
// name: "k8s-client-test-deployment",
|
|
23
|
+
nodered: 'true'
|
|
24
|
+
// app: "k8s-client-test-deployment"
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
spec: {
|
|
28
|
+
securityContext: {
|
|
29
|
+
runAsUser: 1000,
|
|
30
|
+
runAsGroup: 1000,
|
|
31
|
+
fsGroup: 1000
|
|
32
|
+
},
|
|
33
|
+
containers: [
|
|
34
|
+
{
|
|
35
|
+
resources: {
|
|
36
|
+
requests: {
|
|
37
|
+
// 10th of a core
|
|
38
|
+
cpu: '100m',
|
|
39
|
+
memory: '128Mi'
|
|
40
|
+
},
|
|
41
|
+
limits: {
|
|
42
|
+
cpu: '125m',
|
|
43
|
+
memory: '192Mi'
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
name: 'node-red',
|
|
47
|
+
// image: "docker-pi.local:5000/bronze-node-red",
|
|
48
|
+
imagePullPolicy: 'Always',
|
|
49
|
+
env: [
|
|
50
|
+
// {name: "APP_NAME", value: "test"},
|
|
51
|
+
{ name: 'TZ', value: 'Europe/London' }
|
|
52
|
+
],
|
|
53
|
+
ports: [
|
|
54
|
+
{ name: 'web', containerPort: 1880, protocol: 'TCP' },
|
|
55
|
+
{ name: 'management', containerPort: 2880, protocol: 'TCP' }
|
|
56
|
+
],
|
|
57
|
+
securityContext: {
|
|
58
|
+
allowPrivilegeEscalation: false
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
]
|
|
62
|
+
},
|
|
63
|
+
enableServiceLinks: false
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const serviceTemplate = {
|
|
69
|
+
apiVersion: 'v1',
|
|
70
|
+
kind: 'Service',
|
|
71
|
+
metadata: {
|
|
72
|
+
// name: "k8s-client-test-service"
|
|
73
|
+
},
|
|
74
|
+
spec: {
|
|
75
|
+
type: 'ClusterIP',
|
|
76
|
+
selector: {
|
|
77
|
+
// name: "k8s-client-test"
|
|
78
|
+
},
|
|
79
|
+
ports: [
|
|
80
|
+
{ name: 'web', port: 1880, protocol: 'TCP' },
|
|
81
|
+
{ name: 'management', port: 2880, protocol: 'TCP' }
|
|
82
|
+
]
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const ingressTemplate = {
|
|
87
|
+
apiVersion: 'networking.k8s.io/v1',
|
|
88
|
+
kind: 'Ingress',
|
|
89
|
+
metadata: {
|
|
90
|
+
// name: "k8s-client-test-ingress",
|
|
91
|
+
// namespace: 'flowforge',
|
|
92
|
+
annotations: process.env.INGRESS_ANNOTATIONS ? JSON.parse(process.env.INGRESS_ANNOTATIONS) : {}
|
|
93
|
+
},
|
|
94
|
+
spec: {
|
|
95
|
+
ingressClassName: process.env.INGRESS_CLASS_NAME ? process.env.INGRESS_CLASS_NAME : null,
|
|
96
|
+
rules: [
|
|
97
|
+
{
|
|
98
|
+
// host: "k8s-client-test" + "." + "ubuntu.local",
|
|
99
|
+
http: {
|
|
100
|
+
paths: [
|
|
101
|
+
{
|
|
102
|
+
pathType: 'Prefix',
|
|
103
|
+
path: '/',
|
|
104
|
+
backend: {
|
|
105
|
+
service: {
|
|
106
|
+
// name: 'k8s-client-test-service',
|
|
107
|
+
port: { number: 1880 }
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
]
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
]
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
const customIngressTemplate = {
|
|
119
|
+
apiVersion: 'networking.k8s.io/v1',
|
|
120
|
+
kind: 'Ingress',
|
|
121
|
+
metadata: {
|
|
122
|
+
annotations: {}
|
|
123
|
+
},
|
|
124
|
+
spec: {
|
|
125
|
+
rules: [
|
|
126
|
+
{
|
|
127
|
+
http: {
|
|
128
|
+
paths: [
|
|
129
|
+
{
|
|
130
|
+
pathType: 'Prefix',
|
|
131
|
+
path: '/',
|
|
132
|
+
backend: {
|
|
133
|
+
service: {
|
|
134
|
+
port: { number: 1880 }
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
]
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
],
|
|
142
|
+
tls: [
|
|
143
|
+
|
|
144
|
+
]
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
const persistentVolumeClaimTemplate = {
|
|
149
|
+
apiVersion: 'v1',
|
|
150
|
+
kind: 'PersistentVolumeClaim',
|
|
151
|
+
metadata: {
|
|
152
|
+
|
|
153
|
+
},
|
|
154
|
+
spec: {
|
|
155
|
+
accessModes: [
|
|
156
|
+
'ReadWriteMany' // picked for HA mode
|
|
157
|
+
],
|
|
158
|
+
resources: {
|
|
159
|
+
requests: {
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
module.exports = {
|
|
166
|
+
deploymentTemplate,
|
|
167
|
+
serviceTemplate,
|
|
168
|
+
ingressTemplate,
|
|
169
|
+
customIngressTemplate,
|
|
170
|
+
persistentVolumeClaimTemplate
|
|
171
|
+
}
|