@sap/hdi-deploy
The Node.js deployer for SAP HANA Deployment Infrastructure: it writes a database module's design-time files into an HDI container as a delta, and it is what cds deploy runs for SAP HANA.
A Node.js module that deploys a database module's design-time files, the src/ folder and an optional cfg/ folder, into an SAP HANA Deployment Infrastructure (HDI) container. It finds the container among the services bound in VCAP_SERVICES, or for a local run in default-env.json or .env, and TARGET_CONTAINER names the one to use when several are bound. Each run works out which files were added, modified and deleted, and schedules the added and modified ones. Deleted files are not undeployed unless undeploy.json lists them or the run is given --auto-undeploy, so an object whose file is gone stays in the container until someone asks for its removal. Reusable database modules found in node_modules/ are folded into the same deployment. It reads HDI artifacts, not CDS: in a CAP project cds build from @sap/cds-dk@sap/cds-dkThe command line client and development toolkit for CAP projects, with the commands cds build, cds deploy, cds watch and cds add among them.sap official, cap generates them from the model, and cds deploy --to hana starts this package locally against them. It does not create the container either; on Cloud Foundry that is the hdi-shared service instance. The README describes it running on Cloud Foundry and XS Advanced, pushed as an app or run as a task, and locally with npm run start -- --exit; since 4.3.1 it also reads credentials from a Kubernetes secret volume.
Facts
Where it sits
What it declares
Every artifact
- Type
- Package
- Origin
- By SAP
- Runtime
- Node.js
- Runs on
- Cloud Foundrylocal
As a package
- Where it runs
- does not say
- Distributed through
- does not say
Connections
Using native SAP HANA database objects beside the generated model
Getting a model change into a database that already holds data
Managed SAP HANA database service on BTP
Guide migrating the hana-shine-xsa demo from XS Advanced to CAP
Download
Install
npm add @sap/hdi-deploy{
"name": "deploy",
"dependencies": {
"@sap/hdi-deploy": "5.7.0",
"@sap/hana-client": "2.27.19",
"hdb": "2.26.4"
},
"scripts": {
"start": "node node_modules/@sap/hdi-deploy/"
}
}# in the db module's folder, with default-env.json holding the service bindings and TARGET_CONTAINER npm install npm run start -- --exit
- Deleted files in src/ and cfg/ are not undeployed. They must be listed in undeploy.json, or the run given --auto-undeploy, which ignores undeploy.json and undeploys every deleted file.
- Binding more than one HDI Deployer instance to the same target container is not supported and results in undefined behaviour.
- Reusable database modules cannot include other reusable database modules recursively.
Copied from @sap/hdi-deploy 5.7.0 — README, read . Not run by the atlas.
Where it sits in your app
Download
hdi-shared service instance. The README names SAP HANA 1 SPS11/SPS12 and SAP HANA 2 as supported; SAP HANA Cloud appears in the changelog, which added its tenant credential format in 5.4.0.Seen in
README
quoted from @sap/hdi-deploy@5.7.0 under SEE LICENSE IN LICENSE, read@sap/hdi-deploy
@sap/hdi-deploy is a Node.js-based deployment module for SAP HANA DI (HDI)-based persistence models, HDI Deployer for short. The HDI Deployer can be used in XS Advanced (XSA) and in SAP Business Technology Platform (SAP BTP)/Cloud Foundry (CF), and it is also used by the SAP Web IDE for interactive development scenarios. It can also be used in scenarios without XSA (or SAP BTP), e.g. for deploying HDI persistence models into a SAP HANA database where no XSA is installed.
For more information about SAP HANA DI, please check the SAP HANA Developer Guide and the SAP HANA Administration Guide.
Usually, the HDI Deployer is packaged into a database module, a db module, as part of a Multi-Target Application (MTA) and is used to deploy HDI design-time artifacts of the db module to the respective HDI container. When an MTA is deployed via the Deploy Service, the db module is pushed first so that it can "prepare" the SAP HANA persistence; by the time defined services are started, the HDI container is ready for use.
The HDI Deployer can also be used without the Deploy Service and MTAs, without XSA, and also for interactive scenarios or automation scripts.
For an MTA with different modules, e.g. a db module, a Node.js module, etc., this looks as follows:
+-----------------+ +-----------------+ +-----------------+
| db module | | Node.js module | | ... module |
| w/ HDI Deployer | | | | |
+-----------------+ +-----------------+ +-----------------+
| | |
| | |
\/ deploy persistence \/ read/write/extend persistence
| | |
| | |
+---------------------------------------------------------------+
| HDI container |
| |
+---------------------------------------------------------------+
In an SAP HANA-Service-Broker-based HDI setup, each module of the MTA is equipped with it's own technical database user for accessing the runtime schema of the HDI container.
The following diagram illustrates the different users who are involved in this setup with regard to privileges: the application users user1 and user2 who are bound to one of the modules each, and the HDI container's object owner (the #OO user) who is the owner of the objects in the database persistence of the MTA which are managed by HDI:
+-----------------+ +-----------------+ +-----------------+
| db module | | Node.js module | | ... module |
| w/ HDI Deployer | | | | |
+-----------------+ +-----------------+ +-----------------+
| | o
| --------------------------------- X application user user1
| | o
| | ----- X application user user2
| |
+---------------------------------------------------------------+
| HDI container |
| db object 1 db object 2 |
+-------------------------------------\-------------/-----------+
\ /
o \ /
X object owner (#OO user)
The HDI Deployer is packaged into the db module of the MTA. So, in order to use a new HDI Deployer, you need to reference a new version of the HDI Deployer in the db module's package.json file.
The HDI Deployer supports SAP HANA 1 SPS11/SPS12 and SAP HANA 2. The HDI Deployer assumes that for newer versions of SAP HANA, a corresponding version of the SAP HANA Service Broker is used to create the CF/XSA service bindings.
Note: The HDI Deployer assumes ownership of the src/, cfg/, and lib/ folders in the bound target HDI container. Binding more than 1 instance of the HDI Deployer to the same HDI container as the target container, e.g. the db modules of 2 MTAs or 2 applications are bound to the same HDI container as the target container, is not supported and results in undefined behavior.
README.md
Installation:
- Integration into a Database Module
- SAP HANA Client
- Database Connection Details
- Deployment via Push and Tasks
- Deployment via Local Run
The Database Module:
- A Database Module's File System Structure
- Delta Deployment and Undeploy Allowlist
- The default_access_role Role
- The development_debug_role Role
- Reusable Database Modules
- Configuration File Templating
- Permissions to Container-External Objects
Configuration and Reconfiguration:
- Environment Variables for Applications
- Environment Variables for Infrastructure / Development Tools
- Options for Interactive Scenarios
- Ignore List
- Supported Features
Dynamic Deployment:
Library Usage:
Integration into a Database Module
Usually, @sap/hdi-deploy gets installed via a package.json-based dependency inside your application's db module:
db/package.json:
{
"name": "deploy",
"dependencies": {
"@sap/hdi-deploy": "5.7.0",
"@sap/hana-client": "2.27.19",
"hdb": "2.26.4"
},
"scripts": {
"start": "node node_modules/@sap/hdi-deploy/"
}
}
SAP HANA Client
As of version 5.0.0 @sap/hdi-deploy does not contain @sap/hana-client and hdb as dependencies. This was done due to the large size of in some cases unnecessary '@sap/hana-client' dependency. To use @sap/hdi-deploy 5.0.0 and higher you must install @sap/hana-client and/or hdb peer dependencies yourself.
To make use of the @sap/hana-client or hdb clients, simply install the desired client. If both clients are installed, the deployer will give priority to the @sap/hana-client client. Where as to use hdb use --use-hdb option in package.json file or set use_hdb to true in HDI_DEPLOY_OPTIONS. You can find detailed information on how to set --use-hdb option here (#options-for-interactive-scenarios).
Database Connection Details
Connection details for the database, e.g. host, port, credentials, certificates, hostname_in_certificate, encrypt and validate_certificate, are looked up by the HDI Deployer from the standard CF/XSA VCAP_SERVICES environment variable which contains the bound services.
Since version 4.3.1 of hdi-deploy supports reading credentials from a secret volume for Kubernetes.
Mutual Authentication Configuration
To use X.509 certificate-based authentication, you must provide a client certificate and private key. These can be supplied through your service binding in either of these two ways:
-
Combined in a single password field: You can include both the private key and certificate in either the
hdi_passwordorpasswordfield. In this case, the correspondinghdi_useroruserfield must be blank. The system will automatically extract and use both components. -
As separate credential properties:
"credentials": { ... "client_authentication_private_key": "-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----", "client_authentication_certificate": "-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----" }client_authentication_private_keyandclient_authentication_certificatetake precedence over private key and certificate fromhdi_passwordorpassword. Older versions ofhdb(before 2.26.1) do not support this feature.
For local testing, the HDI Deployer supports default configurations via the following configuration files:
default-env.json: a JSON file which contains a set of environment variables and their values.env: a dot env file which contains a set of environment variables and their values. This file is used in the absence ofdefault-env.json.default-services.json: a JSON file which contains a set of service bindings
In addition, you can provide a path to a json file containing VCAP_SERVICES in json format.
This is done using the VCAP_SERVICES_FILE_PATH environment variable.
If the VCAP_SERVICES_FILE_PATH environment variable is set, the deployer will use it for obtaining the VCAP_SERVICES value. Read more about this in the VCAP_SERVICES section.
Details of a bound service from an SAP HANA-Service-Broker-based service binding in CF/XSA usually look as follows:
{
"name" : "foo",
"label" : "hana",
"tags" : [ "hana", "database", "relational" ],
"plan" : "hdi-shared",
"credentials" : {
"schema" : "FOO",
"user" : "FOO_345999596729_RT",
"password" : "<password>",
"hdi_user" : "FOO_645927945801_DT",
"hdi_password" : "<password>",
"host" : "srv1234567.host.name",
"port" : "30115",
"db_hosts" : [ {
"port" : 30115,
"host" : "srv1234567.host.name"
} ],
"url" : "jdbc:sap://srv1234567.host.name:30115/?currentschema=FOO",
"driver" : "com.sap.db.jdbc.Driver"
}
}
Here, the credentials section contains all the data which is needed by the HDI Deployer for connecting to the database. The HDI Deployer uses the hdi_user/hdi_password credentials from a direct service binding. The hdi_user should be minimal, i.e. only have the privileges required to fulfill the deployment. In most cases, access to a container FOO's API in the FOO#DI schema is sufficient.
Splitting passwords across services
The password property and the hdi_password property can also be specified as a combination of passwords from other bound services. Consider the following service binding:
{
"hana" : [],
"user-provided" : [
{
"name" : "split_password_service",
"label" : "user-provided",
"tags" : [],
"credentials" : {
"user" : "user",
"schema": "schema",
"password": ["password_and_hdi_password_service", "password_only_service"],
"hdi_password": ["password_and_hdi_password_service", "hdi_password_only_service"],
"tags" : [ "hana" ]
}
},
{
"name" : "password_and_hdi_password_service",
"label" : "user-provided",
"tags" : [],
"credentials" : {
"password" : "PASSWORD",
"hdi_password": "HDI_PASSWORD",
"tags" : [ "password" ]
}
},
{
"name" : "hdi_password_only_service",
"label" : "user-provided",
"tags" : [],
"credentials" : {
"hdi_password": "123",
"tags" : [ "password" ]
}
},
{
"name" : "password_only_service",
"label" : "user-provided",
"tags" : [],
"credentials" : {
"password" : "456",
"tags" : [ "password" ]
}
} ]
}
When the service shared_password_service is used, the services specified in password and/or hdi_password will be checked and their password and/or hdi_password will be concatenated. The services will be accessed in the order they are defined. The resulting shared_password_service would have the password "PASSWORD456" and the hdi_password "HDI_PASSWORD123".
0 to n services can be specified, specifying 0 services results in the password/hdi_password ''.
VCAP_SERVICES
Connection details for the database are stored in the following format in the VCAP_SERVICES environment variable:
VCAP_SERVICES:
{
"hana" : [
<hana-service-binding-1>,
<hana-service-binding-2>,
...
<hana-service-binding-n>
],
"user-provided" : [
<user-provided-service-binding-1>,
<user-provided-service-binding-2>,
...
<user-provided-service-binding-m>
]
}
'
default-env.json
A default-env.json file can contain a set of environment variables and their values. The HDI Deployer will pick up these settings on startup:
default-env.json:
{
"TARGET_CONTAINER" : "<name-of-the-service-instance-to-use-as-deployment-target>",
"VCAP_SERVICES" : {
"hana" : [
<hana-service-binding-1>,
<hana-service-binding-2>,
...
<hana-service-binding-n>
],
"user-provided" : [
<user-provided-service-binding-1>,
<user-provided-service-binding-2>,
...
<user-provided-service-binding-m>
]
}
}
default-env.json example file with a target container binding and a user-provided service:
{
"TARGET_CONTAINER" : "target-service",
"VCAP_SERVICES" : {
"hana" : [ {
"name" : "target-service",
"label" : "hana",
"tags" : [ "hana", "database", "relational" ],
"plan" : "hdi-shared",
"credentials" : {
"schema" : "SCHEMA",
"hdi_user" : "USER_DT",
"hdi_password" : "PASSWORD_DT",
"certificate" : "-----BEGIN CERTIFICATE-----\nABCD...1234\n-----END CERTIFICATE-----\n",
"host" : "host",
"port" : "30015"
}
} ],
"user-provided" : [ {
"name" : "GRANTING_SERVICE",
"label" : "user-provided",
"tags" : [ ],
"credentials" : {
"schema" : "SYS",
"user" : "GRANT_USER",
"password" : "PASSWORD",
"procedure_schema" : "PRIVILEGE_PROCEDURE_GRANTOR_DEFINER",
"procedure" : "GRANT",
"type" : "procedure",
"tags" : [ "hana" ]
}
} ]
}
}
.env
A .env file can contain a set of environment variables and their values. The HDI Deployer will pick up these settings on startup:
.env example file:
VCAP_SERVICES='{"hana" : [ { "name" : "target-service", "label" : "hana", "tags" : [ "hana", "database", "relational" ], "plan" : "hdi-shared", "credentials" : { "schema" : "SCHEMA", "hdi_user" : "USER_DT", "hdi_password" : "PASSWORD_DT", "certificate" : "-----BEGIN CERTIFICATE-----\nABCD...1234\n-----END CERTIFICATE-----\n", "host" : "host", "port" : "30015" } } ] }'
VCAP_SERVICES_FILE_PATH
The VCAP_SERVICES can be read from a file. This is achieved with the VCAP_SERVICES_FILE_PATH variable.
The variable is an absolute path to an existing file.
The content of that file must be in json format.
Note: default-services.json does not take effect when used in combination with VCAP_SERVICES_FILE_PATH.
.env example file:
VCAP_SERVICES_FILE_PATH='/tmp/vcap_services.json'
Deployment via Push and Tasks
There are two ways of using the HDI Deployer as an application:
- Push the application with one instance. The application will then start and do the HDI deployment of the data model. After a successful deployment, the application will enter an idle loop and can be stopped.
- Push the application with zero instances and then trigger a task on the application which does the HDI deployment of the data model. After deployment of the data model, the task will be completed. An instance of the application is only running while the task is being executed.
For both scenarios, ensure that the health-check-type in the manifest is set to process, instead of the default, port-based health check.
In order to push the application with zero instances, the application can either be pushed with the --no-start option or the number of instances can be set to zero in the manifest.yml file via instances: 0.
The deployment task can be started via xs run-task <app> deployment-task "npm run start -- --exit" --wait-for-completion on XSA. The task will run and the call will propagate the success/failure of the deployment task. On CF, the --wait-for-completion option is not available and the status of the task needs to be checked periodically.
Deployment via Local Run
An HDI deployment can also be triggered without using an application. In this case, the HDI Deployer will be run locally and directly connects to the database. This is possible in the following scenarios: the database is accessible locally from a network point of view or a network tunnel with a local endpoint was established, e.g. a cf ssh-based tunnel is set up in CF.
Apply the following steps to run the HDI Deployer locally: run npm install in the db module's folder to install the HDI Deployer module, then create a default-env.json file in the db module's folder which contains the required service bindings and the TARGET_CONTAINER setting, then run npm run start -- --exit in the db module's folder to trigger the deployment of the data model.
If the database uses SSL/TLS encryption, please ensure that the hostname_in_certificate value is set up correctly in the service bindings, because the network tunnel's local endpoint (e.g. localhost:9000) doesn't match the hostname in the SSL/TLS certificate.
A Database Module's File System Structure
The HDI Deployer expects the following file system structure for the HDI content in your db module:
src/: folder which contains your HDI source artifactscfg/: optional folder with HDI configuration artifactspackage.json: this file is used by npm (the Node.js package manager) to bootstrap and start the application
Other files in the root directory will be ignored by @sap/hdi-deploy.
Please note that the cfg/ folder also might need a .hdiconfig file, e.g. in case .hdbsynonymconfig files are placed there.
In combination with reusable database modules, the HDI Deployer will also consider database modules which are located in the node_modules/ folder and which will be mapped to a corresponding sub-folder hierarchy in the container's lib/ folder.
Note: The design-time files should be protected against unauthorized modifications to guard against unwanted undeployments or deployment of foreign objects. For applications running on XSA or Cloud Foundry, this is taken care of by the platform.
Delta Deployment and Undeploy Allowlist
The HDI Deployer implements a delta-based deployment strategy:
On startup, the HDI Deployer recursively scans the local src/ and cfg/ folders, processes config templates, looks at the HDI container at the server-side and calculates the set of added, modified, and deleted files based on the difference between the local file system state and the deployed file system state of the server-side HDI container.
In normal operation, the HDI Deployer will schedule only the set of added and modified files for deployment. The set of deleted files is not scheduled for undeployment.
In order to undeploy deleted files, an application needs to include an undeploy allowlist via an undeploy.json file in the root directory of the db module (right beside the src/ and cfg/ folders). The undeploy allowlist undeploy.json file is a JSON document with a top-level array of file names.
"real" paths, path patterns and path negations are supported.
undeploy.json:
[
"src/Table.hdbcds",
"src/Procedure.hdbprocedure",
"src/*.hdbtable",
"**/*.hdbtable",
"!**/temp/*.hdbtable"
]
The file must list all artifacts which should be undeployed. The file path of the artifacts must be relative to the root directory of the db module, must use the HDI file path delimiter '/', and must be based on the HDI server-side folder structure. In case of reusable database modules, the server-side top-level folder lib/ needs to be used instead of the local folder node_modules/.
For interactive scenarios, it's possible to pass the auto-undeploy option to the HDI Deployer, e.g.
node deploy --auto-undeploy
In this case, the HDI Deployer will ignore the undeploy allowlist undeploy.json file and will schedule all deleted files in the src/ and cfg/ folders for undeployment.
The default_access_role Role
When an HDI container service instance is created by the SAP HANA Service Broker, for example, service instance foo with schema name FOO, the broker creates an HDI container named FOO (consisting of the run-time schema FOO , the HDI metadata and API schema FOO#DI , and the object owner FOO#OO) and, in addition, the following roles, which are assigned to the application user:
-
FOO::access_role A global access role that equips the application user with privileges on the run-time schema 'FOO'. This access role is assigned a set of default permissions for the run-time schema: SELECT, INSERT, UPDATE, DELETE, EXECUTE, CREATE TEMPORARY TABLE, and SELECT CDS METADATA on the run-time schema
FOO. -
FOO::external_privileges_role A role that grants the application user the privileges required to enable access to schemas and objects outside the HDI container, for example, the run-time container
BAR. By default, external_privileges_role has no privileges assigned. If the application user requires access to external objects, a user with grant-option privileges on those external objects must first explicitly grant the required privileges to the external_privileges_role. Similarly, any explicitly assigned privileges must also be explicitly revoked.
Note : The roles exist as long as the HDI container exists; they are not lost when the application binding user changes. New binding users are automatically assigned these roles by the broker.
Every time the service instance is bound to an application, the service broker creates two new users that are specific to this binding. The first user is the application user who is named user in the instance's credentials. This user is used by the application to access the HDI container's run-time schema FOO. This user is assigned the service instance's global access role FOO::access_role and the role FOO::external_privileges_role. The second user is the HDI API user - named hdi_user in the credentials. This user is equipped with privileges for the container's APIs in the FOO#DI schema.
The following diagram illustrates the binding-specific application users and the role of the global access role (the HDI API users and the bindings for the HDI Deployer are not shown for simplicity):
+-----------------+ +-----------------+ +-----------------+
| db module | | Node.js module | | ... module |
| w/ HDI Deployer | | | | |
+-----------------+ +-----------------+ +-----------------+
| | o
| --------------------------------- X application user user1
| | o \
| | ----- X application user user2 \
| | \ \
\ \
+---------------------------------------------------------------+ role FOO::access_role
| HDI container FOO | /
| | SELECT/INSERT/... on schema FOO
+---------------------------------------------------------------+
Exemplary service binding:
{
"hana" : [ {
"name" : "foo",
"label" : "hana",
"tags" : [ "hana", "database", "relational" ],
"plan" : "hdi-shared",
"credentials" : {
"schema" : "FOO",
"user" : "FOO_345999596729_RT",
"password" : "<password>",
"hdi_user" : "FOO_645927945801_DT,
"hdi_password" : "<password>",
"host" : "srv1234567.host.name",
"port" : "30115",
"db_hosts" : [ {
"port" : 30115,
"host" : "srv1234567.host.name"
} ],
"url" : "jdbc:sap://srv1234567.host.name:30115/?currentschema=FOO",
"driver" : "com.sap.db.jdbc.Driver"
}
} ]
}
In order to assign roles from the HDI content to the application binding users (the user users), the HDI Deployer implements an automatic assignment of the default_access_role role if it is present in the deployed content:
If a role definition file exists at the path src/defaults/default_access_role.hdbrole, and this file defines a role named default_access_role, and this file is included in the deployment (e.g. not excluded via include-filter), then the HDI Deployer grants the deployed default_access_role role to the service instance's global access role (e.g. FOO::access_role). In addition, the HDI Deployer revokes all default permissions (e.g. SELECT, INSERT, UPDATE, DELETE, EXECUTE, CREATE TEMPORARY TABLE, and SELECT CDS METADATA (not on SAP HANA Cloud) on the runtime schema FOO) from the global access role. If the default_access_role is undeployed, the default permission set for the runtime schema will be restored.
Note: If you use a .hdinamespace file in src/ which defines a real namespace prefix for subfolders, then you need to put a .hdinamespace file with the empty namespace "name" : "" at src/defaults/ to ensure that the role can be named default_access_role.
The following diagram illustrates the binding-specific application users, the role of the global access role, and the container-specific default access role:
+-----------------+ +-----------------+ +-----------------+
| db module | | Node.js module | | ... module |
| w/ HDI Deployer | | | | |
+-----------------+ +-----------------+ +-----------------+
| | o
| --------------------------------- X application user user1
| | o \
| | ----- X application user user2 \
| | \ \
\ \
+---------------------------------------------------------------+ role FOO::access_role
| HDI container FOO | /
| role default_access_role ----------------------------+
| / \ |
| role role1 role role2 |
| / / \ |
| structured privileges DCL role 1 / 2 |
+---------------------------------------------------------------+
Note: The default_access_role is assumed to be an "umbrella" role which aggregates other roles.
A role with the default permission set which is granted by the SAP HANA Service Broker on container creation looks as follows:
default_permissions_role.hdbrole:
{
"role":{
"name":"default_permissions_role",
"schema_privileges":[
{
"privileges":[
"SELECT",
"INSERT",
"UPDATE",
"DELETE",
"EXECUTE",
"CREATE TEMPORARY TABLE",
"SELECT CDS METADATA"
]
}
]
}
}
On SAP HANA Cloud, "SELECT CDS METADATA" is not granted.
The development_debug_role Role
Similarly to the default_access_role, a development_debug_role can be used to add additional privileges to the access role. This is only intended for development and debugging, not for productive use!
If a role definition file exists at the path src/defaults/development_debug_role.hdbrole, and this file defines a role named development_debug_role, and this file is explicitly included in the deployment via the --deploy option, then the HDI Deployer grants the deployed development_debug_role role to the service instance's global access role (e.g. FOO::access_role).
In order to remove the privileges granted this way, the file has to be undeployed.
Reusable Database Modules
In order to allow that an application uses (parts of) the database persistence of a reusable component inside its own persistence model, the HDI Deployer allows to link/include the design-time files of reusable components in a consuming application in an automated way. This mechanism is based on the Node.js package management mechanism for defining, publishing, and consuming reusable database modules which also supports versioning based on the semantic versioning concepts (cf. http://semver.org).
A reusable database module is considered to have the same src/ and cfg/ folder structure as a normal database module. The src/.hdiconfig file is mandatory and used by the module mechanism as an indicator that the src/ and cfg/ folders belong to a consumable, reusable database module. In addition, the reusable database module needs to have a package.json file which defines the module's name, the module's version, etc.
A complete reusable database module looks as follows:
/
+-- src/
| +-- .hdiconfig
| +-- <source files ...>
+-- cfg/
| +-- <optional configuration files ...>
+-- package.json
The package.json file contains the module’s name, description, version, repository URL, and the set of files which belong to the module:
package.json:
{
"name": "module1",
"description": "A set of reusable database objects",
"version": "1.3.1",
"repository": {
"url": "git@your.gitserver:modules/module1.git"
},
"files": [
"src",
"cfg",
"package.json"
]
}
The reusable database module should be published to a Node.js package management compliant object repository.
Consumption of a reusable database module is done by adding a dependency in the consuming module's package.json file, right beside the dependency to @sap/hdi-deploy:
{
"name": "deploy",
"dependencies": {
"@sap/hdi-deploy": "5.7.0",
"module1": "1.3.1",
"module2": "1.7.0",
"@sap/hana-client": "2.27.19",
"hdb": "2.26.4"
},
"scripts": {
"start": "node node_modules/@sap/hdi-deploy/"
}
}
Here, the consuming module requires module1 in version 1.3.1 and module2 in version 1.7.0.
When running npm install to download and install the dependencies which are listed in the dependencies section of the package.json file, npm will also download the reusable database modules and places them into the node_modules/ folder of the consuming module. For each module a separate subfolder is created with the name of the module.
When the HDI Deployer is triggered to do the actual deployment of the (consuming) database module, it scans the node_modules/ folder and virtually integrates the src/ and cfg/ folders of found reusable database modules into the (consuming) database module’s lib/ folder. Reusable database modules are identified by the mandatory src/.hdiconfig file.
On successful deployment, the HDI container will contain the consumed modules below the root-level lib/ folder, e.g.
/
+-- src/
+-- cfg/
+-- lib/
| +-- module1/
| | +-- src/
| | +-- cfg/
| +-- module2/
| +-- src/
| +-- cfg/
For the time being, it’s not allowed to recursively include reusable database modules.
The cfg/ folders of reusable database modules are also subject to configuration file templating.
Configuration File Templating
The HDI Deployer implements a templating mechanism for HDI configuration files, e.g. configuration files for synonyms, projection views, etc., based on services which are bound to the db module application. By means of this templating mechanism, it is possible to configure synonyms, projection views, etc. to point to the right database schema without knowing the schema name at development time.
On startup, the HDI Deployer recursively scans the local cfg/ folder and picks up all files with a .*config suffix, e.g. all .hdbsynonymconfig, .hdbvirtualtableconfig, etc. files. For all collected files which contain .configure markers in their content, it applies the configuration templating and creates transient configuration files which are then deployed to the HDI container.
For a synonym configuration file cfg/LOCAL_TARGET.hdbsynonymconfig
{
"LOCAL_TARGET" : {
"target" : {
"schema.configure" : "logical-external-service/schema",
"database.configure" : "logical-external-service/database",
"object" : "TARGET"
}
}
}
the section
"schema.configure" : "logical-external-service/schema",
"database.configure" : "logical-external-service/database",
"object" : "TARGET"
will be transformed by the templating mechanism into
"schema" : "THE_SCHEMA",
"database" : "THE_DATABASE",
"object" : "TARGET"
where THE_SCHEMA and THE_DATABASE are the values for the schema and database fields of the bound service logical-external-service, which are denoted by the path expressionslogical-external-service/schema and logical-external-service/database.
If a field in the service is missing, it will not be configured and will be removed instead, e.g. database might be optional.
The names of the services are subject to the service replacements mechanism, which can be used to map a real service, e.g. real-external-service, to a logical service name which is used in the configuration files, e.g. logical-external-service.
It's not always applicable to use schema.configure, database.configure, etc. in the configuration template files. Therefore, the HDI Deployer provides a generic way of copying a set of properties from the bound service, e.g. schema, database, remote source, etc. if they are present, although the template file doesn't mention them.
For the configuration file cfg/LOCAL_TARGET.hdbsynonymconfig this could looks as follows:
{
"LOCAL_TARGET" : {
"target" : {
"*.configure" : "logical-external-service",
"object" : "TARGET"
}
}
}
When the HDI Deployer encounters a *.configure entry, it simply copies all well-known fields which are present in the bound service into the configuration file. The well-known fields are currently remote, database, and schema.
The HDI Deployer also supports old-style .hdbsynonymtemplate template files: If a .hdbsynonymtemplate file is found in the cfg/ or src/ folder, then it is processed as a configuration template file and a transient file with the suffix .hdbsynonymconfig is created. A field grantor is replaced with the schema value from the referenced service; so, a grantor field is equivalent to a "schema.configure" : "the-service/schema" entry in a configuration template file.
Permissions to Container-External Objects
An HDI container is by default equipped with nearly zero database privileges, e.g. the object owner (#OO user) is mainly equipped with the CREATE ANY privilege on the container's runtime schema (e.g. schema FOO for an HDI container FOO). Since SAP HANA 2 SPS00, the object owner is equipped with an additional restricted set of privileges for system views in the database's SYS schema, e.g. SYS.VIEWS or SYS.TABLES. These system views apply an additional row-level filter based on the object owner's other privileges, e.g. the object owner can only see metadata in SYS.VIEWS for views he has privileges on. So, without additional privileges, the object owner can only see metadata for the objects in his container schema.
In order to access database objects inside other database schemata or other HDI containers, and in order to deploy synonyms into the HDI container which point to these container-external objects, at least the object owner needs additional privileges, e.g. for an object object in schema X SELECT privileges on X.object:
+---------------------------------------------------------------+ +------------------------+
| HDI container FOO | | other schema X |
| synonym ------------------------> object |
+---------------------------------------------------/-----------+ +-------------\----------+
/ \
o / \
X object owner FOO#OO -------------------- SELECT on X.object
Please also refer to the official Using Synonyms to Access External Schemas and Objects in XS Advanced guide.
.hdbrevokes Files
Starting with version 3.8, the deployer now allows revoking rights. Anything that can be granted via .hdbgrants can be revoked via .hdbrevokes. Both files, .hdbgrants and .hdbrevokes use the same structure. For more information on the structure of these files, see the section about .hdbgrants Files.
The .hdbrevokes file will be processed before the .hdbgrants file.
.hdbgrants Files
In order to automatically assign privileges to the object owner and/or the application binding users, the HDI Deployer provides .hdbgrants files with a syntax similar to .hdbrole files:
An .hdbgrants file has the following structure:
granting-service.hdbgrants:
{
"granting-service": {
"object_owner": {
<privileges>
},
"application_user": {
<privileges>
}
}
}
The top-level keys define the names of the bound services which "grant" the privileges, these are the "grantors", e.g. granting-service in the example. The next level defines to which users the privileges will be granted, these are the "grantees": object_owner is used for the HDI container's object owner, and application_user marks the application users which are bound to the application modules, e.g. the Node.js module. The third level defines the set of privileges in a .hdbrole-like structure.
On startup, the HDI Deployer looks for .hdbgrants files and processes them as follows: For each grantor in the file, the HDI Deployer looks up a bound service with the name (subject to service replacements), connects to the database with the service's credentials, and grants the specified privileges to the grantees. If the schema field is omitted for a privilege, then the grantor's schema property is used. If the name field in a global_object_privileges element of type REMOTE SOURCE is omitted, then the grantor's remote property is used.
For backwards compatibility, also the suffix .hdbsynonymgrantor is supported.
Example of a cfg/external-access.hdbgrants file with some privileges for the object owner:
{
"external-access": {
"object_owner": {
"system_privileges" : [
{
"privileges" : [ "SYSTEM_PRIVILEGE_1" ],
"privileges_with_admin_option" : [ "SYSTEM_PRIVILEGE_2", "SYSTEM_PRIVILEGE_3" ]
}
],
"global_roles" : [
{
"roles" : [ "GLOBAL_ROLE_1", "GLOBAL_ROLE_2" ],
"roles_with_admin_option" : [ "GLOBAL_ROLE_3", "GLOBAL_ROLE_4" ]
}
],
"schema_privileges" : [
{
"privileges" : [ "INSERT", "UPDATE" ],
"privileges_with_grant_option" : [ "SELECT" ]
}
],
"schema_roles" : [
{
"roles" : [ "SCHEMA_ROLE_1", "SCHEMA_ROLE_2" ],
"roles_with_admin_option" : [ "SCHEMA_ROLE_3", "SCHEMA_ROLE_4" ]
}
],
"object_privileges" : [
{
"name": "AN_OBJECT",
"privileges": [ "INSERT", "UPDATE" ],
"privileges_with_grant_option" : [ "SELECT" ]
}
],
"global_object_privileges" : [
{
"name" : "A_REMOTE_SOURCE",
"type" : "REMOTE SOURCE",
"privileges" : [ "CREATE VIRTUAL TABLE" ],
"privileges_with_grant_option" : [ "CREATE VIRTUAL PROCEDURE" ]
}
]
}
}
}
The following elements and keys are supported for backwards compatibility or for compatibility with .hdbrole:
container_roles: grant roles from an HDI container; superseded byschema_roleswhich works for normal schemas and HDI containers
"container_roles" : [ "SCHEMA_ROLE_1", "SCHEMA_ROLE_2" ]
roles: grant global roles; superseded byglobal_roles:
"roles" : [ "GLOBAL_ROLE_1", "GLOBAL_ROLE_2" ]
- string-array-style roles and
nameskey (maps to the non-grant/admin-option variant):
"global_roles" : [
"GLOBAL_ROLE_1",
{
"roles" : [ "GLOBAL_ROLE_1", "GLOBAL_ROLE_2" ]
},
{
"names" : [ "GLOBAL_ROLE_1", "GLOBAL_ROLE_2" ]
},
{
"roles_with_admin_option" : [ "GLOBAL_ROLE_3", "GLOBAL_ROLE_4" ]
},
"GLOBAL_ROLE_2"
]
If any non-container privileges are used, then the object owner (#OO user) will need to be given these privileges WITH GRANT option by a user-defined granting-service. Otherwise it won't be able to grant these privileges to e.g. a role in the container.
Creating a Granting Service
The HDI Deployer supports the following types of granting-services:
sql: a technical database user with GRANT privileges for the required object privileges, roles, system privileges, etc.hdi: an HDI container with access to the container's GRANT APIs. An HDI container can only grant roles from the container, without admin option.procedure: a technical database user with EXECUTE privileges on a stored procedure which has GRANT privileges for the required object privileges, roles, system privileges, etc.ignore: grants were already given at the database-level and the HDI Deployer will ignore the content of the.hdbgrantsfile.
For the HDI container case, the corresponding service can simply be bound to the db module application. The HDI Deployer recognizes the bound service by its hdi_user value in the credentials section and calls the container's API procedures to grant the privileges from the .hdbgrants file.
In case a technical database user is used, a 'user-defined service' must be created for this purpose in the same space as the container. The service needs to be set up with the permissions of a specified database user to connect to the database and to grant the privileges specified in the .hdbgrants files during application deployment.
Such a user-provided service can be created as follows:
- Open a command shell and log on to XSA:
xs login - Change to the target space where you want to create the user-defined service:
xs target -s <SPACE> - Create the user-defined service (e.g.
grantor-service):xs cups grantor-service -p '{ "host": "host.acme.com", "port": "30015", "certificate": "<myCertificate>", "user": "TARGET_USER", "password": "Grant_123", "schema": "TARGET_SCHEMA", "tags": [ "hana" ] }'"host"/"port": Required for the connection to the database: port is the SQL port of the index server."certificate": If the database is configured to only accept secure connections, then the granting-service requires an SSL certificate that must be included in the user-provided service, for example, using the "certificate":"" parameter."user"/"password": Connection details for a database user that has grant permissions for the objects in the schema."schema": The database schema that contains the objects to which access is to be granted."type": The type of the grantor mechanism; valid values are"hdi","sql", or"procedure". If the type is not specified, then the type is auto-sensed (see details below)."tags": For the purposes of granting, create user-provided services that are tagged with the"hana"tag. E.g.:"tags": [ "hana" ]or"tags": "hana".
- Use the command
xs servicesto display a list of services available in the current space; the 'grantor-service' service should be visible.
For Cloud Foundry, use the corresponding cf commands.
Note: Starting with version 3.0.0 of the HDI Deployer, the "host", "port", and "certificate" parameters are no longer required since they can be obtained from the target container binding. In this case, you must only specify the "user", "password", and "schema" when creating the user-provided service, e.g. xs cups grantor-service -p '{ "user": "TARGET_USER", "password": "Grant_123", "schema": "TARGET_SCHEMA", "tags": [ "hana" ] }'.
If the "type" is not specified, then the type is selected based on the following rule: if the field hdi_user is present, then the type is auto-sensed as hdi; otherwise, the type is set to sql.
If the technical database user does not have GRANT privileges by its own, but only EXECUTE privileges on a stored procedure which can grant the privileges, then the following settings are required:
- At the database, a GRANT procedure must exist (or be visible) in the schema which is used in the user-provided service; an example is shown below.
- The technical database user must have EXECUTE privileges on the GRANT procedure.
- The name of the GRANT procedure must be specified in the user-provided service in the
"procedure"field, e.g."procedure": "GRANT". - The scheme name of the GRANT procedure can be specified in the user-provided service in the
"procedure_schema"field, e.g."procedure_schema": "A_SCHEMA". - The user-provided service must contain a
"type"field with the value"procedure".
For the different types of privileges, the following fields are passed to the GRANT procedure:
| PRIVILEGE_TYPE | PRIVILEGE_NAME | OBJECT_SCHEMA | OBJECT_NAME | OBJECT_TYPE | GRANTEE_SCHEMA | GRANTEE_NAME | GRANTABLE |
|---|---|---|---|---|---|---|---|
| SCHEMA_OBJECT_PRIVILEGE | privilege | schema | object | NULL | NULL | grantee | TRUE/FALSE |
| GLOBAL_OBJECT_PRIVILEGE | privilege | NULL | object | type | NULL | grantee | TRUE/FALSE |
| SCHEMA_ROLE | NULL | schema | role | NULL | NULL | grantee | TRUE/FALSE |
| GLOBAL_ROLE | NULL | NULL | role | NULL | NULL | grantee | TRUE/FALSE |
| SCHEMA_PRIVILEGE | privilege | NULL | schema | NULL | NULL | grantee | TRUE/FALSE |
| SYSTEM_PRIVILEGE | privilege | NULL | NULL | NULL | NULL | grantee | TRUE/FALSE |
Note: This procedure does not work for SAP HANA1 SPS11, since REPLACE_REGEXPR is not supported. Please use the sample procedure provided with older releases of the deployer.
The old sample procedure does not correctly handle component names of system privileges in .hdbgrants files.
Example of a GRANT procedure:
CREATE PROCEDURE GRANT(
IN PRIVILEGES TABLE (
PRIVILEGE_TYPE NVARCHAR(128), -- 'SCHEMA_OBJECT_PRIVILEGE'
-- 'GLOBAL_OBJECT_PRIVILEGE'
-- 'SCHEMA_ROLE'
-- 'GLOBAL_ROLE'
-- 'SCHEMA_PRIVILEGE'
-- 'SYSTEM_PRIVILEGE'
PRIVILEGE_NAME NVARCHAR(256), -- cf. SYS.PRIVILEGES
OBJECT_SCHEMA NVARCHAR(256), -- NULL or schema
OBJECT_NAME NVARCHAR(256),
OBJECT_TYPE NVARCHAR(128), -- NULL or 'REMOTE SOURCE'
GRANTEE_SCHEMA NVARCHAR(256), -- NULL or schema
GRANTEE_NAME NVARCHAR(256),
GRANTABLE NVARCHAR(5) -- 'TRUE' or 'FALSE'
)
)
LANGUAGE SQLSCRIPT
SQL SECURITY DEFINER
AS
BEGIN
DECLARE ERROR CONDITION FOR SQL_ERROR_CODE 10000;
DECLARE CURSOR PRIVILEGES_CURSOR FOR SELECT * FROM :PRIVILEGES;
-- TODO: add checks for valid grantees, e.g. check with _SYS_DI#<group>.M_CONTAINER_SCHEMAS
-- or with SYS.USERS and creator and grantee like '%#OO'
-- TODO: keep only functionality that should be allowed, e.g. only allow to grant schema-local
-- roles, but no object privileges, etc.
FOR PRIVILEGE AS PRIVILEGES_CURSOR
DO
DECLARE TO_GRANTEE_CLAUSE NVARCHAR(512);
DECLARE GRANTABLE_CLAUSE NVARCHAR(512) = '';
IF PRIVILEGE.GRANTEE_SCHEMA IS NULL THEN
TO_GRANTEE_CLAUSE = ' TO "' || ESCAPE_DOUBLE_QUOTES(PRIVILEGE.GRANTEE_NAME) || '"';
ELSE
TO_GRANTEE_CLAUSE = ' TO "' || ESCAPE_DOUBLE_QUOTES(PRIVILEGE.GRANTEE_SCHEMA)
|| '"."' || ESCAPE_DOUBLE_QUOTES(PRIVILEGE.GRANTEE_NAME) || '"';
END IF;
IF PRIVILEGE.GRANTABLE = 'TRUE' THEN
IF PRIVILEGE.PRIVILEGE_TYPE = 'SYSTEM_PRIVILEGE' OR
PRIVILEGE.PRIVILEGE_TYPE = 'GLOBAL_ROLE' OR
PRIVILEGE.PRIVILEGE_TYPE = 'SCHEMA_ROLE' THEN
GRANTABLE_CLAUSE = ' WITH ADMIN OPTION';
ELSE
GRANTABLE_CLAUSE = ' WITH GRANT OPTION';
END IF;
ELSEIF PRIVILEGE.GRANTABLE != 'FALSE' THEN
SIGNAL ERROR SET MESSAGE_TEXT = 'unsupported value for GRANTABLE: '
|| PRIVILEGE.GRANTABLE;
END IF;
IF PRIVILEGE.PRIVILEGE_TYPE = 'SCHEMA_OBJECT_PRIVILEGE' THEN
EXEC 'GRANT "' || ESCAPE_DOUBLE_QUOTES(PRIVILEGE.PRIVILEGE_NAME) || '"'
|| ' ON "' || ESCAPE_DOUBLE_QUOTES(PRIVILEGE.OBJECT_SCHEMA)
|| '"."' || ESCAPE_DOUBLE_QUOTES(PRIVILEGE.OBJECT_NAME) || '" '
|| TO_GRANTEE_CLAUSE
|| GRANTABLE_CLAUSE;
ELSEIF PRIVILEGE.PRIVILEGE_TYPE = 'GLOBAL_OBJECT_PRIVILEGE' THEN
IF PRIVILEGE.OBJECT_TYPE = 'REMOTE SOURCE' THEN
EXEC 'GRANT "' || ESCAPE_DOUBLE_QUOTES(PRIVILEGE.PRIVILEGE_NAME) || '"'
|| ' ON ' || PRIVILEGE.OBJECT_TYPE || ' "' || ESCAPE_DOUBLE_QUOTES(PRIVILEGE.OBJECT_NAME) || '" '
|| TO_GRANTEE_CLAUSE
|| GRANTABLE_CLAUSE;
ELSE
SIGNAL ERROR SET MESSAGE_TEXT = 'unsupported value for OBJECT_TYPE for GLOBAL_OBJECT_PRIVILEGE: '
|| PRIVILEGE.OBJECT_TYPE;
END IF;
ELSEIF PRIVILEGE.PRIVILEGE_TYPE = 'SCHEMA_ROLE' THEN
EXEC 'GRANT "' || ESCAPE_DOUBLE_QUOTES(PRIVILEGE.OBJECT_SCHEMA)
|| '"."' || ESCAPE_DOUBLE_QUOTES(PRIVILEGE.OBJECT_NAME) || '" '
|| TO_GRANTEE_CLAUSE
|| GRANTABLE_CLAUSE;
ELSEIF PRIVILEGE.PRIVILEGE_TYPE = 'GLOBAL_ROLE' THEN
EXEC 'GRANT "' || ESCAPE_DOUBLE_QUOTES(PRIVILEGE.OBJECT_NAME) || '" '
|| TO_GRANTEE_CLAUSE
|| GRANTABLE_CLAUSE;
ELSEIF PRIVILEGE.PRIVILEGE_TYPE = 'SCHEMA_PRIVILEGE' THEN
EXEC 'GRANT "' || ESCAPE_DOUBLE_QUOTES(PRIVILEGE.PRIVILEGE_NAME) || '"'
|| ' ON SCHEMA "' || ESCAPE_DOUBLE_QUOTES(PRIVILEGE.OBJECT_NAME) || '" '
|| TO_GRANTEE_CLAUSE
|| GRANTABLE_CLAUSE;
ELSEIF PRIVILEGE.PRIVILEGE_TYPE = 'SYSTEM_PRIVILEGE' THEN
EXEC 'GRANT "' || REPLACE_REGEXPR('\.' IN ESCAPE_DOUBLE_QUOTES(PRIVILEGE.PRIVILEGE_NAME) WITH '"."') || '"'
|| TO_GRANTEE_CLAUSE
|| GRANTABLE_CLAUSE;
ELSE
SIGNAL ERROR SET MESSAGE_TEXT = 'unsupported value for PRIVILEGE_TYPE: '
|| PRIVILEGE.PRIVILEGE_TYPE;
END IF;
END FOR;
END;
Defining the Granting Service in the mta[d].yaml
If the container needs a granting-service, then besides the service itself, the Application Development Descriptor mta.yaml needs to be adjusted for the deployer to be able to find the service. The mta.yaml must be modified to:
- The container of the
dbmodule needs to get aTARGET_CONTAINERproperty to mark the service that corresponds to the container - A new entry in
requiresis added for the granting-service - A new entry in
resourcesis added for the granting-service
Example:
mta.yaml:
schema-version: '2.0'
ID: granting-service-example
version: 0.0.1
modules:
- name: db
type: hdb
path: db
requires:
- name: hdi-container
properties: # 1.
TARGET_CONTAINER: ~{hdi-container-service} # 1.
- name: granting-service # 2.
resources:
- name: hdi-container
type: com.sap.xs.hdi-container
properties:
hdi-container-service: ${service-name}
- name: granting-service # 3.
type: org.cloudfoundry.existing-service # 3.
Environment Variables for Applications
@sap/hdi-deploy supports (re-)configuration via the following environment variables which are exposed to applications, e.g. via the CF/XSA manifest.yml or the MTA descriptor mta.yaml:
TARGET_CONTAINER: (optional) service name that specifies the HDI target container (needed, if more than one HDI service is bound to the HDI Deployer)SERVICE_REPLACEMENTS: (optional) JSON-structured list of service replacements, e.g.[ { "key": "logical-service-name-1", "service":"real-service-name-1"}, { "key": "logical-service-name-2", "service":"real-service-name-2"} ], where the logical service names refer to the names in the HDI content and the real service names refer to the services which are bound to the HDI Deployer viaVCAP_SERVICES; if the HDI content references a service name which is not listed in the replacements, then this name is used as a real service name
The structure of the SERVICE_REPLACEMENTS environment variable is based on the MTA specification in order to enable MTA group assignments.
Example manifest.yml:
applications:
- name: app-db
path: db
health-check-type: process
services:
- app-database
- real-grantor-service
- real-external-service
env:
TARGET_CONTAINER: app-database
SERVICE_REPLACEMENTS: >
[
{
"key" : "logical-grantor-service",
"service" : "real-grantor-service"
},
{
"key" : "logical-external-service",
"service" : "real-external-service"
}
]
Environment Variables for Infrastructure / Development Tools
@sap/hdi-deploy supports (re-)configuration via the following environment variables for infrastructure / development tools like the Deploy Service or internal build tools of the WEB IDE
EXIT: (optional) if set, the HDI Deployer will exit when the deployment is done; using the environment variable is equivalent to passing a--exiton the command lineDEPLOY_ID: (optional) if set, the given id will be written to the final application log entry (custom id, to support processes in parsing log outputHDI_DEPLOY_OPTIONS: (optional) JSON-structured set of options for the HDI Deployer, e.g.{ "auto_undeploy" : true, "exit" : true }; command line options can be translated toHDI_DEPLOY_OPTIONSoptions by replacing the-s in the option names with_s; options which can accept multiple values require a JSON array with the values, e.g. path options like the include-filter option.
Example mta.yml:
_schema-version: "2.1"
ID: project
version: 0.0.1
modules:
- name: db
type: hdb
path: db
requires:
- name: hdi_db
properties:
TARGET_CONTAINER: ~{hdi-container-name}
HDI_DEPLOY_OPTIONS: >
{
"validate_external_dependencies": false,
"treat_unmodified_as_modified": true,
"exit": true,
"include_filter": ["src/", "cfg/"]
}
...
APPLICATION_ID: (optional, fallbackSAP_HDI) this will be used, in conjunction with thespace_nameand theorganization_nameof theVCAP_APPLICATIONto set the session variableAPPLICATIONfor all connections to the database. This setting may only be used by applications from SAP.APPLICATION_VERSION_INFO: (optional) this will be logged to the command line, to allow logging of some additional information about the application.
Options from HDI_DEPLOY_OPTIONS and the command line are merged. HDI_DEPLOY_OPTIONS have priority over options from the command line.
Ignore List
The hdi deployer supports ignoring certain files via an .hdiignore file. The file has to be placed at the root of the project folder, just like the undeploy.json.
The file has a structure similar to a .gitignore file, simply lines of texts specifying the paths to exclude. Both "real" paths and path patterns are supported.
src/table_1.hdbtable
src/*_2.hdbtable
The file works just like the --exclude-filter option and they can be used at the same time.
Options for Interactive Scenarios
@sap/hdi-deploy supports the following options for interactive deployment scenarios, e.g. for orchestration via the WEB IDE or for CI scripts:
--version: print version and exit-t, --trace: enable tracing--use-hdb: enable the "hdb" client to connect to the database instead of "@sap/hana-client"; by default "@sap/hana-client" is used--hana-client-trace: enable tracing for the SAP HANA client; All interactions with the SAP HANA server will be traced which can lead to a large amount of trace information to be written--hana-client-packet-trace: enable PACKET tracing for the SAP HANA client; Must only be used in combination with --hana-client-trace--[no-]verbose: [don't] print detailed log messages to the console--skipped-deleted-files-log <filepath> | local | stdout: [filepath] write skipped deleted files (that are not listed in undeploy.json) to the file indicated by the file path. The file must not exist; [local] create a new file called skippedDeletedFiles.json in the deployer working directory and write the deleted files into it. [stdout] write the deleted files to the standard output.--structured-log <file>: write log messages as JSON objects into the given file; messages are appended if the file already exists--[no-]exit: [don't] exit after deployment of artifacts--[no-]lock-container: [don't] acquire the container lock while working with the container--root <path>: use the given root path for artifacts--working-set [<path> ..]: define the given paths (directories and files) as the working set; a non-default working set applies additional restrictions, e.g. other options might be disallowed--include-filter [<path> ..]: only include the given paths (directories and files) during delta detection--deploy [<file> ..]: explicitly schedule the given files for deploy; extends theinclude-filterfor collecting local files. Instead of a real path, a path pattern like src/**/*.hdbtable can be used as well.--[no-]treat-unmodified-as-modified: [don't] treat unmodified files during delta detection as modified files--undeploy [<file> ..]: explicitly schedule the given files for undeploy--parameter [<key>=<value> ..]: pass the given list of key-value parameters to the deployment--path-parameter [<path>:<key>=<value> ..]: pass the given list of path-key-value parameters to the deployment--[no-]auto-undeploy: [don't] undeploy artifacts automatically based on delta detection and ignore theundeploy.jsonfile--[no-]treat-warnings-as-errors: [don't] enable server-side feature for treating warnings as errors--[no-]treat-deployer-warnings-as-errors: [don't] enable deployer-side feature for treating warnings as errors--[no-]validate-external-dependencies: [don't] start a make, even if no files are in the deploy/undeploy sets; all deployed synonyms, projection views, and virtual tables in the container will be checked for changes to referenced objects and redeployed, if a change is detected.--[no-]simulate-make: [don't] simulate the make and skip post-make activities; pre-make activities still take effect, e.g. grants--[no-]stop-on-error: [don't] collect as many erros as possible during the deployment--connection-timeout <ms>: number of milliseconds to wait for the database connection(s)--delete-timeout <ms>: number of milliseconds to wait for the DELETE call--write-timeout <ms>: number of milliseconds to wait for the WRITE call--async-make-timeout <ms>: number of milliseconds to wait for the async make job to finish when--async-makeis active; by default 1800000 ms (30 minutes)--lock-container-timeout <ms>: number of milliseconds to wait for the container lock--exclude-filter [<path> ..]: exclude the given paths during: file walk, delta detection and when explicitly scheduled via --(un)deploy--[no-]optimise-file-upload: [don't] perform delta detection via local SHA256 calculation instead of DELETE and WRITE calls. Will not have any positive effect when used along with --treat-unmodified-as-modified.--[no-]delta-detection: [don't] perform delta detection. The--no-delta-detectiondeploys only what passed in --deploy parameter and undeploys what passed in --undeploy parameter. The--no-delta-detectioncan be combined with the--exclude-filter. However, it will not have any beneficial effect when used with the--optimise-file-upload,--include-filter, or--treat-unmodified-as-modifiedoptions.--[no-]treat-wrong-ownership-as-errors: [don't] treat wrong ownership of objects as errors, not enabled by default--[no-]migrationtable-development-mode: [don't] pass the development mode flag for migration tables to HDI, if the parameter is supported by the server, not enabled by default--[no-]liveness-ping: [don't] send a sign of life from time to time, by default, a sign of life will be sent--[no-]live-messages: [don't] display the make messages while the make is still in progress, by default, the messages will be displayed while the make is in progress--[no-]async-make: [don't] useMAKE_ASYNCinstead ofMAKEfor the HDI make step; prevents connection timeouts for very long-running deployments; by default, the synchronousMAKEis used--[no-]trace-vcap-services: [don't] log VCAP services information, by default, the following VCAP services properties will be logged: name, label, plan, tags, schema, database_id, user, hdi_user, and service_key_name (with --trace, the rest of the properties will also be logged)--write-batch-size <integer>: number of files to write in one batch. Must be a positive integer. Default: 8000
See --help for details and defaults.
Options can also be passed to @sap/hdi-deploy via the HDI_DEPLOY_OPTIONS environment variable. Options from HDI_DEPLOY_OPTIONS and the command line are merged. HDI_DEPLOY_OPTIONS have priority over options from the command line.
Supported Features
@sap/hdi-deploy exposes its set of features via the info option, which can be passed as --option or via HDI_DEPLOY_OPTIONS, e.g.
node deploy --info [<component> [<component> [...]]]
where a list of components can be specified.
The info option allows to pass multiple components. The info request for these components is optional, e.g. if the HDI Deployer doesn't support the component, then it will not throw an error, but simply not return information for that component. The special component all will return the information for all known components; all is the default if no component is specified. For certain future components, e.g. server, the HDI Deployer might need to connect to the HDI container in the database and retrieve feature information from there.
Examples:
node deploy --info all
node deploy --info client server
The result of an info call is a JSON document where the top-level objects correspond to the requested components. Each component should at least report its name, its version, and the set of supported features with name and version number (version numbers are simple numbers (no dots, no double-dots)).
If a version number is negative, then the feature is supported by the client, but not supported by the server.
For a --info client call, the document looks as follows:
{
"client": {
"name": "@sap/hdi-deploy",
"version": "5.7.0",
"features": {
"info": 2,
"verbose": 1,
"structured-log": 1,
"lock-container": 1,
"default-access-role": 1,
"grants": 4,
"working-set": 1,
"include-filter": 1,
"deploy": 1,
"treat-unmodified-as-modified": 1,
"undeploy": 1,
"parameter": 1,
"path-parameter": 1,
"treat-warnings-as-errors": 1,
"validate-external-dependencies": 1,
"simulate-make": 1,
"service-replacements": 1,
"modules": 2,
"config-templates": 2,
"environment-options": 1,
"undeploy-allowlist": 1
}
}
}
For the server component, the document would also contain the following data:
{
...
"server": {
"name": "sap-hana-database",
"version": "1.00.120.04.0000000000",
"features": {}
}
}
Deployment via hdi-dynamic-deploy
The standard XSA/CF way for deploying HDI content at runtime is to make use of @sap/hdi-dynamic-deploy instead of @sap/hdi-deploy directly. The @sap/hdi-dynamic-deploy app is an http server that calls @sap/hdi-deploy when it receives a corresponding HTTP POST request. See the @sap/hdi-dynamic-deploy module for more information.
Using hdi-deploy as a Node.js library
Since version 3.3.0 of @sap/hdi-deploy it is also possible to use it as a Node.js library. By requiring the library.js file from the project root it is possible to start the deployer app from within another Node.js app. The module exports the function
function deploy(contentDir, deployerEnv, callback, io)
with the following parameters:
contentDir: string containing a path pointing to the root of the db module to be deployeddeployerEnv: javascript object containing the OS environment for the call to the deployer (e.g. containing VCAP_SERVICES)callback: a standard callback of the form (errors, result), where result is the result of the call to the deployer of the form:
{
messages: [<list of result messages from the di server>],
exitCode: <exit code of the call to the deployer app, one of -1, 0, 1.>,
signal: <signal that the child process was closed with>
}
io(optional): javascript object containing two callback functionsio.stdoutCBandio.stderrCBof the formfunction(data)for streaming stdout and stderr of the call to the deployer, defaults to piping stdout and stderr of the deployer to stdout and stderr of the calling Node.js app
The exit codes have different meanings:
- -1: The child process was most likely killed externally, check the signal property for details.
- 0: Deployment done succesfully.
- 1: Deployment failed, errors occurred.
The signal property is only set, if exitCode is -1.
History
Other 6
Notes
Features:
- Added support for
grant_using_groupandrevoke_using_groupin.hdbgrantsand.hdbrevokesfiles - Added option
--async-maketo run the HDI make operation asynchronously - Added structured logging support in dynamic deploy (library mode)
- Use @sap/hdi@^4.8.1
Fixes:
- Fixed license field in package.json to use npm-standard format for proper recognition by SCA tools
- Updated license to SAP Developer License Agreement version 3.2
Other 2
Notes
Fixes:
- Fixed X.509 certificate authentication issue
- Patched an issue classified under CWE‑89 (SQL injection vulnerability)
Other 3
Notes
Features:
- Added support for the
VCAP_SERVICES_FILE_PATHenvironment variable - Enhancements in VCAP_SERVICES logging
- Use @sap/xsenv@^6.0.0
- Added support for the
Other 2
Notes
Features:
- Fail with error if credentials.schema property is not a string
Fixes:
- Error: write EPIPE
Other 4
Notes
Features:
- Added option
--write-batch-size <integer> - Use @sap/hdi@^4.8.0
- hdb@^2 support
Fixes:
- Error: EMFILE, too many open files
- Added option
Other 2
Notes
Features:
- Added support for certificate authentication
Fixes:
--optimise-file-uploaderror: "Cannot read properties of undefined (reading 'digest')"
Other 8
Notes
Features:
- Set
--optimise-file-uploadoption to true by default - Added option
--[no-]delta-detectionto enable [don't] perform delta detection - Added implicit fallback to hdb client
- Node >=18.x support
- use @sap/hdi@^4.7.0
Fixes:
- Merge parameters from command line and HDI_DEPLOY_OPTIONS
- Log skipped delted filepath instead of filename
- Added support for HANA Cloud tenants credential format
- Set
Other 1
Notes
Fixes:
- added reference property to validation checks of privilege names and their properties in .hdbgrants and .hdbrevokes files
Other 4
Notes
Features:
- added option
--treat-deployer-warnings-as-errorsto enable deployer-side feature for treating warnings as errors - enhanced liveness ping status messages
Fixes:
- fixed error message truncation in hdicallback
- use @sap/xsenv@5.2.0
- added option
Other 5
Notes
Features:
- added warning message if explicit parameters passed on the command line are overwritten by parameters specified in HDI_DEPLOY_OPTIONS
- provide
--skipped-deleted-files-log <filepath> | local | stdoutoption to log deleted files that are not in undeploy.json
Fixes:
- use micromatch@4.0.7
- use dotenv@16.4.5
- use @sap/xsenv@5.1.0
Other 1
Notes
Fixes:
- fixed accessing undefined data from readableBuffer when using the --optimise-file-upload option
Other 3
Notes
Features:
- validation checks to ensure the correctness of privilege names and their properties in .hdbgrants and .hdbrevokes files.
- enhanced global object privileges with additional support
Fixes:
- fixed accessing undefined data from readableBuffer when using the --optimise-file-upload option
Other 7
Notes
Features:
- Moved hana-client and hdb from dependencies to peerDependencies to allow choice of using either hana-client or hdb.
- hana-client ^2 >= 2.6 support
- hdb ^0 support
- use dotenv@16.3.1
- use handlebars@4.7.8
- use micromatch@4.0.5
Removed:
- Node 12.x, 14.x, and 16.x support
Other 2
Notes
Fixes:
- fixed accessing undefined data from readableBuffer when using the --optimise-file-upload option
- use @sap/hana-client@2.20.15
Other 1
Notes
Fixes:
- fixed accessing undefined data from readableBuffer when using the --optimise-file-upload option
Other 2
Notes
Features:
- only log VCAP_SERVICES of hana service or user-provided service with hana tag
- use @sap/hana-client@2.19.18
Other 7
Notes
Features:
- use @sap/hana-client@2.17.21
- log deleted files before applying undeploy.json
- added option --stop-on-error to stop deploying further files after an error occurs while deploying a file
- merge custom parameters passed via --parameter instead of overriding
Fixes :
- log all errors in stderr instead of stdout
- fix extra space while logging delta time
- set default hdb timeout to 1000 ms
Other 6
Notes
Features:
- use @sap/hana-client@2.16.21
- log cloud version when server is hana cloud
- added support for granting/revoking service in kyma
Fixes :
- log grantor/revoker type used when throwing unknown grantor type error
- log detailed error messages when write call fails
- ensure that the complete VCAP_SERVICES are logged without
--trace
Other 3
Notes
Features:
- use @sap/hana-client@2.13.22
- added option --optimise-file-upload to perform delta detection via local SHA256 calculation instead of DELETE and WRITE calls
- Node 18.x support
Other 2
Notes
Features:
- added option --use-hdb to enable using hdb client instead of @sap/hana-client for connecting to the database
- use @sap/hana-client@2.12.25
Other 4
Notes
Features:
- use @sap/hdi@4.3.1
- use @sap/hana-client@2.12.20
- use async@3.2.3
Fixes :
- handle empty user-provided services
Other 5
Notes
Features:
- added support for retrieving credentials from kubernetes
- use @sap/hdi@4.3.0
- use @sap/hana-client@2.11.20
Fixes:
- log long lists without truncation
- fixed passing arbitrary parameters to @sap/hana-client
Other 3
Notes
Features:
- allow passing arbitrary parameters to @sap/hana-client
- use @sap/hdi@4.2.0
- use @sap/hana-client@2.10.20
Other 4
Notes
Features:
- added option
--hana-client-traceto enable tracing for the SAP HANA client interactions with the SAP HANA server - added option
--hana-client-packet-traceto enable packet tracing for the SAP HANA client interactions with the SAP HANA server - added custom listeners to handle SIGBUS errors
Fixes:
- log client messages and errors to structured log
- added option
Other 6
Notes
Features:
- allow wildcard paths in the undeploy.json file to enable the undeployment of a set of files without having to specify every single file
- added, modified, deleted and "treated as modified" files are logged during deployment
- use @sap/hdi@4.1.0
- use @sap/hana-client@2.9.28
- Node 16.x support
Removed:
- Node 8.x and 10.x support
Other 6
Notes
Features:
- provide
--validate-external-dependenciesoption to always start a make, even if no files are in the deploy/undeploy sets - change wording for
"whitelist"to"allowlist" - use @sap/hdi@4.0.2
- use @sap/hana-client@2.8.20
- added support for reading a
.envfile in the absence ofdefault-env.jsonfile
Fixes:
- with
--trace, ensure that the complete VCAP_SERVICES are logged
- provide
Other 3
Notes
Features:
- use @sap/hdi@4.0.1
- use @sap/hana-client@2.7.26
Fixes:
- corrected improper representation of time in log
Other 2
Notes
Fixes:
- ensure all the messages returned by library.js are structured
- stricter tag validation
Other 3
Notes
Features:
- use @sap/hdi@3.0.2
- use @sap/hana-client@2.7.21
- log start and end time of deployments
Other 4
Notes
Features:
- use @sap/hdi@3.0.1
- use @sap/hana-client@2.7.16
- Node 14.x support
Removed:
- Node 6.x support
Other 1
Notes
Fixes:
- set default for --delete-timeout and --write-timeout to 15 minutes instead of 15 seconds
Other 1
Notes
Features:
- introduce options --delete-timeout and --write-timeout, that can be used to set a timeout for the DELETE and WRITE HDI calls.
Other 5
Notes
Features:
- better logging of WRITE/DELETE calls
Fixes:
- update dependencies
- only handle "CDS METADATA" on non-HANA Cloud systems
- always log errors to the parent process when using library.js
- gracefully handle "trace":false via HDI_DEPLOY_OPTIONS
Other 2
Notes
Changes:
- segfault-handler is no longer installed as a optional dependency - needs to be provided via parallel installation if required
Fixes:
- check the return code of HDI API calls to correctly detect errors
Other 1
Notes
Fixes:
- close all connections before calling process.exit() to work around sporadic segmentation fault
Other 3
Notes
Features:
- node 12 support
Fixes:
- updated dependencies
- gracefully handle a missing grantor service when using library.js
Other 2
Notes
Fixes:
- remove duplicate messages when using the deployer as a library
- update dependencies
Other 2
Notes
Fixes:
- when used as a library, do not exit until all messages have been sent to the parent process
Features:
- use hana-client 2.4.162
Other 6
Notes
Features:
- added option
--liveness-pingto periodically send a signal that notifies the user that the deployer is still working - added option
--live-messagesto display the make messages while the make is still in progress - added function
clean-envtolibrary.jsto allow cleaning a passed environment of all deployer-related variables
Fixes:
library.jswould sometimes return withexitCodenull because of unexpected closing of the child process- update dependencies
- add missing options to HDI_DEPLOY_OPTIONS
- added option
Other 1
Notes
Fixes:
- add full support for .hdbmigrationtable files by adding the --[no-]migrationtable-development-mode flag
Other 3
Notes
Fixes:
- the private key used for mutual authentication was logged if tracing is enabled
- mutual auth was missing on some database connections
- some database connections were not closed correctly
Other 11
Notes
Features:
- allow passing ssl connection parameters in service binding
- allow mutual auth via parameters in service binding
- set session variable APPLICATION on all HANA connections
- support path parameters for HDI
- allow development debug role similar to the default access role
- update @sap/hdi dependency
- better handling of invalid undeploy.json files
- improved timestamps in logging output
- check ownership of objects in the container via --treat-wrong-ownership-as-errors
- allow logging of additional application data
Fixes:
- issue with schema privileges and global roles in the same .hdbgrants file
Other 12
Notes
Features:
- introduced .hdbrevokes as a counterpart to .hdbgrants
- automatically find target service: if only one HDI service is bound, TARGET_CONTAINER does not have to be set
- print timestamp of HDI messages
- print the status of the last build
- fallback to the .hdiconfig in src/ if it is missing in cfg/
- switch to @sap/hdi 2.1.2
- switch from hdb to @sap/hana-client
- check if the container supports locking and skip it if not
Fixes:
- support \n and \r\n as line endings in .hdiignore files
- correctly process grantor files in ZDM mode
- fix 'Maximum call stack size exceeded' in ZDM mode
- don't escape schema names in .hdbgrants
Other 9
Notes
Features:
- warning messages will now be prepended with "WARNING:"
- error messages in case of a bad service binding now offer more detail on what caused the error
- now supports comments in JSON files like default services file
- allow file patterns in --deploy option
- added new options --exclude-filter and .hdiignore file that basically work like .gitignore
- improved error reporting when using the deployer as a library
Fixes:
- correctly handle component names of system privileges in .hdbgrants files
- handle empty privilege objects
- filter client files like .hdbgrants before deploying
Other 3
Notes
Features:
- support ZDM deployment of HDI artifacts modeled in data/ and access/ folders inside db module
- support ZDM deployment of .hdbrole files in access schema
- target service is logged during deployment
Other 2
Notes
Features:
- support ZDM deployment
- added warning message when using .hdbsysnonymtemplate or .hdbsynonymgrantor
Other 5
Notes
Features:
- provide
--treat-unmodified-as-modifiedoption to schedule also unmodified for deploy - support procedure-type granting services
- improve Readme
Fixes:
- fix handling of grantor services which have a
db_hostsvalue, but nohostvalue - fix occasional 'Callback was already called' error in case of deployment failures
- provide
Other 2
Notes
Features:
- provide library.js to fork the deployer from a node.js app for a given content directory including support for stdio callbacks
Fixes:
- don't look at server folders outside cfg/, src/, and lib/
Other 2
Notes
Fixes:
- use
db_hostsfromVCAP_SERVICESif it exists - transform paths from
--include-filter,--deploy,--undeploy,--working-setto the server format where reusable modules are located atlib/instead ofnode_modules/
- use
Other 3
Notes
Features:
- support
--parameteroption to pass key-value parameters to the deployment
Fixes:
- use non-sync write to stdout (and stderr), and on exit, wait until stdout is drained to avoid loss of log output in case of crashes, etc.
- container locking is available since server version 2.0.1.0, not 2.0.0.0
- support
Other 19
Notes
Features:
- check
src/defaults/default_access_role.hdbrolefile against the working set - check
.hdbgrantsfiles against the working set - show the processing of individual
.hdbgrantsfiles - on newer server versions, acquire the container lock while working with the container
- support
--lock-container-timeout <ms>option for setting the number of milliseconds to wait for the container lock, defaults to 120.000 ms - also support grantor services with only
"user","password","schema"; and take"host","port","certificate"from the target container - in
.hdbgrantsfiles, use the first non-undefined schema value ("schema","reference","schema"from grantor service);"reference"is only used for"schema_privileges" - support schema roles in
.hdbgrantsfiles - reject explicit delta detection of files outside the working set
- switch to Node.js 6.9.1 as minimal Node.js version
- provide
--working-setoption to restrict the set of files which can be modified in the container - support global roles with admin option in
.hdbgrantsfiles - support system privileges with admin option in
.hdbgrantsfiles - support
--connection-timeout <ms>option for setting the number of milliseconds to wait for the database connection(s)
Fixes:
- lock the container before showing the
synchronizingmessage - support
.hdbgrantsfiles without a name (folder/.hdbgrants) - support the string-array style in schema_roles, too
- support typed global object privileges in
.hdbgrantsfiles - correctly pass certificate to hdi client
- check
Other 3
Notes
Fixes:
- fix schema name handling to allow schema names with special characters
- fix handling of more than 1 privilege in a single element in
.hdbgrantsfiles - fix trace handling for VCAP_SERVICES and connection data
Other 14
Notes
Features:
- detect server version; provide
--[no-]detect-server-versionoption - invert client feature version numbers if they are not available due to the detected server version
- support
serverin--info - generalize handling of configuration file templating for
cfg/**/*configfiles - provide
--structured-logoption to send messages in a JSON-structured format into a log file - provide
--[no-]verboseoption to suppress detailed messages at the console output - allow consumption of reusable database modules via
package.jsonandnpm install - provide
--simulate-makeoption to enable server-side feature for simulating the make activities - provide
--treat-warnings-as-errorsoption to enable server-side feature for treating warnings as errors - provide
--deployoption to explicitly include a set of files in the deploy set - provide
--undeployoption to explicitly include a set of files in the undeploy set
Fixes:
- reject
--simulate-makeand--treat-warnings-as-errorsif the server doesn't support these features - consider the root path when looking for reuse modules
- throw an error if we find a nested node_modules folder inside a reuse module
- detect server version; provide
Other 4
Notes
Fixes:
- pass the certificate from the service binding down to the database (
certificatefield in the binding,cafield in the database connection) - fix handling of file templating in
cfg/folder and include-filter handling on Windows - fix handling of multiple roles in
container_roleselements in.hdbgrantsfiles - fix handling of
.hdbgrantsfiles with more than 1 grantors inside
- pass the certificate from the service binding down to the database (
Other 20
Notes
Features:
- allow
.hdbgrantsas suffix for privilege grants / grantor mechanism files - apply consistency check on file
src/defaults/default_access_role.hdbrole - show information about used service replacements
- reworked reporting of hdideploy.js errors and HDI errors/warnings
- refactored JSON parser handling
- automatic assignment of the deployed role
default_access_roleif the filesrc/defaults/default_access_role.hdbroleis in the processing file set - provide
--infooption to show supported features - provide timing information for certain actions, e.g. time spent for collecting files, time spent for synchronizing files with the server, etc.
- provide
--include-filteroption to define a filter for restricting the set of files which are processed by the deployer app for deploy/undeploy - allow the indirection of service names via a
SERVICE_REPLACEMENTSenvironment variables - provide a generic templating mechanism for
cfg/**/*configfiles, replacing thehdbsynonymtemplatefiles - support
default-services.jsonanddefault-env.jsonfor local development - show information about the effects of the
undeploy.jsonfile - always show application name plus version number; for support cases
- always consider all deploy directories, even if they do not exist locally
- write the log message
Application can be stopped.only once - ignore errors when deleting non-existing directories
- show information about the steps that are performed
- provide
--[no-]strip-cr-from-csvoption to [not] strip carriage return characters from CSV files; not enabled by default anymore
Fixes:
- don't report a missing
undeploy.jsonfile as an error
- allow
Other 5
Notes
Features:
- replace
--autoUndeploywith--auto-undeploy; keep--autoUndeployfor backwards compatibility - provide
--no-auto-undeployoption to revert--auto-undeploy - provide
--rootoption - provide
--exitand--no-exitoptions - allow to pass options via JSON structured
HDI_DEPLOY_OPTIONSenvironment variable
- replace
Others providing
- @cap-js-community/common@cap-js-community/commonSix independent features for CAP services in one package: replication cache, migration check, rate limiting, a Redis client broker, a local HTML5 repository and a CDM builder.community org, capSix CAP features in one package, from replication cache to rate limits
- cds-dbmcds-dbmA delta deployment and migration tool for CAP on PostgreSQL that diffs the live schema against a reference schema with Liquibase and applies the change, never dropping tables by default.independent, capDelta deployment and migrations for CAP database adapters
- @quadrio/cds-dbm@quadrio/cds-dbmA published fork of cds-dbm — deploy, load, diff and drop as CDS command-line tasks for relational databases the core does not natively support.independent, capFork of cds-dbm with deploy, load, diff and drop tasks
- @sap/cds-mtxs@sap/cds-mtxsMultitenancy, tenant provisioning and model extensibility for CAP.sap official, capMultitenancy, tenant provisioning and extensibility for CAP
- @sap/cds@sap/cdsThe CAP Node.js runtime, which compiles the CDS model, serves the services declared in it, answers generic requests before any handler runs, and loads every cds-plugin.sap official, capCAP Node.js runtime
- cds-federation-synonymscds-federation-synonymsAn experimental CAP plugin for CAP-to-CAP data federation over SAP HANA synonyms, so one project reads another's tables without the rows being copied.sap official, capCAP-to-CAP data federation over SAP HANA synonyms
- @sap/cds-dk@sap/cds-dkThe command line client and development toolkit for CAP projects, with the commands cds build, cds deploy, cds watch and cds add among them.sap official, capCommand line client and development toolkit for CAP
- @sap/cds@sap/cdsThe CAP Node.js runtime, which compiles the CDS model, serves the services declared in it, answers generic requests before any handler runs, and loads every cds-plugin.sap official, capCAP Node.js runtime
- SAP-samples/hana-developer-cli-tool-exampleSAP-samples/hana-developer-cli-tool-exampleA developer-centric command line for SAP HANA, built for local development outside SAP tooling and connecting to a local, cloud or remote HANA instance the same way.sap official, btpDeveloper-centric command line for SAP HANA
Details
Sources
Sources are graph entities: the same page may back several entries, and an unreachable source flags every row that rests on it.
Compatibility and provenance
History in the atlas
- Hand-fed from its npm page. Written from the 5.7.0 README and changelog as published on the registry, and from capire's SAP HANA guide for how cds deploy uses it, all read today.
- First seen.
For your agent
- Ref
artifact:sap-hdi-deploy- JSON
- /artifacts/sap-hdi-deploy.json
- MCP
- Connecting an agent