@sap/cds-dk 4.9.7 → 6.0.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.
Files changed (143) hide show
  1. package/CHANGELOG.md +56 -0
  2. package/bin/activate.js +4 -4
  3. package/bin/add.js +11 -5
  4. package/bin/bind.js +16 -28
  5. package/bin/build/all.js +2 -2
  6. package/bin/build/index.js +12 -19
  7. package/bin/cds.js +16 -17
  8. package/bin/compile/index.js +12 -3
  9. package/bin/deploy/index.js +14 -14
  10. package/bin/deploy/to-hana.js +4 -4
  11. package/bin/deploy/to-sqlite.js +1 -1
  12. package/bin/env.js +13 -4
  13. package/bin/eval.js +1 -1
  14. package/bin/fix-redirects.js +1 -1
  15. package/bin/import.js +44 -179
  16. package/bin/repl.js +1 -1
  17. package/bin/watch.js +10 -15
  18. package/lib/bind/BindingManager.js +87 -0
  19. package/lib/bind/bindingResolver.js +14 -85
  20. package/lib/bind/bindingUtil.js +18 -11
  21. package/lib/bind/cfKeyProvider.js +58 -29
  22. package/lib/bind/kubernetesCredentialsProvider.js +44 -21
  23. package/lib/bind/userCdsrcJsonStorageProvider.js +12 -18
  24. package/lib/cds.js +13 -0
  25. package/lib/client/base_command.js +3 -2
  26. package/lib/client/extend.js +6 -7
  27. package/lib/client/helper/fs_helper.js +7 -8
  28. package/lib/client/settings_manager.js +14 -10
  29. package/lib/compile/index.js +9 -10
  30. package/lib/compile/openapi/csdl2openapi.js +151 -43
  31. package/lib/compile/openapi/index.js +2 -2
  32. package/lib/compile/to-xsuaa.js +3 -2
  33. package/lib/import/common.js +342 -27
  34. package/lib/import/importapi.js +81 -13
  35. package/lib/import/message.js +4 -4
  36. package/lib/import/odata/index.js +141 -0
  37. package/lib/import/{utils → odata/metadataconverter}/MetadataConverter.js +2 -2
  38. package/lib/import/{utils → odata/metadataconverter}/MetadataConverterFactory.js +1 -1
  39. package/lib/import/{utils → odata/util}/MultiMap.js +0 -0
  40. package/lib/import/{v2parser.js → odata/v2parser.js} +405 -468
  41. package/lib/import/{v4parser.js → odata/v4parser.js} +311 -322
  42. package/lib/import/{vocabularies → odata/vocabularies}/Org.OData.Aggregation.V1.json +0 -0
  43. package/lib/import/{vocabularies → odata/vocabularies}/Org.OData.Authorization.V1.json +0 -0
  44. package/lib/import/{vocabularies → odata/vocabularies}/Org.OData.Capabilities.V1.json +0 -0
  45. package/lib/import/{vocabularies → odata/vocabularies}/Org.OData.Core.V1.json +0 -0
  46. package/lib/import/{vocabularies → odata/vocabularies}/Org.OData.Measures.V1.json +0 -0
  47. package/lib/import/{vocabularies → odata/vocabularies}/Org.OData.Validation.V1.json +0 -0
  48. package/lib/import/openapi/importOpenAPI.js +521 -0
  49. package/lib/import/openapi/index.js +19 -0
  50. package/lib/import/openapi/utilities.js +38 -0
  51. package/lib/index.js +1 -1
  52. package/lib/init/constants.js +7 -2
  53. package/lib/init/index.js +10 -3
  54. package/lib/init/template/_merging/existences.js +79 -19
  55. package/lib/init/template/approuter/files/mta.yaml.hbs +25 -11
  56. package/lib/init/template/approuter/files/package.json +1 -1
  57. package/lib/init/template/approuter/files/xs-app.json.hbs +7 -0
  58. package/lib/init/template/approuter/index.js +61 -54
  59. package/lib/init/template/auditlog/index.js +2 -2
  60. package/lib/init/template/data/index.js +2 -2
  61. package/lib/init/template/hana/files/mta.yaml.hbs +17 -17
  62. package/lib/init/template/hana/index.js +8 -4
  63. package/lib/init/template/helm/index.js +39 -0
  64. package/lib/init/template/helm/update/index.js +28 -0
  65. package/lib/init/template/java/index.js +7 -9
  66. package/lib/init/template/kibana-logging/index.js +5 -6
  67. package/lib/init/template/mta/index.js +4 -4
  68. package/lib/init/template/mtx/files/java/package.json +9 -9
  69. package/lib/init/template/mtx/files/mta.yaml.hbs +0 -7
  70. package/lib/init/template/mtx/files/xs-security.json.hbs +11 -20
  71. package/lib/init/template/mtx/index.js +50 -57
  72. package/lib/init/template/nodejs/files/package.json.hbs +2 -2
  73. package/lib/init/template/notebook/index.js +2 -0
  74. package/lib/init/template/templateBase.js +6 -4
  75. package/lib/init/template/xsuaa/index.js +9 -5
  76. package/lib/init/util/fsUtil.js +25 -10
  77. package/lib/init/util/logger.js +1 -1
  78. package/lib/init/util/mvnArchetypeUtil.js +4 -10
  79. package/lib/init/util/projectReader.js +16 -8
  80. package/lib/init/util/templateUtil.js +30 -34
  81. package/lib/k8s/ChartAdder.js +65 -0
  82. package/lib/k8s/ChartBuilder.js +186 -0
  83. package/lib/k8s/Context.js +71 -0
  84. package/lib/k8s/ImageUtil.js +21 -0
  85. package/lib/k8s/Model.d.ts +53 -0
  86. package/lib/k8s/auditlog/index.js +29 -0
  87. package/lib/k8s/auditlog/templates/auditlog.yaml +1 -0
  88. package/lib/k8s/buildModel.js +70 -0
  89. package/lib/k8s/connectivity/index.js +74 -0
  90. package/lib/k8s/connectivity/templates/connectivity-binding.yaml +9 -0
  91. package/lib/k8s/connectivity/templates/connectivity-proxy-info.yaml +16 -0
  92. package/lib/k8s/connectivity/templates/connectivity.yaml +1 -0
  93. package/lib/k8s/deployment/index.js +81 -0
  94. package/lib/k8s/deployment/subchart/Chart.yaml +6 -0
  95. package/lib/k8s/deployment/subchart/templates/_helpers.tpl +156 -0
  96. package/lib/k8s/deployment/subchart/templates/api-rule.yaml +24 -0
  97. package/lib/k8s/deployment/subchart/templates/deployment.yaml +110 -0
  98. package/lib/k8s/deployment/subchart/templates/network-policy.yaml +16 -0
  99. package/lib/k8s/deployment/subchart/templates/pod-disruption-budget.yaml +11 -0
  100. package/lib/k8s/deployment/subchart/templates/secret.yaml +10 -0
  101. package/lib/k8s/deployment/subchart/templates/service-binding.yaml +27 -0
  102. package/lib/k8s/deployment/subchart/templates/service.yaml +11 -0
  103. package/lib/k8s/deployment/subchart/values-lint.yaml +8 -0
  104. package/lib/k8s/deployment/subchart/values.schema.json +449 -0
  105. package/lib/k8s/deployment/subchart/values.yaml +76 -0
  106. package/lib/k8s/deployment/subchart-override/templates/_web_application_helpers.tpl +81 -0
  107. package/lib/k8s/destinations/index.js +40 -0
  108. package/lib/k8s/destinations/lib.js +16 -0
  109. package/lib/k8s/destinations/templates/destinations.yaml +1 -0
  110. package/lib/k8s/docker/push.js +8 -0
  111. package/lib/k8s/event-mesh/index.js +53 -0
  112. package/lib/k8s/event-mesh/lib.js +9 -0
  113. package/lib/k8s/event-mesh/templates/event-mesh.yaml +1 -0
  114. package/lib/k8s/hana-deployer/index.js +38 -0
  115. package/lib/k8s/hana-deployer/templates/hana-deployer-job.yaml +41 -0
  116. package/lib/k8s/helm/Release.js +80 -0
  117. package/lib/k8s/html5-apps-deployer/index.js +43 -0
  118. package/lib/k8s/html5-apps-deployer/templates/_html5_deployment_helpers.tpl +16 -0
  119. package/lib/k8s/html5-apps-deployer/templates/html5-apps-deployer-job.yaml +53 -0
  120. package/lib/k8s/html5-apps-repo-host/index.js +26 -0
  121. package/lib/k8s/html5-apps-repo-host/lib.js +16 -0
  122. package/lib/k8s/html5-apps-repo-host/templates/html5-apps-repo-host.yaml +1 -0
  123. package/lib/k8s/index.js +153 -0
  124. package/lib/k8s/modules.js +36 -0
  125. package/lib/k8s/multitenancy/index.js +24 -0
  126. package/lib/k8s/multitenancy/lib.js +25 -0
  127. package/lib/k8s/multitenancy/templates/saas-registry.yaml +19 -0
  128. package/lib/k8s/readProject.js +14 -0
  129. package/lib/k8s/resources/helm/chart/templates/NOTES.txt +11 -0
  130. package/lib/k8s/resources/helm/chart/templates/_deployment_helpers.tpl +221 -0
  131. package/lib/k8s/resources/helm/chart/templates/_helpers.tpl +167 -0
  132. package/lib/k8s/resources/helm/chart/templates/_sapcp_helpers.tpl +103 -0
  133. package/lib/k8s/util.js +186 -0
  134. package/lib/k8s/wrapFeature.js +55 -0
  135. package/lib/k8s/xsuaa/index.js +64 -0
  136. package/lib/k8s/xsuaa/lib.js +14 -0
  137. package/lib/k8s/xsuaa/templates/xsuaa.yaml +1 -0
  138. package/lib/util/exec.js +1 -1
  139. package/lib/util/write.js +1 -1
  140. package/lib/watch/node-watch.js +43 -14
  141. package/npm-shrinkwrap.json +1221 -2743
  142. package/package.json +5 -5
  143. package/lib/import/index.js +0 -235
