Trove/TroveSSL

Description
Most datastores have support for SSL connections from clients. We should use that.

Deployers should have an option of enabling SSL by default during instance creation or, also optionally, enabling SSL on existing instances.

Justification/Benefits

 * Trove users should have a way to protect their data while it is in flight.
 * No, seriously. Who pipes unencrypted data over the *internet*?

MySQL
MySQL SSL setup requires four things be placed on the guest.
 * Public/Private keypair to use for SSL that have been signed by a CA pair.
 * The CA cert that corresponds to the key used to sign the SSL pair.
 * A configuration file containing the flags which direct MySQL to use the three keys above.

See http://dev.mysql.com/doc/refman/5.0/en/ssl-connections.html for more details.

PostgreSQL
PostgreSQL SSL setup is similar to the MySQL setup. See http://www.postgresql.org/docs/9.1/static/ssl-tcp.html for more details.

MongoDB
MongoDB SSL setup requires three things be placed on the guest.
 * SSL cert file containing public and private keys.
 * The CA cert that corresponds to the key used to sing the SSL pair.
 * A configuration file containing the flags which direct MongoDB to use the keys above.

See http://docs.mongodb.org/manual/tutorial/configure-ssl/ for more details.

Cassandra
Cassandra requires all nodes in a cluster to contain the keys for all other nodes in a cluster. The process, however, appears very similar to the above. It requires that the keys be placed on the guest and an appropriate configuration value be set. Comments requested from Cassandra deployers.

See http://www.datastax.com/documentation/cassandra/1.2/cassandra/security/secureSslEncryptionTOC.html for more details.

Configuration

 * SSL driver option per datastore in task manager configuration.
 * Option for SSL on create per datastore in task manager configuration.

Database

 * No change.

Public API

 * Management API call to enable SSL on existing instances.

CLI interface

 * trove mgmt-ssl-enable
 * trove mgmt-ssl-show

REST Part

 * POST /mgmt/instances/ /ssl => Run SSL setup for a guest. No POST body required.
 * GET /mgmt/instances/ /ssl => Check if SSL is setup for a guest. Body: { "ssl": { "enabled": true } }

Internal API

 * Adds an optional "ssl" argument to the prepare call containing necessary payloads.

RPC API description
Existing instances can be configured for SSL through an API call:

"ssl_payload" => { "public_key": "...", "private_key": "...", "ca_cert": "..." }
 * enable_ssl(ssl_payload))

Where public_key, private_key, and ca_cert contain the information needed for the guest agent SSL handler to successfully configure an instance for SSL. The raw values of public_key, private_key, and ca_cert are dependent upon the driver. For example, private_key could be an HREF to a file, the full body of a private key (or cert file for mongo, .keystore for cassandra, etc.), or nothing at all.

This API call should perform all logic needed to setup SSL except the restart that is required for several datastores. Instead, something like a "RESTART_REQUIRED_SSL" status should be set on the instance.

Guest Agent

 * Agent needs to handle SSL payloads appropriately depending on the SSL driver used.
 * Agent must generate/modify the appropriate configuration files to enable SSL.

Key Provider
There will need to be an implementable driver interface for an SSL key provider. The provider will be paired with an installer and will produce the appropriate ssl_payload.

Key Installers
Each datastore guest agent that supports SSL should have a code path which consumes an SSL payload (either from the prepare call or the enable_ssl call) which performs the setup and configuration changes required for SSL to be enabled.

No Op
ssl_payload => {"public_key": None, "private_key": None, "ca_cert": None} guest behaviour => Do nothing.

HREF/Swift
ssl_payload => {"public_key": "https://...", "private_key": "https://...", "ca_cert": "https://..."} guest behaviour => Download files using the given href's and setup ssl.

Keys
ssl_payload => {"public_key": "BEGIN RSA...", "private_key": "...", "ca_cert": "..."} guest behaviour => Use the keys given in the payload and setup ssl.