@sap/cds-dk 8.5.1 → 8.6.1
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/CHANGELOG.md +29 -3
- package/bin/cds.js +2 -3
- package/bin/deploy/index.js +9 -11
- package/bin/import.js +6 -2
- package/bin/repl.js +82 -56
- package/lib/bind/cfKeyProvider.js +4 -3
- package/lib/bind/index.js +1 -1
- package/lib/build/buildTaskEngine.js +1 -1
- package/lib/build/plugins/helm/files/subcharts/content-deployment/Chart.yaml +3 -1
- package/lib/build/plugins/helm/files/subcharts/content-deployment/templates/_helpers.tpl +3 -5
- package/lib/build/plugins/helm/files/subcharts/content-deployment/values.schema.json +1 -16
- package/lib/build/plugins/helm/files/subcharts/content-deployment/values.yaml +6 -7
- package/lib/build/plugins/helm/files/subcharts/web-application/Chart.yaml +3 -1
- package/lib/build/plugins/helm/files/subcharts/web-application/templates/_helpers.tpl +25 -5
- package/lib/build/plugins/helm/files/subcharts/web-application/templates/api-rule.yaml +13 -4
- package/lib/build/plugins/helm/files/subcharts/web-application/templates/service-binding.yaml +6 -1
- package/lib/build/plugins/helm/files/subcharts/web-application/values.schema.json +55 -48
- package/lib/build/plugins/helm/files/subcharts/web-application/values.yaml +19 -7
- package/lib/build/util.js +3 -1
- package/lib/import/common.js +2 -2
- package/lib/init/constants.js +3 -1
- package/lib/init/index.js +10 -0
- package/lib/init/registries/mta.js +7 -1
- package/lib/init/template/ams/files/Chart.yaml.hbs +4 -0
- package/lib/init/template/ams/files/containerize.yaml.hbs +20 -0
- package/lib/init/template/ams/files/manifest.yml.hbs +24 -0
- package/lib/init/template/ams/files/mta.yaml.hbs +31 -0
- package/lib/init/template/ams/files/package.json.hbs +10 -0
- package/lib/init/template/ams/files/values.yaml.hbs +13 -0
- package/lib/init/template/ams/index.js +80 -0
- package/lib/init/template/approuter/files/mta.yaml.hbs +6 -4
- package/lib/init/template/approuter/files/package.json +1 -1
- package/lib/init/template/helm/files/values.schema.json +0 -2079
- package/lib/init/template/http/index.js +10 -8
- package/lib/init/template/ias/files/Chart.yaml.hbs +4 -0
- package/lib/init/template/ias/files/manifest.yml.hbs +8 -0
- package/lib/init/template/ias/files/mta.yaml.hbs +61 -0
- package/lib/init/template/ias/files/package.json.hbs +22 -0
- package/lib/init/template/ias/files/services-manifest.yml.hbs +6 -0
- package/lib/init/template/ias/files/values.yaml.hbs +52 -0
- package/lib/init/template/ias/index.js +71 -0
- package/lib/init/template/mta/files/mta.yaml.hbs +15 -1
- package/lib/init/template/multitenancy/files/mta.yaml.hbs +38 -5
- package/lib/init/template/multitenancy/files/package.sidecar.json.hbs +5 -2
- package/lib/init/template/multitenancy/index.js +40 -31
- package/lib/init/template/xsuaa/index.js +1 -1
- package/lib/util/cf.js +4 -4
- package/lib/util/command.js +1 -9
- package/npm-shrinkwrap.json +115 -91
- package/package.json +1 -1
|
@@ -225,20 +225,22 @@ module.exports = class HttpTemplate extends require('../../plugin') {
|
|
|
225
225
|
// Later: differentiate between CF and Kyma
|
|
226
226
|
const env = await cf.getEnv(app)
|
|
227
227
|
if (!cds.cli.options.dry) console.error('Fetching credentials from Cloud Foundry app \'' + app + '\'...')
|
|
228
|
-
|
|
229
|
-
const
|
|
230
|
-
const
|
|
231
|
-
|
|
228
|
+
const hostname = `https://${env.application_env_json.VCAP_APPLICATION.application_uris[0]}`
|
|
229
|
+
const { xsuaa, identity } = env.system_env_json.VCAP_SERVICES ?? {}
|
|
230
|
+
const credentials = (xsuaa?.[0] ?? identity?.[0])?.credentials ?? {}
|
|
231
|
+
const { url, clientid, clientsecret, certurl, certificate, key } = credentials
|
|
232
|
+
if (!url) throw new Error('No authentication service found in the environment of ' + app)
|
|
232
233
|
|
|
233
234
|
const auth = certificate ? { maxRedirects: 0, httpsAgent: new https.Agent({ cert: certificate, key }) }
|
|
234
|
-
|
|
235
|
-
const
|
|
235
|
+
: { auth: { username: clientid, password: clientsecret } }
|
|
236
|
+
const suffix = xsuaa ? 'oauth/token' : 'oauth2/token'
|
|
237
|
+
const authUrl = `${certurl ?? url}/${suffix}`
|
|
236
238
|
const data = `grant_type=client_credentials&client_id=${encodeURI(clientid)}`
|
|
237
239
|
const config = { method: 'POST', timeout: 5000, data, ...auth }
|
|
238
240
|
const { access_token } = (await axios(authUrl, config)).data
|
|
239
|
-
|
|
241
|
+
const approuterAuth = `x-approuter-authorization: bearer ${access_token}`
|
|
242
|
+
return [hostname, approuterAuth]
|
|
240
243
|
}
|
|
241
|
-
return [this.hostname, this.approuterAuth]
|
|
242
244
|
}
|
|
243
245
|
|
|
244
246
|
/**
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
modules:
|
|
2
|
+
- name: {{appName}}-srv
|
|
3
|
+
type: {{language}}
|
|
4
|
+
path: {{& srvPath}}
|
|
5
|
+
requires:
|
|
6
|
+
- name: {{appName}}-auth
|
|
7
|
+
parameters:
|
|
8
|
+
config:
|
|
9
|
+
credential-type: X509_GENERATED
|
|
10
|
+
app-identifier: srv
|
|
11
|
+
|
|
12
|
+
- name: {{appName}}
|
|
13
|
+
type: approuter.nodejs
|
|
14
|
+
path: app/router
|
|
15
|
+
requires:
|
|
16
|
+
- name: {{appName}}-auth
|
|
17
|
+
parameters:
|
|
18
|
+
config:
|
|
19
|
+
credential-type: X509_GENERATED
|
|
20
|
+
app-identifier: approuter
|
|
21
|
+
|
|
22
|
+
- name: {{appName}}-mtx
|
|
23
|
+
type: nodejs
|
|
24
|
+
path: gen/mtx/sidecar
|
|
25
|
+
requires:
|
|
26
|
+
- name: {{appName}}-auth
|
|
27
|
+
parameters:
|
|
28
|
+
config:
|
|
29
|
+
credential-type: X509_GENERATED
|
|
30
|
+
app-identifier: mtx
|
|
31
|
+
|
|
32
|
+
resources:
|
|
33
|
+
- name: {{appName}}-auth
|
|
34
|
+
type: org.cloudfoundry.managed-service
|
|
35
|
+
{{#hasApprouter}}
|
|
36
|
+
requires:
|
|
37
|
+
- name: app-api
|
|
38
|
+
{{/hasApprouter}}
|
|
39
|
+
parameters:
|
|
40
|
+
service: identity
|
|
41
|
+
service-name: {{appName}}-auth
|
|
42
|
+
service-plan: application
|
|
43
|
+
config:
|
|
44
|
+
display-name: {{appName}}
|
|
45
|
+
{{#hasApprouter}}
|
|
46
|
+
oauth2-configuration:
|
|
47
|
+
redirect-uris:
|
|
48
|
+
- ~{app-api/app-protocol}://~{app-api/app-uri}/login/callback
|
|
49
|
+
post-logout-redirect-uris:
|
|
50
|
+
- ~{app-api/app-protocol}://~{app-api/app-uri}/*/logout.html
|
|
51
|
+
{{/hasApprouter}}
|
|
52
|
+
{{#hasAms}}
|
|
53
|
+
authorization:
|
|
54
|
+
enabled: true
|
|
55
|
+
{{/hasAms}}
|
|
56
|
+
{{#hasMultitenancy}}
|
|
57
|
+
multi-tenant: true
|
|
58
|
+
{{/hasMultitenancy}}
|
|
59
|
+
{{#hasXsuaa}}
|
|
60
|
+
xsuaa-cross-consumption: true
|
|
61
|
+
{{/hasXsuaa}}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
{{#isNodejs}}
|
|
3
|
+
"dependencies": {
|
|
4
|
+
"@sap/xssec": "^4"
|
|
5
|
+
},
|
|
6
|
+
"cds": {
|
|
7
|
+
{{/isNodejs}}
|
|
8
|
+
"requires": {
|
|
9
|
+
{{#profile}}
|
|
10
|
+
"[{{profile}}]": {
|
|
11
|
+
{{/profile}}
|
|
12
|
+
"auth": {
|
|
13
|
+
"kind": "ias"
|
|
14
|
+
}
|
|
15
|
+
{{#profile}}
|
|
16
|
+
}
|
|
17
|
+
{{/profile}}
|
|
18
|
+
}
|
|
19
|
+
{{#isNodejs}}
|
|
20
|
+
}
|
|
21
|
+
{{/isNodejs}}
|
|
22
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
---
|
|
2
|
+
create-services:
|
|
3
|
+
- name: {{appName}}-auth
|
|
4
|
+
broker: identity
|
|
5
|
+
plan: application
|
|
6
|
+
parameters: "{ \"display-name\": \"{{appName}}\"{{#hasAms}}, \"authorization\": { \"enabled\": true }{{/hasAms}}{{#hasMultitenancy}}, \"multi-tenant\": true {{/hasMultitenancy}}}"
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
{{#hasMultitenancy}}
|
|
2
|
+
sidecar:
|
|
3
|
+
bindings:
|
|
4
|
+
auth:
|
|
5
|
+
serviceInstanceName: identity
|
|
6
|
+
parameters:
|
|
7
|
+
credential-type: X509_GENERATED
|
|
8
|
+
app-identifier: mtx
|
|
9
|
+
{{/hasMultitenancy}}
|
|
10
|
+
{{#hasApprouter}}
|
|
11
|
+
approuter:
|
|
12
|
+
bindings:
|
|
13
|
+
auth:
|
|
14
|
+
serviceInstanceName: identity
|
|
15
|
+
parameters:
|
|
16
|
+
credential-type: X509_GENERATED
|
|
17
|
+
app-identifier: approuter
|
|
18
|
+
{{/hasApprouter}}
|
|
19
|
+
srv:
|
|
20
|
+
bindings:
|
|
21
|
+
auth:
|
|
22
|
+
serviceInstanceName: identity
|
|
23
|
+
parameters:
|
|
24
|
+
credential-type: X509_GENERATED
|
|
25
|
+
app-identifier: srv
|
|
26
|
+
|
|
27
|
+
identity:
|
|
28
|
+
serviceOfferingName: identity
|
|
29
|
+
servicePlanName: application
|
|
30
|
+
parameters:
|
|
31
|
+
display-name: {{appName}}
|
|
32
|
+
{{#hasAms}}
|
|
33
|
+
authorization:
|
|
34
|
+
enabled: true
|
|
35
|
+
{{/hasAms}}
|
|
36
|
+
{{#hasMultitenancy}}
|
|
37
|
+
multi-tenant: true
|
|
38
|
+
{{/hasMultitenancy}}
|
|
39
|
+
{{#hasXsuaa}}
|
|
40
|
+
xsuaa-cross-consumption: true
|
|
41
|
+
{{/hasXsuaa}}
|
|
42
|
+
{{#hasApprouter}}
|
|
43
|
+
oauth2-configuration:
|
|
44
|
+
redirect-uris:
|
|
45
|
+
{{=<% %>=}}
|
|
46
|
+
- https://*.{{ tpl .Values.global.domain . }}/login/callback
|
|
47
|
+
<%={{ }}=%>
|
|
48
|
+
post-logout-redirect-uris:
|
|
49
|
+
{{=<% %>=}}
|
|
50
|
+
- https://*.{{ tpl .Values.global.domain . }}/*/logout.html
|
|
51
|
+
<%={{ }}=%>
|
|
52
|
+
{{/hasApprouter}}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
const { readProject } = require('../../projectReader')
|
|
2
|
+
const { merge } = require('../../merge')
|
|
3
|
+
const { srv4, approuter, mtxSidecar4 } = require('../../registries/mta')
|
|
4
|
+
const cds = require('../../../cds')
|
|
5
|
+
// const mvn = require('../../mvn')
|
|
6
|
+
|
|
7
|
+
module.exports = class IasTemplate extends require('../../plugin') {
|
|
8
|
+
|
|
9
|
+
static help() {
|
|
10
|
+
return 'authentication via IAS'
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
static hasInProduction(env) {
|
|
14
|
+
// REVISIT: Ugly, find more generic solution
|
|
15
|
+
return env.requires?.auth?.kind === 'ias' ||
|
|
16
|
+
cds.cli.argv?.[0]?.includes('ias') || cds.cli.argv?.[0]?.includes('ams') ||
|
|
17
|
+
cds.cli.options?.add?.has('ias') || cds.cli.options?.add?.has('ams') || false
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
async run() {
|
|
21
|
+
const project = readProject()
|
|
22
|
+
const { configFile } = project
|
|
23
|
+
await merge(__dirname, 'files/package.json.hbs').into(configFile, { project, forceOverwrite: true })
|
|
24
|
+
if (project.hasMultitenancy) {
|
|
25
|
+
await merge(__dirname, 'files/package.json.hbs').into('mtx/sidecar/package.json', { project, forceOverwrite: true })
|
|
26
|
+
}
|
|
27
|
+
// if (project.isJava) await mvn.add('ias')
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
async combine() {
|
|
31
|
+
const project = readProject()
|
|
32
|
+
const { isJava, hasMta, hasCfManifest, hasHelm, hasHelmUnifiedRuntime, hasApprouter, hasMultitenancy, srvPath } = project
|
|
33
|
+
|
|
34
|
+
if (hasMta) {
|
|
35
|
+
const srv = srv4(srvPath)
|
|
36
|
+
const identity = { in: 'resources', where: { 'parameters.service': 'identity' } }
|
|
37
|
+
const srvIdentityBinding = { in: [srv, 'requires'], where: { 'parameters.config.app-identifier': 'srv' } }
|
|
38
|
+
const additions = [srv, identity, srvIdentityBinding]
|
|
39
|
+
if (hasApprouter) {
|
|
40
|
+
const approuterIdentityBinding = { in: [approuter, 'requires'], where: { 'parameters.config.app-identifier': 'approuter' } }
|
|
41
|
+
additions.push(approuter, approuterIdentityBinding)
|
|
42
|
+
}
|
|
43
|
+
if (hasMultitenancy) {
|
|
44
|
+
const mtxSidecar = mtxSidecar4(isJava ? 'mtx/sidecar' : 'gen/mtx/sidecar')
|
|
45
|
+
const mtxIdentityBinding = { in: [mtxSidecar, 'requires'], where: { 'parameters.config.app-identifier': 'mtx' } }
|
|
46
|
+
additions.push(mtxSidecar, mtxIdentityBinding)
|
|
47
|
+
}
|
|
48
|
+
await merge(__dirname, 'files/mta.yaml.hbs').into('mta.yaml', { project, additions })
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
if (hasHelm || hasHelmUnifiedRuntime) {
|
|
52
|
+
const identity = { in: 'dependencies', where: { 'alias': 'identity' } }
|
|
53
|
+
await merge(__dirname, 'files/Chart.yaml.hbs').into('chart/Chart.yaml', { project, additions: [identity] })
|
|
54
|
+
await merge(__dirname, 'files/values.yaml.hbs').into('chart/values.yaml', { project })
|
|
55
|
+
// TODO: MTX, approuter
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
if (hasCfManifest) {
|
|
59
|
+
await this.#combineWithCfManifest(project) // REVISIT: we shouldn't overly promote cf-manifest
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
async #combineWithCfManifest(project) {
|
|
64
|
+
const srv = { in: 'applications', where: { 'name': `${project.appName}-srv` } }
|
|
65
|
+
const identityBinding = { in: 'services', where: { 'parameters.app-identifier': project.appName } }
|
|
66
|
+
await merge(__dirname, 'files/manifest.yml.hbs').into('manifest.yml', { project, additions: [srv, identityBinding] })
|
|
67
|
+
|
|
68
|
+
const identity = { in: 'create-services', where: { 'broker': 'identity' } }
|
|
69
|
+
await merge(__dirname, 'files/services-manifest.yml.hbs').into('services-manifest.yml', { project, additions: [identity] })
|
|
70
|
+
}
|
|
71
|
+
}
|
|
@@ -22,6 +22,11 @@ modules:
|
|
|
22
22
|
buildpack: nodejs_buildpack
|
|
23
23
|
readiness-health-check-type: http
|
|
24
24
|
readiness-health-check-http-endpoint: /health
|
|
25
|
+
{{#hasIas}}
|
|
26
|
+
routes:
|
|
27
|
+
- route: "${default-url}"
|
|
28
|
+
- route: "${default-host}.cert.${default-domain}"
|
|
29
|
+
{{/hasIas}}
|
|
25
30
|
build-parameters:
|
|
26
31
|
builder: npm
|
|
27
32
|
{{/isNodejs}}
|
|
@@ -30,6 +35,11 @@ modules:
|
|
|
30
35
|
buildpack: sap_java_buildpack_jakarta
|
|
31
36
|
readiness-health-check-type: http
|
|
32
37
|
readiness-health-check-http-endpoint: /actuator/health/readiness
|
|
38
|
+
{{#hasIas}}
|
|
39
|
+
routes:
|
|
40
|
+
- route: "${default-url}"
|
|
41
|
+
- route: "${default-host}.cert.${default-domain}"
|
|
42
|
+
{{/hasIas}}
|
|
33
43
|
properties:
|
|
34
44
|
SPRING_PROFILES_ACTIVE: cloud,sandbox
|
|
35
45
|
JBP_CONFIG_COMPONENTS: "jres: ['com.sap.xs.java.buildpack.jre.SAPMachineJRE']"
|
|
@@ -43,5 +53,9 @@ modules:
|
|
|
43
53
|
provides:
|
|
44
54
|
- name: srv-api # required by consumers of CAP services (e.g. approuter)
|
|
45
55
|
properties:
|
|
46
|
-
srv-url: ${default-url}
|
|
56
|
+
srv-url: ${default-url}{{#hasIas}}
|
|
57
|
+
srv-cert-url: '${protocol}://${default-host}.cert.${default-domain}'{{/hasIas}}
|
|
47
58
|
requires: []
|
|
59
|
+
|
|
60
|
+
resources:
|
|
61
|
+
[]
|
|
@@ -14,6 +14,7 @@ modules:
|
|
|
14
14
|
- name: srv-api # required by consumers of CAP services (e.g. approuter)
|
|
15
15
|
properties:
|
|
16
16
|
srv-url: ${default-url}
|
|
17
|
+
{{#hasIas}}srv-cert-url: ${protocol}://${default-host}.cert.${default-domain}{{/hasIas}}
|
|
17
18
|
|
|
18
19
|
- name: {{appName}}-mtx
|
|
19
20
|
type: nodejs
|
|
@@ -33,17 +34,20 @@ modules:
|
|
|
33
34
|
{{/isJava}}
|
|
34
35
|
parameters:
|
|
35
36
|
memory: 256M
|
|
36
|
-
disk-quota: 512M
|
|
37
|
+
disk-quota: 512M{{#hasIas}}
|
|
38
|
+
routes:
|
|
39
|
+
- route: "${default-url}"
|
|
40
|
+
- route: "${default-host}.cert.${default-domain}"{{/hasIas}}
|
|
37
41
|
provides:
|
|
38
42
|
- name: mtx-api
|
|
39
43
|
properties:
|
|
40
|
-
mtx-url: ${default-url}
|
|
41
|
-
|
|
44
|
+
mtx-url: ${default-url}{{#hasIas}}
|
|
45
|
+
mtx-cert-url: ${protocol}://${default-host}.cert.${default-domain}{{/hasIas}}
|
|
42
46
|
requires:
|
|
43
|
-
|
|
44
|
-
{{/hasXsuaa}}
|
|
47
|
+
[]
|
|
45
48
|
|
|
46
49
|
resources:
|
|
50
|
+
{{#hasXsuaa}}
|
|
47
51
|
- name: {{appName}}-registry
|
|
48
52
|
type: org.cloudfoundry.managed-service
|
|
49
53
|
requires:
|
|
@@ -75,3 +79,32 @@ resources:
|
|
|
75
79
|
onUnSubscriptionAsync: true
|
|
76
80
|
onUpdateDependenciesAsync: true
|
|
77
81
|
callbackTimeoutMillis: 300000 # Increase if your deployments are taking longer than that
|
|
82
|
+
{{/hasXsuaa}}
|
|
83
|
+
|
|
84
|
+
{{#hasIas}}
|
|
85
|
+
- name: {{appName}}-sms
|
|
86
|
+
type: org.cloudfoundry.managed-service
|
|
87
|
+
parameters:
|
|
88
|
+
service: subscription-manager
|
|
89
|
+
service-plan: provider
|
|
90
|
+
config:
|
|
91
|
+
applicationType: application
|
|
92
|
+
appName: {{appName}}-${org}-${space}
|
|
93
|
+
appCallbacks:
|
|
94
|
+
dependenciesCallbacks:
|
|
95
|
+
url: ~{mtx-api/mtx-cert-url}/-/cds/sms-provisioning/dependencies/{app_tid}
|
|
96
|
+
subscriptionCallbacks:
|
|
97
|
+
url: ~{mtx-api/mtx-cert-url}/-/cds/sms-provisioning/tenant/{app_tid}
|
|
98
|
+
async:
|
|
99
|
+
subscribeEnable: true
|
|
100
|
+
unSubscribeEnable: true
|
|
101
|
+
timeoutInMillis: 300000 # Increase if your deployments are taking longer than that
|
|
102
|
+
displayName: {{appName}}
|
|
103
|
+
description: Description for {{appName}}
|
|
104
|
+
category: Category
|
|
105
|
+
iasServiceInstanceName: {{appName}}-auth{{#hasXsuaa}}
|
|
106
|
+
saasManagerServiceInstanceName: {{appName}}-registry{{/hasXsuaa}}
|
|
107
|
+
requires:
|
|
108
|
+
- name: mtx-api
|
|
109
|
+
{{#hasXsuaa}}processed-after: [{{appName}}-registry, {{appName}}-auth]{{/hasXsuaa}}
|
|
110
|
+
{{/hasIas}}
|
|
@@ -15,7 +15,10 @@
|
|
|
15
15
|
"build": "cds build ../.. --for mtx-sidecar --production && npm ci --prefix gen"{{/isJava}}
|
|
16
16
|
},
|
|
17
17
|
"cds": {
|
|
18
|
-
{{#isJava}}"profiles": ["mtx-sidecar", "java"]{{/isJava}}
|
|
19
|
-
{{#isNodejs}}
|
|
18
|
+
{{#isJava}}"profiles": ["mtx-sidecar", "java"{{#hasIas}}, "subscription-manager"{{/hasIas}}]{{/isJava}}
|
|
19
|
+
{{#isNodejs}}
|
|
20
|
+
{{^hasIas}}"profile": "mtx-sidecar"{{/hasIas}}
|
|
21
|
+
{{#hasIas}}"profiles": ["mtx-sidecar", "subscription-manager"]{{/hasIas}}
|
|
22
|
+
{{/isNodejs}}
|
|
20
23
|
}
|
|
21
24
|
}
|
|
@@ -8,8 +8,8 @@ const { copyRenderedJSON } = require('../../../util/fs')
|
|
|
8
8
|
const {
|
|
9
9
|
srv4, // Server
|
|
10
10
|
mtxSidecar4, // Additional Modules
|
|
11
|
-
saasRegistry, // BTP Services
|
|
12
|
-
srvApi4, providedMtxApiSidecar4, requiredMtxSidecarApi4 // APIs
|
|
11
|
+
saasRegistry, subscriptionManager, // BTP Services
|
|
12
|
+
srvApi4, providedMtxApiSidecar4, requiredMtxSidecarApi4, // APIs
|
|
13
13
|
} = require('../../registries/mta')
|
|
14
14
|
|
|
15
15
|
module.exports = class MultitenancyTemplate extends require('../../plugin') {
|
|
@@ -40,60 +40,70 @@ module.exports = class MultitenancyTemplate extends require('../../plugin') {
|
|
|
40
40
|
|
|
41
41
|
async combine() {
|
|
42
42
|
const project = readProject()
|
|
43
|
-
const {
|
|
43
|
+
const {
|
|
44
|
+
isNodejs, isJava, hasMta, hasHelm, hasHelmUnifiedRuntime,
|
|
45
|
+
hasXsuaa, hasIas, hasHana, hasContainerize, hasApprouter,
|
|
46
|
+
srvPath, appName
|
|
47
|
+
} = project
|
|
44
48
|
|
|
45
49
|
if (hasMta) {
|
|
46
50
|
const srv = srv4(srvPath)
|
|
47
51
|
const mtxSidecar = mtxSidecar4(isJava ? 'mtx/sidecar' : 'gen/mtx/sidecar')
|
|
48
52
|
const modules = [srv, mtxSidecar]
|
|
49
|
-
const services = [
|
|
53
|
+
const services = []
|
|
54
|
+
if (hasIas) services.push(subscriptionManager)
|
|
55
|
+
if (!hasIas || hasXsuaa) services.push(saasRegistry)
|
|
50
56
|
const apis = [srvApi4(srv), providedMtxApiSidecar4(mtxSidecar)]
|
|
51
57
|
if (isJava) apis.push(requiredMtxSidecarApi4(srv))
|
|
52
58
|
const additions = [...modules, ...services, ...apis]
|
|
53
|
-
const relationships =
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
59
|
+
const relationships = []
|
|
60
|
+
if (hasXsuaa) {
|
|
61
|
+
relationships.push({
|
|
62
|
+
insert: [saasRegistry, 'name'],
|
|
63
|
+
into: [isJava ? srv : mtxSidecar, 'requires', 'name']
|
|
64
|
+
})
|
|
65
|
+
}
|
|
66
|
+
if (hasIas) {
|
|
67
|
+
relationships.push({
|
|
68
|
+
insert: [subscriptionManager, 'name'],
|
|
69
|
+
into: [isJava ? srv : mtxSidecar, 'requires', 'name']
|
|
70
|
+
})
|
|
71
|
+
}
|
|
57
72
|
if (isJava) {
|
|
58
73
|
relationships.push({
|
|
59
74
|
insert: [srv, 'name'],
|
|
60
75
|
into: [mtxSidecar, 'build-parameters.requires', 'name']
|
|
61
76
|
})
|
|
62
77
|
}
|
|
63
|
-
|
|
64
78
|
const templateMtaPath = join(__dirname, 'files/mta.yaml.hbs')
|
|
65
79
|
await merge(templateMtaPath).into('mta.yaml', { with: project, additions, relationships })
|
|
66
80
|
}
|
|
67
81
|
|
|
68
82
|
if (hasHelm || hasHelmUnifiedRuntime) {
|
|
69
|
-
|
|
70
83
|
await merge(__dirname, 'files/values.yaml.hbs').into('chart/values.yaml', { with: project })
|
|
71
|
-
|
|
72
84
|
const domain = hasApprouter ? 'svc.cluster.local:8080' : '{{ .Values.global.domain }}'
|
|
73
85
|
const applicationWorkload = hasApprouter ? 'approuter' : 'srv'
|
|
74
|
-
const serviceCommunicatingWithSaasReg = hasApprouter ? 'approuter' : isNodejs ? 'sidecar' : 'srv'
|
|
86
|
+
const serviceCommunicatingWithSaasReg = hasApprouter ? 'approuter' : isNodejs ? 'sidecar' : 'srv'
|
|
87
|
+
const prefix = `https://{{ .Release.Name }}-${serviceCommunicatingWithSaasReg}-{{ .Release.Namespace }}.{{ .Values.global.domain }}`
|
|
88
|
+
const getDependencies = `${prefix}${isNodejs ? '/-/cds/saas-provisioning' : '/mt/v1.0/subscriptions'}/dependencies`
|
|
89
|
+
const onSubscription = `${prefix}${isNodejs ? '/-/cds/saas-provisioning/tenant/{tenantId}' : '/mt/v1.0/subscriptions/tenants/{tenantId}'}`
|
|
75
90
|
await merge({
|
|
76
91
|
'saas-registry': {
|
|
77
|
-
|
|
78
|
-
xsappname: `${
|
|
79
|
-
appName: `${
|
|
92
|
+
parameters: {
|
|
93
|
+
xsappname: `${appName}-{{ .Release.Namespace }}`,
|
|
94
|
+
appName: `${appName}-{{ .Release.Namespace }}`,
|
|
80
95
|
appUrls: {
|
|
81
|
-
getDependencies
|
|
82
|
-
onSubscription: `https://{{ .Release.Name }}-${serviceCommunicatingWithSaasReg}-{{ .Release.Namespace }}.{{ .Values.global.domain }}${isNodejs ? '/-/cds/saas-provisioning/tenant/{tenantId}' : '/mt/v1.0/subscriptions/tenants/{tenantId}'}`,
|
|
96
|
+
getDependencies, onSubscription
|
|
83
97
|
}
|
|
84
98
|
}
|
|
85
99
|
},
|
|
86
|
-
...(isNodejs) && { sidecar: {
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
CDS_MULTITENANCY_APPUI_URL: `https://{{ .Release.Name }}-${applicationWorkload}-{{ .Release.Namespace }}.{{ .Values.global.domain }}`,
|
|
94
|
-
CDS_MULTITENANCY_SIDECAR_URL: `http${hasApprouter ? '' : 's'}://{{ .Release.Name }}-sidecar${hasApprouter ? '.' : '-'}{{ .Release.Namespace }}.${domain}`
|
|
95
|
-
}
|
|
96
|
-
}}
|
|
100
|
+
...(isNodejs) && { sidecar: { env: {
|
|
101
|
+
SUBSCRIPTION_URL: `https://\${tenant_subdomain}-{{ .Release.Name }}-${applicationWorkload}-{{ .Release.Namespace }}.{{ .Values.global.domain }}`
|
|
102
|
+
}}},
|
|
103
|
+
...(isJava) && { srv: { env: {
|
|
104
|
+
CDS_MULTITENANCY_APPUI_URL: `https://{{ .Release.Name }}-${applicationWorkload}-{{ .Release.Namespace }}.{{ .Values.global.domain }}`,
|
|
105
|
+
CDS_MULTITENANCY_SIDECAR_URL: `http${hasApprouter ? '' : 's'}://{{ .Release.Name }}-sidecar${hasApprouter ? '.' : '-'}{{ .Release.Namespace }}.${domain}`
|
|
106
|
+
}}}
|
|
97
107
|
}).into('chart/values.yaml',{ forceOverwrite: true })
|
|
98
108
|
}
|
|
99
109
|
|
|
@@ -103,14 +113,13 @@ module.exports = class MultitenancyTemplate extends require('../../plugin') {
|
|
|
103
113
|
deletions.push({
|
|
104
114
|
item: {
|
|
105
115
|
in: 'modules',
|
|
106
|
-
where: { name: `${
|
|
116
|
+
where: { name: `${appName}-hana-deployer` }
|
|
107
117
|
}
|
|
108
118
|
})
|
|
109
119
|
}
|
|
110
|
-
|
|
111
120
|
const additions = [{
|
|
112
121
|
in: 'modules',
|
|
113
|
-
where: { name: `${
|
|
122
|
+
where: { name: `${appName}-sidecar` }
|
|
114
123
|
}]
|
|
115
124
|
await merge(__dirname, '/files/containerize.yaml.hbs').into('containerize.yaml', { with: project, additions, deletions })
|
|
116
125
|
}
|
|
@@ -11,7 +11,7 @@ module.exports = class XsuaaTemplate extends require('../../plugin') {
|
|
|
11
11
|
}
|
|
12
12
|
|
|
13
13
|
static hasInProduction(env) {
|
|
14
|
-
return env.requires?.auth?.kind === 'xsuaa'
|
|
14
|
+
return env.requires?.auth?.kind === 'xsuaa' || cds.cli.options?.add?.has('xsuaa') || false
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
async run() {
|
package/lib/util/cf.js
CHANGED
|
@@ -218,7 +218,7 @@ Deployment will stop in the near future for Cloud Foundry client versions < ${CF
|
|
|
218
218
|
}
|
|
219
219
|
|
|
220
220
|
async getService(serviceName, showMessage = true) {
|
|
221
|
-
showMessage && console.log(`
|
|
221
|
+
showMessage && console.log(`getting service ${bold(serviceName)}`);
|
|
222
222
|
const spaceInfo = await this.getCfSpaceInfo();
|
|
223
223
|
|
|
224
224
|
let counter = POLL_COUNTER;
|
|
@@ -263,7 +263,7 @@ Deployment will stop in the near future for Cloud Foundry client versions < ${CF
|
|
|
263
263
|
|
|
264
264
|
const probeService = await this.getService(serviceName, false);
|
|
265
265
|
if (probeService) {
|
|
266
|
-
console.log(`
|
|
266
|
+
console.log(`getting service ${bold(serviceName)}`);
|
|
267
267
|
return probeService;
|
|
268
268
|
}
|
|
269
269
|
|
|
@@ -318,7 +318,7 @@ Deployment will stop in the near future for Cloud Foundry client versions < ${CF
|
|
|
318
318
|
}
|
|
319
319
|
|
|
320
320
|
async _getServiceKey(serviceInstance, serviceKeyName, showMessage = true) {
|
|
321
|
-
showMessage && console.log(`
|
|
321
|
+
showMessage && console.log(`getting service key ${bold(serviceKeyName)}`);
|
|
322
322
|
|
|
323
323
|
let counter = POLL_COUNTER;
|
|
324
324
|
while (counter > 0) {
|
|
@@ -358,7 +358,7 @@ Deployment will stop in the near future for Cloud Foundry client versions < ${CF
|
|
|
358
358
|
async getOrCreateServiceKey(serviceInstance, serviceKeyName, parameters, { silent = false, create = true } = {}) {
|
|
359
359
|
const serviceKey = await this._getServiceKey(serviceInstance, serviceKeyName, false);
|
|
360
360
|
if (serviceKey || !create) {
|
|
361
|
-
if (serviceKey && !silent) console.log(`
|
|
361
|
+
if (serviceKey && !silent) console.log(`getting service key ${bold(serviceKeyName)}`);
|
|
362
362
|
return serviceKey;
|
|
363
363
|
}
|
|
364
364
|
|
package/lib/util/command.js
CHANGED
|
@@ -20,7 +20,7 @@ class CommandUtil {
|
|
|
20
20
|
* @returns Promise
|
|
21
21
|
*/
|
|
22
22
|
async spawnCommand(cmd, args, options = {}, collectResult = false, showOutput = true) {
|
|
23
|
-
args =
|
|
23
|
+
args = args.map(arg => arg.replace(/[&;|]/g, '')); // sanitize args
|
|
24
24
|
return new Promise((resolve, reject) => {
|
|
25
25
|
DEBUG?.(`[spawn] ${cmd} ${args.join(' ')}`);
|
|
26
26
|
|
|
@@ -84,14 +84,6 @@ class CommandUtil {
|
|
|
84
84
|
});
|
|
85
85
|
}
|
|
86
86
|
|
|
87
|
-
_sanitizeArgs(args) {
|
|
88
|
-
const result = [];
|
|
89
|
-
for (const arg of args) {
|
|
90
|
-
result.push(arg.replace(/[&;|]/g, ''));
|
|
91
|
-
}
|
|
92
|
-
return result;
|
|
93
|
-
}
|
|
94
|
-
|
|
95
87
|
}
|
|
96
88
|
|
|
97
89
|
class LogBuffer {
|