@sap/cds-dk 6.4.0 → 6.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (93) hide show
  1. package/CHANGELOG.md +28 -1
  2. package/bin/bind.js +30 -34
  3. package/bin/cds.js +14 -3
  4. package/bin/deploy/index.js +3 -1
  5. package/bin/deploy/to-sqlite.js +2 -1
  6. package/bin/env.js +4 -4
  7. package/bin/migrate.js +25 -4
  8. package/bin/push.js +4 -0
  9. package/bin/watch.js +3 -3
  10. package/lib/bind/KubernetesApiAccessor.js +79 -0
  11. package/lib/bind/{BindingManager.js → bindingManager.js} +16 -15
  12. package/lib/bind/bindingResolver.js +41 -68
  13. package/lib/bind/bindingUtil.js +93 -104
  14. package/lib/bind/cfKeyProvider.js +85 -74
  15. package/lib/bind/kubernetesCredentialsProvider.js +34 -132
  16. package/lib/bind/userCdsrcJsonStorageProvider.js +12 -18
  17. package/lib/client/params.js +2 -2
  18. package/lib/client/push.js +11 -6
  19. package/lib/client/settings_manager.js +2 -1
  20. package/lib/client/subscription.js +4 -1
  21. package/lib/import/odata/v2parser.js +32 -8
  22. package/lib/import/odata/v4parser.js +11 -3
  23. package/lib/init/constants.js +1 -1
  24. package/lib/init/index.js +3 -11
  25. package/lib/init/template/approuter/files/approuter-configmap.yaml +4 -1
  26. package/lib/init/template/approuter/files/approuter-mtxs-configmap.yaml +5 -1
  27. package/lib/init/template/approuter/files/package.json +1 -1
  28. package/lib/init/template/approuter/files/values.yaml.hbs +1 -1
  29. package/lib/init/template/approuter/files/xs-app.json.hbs +2 -2
  30. package/lib/init/template/approuter/index.js +4 -5
  31. package/lib/init/template/auditlog/index.js +1 -1
  32. package/lib/init/template/data/index.js +1 -1
  33. package/lib/init/template/destinations/index.js +1 -1
  34. package/lib/init/template/enterprise-messaging/index.js +1 -1
  35. package/lib/init/template/extensibility/index.js +6 -1
  36. package/lib/init/template/hana/files/chart.yaml +4 -0
  37. package/lib/init/template/hana/files/hana.yaml +1 -0
  38. package/lib/init/template/hana/files/java/db/package.json +1 -1
  39. package/lib/init/template/hana/files/values.yaml.hbs +6 -3
  40. package/lib/init/template/hana/index.js +73 -21
  41. package/lib/init/template/helm/chart/templates/_deployment_helpers.tpl +14 -6
  42. package/lib/init/template/helm/chart/values.root.schema.json +10 -0
  43. package/lib/init/template/helm/chart/values.schema.json +11 -110
  44. package/lib/init/template/helm/index.js +2 -2
  45. package/lib/init/template/helm/subcharts/content-deployment/Chart.yaml +5 -0
  46. package/lib/init/template/helm/subcharts/content-deployment/templates/_helpers.tpl +207 -0
  47. package/lib/init/template/helm/subcharts/content-deployment/templates/job.yaml +66 -0
  48. package/lib/init/template/helm/subcharts/content-deployment/templates/secret.yaml +10 -0
  49. package/lib/init/template/helm/subcharts/content-deployment/templates/service-account.yaml +4 -0
  50. package/lib/init/template/helm/subcharts/content-deployment/templates/service-binding.yaml +28 -0
  51. package/lib/init/template/helm/subcharts/content-deployment/values-lint.yaml +5 -0
  52. package/lib/init/template/helm/subcharts/content-deployment/values.md +1014 -0
  53. package/lib/init/template/helm/subcharts/content-deployment/values.schema.json +589 -0
  54. package/lib/init/template/helm/subcharts/content-deployment/values.yaml +54 -0
  55. package/lib/init/template/helm/{subchart → subcharts/web-application}/Chart.yaml +0 -0
  56. package/lib/init/template/helm/{subchart → subcharts/web-application}/templates/_helpers.tpl +56 -50
  57. package/lib/init/template/helm/{subchart → subcharts/web-application}/templates/api-rule.yaml +1 -1
  58. package/lib/init/template/helm/{subchart → subcharts/web-application}/templates/deployment.yaml +15 -9
  59. package/lib/init/template/helm/{subchart → subcharts/web-application}/templates/network-policy.yaml +0 -0
  60. package/lib/init/template/helm/{subchart → subcharts/web-application}/templates/pod-disruption-budget.yaml +2 -2
  61. package/lib/init/template/helm/{subchart → subcharts/web-application}/templates/secret.yaml +0 -0
  62. package/lib/init/template/helm/subcharts/web-application/templates/service-account.yaml +6 -0
  63. package/lib/init/template/helm/{subchart → subcharts/web-application}/templates/service-binding.yaml +4 -3
  64. package/lib/init/template/helm/{subchart → subcharts/web-application}/templates/service.yaml +0 -0
  65. package/lib/init/template/helm/subcharts/web-application/templating.md +44 -0
  66. package/lib/init/template/helm/{subchart → subcharts/web-application}/values-lint.yaml +0 -0
  67. package/lib/init/template/helm/{subchart → subcharts/web-application}/values.md +254 -200
  68. package/lib/init/template/helm/{subchart → subcharts/web-application}/values.schema.json +82 -28
  69. package/lib/init/template/helm/{subchart → subcharts/web-application}/values.yaml +15 -5
  70. package/lib/init/template/html5-repo/files/chart.yaml +4 -0
  71. package/lib/init/template/html5-repo/files/html5-apps-deployer-configmap.yaml +14 -0
  72. package/lib/init/template/html5-repo/index.js +39 -7
  73. package/lib/init/template/kibana-logging/index.js +1 -1
  74. package/lib/init/template/lint/index.js +1 -1
  75. package/lib/init/template/multitenancy/files/saas-registry.yaml +2 -2
  76. package/lib/init/template/multitenancy/files/service-manager.yaml +1 -0
  77. package/lib/init/template/multitenancy/files/values.yaml.hbs +10 -6
  78. package/lib/init/template/multitenancy/index.js +21 -3
  79. package/lib/init/util/commandUtil.js +5 -5
  80. package/lib/init/util/merge.js +27 -1
  81. package/lib/init/util/mvnArchetypeUtil.js +1 -1
  82. package/lib/init/util/projectReader.js +2 -2
  83. package/lib/util/exec.js +3 -3
  84. package/lib/util/term.js +7 -7
  85. package/lib/watch/livereload-connect.js +187 -0
  86. package/lib/watch/livereload-server.js +12 -12
  87. package/lib/watch/node-watch.js +1 -1
  88. package/npm-shrinkwrap.json +191 -404
  89. package/package.json +2 -5
  90. package/lib/init/template/hana/files/hana-deployer-job.yaml +0 -49
  91. package/lib/init/template/html5-repo/files/_html5_deployment_helpers.tpl +0 -16
  92. package/lib/init/template/html5-repo/files/html5-apps-deployer-job.yaml +0 -61
  93. package/lib/init/util/spinner.js +0 -80
