@sap/cds-dk 9.1.3 → 9.2.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 +48 -0
- package/bin/bind.js +2 -0
- package/bin/cds.js +2 -0
- package/bin/repl.js +4 -2
- package/bin/up.js +12 -2
- package/bin/util/log.js +8 -1
- package/bin/version.js +20 -15
- package/lib/bind/shared.js +6 -2
- package/lib/build/plugins/helm/files/subcharts/web-application/Chart.yaml +1 -1
- package/lib/build/plugins/helm/files/subcharts/web-application/templates/_helpers.tpl +1 -1
- package/lib/build/plugins/helm/files/subcharts/web-application/templates/deployment.yaml +8 -0
- package/lib/build/plugins/helm/files/subcharts/web-application/templates/virtual-service.yaml +38 -0
- package/lib/build/plugins/helm/files/subcharts/web-application/values.schema.json +15 -0
- package/lib/build/plugins/helm/files/subcharts/web-application/values.yaml +12 -9
- package/lib/build/plugins/helm/index.js +1 -1
- package/lib/build/provider/hana/index.js +5 -4
- package/lib/build/provider/hana/template/.hdiconfig-all +6 -0
- package/lib/compile/to-xsuaa.js +14 -4
- package/lib/deploy/to-hana/hana.js +1 -1
- package/lib/deploy/to-hana/hdiDeployUtil.js +1 -1
- package/lib/init/constants.js +5 -3
- package/lib/init/index.js +6 -1
- package/lib/init/merge.js +7 -3
- package/lib/init/projectReader.js +7 -2
- package/lib/init/registries/mta.js +6 -0
- package/lib/init/template/ams/files/values.yaml.hbs +5 -0
- package/lib/init/template/approuter/files/containerize.yaml.hbs +1 -1
- package/lib/init/template/approuter/files/values.yaml.hbs +1 -5
- package/lib/init/template/attachments/index.js +1 -1
- package/lib/init/template/audit-logging/index.js +1 -1
- package/lib/init/template/data/as-json.js +4 -3
- package/lib/init/template/data/index.js +1 -0
- package/lib/init/template/destination/files/mta.yaml.hbs +1 -20
- package/lib/init/template/extension/index.js +1 -1
- package/lib/init/template/github-actions/files/cf-github-deploy/action.yaml +48 -0
- package/lib/init/template/github-actions/files/cf-setup/action.yaml +53 -0
- package/lib/init/template/github-actions/files/kyma-info/action.yaml +37 -0
- package/lib/init/template/github-actions/files/kyma-setup/action.yaml +64 -0
- package/lib/init/template/github-actions/files/workflows/cf.yaml.hbs +52 -0
- package/lib/init/template/github-actions/files/workflows/kyma.yaml.hbs +39 -0
- package/lib/init/template/github-actions/files/workflows/test.yaml.hbs +21 -0
- package/lib/init/template/github-actions/index.js +69 -0
- package/lib/init/template/helm/index.js +5 -1
- package/lib/init/template/html5-repo/files/containerize.yaml.hbs +4 -4
- package/lib/init/template/html5-repo/files/mta.yaml.hbs +24 -0
- package/lib/init/template/html5-repo/files/values.yaml.hbs +2 -1
- package/lib/init/template/html5-repo/index.js +9 -3
- package/lib/init/template/http/index.js +4 -4
- package/lib/init/template/ias/files/package.json.hbs +7 -0
- package/lib/init/template/ias/files/values.yaml.hbs +1 -4
- package/lib/init/template/ias/index.js +2 -1
- package/lib/init/template/kyma/index.js +10 -0
- package/lib/init/template/lint/index.js +6 -11
- package/lib/init/template/malware-scanner/index.js +1 -1
- package/lib/init/template/multitenancy/files/values.yaml.hbs +53 -1
- package/lib/init/template/multitenancy/index.js +0 -13
- package/lib/init/template/nodejs/files/.vscode/settings.json +2 -2
- package/lib/init/template/notifications/index.js +1 -1
- package/lib/init/template/pipeline/files/Jenkinsfile +2 -2
- package/lib/init/template/pipeline/index.js +1 -1
- package/lib/init/template/portal/files/containerize.yaml.hbs +15 -0
- package/lib/init/template/portal/files/values.yaml.hbs +1 -1
- package/lib/init/template/portal/index.js +9 -1
- package/lib/init/template/postgres/index.js +1 -1
- package/lib/init/template/sample/index.js +1 -1
- package/lib/init/template/test/index.js +1 -1
- package/lib/init/template/tiny-sample/index.js +1 -1
- package/lib/init/template/typescript/index.js +1 -1
- package/lib/init/template/workzone-standard/index.js +13 -4
- package/lib/init/template/xsuaa/files/mta.yaml.hbs +8 -0
- package/lib/init/template/xsuaa/index.js +11 -0
- package/lib/init/template.js +38 -26
- package/lib/lint/eslintHelp.json +1 -1
- package/lib/util/cf.js +7 -7
- package/lib/watch/watched.js +1 -1
- package/npm-shrinkwrap.json +24 -24
- package/package.json +1 -1
- /package/lib/init/template/html5-repo/files/{ui-resources/package.json.hbs → html5-deployer.package.json.hbs} +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -6,8 +6,56 @@ This project adheres to [Semantic Versioning](https://semver.org/).
|
|
|
6
6
|
|
|
7
7
|
The format is based on [Keep a Changelog](https://keepachangelog.com/).
|
|
8
8
|
|
|
9
|
+
## Version 9.2.1 - 2025-08-22
|
|
10
|
+
|
|
11
|
+
### Changed
|
|
12
|
+
|
|
13
|
+
- `cds add github-actions` adds `if: always()` to the scripts retrieving Cloud Foundry logs.
|
|
14
|
+
- `cds up` uses a default timeout of 10 minutes for Helm upgrades.
|
|
15
|
+
- `cds bind` works out-of-the-box for PostgreSQL databases.
|
|
16
|
+
- `cds bind -a` gives warning if no services are bound to the targeted app.
|
|
17
|
+
|
|
18
|
+
### Fixed
|
|
19
|
+
|
|
20
|
+
- `cds add github-actions` won't try to merge a `cf-info` action if there's an existing `mta.yaml`.
|
|
21
|
+
- `cds add workzone` with missing `sap.app` config in `manifest.json` does not throw a `TypeError`.
|
|
22
|
+
- `cds compile --to xsuaa` generates roles for `@requires` in bound actions.
|
|
23
|
+
- `cds add lint` now adds proper configuration to enable linting of JavaScript and TypeScript files in VS Code.
|
|
24
|
+
- `cds add mta` does no longer adds services in `mta.yaml` for plugins coming from `devDependencies`.
|
|
25
|
+
|
|
26
|
+
## Version 9.2.0 - 2025-07-31
|
|
27
|
+
|
|
28
|
+
### Added
|
|
29
|
+
|
|
30
|
+
- `cds add xsuaa` now also creates a default `role-collections` field in the `mta.yaml`.
|
|
31
|
+
- `cds add github-actions` (shortcut `gha`) adds pipeline configuration for GitHub Actions.
|
|
32
|
+
- `cds add kyma` as a shortcut for `cds add helm,containerize`.
|
|
33
|
+
- `cds add multitenancy` creates a `package-lock.json` in `mtx/sidecar` for Java projects if not existing.
|
|
34
|
+
- `cds build` provides more defaults in its standard `.hdiconfig`.
|
|
35
|
+
|
|
36
|
+
### Changed
|
|
37
|
+
|
|
38
|
+
- `cds up` auto-creates `package-lock.json` if required for `app/router`, `app/portal`, and `app/html5-deployer`.
|
|
39
|
+
- `cds up` does not do retries when not running in CI/CD (`CI` environment variable is not set).
|
|
40
|
+
- `cds add html5-repo` uses a folder `app/html5-deployer` instead of `ui-resources` for Kyma.
|
|
41
|
+
- `cds add http` now generates auth headers with `:` separators again, as this is the only separator supporting empty passwords with the RestClient extension in VS Code. (For use with IntelliJ, separate username and password with a blank.)
|
|
42
|
+
- `cds add html5-repo` will add the destinations to the application content deployer instead of the service instance.
|
|
43
|
+
- `cds add helm` exposes the `srv` module by default in Kyma scenarios.
|
|
44
|
+
- `cds add multitenancy` with Helm exposes the sidecar URL for consumption by Java.
|
|
45
|
+
- `cds add ias` will use the `production` profile by default, if no other profile is specified.
|
|
46
|
+
- `cds add http` now uses the proper service name in the generated requests.
|
|
47
|
+
- `cds build` error messages for build plugins are improved.
|
|
48
|
+
|
|
49
|
+
### Fixed
|
|
50
|
+
|
|
51
|
+
- `cds add multitenancy` for Kyma with IAS correctly adds the `subscription-manager` service.
|
|
52
|
+
- `cds watch/run myapp/` now outputs correct error locations like `myapp/srv/broken.cds` instead of `srv/broken.cds`. These locations can be opened from shells as they are relative to the working folder, not to the project folder.
|
|
53
|
+
- `cds add data --records` now correctly generates decimals within the range of the specified precision and scale.
|
|
54
|
+
|
|
9
55
|
## Version 9.1.3 - 2025-07-24
|
|
10
56
|
|
|
57
|
+
### Fixed
|
|
58
|
+
|
|
11
59
|
- Fix installation issues with version 9.1.2.
|
|
12
60
|
|
|
13
61
|
## Version 9.1.2 - 2025-07-24
|
package/bin/bind.js
CHANGED
|
@@ -159,6 +159,8 @@ async function cds_bind(args, options) {
|
|
|
159
159
|
const resolvedServices = [], unresolvedServices = {}
|
|
160
160
|
const services = (await require('../lib/util/cf').services(app)).filter(s => Object.keys(s.credentials).length > 0)
|
|
161
161
|
|
|
162
|
+
if (!services) console.warn(`no services bound to app ${app} - nothing to bind`)
|
|
163
|
+
|
|
162
164
|
services.forEach(service => {
|
|
163
165
|
const type = service.label || service.type;
|
|
164
166
|
const requiredServiceEntry = Object.entries(cds.env.requires).find(([, requiredService]) => requiredService.kind === type && requiredService?.vcap?.name === service.name)
|
package/bin/cds.js
CHANGED
|
@@ -101,6 +101,8 @@ const cli = {
|
|
|
101
101
|
} catch (e) {
|
|
102
102
|
process.exitCode ??= 1
|
|
103
103
|
if (cds.watched) throw e // bin/watched.js handles errors
|
|
104
|
+
if (e.messages?.length)
|
|
105
|
+
cds._log(e.messages, { 'log-level': cds.env.log.levels.cli }) // REVISIT: no special handling for compiler messages
|
|
104
106
|
else return console.error(e)
|
|
105
107
|
}
|
|
106
108
|
},
|
package/bin/repl.js
CHANGED
|
@@ -56,8 +56,10 @@ async function repl (_, options={}) {
|
|
|
56
56
|
ignoreUndefined: true,
|
|
57
57
|
useGlobal: true,
|
|
58
58
|
writer: o => {
|
|
59
|
+
const options = {}
|
|
59
60
|
if (!o || typeof o !== 'object') return o
|
|
60
|
-
|
|
61
|
+
if ('init' in o && 'on' in o && 'run' in o) options.depth = 0
|
|
62
|
+
return inspect(o,options).replace(/\[Object: null prototype\] /g, '')
|
|
61
63
|
}
|
|
62
64
|
})
|
|
63
65
|
|
|
@@ -125,7 +127,7 @@ async function repl (_, options={}) {
|
|
|
125
127
|
}
|
|
126
128
|
|
|
127
129
|
async function _inspect (_args) {
|
|
128
|
-
const args = _args.split(' '), subjects={}, options = {}, defaults = inspect.defaultOptions
|
|
130
|
+
const args = _args.split(' '), subjects={}, options = { depth:0 }, defaults = inspect.defaultOptions
|
|
129
131
|
for (let each of args) {
|
|
130
132
|
// args of shape .<option>=<value> set inspect options
|
|
131
133
|
if (each[0] === '.') each = eval(`options${each}`)
|
package/bin/up.js
CHANGED
|
@@ -79,6 +79,15 @@ async function up() {
|
|
|
79
79
|
if (exists('mtx/sidecar') && !exists('mtx/sidecar/package-lock.json')) {
|
|
80
80
|
run('npm i --package-lock-only --prefix mtx/sidecar')
|
|
81
81
|
}
|
|
82
|
+
if (exists('app/router/package.json') && !exists('app/router/package-lock.json')) {
|
|
83
|
+
run('npm i --package-lock-only --prefix app/router')
|
|
84
|
+
}
|
|
85
|
+
if (exists('app/portal/package.json') && !exists('app/portal/package-lock.json')) {
|
|
86
|
+
run('npm i --package-lock-only --prefix app/portal')
|
|
87
|
+
}
|
|
88
|
+
if (exists('app/html5-deployer/package.json') && !exists('app/html5-deployer/package-lock.json')) {
|
|
89
|
+
run('npm i --package-lock-only --prefix app/html5-deployer')
|
|
90
|
+
}
|
|
82
91
|
|
|
83
92
|
if (cds.cli.options.to === 'k8s') {
|
|
84
93
|
if (!exists('chart')) run('cds add helm')
|
|
@@ -107,7 +116,7 @@ async function up() {
|
|
|
107
116
|
|
|
108
117
|
run('npm i --package-lock')
|
|
109
118
|
await runDetectingError('ctz containerize.yaml --log --push', /^\[?ERROR\]?.*/m)
|
|
110
|
-
let helmUpgrade = `helm upgrade --install ${appName} ./gen/chart ${nsHelm} --wait --wait-for-jobs`
|
|
119
|
+
let helmUpgrade = `helm upgrade --install ${appName} ./gen/chart ${nsHelm} --wait --wait-for-jobs --timeout=10m`
|
|
111
120
|
if (hasXsuaa) helmUpgrade += ' --set-file xsuaa.jsonParameters=xs-security.json'
|
|
112
121
|
run(helmUpgrade)
|
|
113
122
|
run(`kubectl rollout status deployment ${appName}-srv ${nsKubectl} --timeout=8m`)
|
|
@@ -115,6 +124,7 @@ async function up() {
|
|
|
115
124
|
if (exists('mtx/sidecar')) run(`kubectl rollout status deployment ${appName}-sidecar ${nsKubectl} --timeout=8m`)
|
|
116
125
|
} else {
|
|
117
126
|
run('mbt build -t gen --mtar mta.tar')
|
|
118
|
-
|
|
127
|
+
const retries = process.env.CI ? '' : '--retries 0'
|
|
128
|
+
run(`cf deploy gen/mta.tar -f ${retries}`)
|
|
119
129
|
}
|
|
120
130
|
}
|
package/bin/util/log.js
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
|
-
|
|
1
|
+
|
|
2
|
+
/**
|
|
3
|
+
* Sorts, filters, and writes compilation messages to console
|
|
4
|
+
* @param {import('@sap/cds-compiler').CompileMessage[]} messages
|
|
5
|
+
* @param {object} options
|
|
6
|
+
*/
|
|
2
7
|
module.exports = (messages, options={}) => {
|
|
8
|
+
const cds = require('../../lib')
|
|
3
9
|
const { format } = require('../../lib/util/term')
|
|
4
10
|
const logLevel = options && options['log-level'] || require('../../lib').env.log.levels.cli || ''
|
|
5
11
|
const levels = {
|
|
@@ -17,6 +23,7 @@ module.exports = (messages, options={}) => {
|
|
|
17
23
|
const internalError = m.name === 'EvalError' || m.name === 'InternalError' || m.name === 'RangeError'
|
|
18
24
|
|| m.name === 'ReferenceError' || m.name === 'SyntaxError' || m.name === 'TypeError'
|
|
19
25
|
|| m.name === 'URIError'
|
|
26
|
+
if (m.$location?.file) m.$location.file = cds.utils.local(m.$location.file) // recompute file locations based on original cwd
|
|
20
27
|
const mf = format (m, m.severity, internalError, true)
|
|
21
28
|
log (mf)
|
|
22
29
|
}
|
package/bin/version.js
CHANGED
|
@@ -33,7 +33,7 @@ module.exports = Object.assign(list_versions, {
|
|
|
33
33
|
|
|
34
34
|
const MISSING = '-- missing --'
|
|
35
35
|
|
|
36
|
-
function list_versions(args, options) {
|
|
36
|
+
function list_versions (args, options) {
|
|
37
37
|
const {colors} = require('../lib/util/term')
|
|
38
38
|
|
|
39
39
|
if (options['npm-list'] || options['npm-tree']) {
|
|
@@ -60,40 +60,46 @@ function list_versions(args, options) {
|
|
|
60
60
|
process.stdout.isTTY && console.log()
|
|
61
61
|
}
|
|
62
62
|
|
|
63
|
-
function info({ root:cwd=process.cwd() }) {
|
|
63
|
+
function info({ root: cwd = process.cwd() }) {
|
|
64
|
+
|
|
64
65
|
const cds = require('../lib')
|
|
65
66
|
const env = cds.env.for('cds', cwd)
|
|
66
|
-
env.cli ??= {}; env.cli.version ??= {}
|
|
67
|
-
const javaInfo = !env.cli.version.skipjava && env['project-nature'] === 'java'
|
|
68
|
-
if (javaInfo && process.stderr.isTTY) {
|
|
69
|
-
console.error('\x1b[2m'+'This takes a while. Collecting Java versions...', '\x1b[0m')
|
|
70
|
-
}
|
|
71
67
|
|
|
68
|
+
// Fetch versions for all CAP Node packages in the current project
|
|
72
69
|
const npmRoot = execSync('npm root -g').toString().trim()
|
|
73
|
-
|
|
70
|
+
const versions = {
|
|
74
71
|
..._versions_from(_pkg_path('@sap/cds-dk', npmRoot), '@sap/cds-dk (global)'), // linked in cap/dev or installed globally
|
|
75
72
|
..._versions_from(_pkg_path('@sap/cds-dk', cwd)), // local dk, important for Java projects
|
|
76
73
|
..._versions_from(_pkg_path('@sap/cds', __dirname)), // @sap/cds from here
|
|
77
74
|
..._versions_from(_pkg_path('@sap/cds', cds.home)), // ... or local @sap/cds
|
|
78
75
|
..._versions_from(_pkg_path('@cap-js/db-service', cwd)), // only required transitively
|
|
79
|
-
..._versions_from(cwd), // ... more from local app dependencies
|
|
76
|
+
..._versions_from(cwd,false), // ... more from local app dependencies
|
|
80
77
|
'@sap/cds-compiler': cds.compiler.version(),
|
|
81
78
|
'Node.js': process.version,
|
|
82
79
|
'home': cds.home, // effective cds home
|
|
83
80
|
}
|
|
84
|
-
// sort Node entries
|
|
85
|
-
versions = Object.keys(versions).sort().reduce((all, key) => { all[key] = versions[key]; return all }, {})
|
|
86
81
|
|
|
82
|
+
// Sort entries, with @sap/cds packages on top, followed by @cap-js packages
|
|
83
|
+
const keys = Object.keys(versions).sort(), sorted={}
|
|
84
|
+
for (let k of ['@sap/cds','@sap/cds-dk']) if (!(k in sorted)) sorted[k] = versions[k]
|
|
85
|
+
for (let k of keys) if (!(k in sorted) && k.startsWith('@sap/cds')) sorted[k] = versions[k]
|
|
86
|
+
for (let k of keys) if (!(k in sorted) && k.startsWith('@cap-js')) sorted[k] = versions[k]
|
|
87
|
+
for (let k of keys) if (!(k in sorted)) sorted[k] = versions[k]
|
|
88
|
+
|
|
89
|
+
// For Java projects we also need to collect the Java SDK version
|
|
90
|
+
const javaInfo = !env.cli?.version?.skipjava && env['project-nature'] === 'java'
|
|
87
91
|
if (javaInfo) {
|
|
88
|
-
|
|
92
|
+
if (process.stderr.isTTY) console.error('\x1b[2m'+'This takes a while. Collecting Java versions...', '\x1b[0m')
|
|
93
|
+
Object.assign(sorted, capJavaVersion(cwd))
|
|
89
94
|
}
|
|
90
|
-
|
|
95
|
+
|
|
96
|
+
return sorted
|
|
91
97
|
}
|
|
92
98
|
|
|
93
99
|
function _versions_from(pkg_path, pkg_label) {
|
|
94
100
|
let pkg; try { pkg = require(join(pkg_path, 'package.json')) } catch { return {} }
|
|
95
101
|
let versions = {}
|
|
96
|
-
if (pkg.name) versions[pkg_label || pkg.name] = pkg.version
|
|
102
|
+
if (pkg.name && pkg_label !== false) versions[pkg_label || pkg.name] = pkg.version
|
|
97
103
|
|
|
98
104
|
const deps = { ...pkg.dependencies, ...pkg.devDependencies }
|
|
99
105
|
for (let dep in deps) {
|
|
@@ -121,7 +127,6 @@ function _markdown (versions) {
|
|
|
121
127
|
|
|
122
128
|
Object.keys(versions)
|
|
123
129
|
.filter(mod => mod != pkg.name)
|
|
124
|
-
.sort()
|
|
125
130
|
.forEach(id => console.log ('|', $(id, versions[id]), '|'))
|
|
126
131
|
|
|
127
132
|
function $ (key, val=MISSING) {
|
package/lib/bind/shared.js
CHANGED
|
@@ -4,6 +4,7 @@ const { exists, read, fs, path } = cds.utils
|
|
|
4
4
|
const git = require('../util/git')
|
|
5
5
|
const { bold } = require('../util/term')
|
|
6
6
|
|
|
7
|
+
// REVISIT: We should get rid of this...
|
|
7
8
|
const KindToRequiresNameMap = {
|
|
8
9
|
xsuaa: 'auth',
|
|
9
10
|
'xsuaa-auth': 'auth',
|
|
@@ -21,7 +22,9 @@ const KindToRequiresNameMap = {
|
|
|
21
22
|
'enterprise-messaging-http': 'messaging',
|
|
22
23
|
'enterprise-messaging-shared': 'messaging',
|
|
23
24
|
'redis-messaging': 'messaging',
|
|
24
|
-
'multitenancy': 'multitenancy'
|
|
25
|
+
'multitenancy': 'multitenancy',
|
|
26
|
+
'portal': 'portal',
|
|
27
|
+
'postgres': 'db'
|
|
25
28
|
}
|
|
26
29
|
|
|
27
30
|
const PreferredKinds = {
|
|
@@ -75,7 +78,8 @@ async function bind(options = { on: 'cf' }) {
|
|
|
75
78
|
resolved.name = options.serviceArg
|
|
76
79
|
} else if (kind) {
|
|
77
80
|
const requiresName = KindToRequiresNameMap[kind]
|
|
78
|
-
|
|
81
|
+
|
|
82
|
+
if (!requiresName) throw `unknown CDS service name for service ${bold(instance)} of kind ${bold(kind)} – please specify as argument for ${bold('cds bind')}`
|
|
79
83
|
resolved.name = requiresName
|
|
80
84
|
}
|
|
81
85
|
resolved.name ??= `custom-service:${instance || secret}`
|
|
@@ -34,7 +34,7 @@ Define Hosts for the APIRule (since v2alpha1)
|
|
|
34
34
|
*/}}
|
|
35
35
|
{{- define "web-application.internal.exposeHosts" -}}
|
|
36
36
|
{{- if .Values.expose.hosts }}
|
|
37
|
-
{{ .Values.expose.hosts | toYaml }}
|
|
37
|
+
{{ tpl (.Values.expose.hosts | toYaml) . }}
|
|
38
38
|
{{- else }}
|
|
39
39
|
{{- $name := (include "web-application.fullname" .) }}
|
|
40
40
|
{{- if hasPrefix $name .Release.Namespace }}
|
|
@@ -68,6 +68,10 @@ spec:
|
|
|
68
68
|
- name: OTEL_EXPORTER_OTLP_METRICS_ENDPOINT
|
|
69
69
|
value: {{ .Values.otlp.metrics.endpoint }}
|
|
70
70
|
{{- end }}
|
|
71
|
+
{{- if .Values.otlp.logs.enabled }}
|
|
72
|
+
- name: OTEL_EXPORTER_OTLP_LOGS_ENDPOINT
|
|
73
|
+
value: {{ .Values.otlp.logs.endpoint }}
|
|
74
|
+
{{- end }}
|
|
71
75
|
{{- $envVars := (include "web-application.internal.processEnv" (dict "env" .Values.env "context" $) | fromJson) }}
|
|
72
76
|
{{- if not $envVars.appName}}
|
|
73
77
|
- name: APPLICATION_NAME
|
|
@@ -142,6 +146,10 @@ spec:
|
|
|
142
146
|
- name: OTEL_EXPORTER_OTLP_METRICS_ENDPOINT
|
|
143
147
|
value: {{ $.Values.otlp.metrics.endpoint }}
|
|
144
148
|
{{- end }}
|
|
149
|
+
{{- if $.Values.otlp.logs.enabled }}
|
|
150
|
+
- name: OTEL_EXPORTER_OTLP_LOGS_ENDPOINT
|
|
151
|
+
value: {{ $.Values.otlp.logs.endpoint }}
|
|
152
|
+
{{- end }}
|
|
145
153
|
{{- $envVars := (include "web-application.internal.processEnv" (dict "env" $sidecar.env "context" $) | fromJson) }}
|
|
146
154
|
{{- if not (eq (len $envVars.vars) 0) }}
|
|
147
155
|
{{- $envVars.vars | toYaml | nindent 8}}
|
package/lib/build/plugins/helm/files/subcharts/web-application/templates/virtual-service.yaml
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
{{- if and .Values.expose.enabled (include "web-application.internal.TENANT_HOST_PATTERN" .) -}}
|
|
2
|
+
---
|
|
2
3
|
apiVersion: networking.istio.io/v1beta1
|
|
3
4
|
kind: VirtualService
|
|
4
5
|
metadata:
|
|
@@ -13,7 +14,15 @@ spec:
|
|
|
13
14
|
{{- range $httpRule := .Values.expose.rules }}
|
|
14
15
|
- match:
|
|
15
16
|
- uri:
|
|
17
|
+
{{- if or $.Values.expose.APIRule.experimental (not $.Values.expose.APIRule.legacy)}}
|
|
18
|
+
{{- if eq $httpRule.path "/*" }}
|
|
19
|
+
prefix: "/"
|
|
20
|
+
{{- else }}
|
|
21
|
+
regex: "^{{ $httpRule.path | replace "{*}" "([A-Za-z0-9-._~!$&'()*+,;=:@]|%[0-9a-fA-F]{2})+" | replace "{**}" "([A-Za-z0-9-._~!$&'()*+,;=:@/]|%[0-9a-fA-F]{2})*" }}$"
|
|
22
|
+
{{- end }}
|
|
23
|
+
{{- else }}
|
|
16
24
|
regex: {{ $httpRule.path }}
|
|
25
|
+
{{- end }}
|
|
17
26
|
{{- if $httpRule.methods }}
|
|
18
27
|
method:
|
|
19
28
|
regex: ^({{ join "|" $httpRule.methods }})$
|
|
@@ -44,4 +53,33 @@ spec:
|
|
|
44
53
|
- regex: .*
|
|
45
54
|
{{- end }}
|
|
46
55
|
{{- end }}
|
|
56
|
+
{{ if not .Values.expose.APIRule.legacy }}
|
|
57
|
+
---
|
|
58
|
+
apiVersion: security.istio.io/v1
|
|
59
|
+
kind: AuthorizationPolicy
|
|
60
|
+
metadata:
|
|
61
|
+
name: {{ include "web-application.fullname" . }}-multitenancy
|
|
62
|
+
labels: {{- include "web-application.labels" . | nindent 4 }}
|
|
63
|
+
spec:
|
|
64
|
+
rules:
|
|
65
|
+
- from:
|
|
66
|
+
- source:
|
|
67
|
+
principals:
|
|
68
|
+
- cluster.local/ns/istio-system/sa/istio-ingressgateway-service-account
|
|
69
|
+
to:
|
|
70
|
+
{{- range $httpRule := .Values.expose.rules }}
|
|
71
|
+
- operation:
|
|
72
|
+
hosts:
|
|
73
|
+
- '*'
|
|
74
|
+
methods: {{ $httpRule.methods | toYaml | nindent 10 }}
|
|
75
|
+
paths:
|
|
76
|
+
{{- if eq $httpRule.path "/*" }}
|
|
77
|
+
- "/{**}"
|
|
78
|
+
{{- else }}
|
|
79
|
+
- {{ $httpRule.path }}
|
|
80
|
+
{{- end }}
|
|
81
|
+
{{- end }}
|
|
82
|
+
selector:
|
|
83
|
+
matchLabels: {{- include "web-application.selectorLabels" . | nindent 6 }}
|
|
84
|
+
{{- end }}
|
|
47
85
|
{{- end }}
|
|
@@ -1281,6 +1281,21 @@
|
|
|
1281
1281
|
"default": "http://telemetry-otlp-metrics.kyma-system.svc.cluster.local:4317"
|
|
1282
1282
|
}
|
|
1283
1283
|
}
|
|
1284
|
+
},
|
|
1285
|
+
"logs": {
|
|
1286
|
+
"type": "object",
|
|
1287
|
+
"additionalProperties": false,
|
|
1288
|
+
"properties": {
|
|
1289
|
+
"enabled": {
|
|
1290
|
+
"type": "boolean",
|
|
1291
|
+
"title": "Add env variables",
|
|
1292
|
+
"default": false
|
|
1293
|
+
},
|
|
1294
|
+
"endpoint": {
|
|
1295
|
+
"type": "string",
|
|
1296
|
+
"default": "http://telemetry-otlp-logs.kyma-system.svc.cluster.local:4317"
|
|
1297
|
+
}
|
|
1298
|
+
}
|
|
1284
1299
|
}
|
|
1285
1300
|
}
|
|
1286
1301
|
},
|
|
@@ -14,7 +14,7 @@ global:
|
|
|
14
14
|
_internal:
|
|
15
15
|
web-application:
|
|
16
16
|
versions:
|
|
17
|
-
1.
|
|
17
|
+
2.1.0: true
|
|
18
18
|
## Will be used instead of the `.Chart.Name`, e.g. when generating the Deployment name.
|
|
19
19
|
# nameOverride: name
|
|
20
20
|
|
|
@@ -75,9 +75,9 @@ additionalVolumes: []
|
|
|
75
75
|
# memory: 1G
|
|
76
76
|
|
|
77
77
|
## Enable or disable istio sidecars for this workload (other default is taken, e.g. namespace)
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
78
|
+
## The default value is `true`, since the APIRule v2 requires an app to be part of the mesh.
|
|
79
|
+
istio:
|
|
80
|
+
enabled: true
|
|
81
81
|
# Availability related configuration
|
|
82
82
|
availability:
|
|
83
83
|
# The max disruption to the pods, see https://kubernetes.io/docs/tasks/run-application/configure-pdb/ for details
|
|
@@ -160,7 +160,7 @@ envFrom: []
|
|
|
160
160
|
|
|
161
161
|
expose:
|
|
162
162
|
APIRule:
|
|
163
|
-
legacy:
|
|
163
|
+
legacy: false
|
|
164
164
|
# experimental: true
|
|
165
165
|
## Specifies the service's dns name for inbound external traffic. If it doesn't contain a dot, the default cluster domain will be appended.
|
|
166
166
|
# host: ""
|
|
@@ -177,8 +177,7 @@ expose:
|
|
|
177
177
|
|
|
178
178
|
# Rules represents collection of Rule to apply.
|
|
179
179
|
rules:
|
|
180
|
-
-
|
|
181
|
-
- handler: no_auth
|
|
180
|
+
- noAuth: true
|
|
182
181
|
methods:
|
|
183
182
|
- GET
|
|
184
183
|
- POST
|
|
@@ -187,7 +186,7 @@ expose:
|
|
|
187
186
|
- DELETE
|
|
188
187
|
- HEAD
|
|
189
188
|
- OPTIONS
|
|
190
|
-
path:
|
|
189
|
+
path: /*
|
|
191
190
|
## APIRule CORS policy configuration
|
|
192
191
|
## https://kyma-project.io/#/api-gateway/user/custom-resources/apirule/04-10-apirule-custom-resource
|
|
193
192
|
# corsPolicy:
|
|
@@ -221,8 +220,12 @@ otlp:
|
|
|
221
220
|
endpoint: http://telemetry-otlp-metrics.kyma-system.svc.cluster.local:4317
|
|
222
221
|
traces:
|
|
223
222
|
enabled: true
|
|
224
|
-
#
|
|
223
|
+
# Traces endpoint
|
|
225
224
|
endpoint: http://telemetry-otlp-traces.kyma-system.svc.cluster.local:4317
|
|
225
|
+
logs:
|
|
226
|
+
enabled: true
|
|
227
|
+
# Logs endpoint
|
|
228
|
+
endpoint: http://telemetry-otlp-logs.kyma-system.svc.cluster.local:4317
|
|
226
229
|
networkSecurity:
|
|
227
230
|
enabled: true
|
|
228
231
|
# allowNamespaceInternal: true
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
const cds = require('../../../cds')
|
|
2
2
|
const yaml = require('yaml')
|
|
3
3
|
const { exists, path, readFileSync } = cds.utils
|
|
4
|
-
const { Plugin, BuildError } = require('
|
|
4
|
+
const { Plugin, BuildError } = require('../..')
|
|
5
5
|
const { join } = path
|
|
6
6
|
const { readProject } = require('../../../init/projectReader')
|
|
7
7
|
|
|
@@ -39,7 +39,7 @@ class HanaBuildPlugin extends InternalBuildPlugin {
|
|
|
39
39
|
return
|
|
40
40
|
}
|
|
41
41
|
let wsPaths = []
|
|
42
|
-
if(getJournalEntities(model).length || cds.cli.options?.[OPTION_WS] || hasOptionValue(this.task.options[OPTION_WS], true)) {
|
|
42
|
+
if (getJournalEntities(model).length || cds.cli.options?.[OPTION_WS] || hasOptionValue(this.task.options[OPTION_WS], true)) {
|
|
43
43
|
// workspace paths don't include the current project root
|
|
44
44
|
wsPaths = await getWorkspacePaths()
|
|
45
45
|
}
|
|
@@ -248,7 +248,7 @@ class HanaBuildPlugin extends InternalBuildPlugin {
|
|
|
248
248
|
const options = { ...this.options(), messages: this.messages, dirs: csvDirs, baseDir: this.task.options.compileDest }
|
|
249
249
|
|
|
250
250
|
const toHdbtabledata = cds.compile.to.hdbtabledata
|
|
251
|
-
if (!toHdbtabledata)
|
|
251
|
+
if (!toHdbtabledata) throw `hdbtabledata plugin not found – make sure to install package '@cap-js/hana'`
|
|
252
252
|
const tableDataResult = await toHdbtabledata(model, options)
|
|
253
253
|
|
|
254
254
|
for (let [tableData, { file, csvFolder }] of tableDataResult) {
|
|
@@ -472,8 +472,9 @@ class HanaBuildPlugin extends InternalBuildPlugin {
|
|
|
472
472
|
content['file_suffixes'][key] = template['file_suffixes'][key]
|
|
473
473
|
}
|
|
474
474
|
}
|
|
475
|
-
if (Object.keys(content['file_suffixes']).length
|
|
476
|
-
|
|
475
|
+
if (Object.keys(content['file_suffixes']).length < hdiPlugins.size) {
|
|
476
|
+
const missingPlugins = Array.from(hdiPlugins).filter(key => !content['file_suffixes'][key.slice(1)])
|
|
477
|
+
this.pushMessage(`'HANA database plugin not found for following file suffix [${missingPlugins.join(', ')}]`)
|
|
477
478
|
}
|
|
478
479
|
await this.write(content).to(hdiConfigPath)
|
|
479
480
|
}
|
|
@@ -161,6 +161,12 @@
|
|
|
161
161
|
},
|
|
162
162
|
"hdbeshconfig": {
|
|
163
163
|
"plugin_name": "com.sap.hana.di.eshconfig"
|
|
164
|
+
},
|
|
165
|
+
"hdbfabricvirtualtable" : {
|
|
166
|
+
"plugin_name" : "com.sap.hana.di.sharedreplica"
|
|
167
|
+
},
|
|
168
|
+
"hdbschedulerjob" : {
|
|
169
|
+
"plugin_name" : "com.sap.hana.di.schedulerjob"
|
|
164
170
|
}
|
|
165
171
|
}
|
|
166
172
|
}
|
package/lib/compile/to-xsuaa.js
CHANGED
|
@@ -60,8 +60,10 @@ module.exports = function compile_to_xsuaa (model, options) {
|
|
|
60
60
|
return findUserAttrInExpression(expr)
|
|
61
61
|
}
|
|
62
62
|
|
|
63
|
-
|
|
64
|
-
|
|
63
|
+
const authAnnotations = def => {
|
|
64
|
+
if (!def) return
|
|
65
|
+
|
|
66
|
+
let reqAnnotations = def['@requires']
|
|
65
67
|
if(!Array.isArray(reqAnnotations)) reqAnnotations=[reqAnnotations]
|
|
66
68
|
|
|
67
69
|
reqAnnotations.forEach(scope => {
|
|
@@ -73,7 +75,7 @@ module.exports = function compile_to_xsuaa (model, options) {
|
|
|
73
75
|
const annotationRes = def['@restrict']
|
|
74
76
|
if (annotationRes) {
|
|
75
77
|
annotationRes.forEach(restriction => {
|
|
76
|
-
|
|
78
|
+
let restrTo = restriction.to
|
|
77
79
|
if(!Array.isArray(restrTo)) restrTo=[restrTo]
|
|
78
80
|
restrTo.forEach(scope =>{
|
|
79
81
|
if (scope && !hardcoded.Scopes.includes(scope)) {
|
|
@@ -84,8 +86,15 @@ module.exports = function compile_to_xsuaa (model, options) {
|
|
|
84
86
|
lattributes.forEach(attr => attributes[attr] = true)
|
|
85
87
|
})
|
|
86
88
|
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
cds.reflect(model).foreach(def => {
|
|
92
|
+
authAnnotations(def)
|
|
93
|
+
if (def.actions) Object.values(def.actions).forEach(authAnnotations)
|
|
94
|
+
if (def.functions) Object.values(def.functions).forEach(authAnnotations)
|
|
87
95
|
})
|
|
88
|
-
|
|
96
|
+
|
|
97
|
+
const roleTemplates = Object.keys(scopes).map((s) => {
|
|
89
98
|
return {
|
|
90
99
|
name: s,
|
|
91
100
|
description: 'generated',
|
|
@@ -140,6 +149,7 @@ function mergeConfig(base, generated) {
|
|
|
140
149
|
mergeByName('scopes')
|
|
141
150
|
mergeByName('attributes')
|
|
142
151
|
mergeByName('role-templates')
|
|
152
|
+
mergeByName('role-collections')
|
|
143
153
|
|
|
144
154
|
return result
|
|
145
155
|
}
|
|
@@ -250,7 +250,7 @@ spec:
|
|
|
250
250
|
if (/[^\w-_]+/g.exec(cfServiceInstanceName)) {
|
|
251
251
|
throw `Service name ${cfServiceInstanceName} must only contain alpha-numeric, hyphens, and underscores.`;
|
|
252
252
|
}
|
|
253
|
-
console.log(`
|
|
253
|
+
console.log(`using container ${bold(cfServiceInstanceName)}`);
|
|
254
254
|
|
|
255
255
|
const cfConfig = cfServiceInstanceMta?.parameters?.config;
|
|
256
256
|
const serviceInstance = await cfUtil.getOrCreateService('hana', 'hdi-shared', cfServiceInstanceName, cfConfig);
|
|
@@ -6,7 +6,7 @@ const HDI_DEPLOY_LIB = '@sap/hdi-deploy';
|
|
|
6
6
|
module.exports = new class HdiDeployUtil {
|
|
7
7
|
|
|
8
8
|
async deploy(dbDir, vcapEnv = {}, { autoUndeploy, parameter={} } = {}) {
|
|
9
|
-
console.log(`
|
|
9
|
+
console.log(`deploying to HANA from ${dbDir}`);
|
|
10
10
|
|
|
11
11
|
const { clean_env, deploy } = this._loadHdiDeployLib(dbDir);
|
|
12
12
|
|
package/lib/init/constants.js
CHANGED
|
@@ -22,6 +22,7 @@ module.exports = {
|
|
|
22
22
|
HELM: 'helm',
|
|
23
23
|
HELM_UNIFIED_RUNTIME: 'helm-unified-runtime',
|
|
24
24
|
CONTAINERIZE: 'containerize',
|
|
25
|
+
KYMA: 'kyma',
|
|
25
26
|
SAMPLES: 'samples', // deprecated
|
|
26
27
|
TINY_SAMPLE: 'tiny-sample',
|
|
27
28
|
SAMPLE: 'sample',
|
|
@@ -41,15 +42,15 @@ module.exports = {
|
|
|
41
42
|
EXTENSIBILITY: 'extensibility',
|
|
42
43
|
SIDE_BY_SIDE_EXTENSIBILITY: 'side-by-side-extensibility',
|
|
43
44
|
MTX: 'mtx',
|
|
44
|
-
|
|
45
|
-
MALWARE_SCANNER: 'malware-scanner',
|
|
45
|
+
APPROUTER: 'approuter',
|
|
46
46
|
LOCAL_MESSAGING: 'local-messaging',
|
|
47
47
|
FILE_BASED_MESSAGING: 'file-based-messaging',
|
|
48
48
|
ENTERPRISE_MESSAGING: 'enterprise-messaging',
|
|
49
49
|
ENTERPRISE_MESSAGING_SHARED: 'enterprise-messaging-shared',
|
|
50
50
|
REDIS_MESSAGING: 'redis-messaging',
|
|
51
51
|
KAFKA: 'kafka',
|
|
52
|
-
|
|
52
|
+
ATTACHMENTS: 'attachments',
|
|
53
|
+
MALWARE_SCANNER: 'malware-scanner',
|
|
53
54
|
CONNECTIVITY: 'connectivity',
|
|
54
55
|
DESTINATION: 'destination',
|
|
55
56
|
HTML5_REPO: 'html5-repo',
|
|
@@ -64,6 +65,7 @@ module.exports = {
|
|
|
64
65
|
LINT: 'lint',
|
|
65
66
|
LINT_DEV: 'lint:dev',
|
|
66
67
|
PIPELINE: 'pipeline',
|
|
68
|
+
GITHUB_ACTIONS: 'github-actions',
|
|
67
69
|
}),
|
|
68
70
|
|
|
69
71
|
REGEX_JAVA_PACKAGE: /^[a-z_][a-z0-9_]*(\.[a-z_][a-z0-9_]*)*$/g,
|
package/lib/init/index.js
CHANGED
|
@@ -139,7 +139,7 @@ module.exports = class CDSGenerator {
|
|
|
139
139
|
throw 'the --for argument must not be empty'
|
|
140
140
|
}
|
|
141
141
|
if (cds.cli.options.force && !cds.cli.options.dry) {
|
|
142
|
-
console.log(`using '--force' ... existing files will be overwritten`)
|
|
142
|
+
console.log(`using '--force' ... existing files will be overwritten\n`)
|
|
143
143
|
}
|
|
144
144
|
}
|
|
145
145
|
|
|
@@ -190,6 +190,10 @@ module.exports = class CDSGenerator {
|
|
|
190
190
|
if (cds.env['project-nature'] === 'java') {
|
|
191
191
|
console.log('updating frozen dependencies in package-lock.json…')
|
|
192
192
|
await cmd.spawnCommand('npm' , ['i', '--package-lock-only'], { cwd:cds.root })
|
|
193
|
+
if (exists('mtx/sidecar/package.json') && !exists('mtx/sidecar/package-lock.json')) {
|
|
194
|
+
console.log('updating frozen dependencies in mtx/sidecar/package-lock.json…')
|
|
195
|
+
await cmd.spawnCommand('npm', ['i', '--package-lock-only'], { cwd: path.join(cds.root, 'mtx/sidecar') })
|
|
196
|
+
}
|
|
193
197
|
}
|
|
194
198
|
|
|
195
199
|
if (cds.cli.command === COMMAND_INIT) {
|
|
@@ -237,6 +241,7 @@ module.exports = class CDSGenerator {
|
|
|
237
241
|
if (plugin === 'sample-tiny') plugin = 'tiny-sample'
|
|
238
242
|
if (plugin in { 'kibana-logging': 1, 'kibana': 1 }) plugin = 'application-logging'
|
|
239
243
|
if (plugin === 'postgresql') plugin = 'postgres'
|
|
244
|
+
if (plugin === 'gha') plugin = 'github-actions'
|
|
240
245
|
|
|
241
246
|
if (!templates.has(plugin)) {
|
|
242
247
|
const template = await this._createTemplate(plugin)
|
package/lib/init/merge.js
CHANGED
|
@@ -143,9 +143,13 @@ async function _mergeYAML(into, from, project, semantics = {}) {
|
|
|
143
143
|
}).forEach(item => {
|
|
144
144
|
if (Array.isArray(item)) item = item[0]
|
|
145
145
|
const json = JSON.parse(String(node))
|
|
146
|
-
const whereFulfilled = Object.entries(item.where).every(([key, value]) =>
|
|
147
|
-
|
|
148
|
-
|
|
146
|
+
const whereFulfilled = Object.entries(item.where).every(([key, value]) => {
|
|
147
|
+
if (Array.isArray(value)) {
|
|
148
|
+
return value.every(v => _getProperty(json, key) === v)
|
|
149
|
+
} else {
|
|
150
|
+
return _getProperty(json, key) === value
|
|
151
|
+
}
|
|
152
|
+
})
|
|
149
153
|
if (whereFulfilled) {
|
|
150
154
|
const [collection] = collectionStack
|
|
151
155
|
dict.set(item, { json, node, index, collection })
|