service-prov
Installation
The REST API can be installed on RPM-based Linux distributions.
RPM Installation
To start, either obtain a rpm package file from Dispersive or set up the Dispersive JFrog yum repository for 4.3.0. Tim Smith or Scottie Higgins can help set up JFrog for your organization.
If you have a physical rpm file, run the following (replacing the rpm filename with your actual filename):
rpm -ivh ./dvn-service-prov-4.3.0.00147-1.el7.x86_64.rpm
If you are connected to the yum repository, run the following:
yum install dvn-service-prov
RPM File List
The following files will be installed on the machine:
/usr/lib/systemd/system/dvn-service-prov.service
/usr/local/dispersive
/usr/local/dispersive/RELEASE
/usr/local/dispersive/bin
/usr/local/dispersive/bin/service-prov
/usr/local/dispersive/certificates
/usr/local/dispersive/certificates/dart.key
/usr/local/dispersive/certificates/dart.pem
/usr/local/dispersive/certificates/server-cert.pem
/usr/local/dispersive/certificates/server-key.pem
/usr/local/dispersive/config.json
/usr/local/dispersive/logs
/usr/local/dispersive/logs/README.md
/usr/local/dispersive/public/doc/favicon-16x16.png
/usr/local/dispersive/public/doc/favicon-32x32.png
/usr/local/dispersive/public/doc/index.html
/usr/local/dispersive/public/doc/oauth2-redirect.html
/usr/local/dispersive/public/doc/service-prov.yml
/usr/local/dispersive/public/doc/swagger-ui-bundle.js
/usr/local/dispersive/public/doc/swagger-ui-bundle.js.map
/usr/local/dispersive/public/doc/swagger-ui-es-bundle-core.js
/usr/local/dispersive/public/doc/swagger-ui-es-bundle-core.js.map
/usr/local/dispersive/public/doc/swagger-ui-es-bundle.js
/usr/local/dispersive/public/doc/swagger-ui-es-bundle.js.map
/usr/local/dispersive/public/doc/swagger-ui-standalone-preset.js
/usr/local/dispersive/public/doc/swagger-ui-standalone-preset.js.map
/usr/local/dispersive/public/doc/swagger-ui.css
/usr/local/dispersive/public/doc/swagger-ui.css.map
/usr/local/dispersive/public/doc/swagger-ui.js
/usr/local/dispersive/public/doc/swagger-ui.js.map
/usr/local/dispersive/public/pw_reset_email.html
/usr/local/dispersive/public/service-prov.postman_collection.json
These files consist of the main binary as well as supporting files. Some important files to note:
| FIle | Purpose |
|---|---|
| dvn-service-prov.service | systemd service file |
| service-prov | compiled binary application |
| server-cert.pem & server-key.pem | TLS certificate + private key for the listening webserver |
| config.json | primary means of configuring the service, very important file |
| service-prov.postman_collection.json | a JSON Postman v2 collection of API requests - useful for testing |
Configuring the API
Unlike previous versions of our API, the new service-prov can communicate with any and all of the controllers at the same time. In the past, if you had a 3 controller cluster on your network, you would need 1 instance of REST for each controller. Now you can create 1 instance of service-prov and communicate with all controllers (and all VTCs) at once.
The config.json file located in the /usr/local/dispersive directory contains the necessary instructions for the API. An example file is shipped with the RPM installer. The example file has usernames and passwords saved in an decrypted format. Upon running service-prov for the first time, any sensitive data (usernames and passwords) will be encrypted and re-written back to the file, allowing the API to read the values on a restart but preventing anyone from stealing information from the file.
The config.json contains several important configuration sections.
Host
"host": {
"address": "0.0.0.0",
"port": "3004"
}
The host section controls how the API listens for incoming request. You can set the address field to 127.0.0.1 to allow only local machine connections, or 0.0.0.0 to allow connections on any of the NICs on the machine. The port simply controls which port the API will listen on. The default is 3004.
JWT
"jwt": {
"sessionTimeoutHours": 4,
"signingKeyLength": 32,
"generateNewOnStartup": false
}
The new provisioning tools use secure JWTs (JSON Web Tokens) to authenticate. This section of the API allows you to specify the duration (in hours) that a token will remain valid. The signing key length (in characters) can also be specified. The default value of 32 is secure and well-tested. Finally, the generateNewOnStartup property configures whether or not a new JWT is used every time the service-prov application restarts. Setting this value to true would be a way to instantly invalidate all existing session tokens by simply restarting the service.
provDb
"provDb": {
"database": "dvn",
"hosts": [
{
"host": "10.10.4.200",
"port": "3306"
}
],
"user": "root",
"password": "something!",
"useTls": false,
"caCertFile": "/etc/mysql-ssl/ca-cert.pem",
"clientCertFile": "/etc/mysql-ssl/client-cert.pem",
"clientKeyFile": "/etc/mysql-ssl/client-key.pem"
}
This section controls connecting to the provisioning database. If your database is a part of a Percona cluster, you can specify all hosts inside of the hosts array. If the connection to the first host is lost, the next host will be tried and so on (until the service runs out of hosts to check). User and password are the only required fields (which will be encrypted once the service starts). If your database uses TLS/SSL certificates to make connections, you can specify the certificate files above and change the useTls option to true. If the value is left as false then the certificate file options are ignored.
halDb
"halDb": {
"database": "hal",
"hosts": [
{
"host": "10.10.4.200",
"port": "3306"
}
],
"user": "root",
"password": "something!",
"useTls": false,
"caCertFile": "/etc/mysql-ssl/ca-cert.pem",
"clientCertFile": "/etc/mysql-ssl/client-cert.pem",
"clientKeyFile": "/etc/mysql-ssl/client-key.pem"
}
This section controls connecting to the Historical Alarms database. If your database is a part of a Percona cluster, you can specify all hosts inside of the hosts array. If the connection to the first host is lost, the next host will be tried and so on (until the service runs out of hosts to check). User and password are the only required fields (which will be encrypted once the service starts). If your database uses TLS/SSL certificates to make connections, you can specify the certificate files above and change the useTls option to true. If the value is left as false then the certificate file options are ignored.
controllers
"controllers": {
"hosts": [
{
"id": "dsx01",
"host": "10.10.4.200",
"port": "49010"
},
{
"id": "dsx02",
"host": "10.10.4.201",
"port": "49010"
},
{
"id": "dsx03",
"host": "10.10.4.202",
"port": "49010"
}
]
}
The controllers object defines a array called hosts. Each object inside of the hosts array must consist of an id, a host, and a port. These values should match the actual values of your controllers. Id must be the controller id as defined in our provisioning database. The host should be the ip address of the controllers (it can be 127.0.0.1 if the service is co-located with a controller). The port is the admin port which the API will used to securely communicate with the controllers. It is necessary to include all of your controllers in this array. This will allow you full access to your system. Failing to include all controllers in your system will make pieces of the API and Orchestrator function improperly and incompletely.
Running the API
The API service can be run with standard systemd controls:
systemctl start dvn-service-prov # start the service
systemctl stop dvn-service-prov # stop the service
systemctl restart dvn-service-prov # restart the service
systemctl enable dvn-service-prov # enable upon reboot
Logs
Live output from the service can be monitored using journalctl:
journalctl -u dvn-service-prov # view complete service output in a text editor
journalctl -u dvn-service-prov -f # tail and stream the output
The logs are also written to disk, and the logs can be found inside of the /usr/local/dispersive/logs directory. Logs are rotated automatically by the API. See /usr/local/dispersive/logs/README.md for details.
Updating the API
Updating the API is very simple.
From a physical package file (replace filename here with your actual file):
rpm -Uhv ./dvn-service-prov-4.3.0.00147-1.el7.x86_64.rpm
Using the yum repository:
# update cache first, and then:
yum update dvn-service-prov
The RPM package should automatically restart the service for you.
Notes
Encrypted Configuration File
When the API is run, it will check the config.json file for a key with the title credentialsEncrypted. If this key is missing or is set to false, then the API will interpret all username and password fields as non-encrypted plaintext. If the field is set to true, then the service will read the encrypted values, decrypt them internally, and use the actual values. This allows sensitive information to be stored safely. As an example, the provisioning database section might look something like this after the service has encrypted the login credentials:
...
"credentialsEncrypted": "true",
"provDb": {
"database": "dsx_db",
"hosts": [
{
"host": "192.168.77.28",
"port": "3306"
}
],
"password": "e7ad173ce45b0baf-084e1c14a90c9fb2c52ec41c-28b3715a5d56184d48ec602f6d32686d",
"user": "70e46adaafefe18a-5a0f461ac31fb61635029c10-901e5534226a1134a00f17ab71e12c5f5b88d1cf"
},
...
Custom Certificates
In your environment, it's very likely that our default self-signed development certs won't provide the security and peace-of-mind that you're looking for when making secure connections to the API. It is very easy to update these:
cd /usr/local/dispersive/certificates
mv </path/to/your/certfile> /usr/local/dispersive/certificates/server-cert.pem
mv </path/to/your/keyfile> /usr/local/dispersive/certificates/server-key.pem
systemctl restart dvn-service-prov
Note that when you move in your files they must keep the names server-cert.pem and server-key.pem for the API to recognize them.
Firewalls and Ports
If you want your API to be accessible from other machines, you'll need to allow incoming connections on the port you defined in the host section in the configuration files. Additionally, to function properly, the API needs to be able to make connections to the database on each node of the Percona cluster (or just the single database in a non-cluster environment) and needs to be able to make connections on the admin port of each controller.
For example, let's say I have 3 machines. Each machine hosts 1 node of my Percona cluster and 1 DVN controller. On each of those 3 machines, I should whitelist incoming connections on the database port (MySQL defaults to 3306) and the admin port. To enhance security, you can use rich firewall rules to restrict these incoming connections to the source IP address of the service-prov host machine.
Special Characters in API Calls
Certain routes in the API calls place the IDs of certain objects in the url as path or query parameters. For any objects that contain special characters in the name (e.g. spaces, ?, &, !, etc.), the url needs to be URI encoded before it is sent to the API. There are many tools and libraries for doing this. Note that the Orchestrator performs this automatically for any API calls.