@@ -106,12 +106,7 @@
106
106
  "$id": "#/properties/serviceAccountName",
107
107
  "title": "Service Account name",
108
108
  "description": "Name of the Service Account assigned to pods.",
109
- "default": "default",
110
- "allOf": [
111
- {
112
- "$ref": "#/definitions/KubernetesName"
113
- }
114
- ]
109
+ "type": "string"
115
110
  },
116
111
  "image": {
117
112
  "$id": "#/properties/image",
@@ -238,9 +233,8 @@
238
233
  "properties": {
239
234
  "enabled": {
240
235
  "$id": "#/properties/ha/properties/enabled",
241
- "description": "Enables additional high-availability related configuration, like Pod Disruption Budget and Topology Spread Constraints.",
242
- "type": "boolean",
243
- "default": true
236
+ "description": "[Deprecated: Will be always enabled in future] Enables additional high-availability related configuration, like Pod Disruption Budget and Topology Spread Constraints.",
237
+ "type": "boolean"
244
238
  }
245
239
  }
246
240
  },
@@ -340,6 +334,57 @@
340
334
  }
341
335
  }
342
336
  },
337
+ "availability": {
338
+ "$id": "#/properties/availability",
339
+ "title": "Availability related configuration",
340
+ "type": "object",
341
+ "additionalProperties": false,
342
+ "properties": {
343
+ "podDisruptionBudget": {
344
+ "$id": "#/properties/availability/properties/podDisruptionBudget",
345
+ "description": "The max disruption to the pods.",
346
+ "type": "object",
347
+ "additionalProperties": false,
348
+ "properties": {
349
+ "maxUnavailable": {
350
+ "description": "An eviction is allowed if this maximum of pods are unavailable.",
351
+ "type": "string",
352
+ "default": "10%"
353
+ }
354
+ }
355
+ },
356
+ "topologySpreadConstraints": {
357
+ "$id": "#/properties/availability/properties/topologySpreadConstraints",
358
+ "description": "How pods ought to spread across topology domains.",
359
+ "uniqueItems": true,
360
+ "items": {
361
+ "type": "object",
362
+ "additionalProperties": false,
363
+ "required": ["topologyKey", "maxSkew", "whenUnsatisfiable"],
364
+ "properties": {
365
+ "topologyKey": {
366
+ "type": "string",
367
+ "description": "Nodes that have a label with this key and identical values are considered to be in the same topology."
368
+ },
369
+ "maxSkew": {
370
+ "type": "integer",
371
+ "description": "Describes the degree to which pods may be unevenly distributed.",
372
+ "minimum": 1
373
+ },
374
+ "whenUnsatisfiable": {
375
+ "type": "string",
376
+ "description": "Indicates how to deal with a pod if it doesn't satisfy the spread constraint.",
377
+ "enum": ["ScheduleAnyway", "DoNotSchedule"]
378
+ }
379
+ }
380
+ },
381
+ "default": [
382
+ {"maxSkew":1, "topologyKey":"topology.kubernetes.io/zone", "whenUnsatisfiable":"ScheduleAnyway"},
383
+ {"maxSkew":1, "topologyKey":"kubernetes.io/hostname", "whenUnsatisfiable":"ScheduleAnyway"}
384
+ ]
385
+ }
386
+ }
387
+ },
343
388
  "health": {
344
389
  "$id": "#/properties/health",
345
390
  "title": "Health-check configuration",
@@ -376,11 +421,24 @@
376
421
  },