@@ -0,0 +1,53 @@
1
+ const wrapFeature = require('../wrapFeature');
2
+ const { cds } = require('../modules');
3
+ const LOG = cds.log();
4
+
5
+ module.exports = wrapFeature('event_mesh', {
6
+ async isRequired(context) {
7
+ const env = await context.get('env');
8
+ return eventMeshServices(env).length > 0;
9
+ },
10
+
11
+ async getServiceBindings() {
12
+ return {
13
+ messaging: {
14
+ serviceInstanceName: 'event-mesh'
15
+ }
16
+ };
17
+ },
18
+
19
+ async getChartCapabilities() {
20
+ return {
21
+ "event_mesh": {
22
+ serviceOfferingName: 'enterprise-messaging',
23
+ servicePlanName: 'default',
24
+ config: 'event-mesh.json'
25
+ }
26
+ }
27
+ },
28
+
29
+ async addToChart(builder, { 'event_mesh': eventMesh }) {
30
+ await builder.addAllTemplates(__dirname);
31
+
32
+ const { config } = eventMesh;
33
+ if (config) {
34
+ if (!await builder.addChartFile(config, { optional: true })) {
35
+ LOG.warn(`Please add the "${config}" file to the chart folder.`);
36
+ }
37
+ }
38
+ }
39
+ });
40
+
41
+ function eventMeshServices(env) {
42
+ const kinds = [ '$', '$-http', '$-amqp', '$-shared', 'default-messaging' ].reduce( (map, key) => {
43
+ map[key.replace(/\$/, 'enterprise-messaging')] = true;
44
+ return map;
45
+ }, {});
46
+ const names = [];
47
+ for (const name in env.requires) {
48
+ const service = env.requires[name];
49
+ if (!kinds[name] && kinds[service.kind]) names.push(name);
50
+ }
51
+
52
+ return names;
53
+ }
@@ -0,0 +1,9 @@
1
+ const Path = require("path");
2
+
3
+ async function addTemplates(builder) {
4
+ await builder.addTemplate(Path.join(__dirname, "resources/templates"), 'event-mesh.yaml');
5
+ }
6
+
7
+ module.exports = {
8
+ addTemplates
9
+ };
@@ -0,0 +1 @@
1
+ {{- include "cap.service-instance" . }}
@@ -0,0 +1,38 @@
1
+ const wrapFeature = require('../wrapFeature');
2
+
3
+ module.exports = wrapFeature('hana_deployer', {
4
+ async isRequired(context) {
5
+ const env = await context.get('env');
6
+ return env.requires.db && (env.requires.db.kind === 'sql' || env.requires.db.kind === 'hana');
7
+ },
8
+
9
+ async getChartCapabilities(context) {
10
+ const model = await context.get('model');
11
+
12
+ return {
13
+ hana_deployer: {
14
+ image: {
15
+ repository: '<your-container-registry>/'+model.app.name+'-hana-deployer',
16
+ tag: 'latest'
17
+ },
18
+ bindings: {
19
+ hana: {
20
+ fromSecret: null
21
+ }
22
+ }
23
+ }
24
+ };
25
+ },
26
+
27
+ getServiceBindings() {
28
+ return {
29
+ db: {
30
+ fromSecret: null
31
+ }
32
+ }
33
+ },
34
+
35
+ async addToChart(builder) {
36
+ await builder.addAllTemplates(__dirname);
37
+ }
38
+ });
@@ -0,0 +1,41 @@
1
+ #
2
+ # HANA single-tenant DB deployment
3
+ #
4
+ {{- if .Values.hana_deployer }}
5
+ {{- if or (not (hasKey .Values.hana_deployer "enabled")) .Values.hana_deployer.enabled }}
6
+ {{- $ := merge (dict "root" . "name" "hana-deployer") .Values.hana_deployer . }}
7
+ {{- template "cap.expect" (list . "hana_deployer.bindings.hana.fromSecret" "hana_deployer.image.repository") }}
8
+ apiVersion: batch/v1
9
+ kind: Job
10
+ metadata:
11
+ name: {{ .Release.Name }}-hana-deployer
12
+ labels: {{- include "cap.labels" $ | nindent 4 }}
13
+ annotations:
14
+ "helm.sh/hook": "post-install,pre-upgrade"
15
+ "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded
16
+ namespace: {{ .Release.Namespace }}
17
+ spec:
18
+ backoffLimit: 4
19
+ template:
20
+ metadata:
21
+ labels:
22
+ {{- include "cap.labels" $ | nindent 8 }}
23
+ sidecar.istio.io/inject: "false"
24
+ spec:
25
+ restartPolicy: Never
26
+ {{- include "cap.imagePullSecrets" $ | nindent 6 }}
27
+ volumes:
28
+ {{- include "cap.sapcp.bindingsVolumes" $ | nindent 10 }}
29
+ containers:
30
+ - name: hana-deployer
31
+ image: {{ include "cap.image" $ }}
32
+ imagePullPolicy: {{ include "cap.imagePullPolicy" $ }}
33
+ env:
34
+ - name: EXIT
35
+ value: 'true'
36
+ volumeMounts:
37
+ {{- include "cap.sapcp.bindingsVolumeMounts" $ | nindent 10 }}
38
+ ---
39
+ {{ include "cap.sapcp.bindings" $ }}
40
+ {{ end }}
41
+ {{ end }}
@@ -0,0 +1,80 @@
1
+ const { throwError } = require('../util');
2
+ const { exec } = require('../../util/exec');
3
+ const { yaml } = require('../modules');
4
+ const fs = require('fs').promises;
5
+ const Path = require('path');
6
+
7
+ async function status({ releaseName, namespace }) {
8
+ const result = await exec({stdio: [ 'inherit', 'pipe', 'inherit'], acceptStatuses: '*'}) `helm status ${releaseName} --namespace ${namespace}`;
9
+ if (result.status === 0) {
10
+ const output = Buffer.from(result.output[1]).toString();
11
+ const lines = output.split(/[\n\r]+/sg);
12
+ const status = {};
13
+ for (const line of lines) {
14
+ const m = line.match(/\s*([^:]+)\s*:\s*(.*)/);
15
+ if (m) {
16
+ status[m[1].toLowerCase()] = m[2];
17
+ }
18
+ }
19
+
20
+ if (!status.status) throwError(`Internal error: helm status didn't return STATUS value.`);
21
+ return status;
22
+ } else {
23
+ return { name: releaseName, status: 'not found' }
24
+ }
25
+ }
26
+
27
+ async function deploy({ options, releaseName, namespace, chartPath, values }) {
28
+ const valuesArg = formatValues(values);
29
+ await exec `helm upgrade ${releaseName} ./${chartPath} --install --namespace ${namespace} ${valuesArg && ['--set', valuesArg]} ${formatOptions(options)}`;
30
+ }
31
+
32
+ async function template({ options, releaseName, namespace, chartPath, values }) {
33
+ const valuesArg = formatValues(values);
34
+ await exec `helm template ${releaseName} ./${chartPath} --namespace ${namespace} ${valuesArg && ['--set', valuesArg]} ${formatOptions(options)}`;
35
+ }
36
+
37
+ function formatOptions(options = {}) {
38
+ const args = [];
39
+ if (options.debug) args.push('--debug');
40
+ return args;
41
+ }
42
+
43
+ async function undeploy({ releaseName, namespace }) {
44
+ await exec `helm uninstall ${releaseName} --namespace ${namespace}`;
45
+ }
46
+
47
+ function formatValues(values) {
48
+ const valuesArray = collectValues(values);
49
+ return valuesArray.join(',');
50
+ }
51
+
52
+ function collectValues(values, prefix = '') {
53
+ const valuesArray = [];
54
+
55
+ for (const name of Reflect.ownKeys(values)) {
56
+ const value = values[name];
57
+ if (typeof value === 'object') {
58
+ valuesArray.push(...collectValues(value, `${prefix}${name}.`));
59
+ } else if (typeof value !== 'undefined') {
60
+ // @TODO: Escaping?
61
+ valuesArray.push(`${prefix}${name}=${values[name]}`);
62
+ }
63
+ }
64
+
65
+ return valuesArray;
66
+ }
67
+
68
+ async function values(chartPath) {
69
+ return yaml.parse(await fs.readFile(Path.join(chartPath, 'values.yaml'), 'utf-8'));
70
+
71
+ }
72
+
73
+
74
+ module.exports = {
75
+ status,
76
+ deploy,
77
+ undeploy,
78
+ template,
79
+ values
80
+ }
@@ -0,0 +1,43 @@
1
+ const wrapFeature = require('../wrapFeature');
2
+
3
+ module.exports = wrapFeature('html5_apps_deployer', {
4
+ async getChartCapabilities(context) {
5
+ const model = await context.get('model');
6
+ const projectName = model.app.name;
7
+ return {
8
+ 'html5_apps_deployer': {
9
+ cloudService: null,
10
+ backendDestinations: {},
11
+ image: {
12
+ repository: "<your-container-registry>/" + projectName + "-html5-deployer" ,
13
+ tag: "latest"
14
+ },
15
+ bindings: {
16
+ xsuaa: {
17
+ serviceInstanceName: 'xsuaa'
18
+ },
19
+ destination: {
20
+ serviceInstanceName: 'destinations'
21
+ },
22
+ html5_apps_repo: {
23
+ serviceInstanceName: 'html5-apps-repo-host'
24
+ }
25
+ }
26
+ }
27
+ }
28
+ },
29
+
30
+ getDestinationsParameters() {
31
+ return {
32
+ HTML5Runtime_enabled: true
33
+ }
34
+ },
35
+
36
+ isHtml5AppsRepoHostRequired() {
37
+ return true;
38
+ },
39
+
40
+ async addToChart(builder) {
41
+ await builder.addAllTemplates(__dirname);
42
+ }
43
+ });
@@ -0,0 +1,16 @@
1
+ {{/*
2
+ Backend Destinations
3
+ */}}
4
+ {{- define "cap.backendDestinations" -}}
5
+ {{- $ := . -}}
6
+ {{- $destinations := list -}}
7
+ {{- range $destinationName, $destination := .backendDestinations -}}
8
+ {{- $destination := merge (dict "name" $destinationName) $destination -}}
9
+ {{- $deployment := (get $.root.Values $destination.service) -}}
10
+ {{- $srv := merge (dict "name" $destination.service "destination" $destination "deployment" $deployment) $.root -}}
11
+ {{- $destinationHost := include "cap.deploymentHost" $srv -}}
12
+ {{- $currentDestination := dict "Name" $destination.name "Type" "HTTP" "ProxyType" "Internet" "URL" (print "https://" $destinationHost "." $.root.Values.global.domain ($destination.path | default "")) "Authentication" "NoAuthentication" "sap.cloud.service" $.cloudService "HTML5.forwardAuthToken" "true" -}}
13
+ {{- $destinations = (append $destinations $currentDestination) -}}
14
+ {{- end -}}
15
+ {{- $destinations | toJson }}
16
+ {{- end -}}
@@ -0,0 +1,53 @@
1
+ {{- if .Values.html5_apps_deployer }}
2
+ {{- if or (not (hasKey .Values.html5_apps_deployer "enabled")) .Values.html5_apps_deployer.enabled }}
3
+
4
+ {{- $ := merge (dict "root" . "name" "html5-apps-deployer") .Values.html5_apps_deployer . }}
5
+ {{- if $.backendDestinations }}
6
+ {{- if not (.Values.destinations.parameters.HTML5Runtime_enabled) }}
7
+ {{- fail "destinations.parameters.HTML5Runtime_enabled must be set to true for use with Launchpad Service" }}
8
+ {{- end }}
9
+ {{- end }}
10
+ {{- template "cap.expect" (list . "html5_apps_deployer.image.repository") }}
11
+ apiVersion: batch/v1
12
+ kind: Job
13
+ metadata:
14
+ name: {{ .Release.Name }}-html5-apps-deployer
15
+ namespace: {{ .Release.Namespace }}
16
+ labels: {{- include "cap.labels" $ | nindent 4 }}
17
+ annotations:
18
+ "helm.sh/hook": "post-install,post-upgrade"
19
+ "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded
20
+ spec:
21
+ backoffLimit: 4
22
+ template:
23
+ metadata:
24
+ labels:
25
+ {{- include "cap.labels" $ | nindent 8 }}
26
+ sidecar.istio.io/inject: "false"
27
+ spec:
28
+ {{- include "cap.imagePullSecrets" $ | nindent 6 }}
29
+ restartPolicy: Never
30
+ volumes:
31
+ {{- include "cap.sapcp.bindingsVolumes" $ | nindent 10 }}
32
+ containers:
33
+ - name: html5-deployer
34
+ image: {{ include "cap.image" $ }}
35
+ imagePullPolicy: {{ include "cap.imagePullPolicy" $ }}
36
+ volumeMounts:
37
+ {{- include "cap.sapcp.bindingsVolumeMounts" $ | nindent 10 }}
38
+ env:
39
+ - name: EXIT_PROCESS_AFTER_UPLOAD
40
+ value: "true"
41
+ - name: PORT
42
+ value: "5000"
43
+ # TODO: cloud service should be configurable in the HTML5 apps
44
+ - name: SAP_CLOUD_SERVICE
45
+ value: {{ $.cloudService }}
46
+ # TODO: destination name should be configurable in the HTML5 apps
47
+ - name: BACKEND_DESTINATIONS
48
+ value: >
49
+ {{ include "cap.backendDestinations" $ }}
50
+ ---
51
+ {{ include "cap.sapcp.bindings" $ }}
52
+ {{- end }}
53
+ {{- end }}
@@ -0,0 +1,26 @@
1
+ const wrapFeature = require('../wrapFeature');
2
+
3
+ module.exports = wrapFeature('html5_apps_repo_host', {
4
+
5
+ async isRequired(context) {
6
+ return await context.collectBool('isHtml5AppsRepoHostRequired');
7
+ },
8
+
9
+ async getChartCapabilities() {
10
+ return {
11
+ 'html5_apps_repo_host': {
12
+ serviceOfferingName: 'html5-apps-repo',
13
+ servicePlanName: 'app-host'
14
+ }
15
+ }
16
+ },
17
+
18
+ async addToChart(builder, { html5_apps_repo_host }) {
19
+ await builder.addAllTemplates(__dirname);
20
+
21
+ const { config } = html5_apps_repo_host;
22
+ if (config) {
23
+ await builder.addChartFile(config);
24
+ }
25
+ }
26
+ });
@@ -0,0 +1,16 @@
1
+ function checkNeedDestinations(env) {
2
+ const kinds = [ 'odata', 'odata-v2', 'odata-v4', 'rest' ].reduce( (map, key) => {
3
+ map[key] = true;
4
+ return map;
5
+ }, {});
6
+ for (const service in env.requires) {
7
+ const require = env.requires[service];
8
+ if (!kinds[service] && kinds[require.kind]) return true;
9
+ }
10
+
11
+ return false;
12
+ }
13
+
14
+ module.exports = {
15
+ checkNeedDestinations
16
+ };
@@ -0,0 +1 @@
1
+ {{- include "cap.service-instance" . }}
@@ -0,0 +1,153 @@
1
+ const Context = require('./Context');
2
+ const buildModel = require('./buildModel');
3
+ const ChartAdder = require('./ChartAdder');
4
+ const ChartBuilder = require('./ChartBuilder');
5
+ const { resource, mergeDeep, readFileIfExists } = require('./util');
6
+ const fs = require('fs');
7
+ const Path = require('path');
8
+ const { cds, yaml } = require('./modules');
9
+
10
+ async function context(projectPath, features = []) {
11
+ if (!Path.isAbsolute(projectPath)) projectPath = Path.join(process.cwd(), projectPath);
12
+
13
+ const projectEnv = cds.env.for('cds', projectPath);
14
+ process.env.NODE_ENV='production';
15
+ process.env.CDS_ENV='production';
16
+ const productiveEnv = cds.env.for('cds', projectPath);
17
+
18
+ const config = JSON.parse(JSON.stringify(projectEnv.k8s || {}));
19
+
20
+ const context = new Context({
21
+ projectPath,
22
+ config,
23
+ 'effective-config': context => effectiveConfig(context),
24
+ features: featuresFactory(features),
25
+ env: productiveEnv,
26
+ model: buildModel,
27
+ auth: require('./xsuaa'),
28
+ multitenancy: require('./multitenancy'),
29
+ 'hana-deployer': require('./hana-deployer'),
30
+ connectivity: require('./connectivity'),
31
+ destinations: require('./destinations'),
32
+ 'event-mesh': require('./event-mesh'),
33
+ 'auditlog': require('./auditlog'),
34
+ 'html5-apps-deployer': require('./html5-apps-deployer'),
35
+ 'html5-apps-repo-host': require('./html5-apps-repo-host'),
36
+ 'srv': require('./deployment'),
37
+ });
38
+
39
+ return context;
40
+ }
41
+
42
+ // eslint-disable-next-line no-unused-vars
43
+ async function addChart(context, path = 'chart', _features) {
44
+ const model = await context.get('model');
45
+
46
+ const mergeSemantics = {
47
+ existences: []
48
+ };
49
+
50
+ context.add('chartPath', path);
51
+
52
+ await context.forEach('prepareChart',
53
+ async plugin => plugin.prepareChart()
54
+ );
55
+
56
+ // Collect chart values
57
+ let chartValues = {};
58
+ await context.forEach('getChartValues',
59
+ async plugin => chartValues = {...chartValues, ...await plugin.getChartValues()}
60
+ );
61
+
62
+ // Collect deployments
63
+ let deployments = {};
64
+ await context.forEach('getChartDeployments',
65
+ async plugin => deployments = {...deployments, ...await plugin.getChartDeployments(context)}
66
+ );
67
+
68
+ // Extend deployments
69
+ for (const name in deployments) {
70
+ await context.forEach('extendChartDeployment',
71
+ async plugin => await plugin.extendChartDeployment(context, name, deployments[name], mergeSemantics)
72
+ );
73
+ }
74
+
75
+ Object.assign(chartValues, deployments);
76
+
77
+ // Collect capabilities
78
+ let capabilities = {};
79
+ await context.forEach('getChartCapabilities',
80
+ async plugin => capabilities = {...capabilities, ...await plugin.getChartCapabilities(context)}
81
+ );
82
+
83
+ Object.assign(chartValues, capabilities);
84
+
85
+ // Collect chart dependencies (subcharts)
86
+ let chartDependencies = [];
87
+ await context.forEach('getChartDependencies',
88
+ async plugin => chartDependencies.push(...await plugin.getChartDependencies(context))
89
+ );
90
+
91
+ // Create chart
92
+ const projectPath = await context.get('projectPath');
93
+ const builder = new ChartBuilder({ path, rootPath: projectPath });
94
+ await builder.begin();
95
+
96
+ const chartAdder = new ChartAdder({ builder, chartValues, chartDependencies, template: resource('helm/chart'), app: model.app, mergeSemantics });
97
+ await chartAdder.execute();
98
+
99
+ let values;
100
+ try {
101
+ values = await chartAdder.getSavedValues();
102
+ } catch (error) {
103
+ console.log('Skip adding features because of broken chart/values.yaml file.')
104
+ }
105
+
106
+ if (values) await context.forEach('addToChart', async plugin => plugin.addToChart(builder, values));
107
+
108
+ await builder.end();
109
+ }
110
+
111
+
112
+ async function hasChart(context, path = 'chart') {
113
+ return fs.existsSync(path);
114
+ }
115
+
116
+ function featuresFactory(_features) {
117
+ return async function(context) {
118
+ const features = new Set(_features);
119
+
120
+ // Collect enabled features
121
+ const effectiveConfig = await context.get('effective-config');
122
+ for (const name in effectiveConfig) {
123
+ const entry = effectiveConfig[name];
124
+ if (entry && entry.enabled !== false) features.add(name);
125
+ }
126
+
127
+ return features;
128
+ }
129
+ }
130
+
131
+ async function effectiveConfig(context) {
132
+ const skeleton = { images: {} };
133
+ let result;
134
+
135
+ const chartPath = context.has('chartPath') ? await context.get('chartPath') : 'chart';
136
+ const valuesFile = await readFileIfExists(Path.join(chartPath, 'values.yaml'), 'utf-8');
137
+ if (valuesFile) {
138
+ const values = yaml.parse(valuesFile);
139
+ const config = await context.get('config');
140
+ result = mergeDeep(values, config);
141
+ } else {
142
+ result = await context.get('config');
143
+ }
144
+
145
+ return Object.assign(skeleton, result);
146
+ }
147
+
148
+ module.exports = {
149
+ context,
150
+ addChart,
151
+ hasChart,
152
+ effectiveConfig
153
+ }
@@ -0,0 +1,36 @@
1
+ /* @sap/cds */
2
+ const cds = require('@sap/cds/lib');
3
+ const cds_cli = require('@sap/cds/bin/cds');
4
+
5
+ /* @sap/cds-dk */
6
+ const term = require('../util/term');
7
+ const ProjectReader = require('../init/util/projectReader');
8
+ const TemplateBase = require('../init/template/templateBase');
9
+ const CDSGenerator = require('../init/index');
10
+
11
+ /* @sap/cds-foss */
12
+ const yaml = require("@sap/cds-foss")("yaml");
13
+
14
+ /* other FOSS */
15
+ const glob = require('glob');
16
+ const xmlJs = require('xml-js');
17
+
18
+ module.exports = {
19
+ /* @sap/cds */
20
+ cds,
21
+ cds_cli,
22
+ env: cds.env,
23
+
24
+ /* @sap/cds-dk */
25
+ term,
26
+ ProjectReader,
27
+ TemplateBase,
28
+ CDSGenerator,
29
+
30
+ /* @sap/cds-foss */
31
+ yaml,
32
+
33
+ /* other FOSS */
34
+ glob,
35
+ xmlJs
36
+ };
@@ -0,0 +1,24 @@
1
+ const wrapFeature = require('../wrapFeature');
2
+
3
+ module.exports = wrapFeature('multitenancy', {
4
+ /**
5
+ * @param {import('../ChartBuilder')} builder
6
+ */
7
+ async addToChart(builder, { multitenancy }) {
8
+ await builder.addAllTemplates(__dirname);
9
+
10
+ if (multitenancy.config) {
11
+ await builder.addChartFile(multitenancy.config);
12
+ }
13
+ },
14
+
15
+ // eslint-disable-next-line no-unused-vars
16
+ async getChartCapabilities(context) {
17
+ return {
18
+ xsuaa: {
19
+ serviceOfferingName: 'saas-registry',
20
+ servicePlanName: 'application'
21
+ }
22
+ }
23
+ },
24
+ });
@@ -0,0 +1,25 @@
1
+ const { exec } = require("../../util/exec");
2
+ const Path = require("path");
3
+
4
+ async function renderXsSecurityJson(projectPath) {
5
+ const result = await exec({
6
+ cwd: projectPath,
7
+ stdio: ["inherit", "pipe", "inherit"],
8
+ })`cds compile srv -2 xsuaa`;
9
+ const xsSecurityJson = result.stdout;
10
+ return xsSecurityJson;
11
+ }
12
+
13
+ /**
14
+ * @param {import('../ChartBuilder')} builder
15
+ */
16
+ async function addTemplates(builder) {
17
+ const templates = Path.join(__dirname, 'templates');
18
+ await builder.addTemplate(templates, 'xsuaa.yaml');
19
+ await builder.addTemplate(templates, 'registry.yaml');
20
+ }
21
+
22
+ module.exports = {
23
+ renderXsSecurityJson,
24
+ addTemplates
25
+ };
@@ -0,0 +1,19 @@
1
+ {{- if (default dict .Values.multitenancy).enabled }}
2
+ {{- $srvHostFull := include "cap.deploymentHostFull" (merge (dict "name" "srv" "deployment" .Values.srv) . ) }}
3
+ {{- $defaultAppUrls := dict
4
+ "getDependencies" (print "https://" $srvHostFull "/mtx/v1/provisioning/dependencies")
5
+ "onSubscription" (print "https://" $srvHostFull "/mtx/v1/provisioning/tenant/{tenantId}")
6
+ "onSubscriptionAsync" false
7
+ "onUnSubscriptionAsync" false
8
+ "callbackTimeoutMillis" 300000
9
+ }}
10
+ {{- $defaultParameters := dict
11
+ "xsappname" .Values.xsuaa.parameters.xsappname
12
+ "appName" .Values.xsuaa.parameters.xsappname
13
+ "displayName" .Chart.Name
14
+ "description" .Chart.Description
15
+ "category" "CAP Application"
16
+ "appUrls" $defaultAppUrls
17
+ }}
18
+ {{- include "cap.service-instance" (merge (dict "defaultParameters" $defaultParameters . )) }}
19
+ {{ end }}
@@ -0,0 +1,14 @@
1
+
2
+
3
+ const { ProjectReader, TemplateBase, CDSGenerator } = require('./modules');
4
+
5
+ async function readProject(path = '') {
6
+ /* TODO: Ugly way to access project information -> talk to the guys */
7
+ const reader = new ProjectReader(new ProjectTemplate(path, new CDSGenerator(), ''));
8
+ return await reader.read();
9
+ }
10
+
11
+ class ProjectTemplate extends TemplateBase {
12
+ }
13
+
14
+ module.exports = readProject;
@@ -0,0 +1,11 @@
1
+ Thank you for installing {{ .Chart.Name }} version {{ .Chart.Version }}.
2
+
3
+ The release "{{ .Release.Name }}" is installed in namespace "{{ .Release.Namespace }}".
4
+
5
+ Your services are available at:
6
+ {{- $root := . }}
7
+ {{- range $name := include "cap.deploymentNames" . | split ";" }}
8
+ {{- $deployment := (get $root.Values $name) }}
9
+ {{- $ := merge (dict "name" $name "deployment" $deployment) $root }}
10
+ - https://{{ include "cap.deploymentHostFull" $ }}
11
+ {{- end }}