377
422
  "startupTimeout": {
378
423
  "$id": "#/properties/startupTimeout",
424
+ "description": "[Deprecated] use startupTimeoutSeconds instead",
425
+ "type": "integer",
426
+ "minimum": 1
427
+ },
428
+ "startupTimeoutSeconds": {
429
+ "$id": "#/properties/startupTimeoutSeconds",
379
430
  "description": "Initial timeout in seconds, during which the app must start giving the response to the liveness-probe.",
380
431
  "type": "integer",
381
432
  "minimum": 1,
382
433
  "default": 30
383
434
  },
435
+ "terminationGracePeriodSeconds": {
436
+ "$id": "#/properties/terminationGracePeriodSeconds",
437
+ "description": "Time in seconds after which the pod will be forcefully stopped after receiving SIGTERM.",
438
+ "type": "integer",
439
+ "minimum": 0,
440
+ "default": 30
441
+ },
384
442
  "env": {
385
443
  "$id": "#/properties/env",
386
444
  "description": "Key-value map of environment variables, which should be added to the Pod spec.",
@@ -408,7 +466,7 @@
408
466
  "properties": {
409
467
  "name": {
410
468
  "description": "Name of a ConfigMap.",
411
- "$ref": "#/definitions/KubernetesName"
469
+ "type": "string"
412
470
  },
413
471
  "key": {
414
472
  "description": "Key in that ConfigMap, which value will be used.",
@@ -423,7 +481,7 @@
423
481
  "properties": {
424
482
  "name": {
425
483
  "description": "Name of a Secret.",
426
- "$ref": "#/definitions/KubernetesName"
484
+ "type": "string"
427
485
  },
428
486
  "key": {
429
487
  "description": "Key in that Secret, which value will be used.",
@@ -490,7 +548,7 @@
490
548
  "properties": {
491
549
  "name": {
492
550
  "description": "Name of a ConfigMap.",
493
- "$ref": "#/definitions/KubernetesName"
551
+ "type": "string"
494
552
  },
495
553
  "key": {
496
554
  "description": "Key in that ConfigMap, which value will be used.",
@@ -505,7 +563,7 @@
505
563
  "properties": {
506
564
  "name": {
507
565
  "description": "Name of a Secret.",
508
- "$ref": "#/definitions/KubernetesName"
566
+ "type": "string"
509
567
  },
510
568
  "key": {
511
569
  "description": "Key in that Secret, which value will be used.",
@@ -571,11 +629,6 @@
571
629
  "name": {
572
630
  "description": "Name of a ConfigMap.",
573
631
  "type": "string"
574
- },
575
- "tpl": {
576
- "description": "Flag which tells whether the name is a template string or not.",
577
- "type": "boolean",
578
- "default": false
579
632
  }
580
633
  },
581
634
  "required": [ "name" ],
@@ -594,11 +647,6 @@
594
647
  "name": {
595
648
  "description": "Name of a Secret.",
596
649
  "type": "string"
597
- },
598
- "tpl": {
599
- "description": "Flag which tells whether the name is a template string or not.",
600
- "type": "boolean",
601
- "default": false
602
650
  }
603
651
  },
604
652
  "required": [ "name" ],
@@ -627,6 +675,12 @@
627
675
  "description": "Expose the application to the internet.",
628
676
  "type": "boolean",
629
677
  "default": true
678
+ },
679
+ "gateway": {
680
+ "$id": "#/properties/expose/properties/gateway",
681
+ "description": "Use this istio gateway for incoming traffic.",
682
+ "type": "string",
683
+ "default": "kyma-gateway.kyma-system.svc.cluster.local"
630
684
  }
631
685
  }
632
686
  },
@@ -647,7 +701,7 @@
647
701
  "properties": {
648
702
  "fromSecret": {
649
703
  "description": "Name of a Kubernetes Secret, with the binding content, compliant to the SAP Kubernetes Service Binding spec https://github.tools.sap/Kubernetes-Service-Bindings/doc/",
650
- "$ref": "#/definitions/KubernetesName"
704
+ "type": "string"
651
705
  }
652
706
  }
653
707
  },
@@ -657,11 +711,11 @@
657
711
  "properties": {
658
712
  "serviceInstanceName": {
659
713
  "description": "Name of a BTP Operator Service Instance, created by the `service-instance` Helm chart. Can't be used with the `serviceInstanceFullname` option.",
660
- "$ref": "#/definitions/KubernetesName"
714
+ "type": "string"
661
715
  },
662
716
  "serviceInstanceFullname": {
663
717
  "description": "Full name of a BTP Operator Service Instance. Can't be used with the `serviceInstanceName` option.",
664
- "$ref": "#/definitions/KubernetesName"
718
+ "type": "string"
665
719
  },
666
720
  "externalName": {
667
721
  "description": "The name for the service binding in SAP BTP",
@@ -669,7 +723,7 @@
669
723
  },
670
724
  "secretName": {
671
725
  "description": "The name of the secret where the credentials are stored.",
672
- "$ref": "#/definitions/KubernetesName"
726
+ "type": "string"
673
727
  },
674
728
  "parameters": {
675
729
  "description": "Some services support the provisioning of additional configuration parameters during the bind request. For the list of supported parameters, check the documentation of the particular service offering.",
@@ -695,7 +749,7 @@
695
749
  "properties": {
696
750
  "name": {
697
751
  "description": "Name of a Secret.",
698
- "$ref": "#/definitions/KubernetesName"
752
+ "type": "string"
699
753
  },
700
754
  "key": {
701
755
  "description": "Key in that Secret, which contains a string that represents the json to include in the set of parameters to be sent to the broker.",
@@ -8,7 +8,7 @@ global:
8
8
 
9
9
  replicaCount: 1
10
10
  port: 8080
11
- serviceAccountName: default
11
+ #serviceAccountName: my-serviceaccount
12
12
 
13
13
  # To use a digest, change those values like that
14
14
  # repository: nginx@sha256
@@ -30,9 +30,6 @@ additionalVolumes: []
30
30
  # mountPath: /etc/mysecret
31
31
  # readOnly: true
32
32
 
33
- ha:
34
- enabled: true
35
-
36
33
  # resources:
37
34
  # limits:
38
35
  # cpu: 100m
@@ -43,13 +40,25 @@ ha:
43
40
  # ephemeral-storage: 1G
44
41
  # memory: 1G
45
42
 
43
+ availability:
44
+ podDisruptionBudget:
45
+ maxUnavailable: 10%
46
+ topologySpreadConstraints:
47
+ - topologyKey: topology.kubernetes.io/zone
48
+ maxSkew: 1
49
+ whenUnsatisfiable: ScheduleAnyway
50
+ - topologyKey: kubernetes.io/hostname
51
+ maxSkew: 1
52
+ whenUnsatisfiable: ScheduleAnyway
53
+
46
54
  health:
47
55
  liveness:
48
56
  path: /healthz
49
57
  readiness:
50
58
  path: /healthz
51
59
 
52
- startupTimeout: 30
60
+ terminationGracePeriodSeconds: 30
61
+ startupTimeoutSeconds: 30
53
62
 
54
63
  envFrom: []
55
64
  # - configMapRef:
@@ -79,6 +88,7 @@ env: {}
79
88
 
80
89
  expose:
81
90
  enabled: true
91
+ gateway: kyma-gateway.kyma-system.svc.cluster.local
82
92
  # host: ""
83
93
 
84
94
  # bindings:
@@ -0,0 +1,4 @@
1
+ dependencies:
2
+ - name: content-deployment
3
+ alias: html5-apps-deployer
4
+ version: 0.1.0
@@ -0,0 +1,14 @@
1
+ # Please do not modify this file. This file may be overwritten.
2
+
3
+ {{- $cloudService := index .Values "html5-apps-deployer.env.SAP_CLOUD_SERVICE" -}}
4
+ {{- $defaultParameters := dict "Type" "HTTP" "ProxyType" "Internet" "Authentication" "NoAuthentication" "sap.cloud.service" "sap.fe.cap.sflight" "HTML5.forwardAuthToken" "true" }}
5
+ {{- $ := dict "root" . "defaultParameters" $defaultParameters "html5" true }}
6
+
7
+ apiVersion: v1
8
+ kind: ConfigMap
9
+ metadata:
10
+ name: "{{ .Release.Name }}-html5-apps-deployer-configmap"
11
+ namespace: "{{ .Release.Namespace }}"
12
+ data:
13
+ BACKEND_DESTINATIONS: >
14
+ {{ include "cap.backendDestinations" $ }}
@@ -52,9 +52,18 @@ module.exports = class Html5RepoTemplate extends require('../templateBase') {
52
52
  serviceOfferingName: 'html5-apps-repo',
53
53
  servicePlanName: 'app-host'
54
54
  },
55
- html5_apps_deployer: {
56
- cloudService: null,
57
- backendDestinations: {},
55
+ 'html5-apps-deployer': {
56
+ env: {
57
+ SAP_CLOUD_SERVICE: null
58
+ },
59
+ envFrom: [
60
+ {
61
+ configMapRef: {
62
+ name: "{{ .Release.Name }}-html5-apps-deployer-configmap",
63
+ tpl: true
64
+ }
65
+ }
66
+ ],
58
67
  image: {
59
68
  repository: `<your-container-registry>/${appName}-html5-deployer`,
60
69
  tag: 'latest'
@@ -62,17 +71,40 @@ module.exports = class Html5RepoTemplate extends require('../templateBase') {
62
71
  bindings: {
63
72
  xsuaa: { serviceInstanceName: 'xsuaa' },
64
73
  destination: { serviceInstanceName: 'destination' },
65
- html5_apps_repo: { serviceInstanceName: 'html5-apps-repo-host' }
74
+ 'html5-apps-repo': { serviceInstanceName: 'html5-apps-repo-host' }
66
75
  },
67
76
  resources: {
68
77
  limits: { cpu: '2000m', memory: '1G' },
69
78
  requests: { cpu: '1000m', memory: '1G' }
70
79
  }
71
- }
80
+ },
81
+ backendDestinations: {},
72
82
  }
73
83
  )
74
- await copyAndTrack(join(__dirname, 'files', '_html5_deployment_helpers.tpl'), join(this.projectPath, 'chart', 'templates', '_html5_deployment_helpers.tpl'), context)
75
- await copyAndTrack(join(__dirname, 'files', 'html5-apps-deployer-job.yaml'), join(this.projectPath, 'chart', 'templates', 'html5-apps-deployer-job.yaml'), context)
84
+
85
+ // copy content deployment chart if it is not present
86
+ const contentDeploymentSubchartPath = join(this.projectPath, 'chart', 'charts', 'content-deployment');
87
+ if(!exists(contentDeploymentSubchartPath)) {
88
+ const contentDeploymentResourcePath = join(__dirname, '..', 'helm', 'subcharts', 'content-deployment');
89
+ await copyAndTrack(contentDeploymentResourcePath, contentDeploymentSubchartPath, context);
90
+ }
91
+
92
+ // add dependency entry in chart.yaml
93
+ await mergeYAML(
94
+ join(this.projectPath, 'chart', 'Chart.yaml'),
95
+ join(__dirname, 'files', 'chart.yaml'),
96
+ projectDescriptor,
97
+ { additions: [{
98
+ ref: `content-deployment-html5-apps-deployer`,
99
+ in: `dependencies`,
100
+ where: [{
101
+ property: 'alias',
102
+ isEqualTo: 'html5-apps-deployer'
103
+ }]
104
+ }]}
105
+ )
106
+
107
+ await copyAndTrack(join(__dirname, 'files', 'html5-apps-deployer-configmap.yaml'), join(this.projectPath, 'chart', 'templates', 'html5-apps-deployer-configmap.yaml'), context)
76
108
  await copyAndTrack(join(__dirname, 'files', 'html5-apps-repo-host.yaml'), join(this.projectPath, 'chart', 'templates', 'html5-apps-repo-host.yaml'), context)
77
109
  if(isIndependentCommand) await writeMd5File(join(this.projectPath, 'chart', '.cds-add-helm-files.md5'), context.newTrackingData)
78
110
  }
@@ -50,7 +50,7 @@ module.exports = class KibanaTemplate extends require('../templateBase') {
50
50
  const mtaYAMLPath = join(this.projectPath, 'mta.yaml')
51
51
  await mergeYAML(
52
52
  mtaYAMLPath,
53
- `${__dirname}/files/mta.yaml.hbs`,
53
+ join(__dirname, 'files', 'mta.yaml.hbs'),
54
54
  projectDescriptor,
55
55
  {
56
56
  additions: [srv, kibanaLogging],
@@ -158,7 +158,7 @@ module.exports = class LintTemplate extends require('../templateBase') {
158
158
  async _addEslintPluginConfig() {
159
159
  let configPath = getConfigPath(this.projectPath);
160
160
  if (!configPath) {
161
- configPath = path.join(this.projectPath, ".eslintrc");
161
+ configPath = path.join(this.projectPath, ".eslintrc.json");
162
162
  }
163
163
  await io.sanitizeEslintConfig(configPath, this.customRuleExample);
164
164
  return;
@@ -1,7 +1,7 @@
1
1
  {{- $srvHostFull := include "cap.deploymentHostFull" (merge (dict "name" "srv" "deployment" .Values.srv) . ) }}
2
2
  {{- $defaultAppUrls := dict
3
- "getDependencies" (printf "https://%s%s" $srvHostFull .Values.saas_registry.getDependencies)
4
- "onSubscription" (printf "https://%s%s" $srvHostFull .Values.saas_registry.onSubscription)
3
+ "getDependencies" (printf "https://%s%s" $srvHostFull .Values.saas_registry.parameters.getDependencies)
4
+ "onSubscription" (printf "https://%s%s" $srvHostFull .Values.saas_registry.parameters.onSubscription)
5
5
  "onSubscriptionAsync" false
6
6
  "onUnSubscriptionAsync" false
7
7
  "callbackTimeoutMillis" 300000
@@ -0,0 +1 @@
1
+ {{- include "cap.service-instance" . }}
@@ -4,22 +4,26 @@ srv:
4
4
  saas-registry:
5
5
  serviceInstanceName: saas-registry
6
6
  service-manager:
7
- fromSecret: null
7
+ serviceInstanceName: service-manager
8
8
  {{#cap.hasXsuaa}}
9
9
  xsuaa:
10
10
  parameters:
11
11
  tenant-mode: shared
12
12
  {{/cap.hasXsuaa}}
13
+ service_manager:
14
+ serviceOfferingName: service-manager
15
+ servicePlanName: container
13
16
  saas_registry:
14
17
  serviceOfferingName: saas-registry
15
18
  servicePlanName: application
19
+ parameters:
16
20
  {{#cap.isNodejs}}
17
- getDependencies: "/-/cds/saas-provisioning/dependencies"
18
- onSubscription: "/-/cds/saas-provisioning/tenant/{tenantId}"
21
+ getDependencies: "/-/cds/saas-provisioning/dependencies"
22
+ onSubscription: "/-/cds/saas-provisioning/tenant/{tenantId}"
19
23
  {{/cap.isNodejs}}
20
24
  {{#cap.isJava}}
21
- getDependencies: "/mt/v1.0/subscriptions/dependencies"
22
- onSubscription: "/mt/v1.0/subscriptions/tenants/{tenantId}"
25
+ getDependencies: "/mt/v1.0/subscriptions/dependencies"
26
+ onSubscription: "/mt/v1.0/subscriptions/tenants/{tenantId}"
23
27
  sidecar:
24
28
  bindings:
25
29
  {{#cap.hasXsuaa}}
@@ -27,7 +31,7 @@ sidecar:
27
31
  serviceInstanceName: xsuaa
28
32
  {{/cap.hasXsuaa}}
29
33
  service-manager:
30
- fromSecret: null
34
+ serviceInstanceName: service-manager
31
35
  image:
32
36
  repository: <your-container-registry>/{{cap.appName}}-sidecar
33
37
  tag: latest
@@ -102,8 +102,7 @@ module.exports = class MultitenancyTemplate extends require('../templateBase') {
102
102
  envFrom: [
103
103
  {
104
104
  configMapRef: {
105
- name: "{{ .Release.Name }}-mtxs-configmap",
106
- tpl: true
105
+ name: "{{ .Release.Name }}-mtxs-configmap"
107
106
  }
108
107
  }
109
108
  ]
@@ -118,7 +117,7 @@ module.exports = class MultitenancyTemplate extends require('../templateBase') {
118
117
  join(__dirname, 'files', 'chart.yaml'),
119
118
  projectDescriptor,
120
119
  {
121
- additions: [{
120
+ additions: [{
122
121
  ref: `web-application-sidecar`,
123
122
  in: `dependencies`,
124
123
  where: [{
@@ -141,6 +140,12 @@ module.exports = class MultitenancyTemplate extends require('../templateBase') {
141
140
  context
142
141
  )
143
142
 
143
+ await copyAndTrack(
144
+ join(__dirname, 'files', 'service-manager.yaml'),
145
+ join(this.projectPath, 'chart', 'templates', 'service-manager.yaml'),
146
+ context
147
+ )
148
+
144
149
  await copyAndTrack(
145
150
  join(__dirname, 'files', 'saas-registry.yaml'),
146
151
  join(this.projectPath, 'chart', 'templates', 'saas-registry.yaml'),
@@ -183,6 +188,19 @@ module.exports = class MultitenancyTemplate extends require('../templateBase') {
183
188
  join(this.projectPath, 'chart', 'xs-security.json'),
184
189
  context
185
190
  )
191
+
192
+ await mergeYAML(
193
+ join(this.projectPath, 'chart', 'values.yaml'),
194
+ {
195
+ xsuaa: {
196
+ parameters: {
197
+ 'tenant-mode': 'shared'
198
+ }
199
+ }
200
+ },
201
+ null,
202
+ { forceOverwrite: true }
203
+ )
186
204
  if (isIndependentCommand) await writeMd5File(join(this.projectPath, 'chart', '.cds-add-helm-files.md5'), context.newTrackingData)
187
205
  }
188
206
  }
@@ -1,7 +1,7 @@
1
1
  const cp = require('child_process');
2
2
  const os = require('os');
3
- const cds = require('../../cds')
4
- const LOG = cds.log('cds')
3
+ const DEBUG = /\b(y|all|cli)\b/.test(process.env.DEBUG) && console.debug
4
+
5
5
 
6
6
  const { IS_WIN } = require('../constants');
7
7
 
@@ -21,21 +21,21 @@ class CommandUtil {
21
21
  async spawnCommand(cmd, args, options = {}, collectResult = false) {
22
22
  args = this._sanitizeArgs(args);
23
23
  return new Promise((resolve, reject) => {
24
- LOG.debug(`[spawn] ${cmd} ${args.join(' ')}`);
24
+ DEBUG && console.debug(`[spawn] ${cmd} ${args.join(' ')}`);
25
25
 
26
26
  options.env = options.env || process.env;
27
27
 
28
28
  const child = this._getChildProcess(cmd, args, options);
29
29
 
30
30
  // use inplace methods to ensure logger is called in context
31
- const stdLogBuffer = new LogBuffer((chunk) => LOG.info(chunk), collectResult);
31
+ const stdLogBuffer = new LogBuffer((chunk) => console.log(chunk), collectResult);
32
32
  child.stdout.on('data', (chunk) => {
33
33
  stdLogBuffer.handleChunk(chunk);
34
34
  });
35
35
 
36
36
  // use inplace methods to ensure logger is called in context
37
37
  // collect error log in case of Win to handle command not found (ENOENT),
38
- const errLogBuffer = new LogBuffer((chunk) => LOG.error(chunk), (IS_WIN || collectResult));
38
+ const errLogBuffer = new LogBuffer((chunk) => console.error(chunk), (IS_WIN || collectResult));
39
39
  child.stderr.on('data', (chunk) => {
40
40
  errLogBuffer.handleChunk(chunk);
41
41
  });
@@ -328,9 +328,35 @@ async function removeFromYAML(name, keyPaths) {
328
328
  await writeYAML(name, yaml)
329
329
  }
330
330
 
331
+ async function removeFromYAMLArray(name, keyPath, aliasToRemove) {
332
+ const yaml = await readYAML(name)
333
+
334
+ let node = yaml
335
+ // traverse to the array node
336
+ const keys = keyPath.split('.')
337
+ for (const key of keys) {
338
+ node = node.get(key)
339
+ }
340
+
341
+ // find index of array entry with aliasToRemove entry
342
+ let index = 0;
343
+ let entryNode = node.getIn([index])
344
+ while(entryNode !== undefined) {
345
+ if(entryNode.toJSON().alias === aliasToRemove) {
346
+ node.deleteIn([index])
347
+ break;
348
+ }
349
+ index++;
350
+ entryNode = node.getIn([index])
351
+ }
352
+
353
+ await writeYAML(name, yaml)
354
+ }
355
+
331
356
  module.exports = {
332
357
  sortDependencies,
333
358
  mergeJSON,
334
359
  mergeYAML,
335
- removeFromYAML
360
+ removeFromYAML,
361
+ removeFromYAMLArray
336
362
  }
@@ -5,7 +5,7 @@ const { MAVEN_ARCHETYPE_VERSION, OPTION_JAVA_MVN,
5
5
  const DEFAULT_GROUP_ID = 'customer';
6
6
 
7
7
  const LOG = console
8
- const DEBUG = /\bcli\b/.test(process.env.DEBUG) && console.debug
8
+ const DEBUG = /\b(y|all|cli)\b/.test(process.env.DEBUG) && console.debug
9
9
 
10
10
  class MvnArchetypeUtil {
11
11
 
@@ -13,7 +13,7 @@ const BUILD_TASK_HANA = "hana"
13
13
  const BUILD_TASK_FIORI = "fiori"
14
14
  const BUILD_TASK_MTX = "mtx"
15
15
  const BUILD_TASK_MTX_SIDECAR = "mtx-sidecar"
16
- const DEBUG = /\b(cli)\b/.test(process.env.DEBUG) && console.debug
16
+ const DEBUG = /\b(y|all|cli)\b/.test(process.env.DEBUG) && console.debug
17
17
  const LOG = console
18
18
 
19
19
  module.exports = class ProjectReader {
@@ -90,7 +90,7 @@ module.exports = class ProjectReader {
90
90
  cds.env = env
91
91
 
92
92
  const nullLogger = { debug: () => { }, log: () => { }, warn: () => { }, error: () => { }, write: () => { } }
93
-
93
+
94
94
  // no file path resolving as the directories might not exist - e.g. cds add will create the mtx/sidecar folder
95
95
  const buildTasks = await new BuildTaskFactory(nullLogger, cds).getTasks({ root: this.projectPath, resolve: false, mta: false })
96
96
 
package/lib/util/exec.js CHANGED
@@ -156,7 +156,7 @@ function executeSync(options = {}, command, ...args) {
156
156
  log.debug(`exec: ${command} ${args.map( v => v.match(/\s/) ? `"${v}"` : v ).join(' ')}`);
157
157
  const result = spawnSync(command, args, execOptions);
158
158
 
159
- if (acceptStatuses !== '*' && acceptStatuses.indexOf(result.status) === -1) throw new Error(`Command returned with status code ${result.status}`);
159
+ if (acceptStatuses !== '*' && acceptStatuses.indexOf(result.status) === -1) throw new Error(`Command '${command} ${args.join(' ')}' returned with status code ${result.status}`);
160
160
  return processResult(result, options);
161
161
  }
162
162
 
@@ -185,7 +185,7 @@ async function executeAsync(options = {}, command, ...args) {
185
185
  }
186
186
 
187
187
  const exit = status => {
188
- if (acceptStatuses !== '*' && acceptStatuses.indexOf(status) === -1) reject(new Error(`Command returned with status code ${status}`))
188
+ if (acceptStatuses !== '*' && acceptStatuses.indexOf(status) === -1) reject(new Error(`Command '${command} ${args.join(' ')}' returned with status code ${status}`))
189
189
  else resolve({
190
190
  status,
191
191
  stdout: child.stdout ? Buffer.concat(stdoutChunks).toString("utf-8") : undefined,
@@ -207,4 +207,4 @@ module.exports = {
207
207
  exec,
208
208
  execSync,
209
209
  $ : execSync
210
- }
210
+ }
package/lib/util/term.js CHANGED
@@ -1,5 +1,5 @@
1
1
  // FIXME: Nicht gut, das wir das zweimal redundant haben!
2
- const debug = process.env.DEBUG
2
+ const DEBUG = /\b(y|all|cli)\b/.test(process.env.DEBUG) && console.debug
3
3
 
4
4
  // https://docs.microsoft.com/en-us/windows/console/console-virtual-terminal-sequences
5
5
  const t = module.exports.codes = {
@@ -18,9 +18,9 @@ const as = module.exports.as = (codes, o) => {
18
18
  return module.exports.isTTY ? (codes + o + t.reset) : ('' + o)
19
19
  }
20
20
 
21
- const asErr = module.exports.error = o => debug ? o : as(t.red + t.bold, o)
22
- const asWarn = module.exports.warn = o => debug ? o : as(t.orange + t.bold, o)
23
- const asInfo = module.exports.info = o => debug ? o : as(t.green + t.bold, o)
21
+ const asErr = module.exports.error = o => DEBUG ? o : as(t.red + t.bold, o)
22
+ const asWarn = module.exports.warn = o => DEBUG ? o : as(t.orange + t.bold, o)
23
+ const asInfo = module.exports.info = o => DEBUG ? o : as(t.green + t.bold, o)
24
24
  module.exports.warn = o => as(t.orange, o)
25
25
  module.exports.info = o => as(t.green, o)
26
26
  module.exports.link = o => as(t.link, o)
@@ -39,14 +39,14 @@ const format = module.exports.format = (o, severity='Error', asInternalError=fal
39
39
  // 'Error: foo' -> '[ERROR] foo' (Maven-like, allows for better grepping in logs)
40
40
  Object.assign (format, {
41
41
  error: (o, asInternalError, withStack) => {
42
- if (debug) return o
42
+ if (DEBUG) return o
43
43
  if (asInternalError) {
44
44
  return `[${asErr('INTERNAL ERROR')}] ${o.stack || o.toString()}\nPlease report this error.\n`
45
45
  }
46
46
  return `[${asErr('ERROR')}] ${toString(o, 'Error', withStack)}`
47
47
  },
48
- warn: o => debug ? o : `[${asWarn('WARNING')}] ${toString(o, 'Warning')}`,
49
- info: o => debug ? o : `[${asInfo('INFO')}] ${toString(o, 'Info')}`,
48
+ warn: o => DEBUG ? o : `[${asWarn('WARNING')}] ${toString(o, 'Warning')}`,
49
+ info: o => DEBUG ? o : `[${asInfo('INFO')}] ${toString(o, 'Info')}`,
50
50
 
51
51
  poorMarkdown: (md) => { return md
52
52
  .replace(/\n# ([^\n]*)\n/g, `\n${as(t.bold, '$1')}\n`)