From c9ecbb663acf02ee779f26eb5575478b7386bc7c Mon Sep 17 00:00:00 2001 From: Vishal Nayak Date: Fri, 28 Jun 2019 14:09:14 -0400 Subject: [PATCH] Raft Docs (#6966) * Raft configuration doc * API docs * join sample * Fix the Join API * Add snapshot-force * Update sys/storage subsection * Use actual certs in examples * Add sample configuration response * Fix link * remove TLS config options --- .../source/api/system/storage/index.html.md | 12 ++ .../source/api/system/storage/raft.html.md | 195 ++++++++++++++++++ .../docs/configuration/storage/raft.html.md | 47 +++++ website/source/layouts/api.erb | 6 + website/source/layouts/docs.erb | 1 + 5 files changed, 261 insertions(+) create mode 100644 website/source/api/system/storage/index.html.md create mode 100644 website/source/api/system/storage/raft.html.md create mode 100644 website/source/docs/configuration/storage/raft.html.md diff --git a/website/source/api/system/storage/index.html.md b/website/source/api/system/storage/index.html.md new file mode 100644 index 0000000000..07aa5ff922 --- /dev/null +++ b/website/source/api/system/storage/index.html.md @@ -0,0 +1,12 @@ +--- +layout: "api" +page_title: "/sys/storage - HTTP API" +sidebar_title: "/sys/storage " +sidebar_current: "api-http-system-storage" +description: |- + + The '/sys/storage' endpoints are used to manage Vault's storage backends. + +--- + +This API sub-section is currently only used to manage [Raft](raft.html) storage backend. diff --git a/website/source/api/system/storage/raft.html.md b/website/source/api/system/storage/raft.html.md new file mode 100644 index 0000000000..438abecbc3 --- /dev/null +++ b/website/source/api/system/storage/raft.html.md @@ -0,0 +1,195 @@ +--- +layout: "api" +page_title: "/sys/storage/raft - HTTP API" +sidebar_title: "/sys/storage/raft" +sidebar_current: "api-http-system-storage-raft" +description: |- + + The `/sys/storage/raft` endpoints are used to manage Vault's Raft storage + backend. + +--- + +## Join a Raft cluster + +This endpoint joins a new server node to the Raft cluster. When using Shamir +seal, as soon as the Vault server is brought up, this API should be invoked +instead of `sys/init`. This API completes in 2 phases. Once this is invoked, +the joining node will receive a challenge from the Raft's leader node. This +challenge can be answered by the joining node only after a successful unseal. +Hence, the joining node should be unsealed using the unseal keys of the Raft's +leader node. + +| Method | Path | +| :--------------------------- | :--------------------- | +| `POST` | `/sys/storage/raft/join` | + +### Parameters + +- `leader_api_addr` `(string: )` – Address of the leader node in the + Raft cluster to which this node is trying to join. + +- `retry` `(bool: false)` - Retry joining the Raft cluster in case of + failures. + +- `leader_ca_cert` `(string: "")` - CA certificate used to communicate with + Raft's leader node. + +- `leader_client_cert` `(string: "")` - Client certificate used to communicate + with Raft's leader node. + +- `leader_client_key` `(string: "")` - Client key used to communicate with + Raft's leader node. + +### Sample Payload +```json +{ + "leader_api_addr": "https://127.0.0.1:8200", + "leader_ca_cert": "-----BEGIN CERTIFICATE-----\nMIIDKTCCAhGgAwIBAgIUcd+Uyk1Tz+FhcbYP0zmynlkARoEwDQYJKoZIhvcNAQEL\nBQAwFDESMBAGA1UEAxMJbG9jYWxob3N0MB4XDTE5MDYyNDIyMjgzNVoXDTE5MDYy\nNzIyMjkwNVowADCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKdYr6rU\n21vYf7q/cpPigtBchqHvGZvpbA9DZucuUdQ0g4oAXRyShQ8omzmZOmO4A1GI3gqz\nHBePSYl+1IZCwgbPBk2CH7MhlMMINdwoEH6IxFgHNBkNK6GbwnGLyKL0Sym88ly1\n+sPP6+llS8uWNKu5GcObHLysD3Ce6QTt3usDPiw0cxp/KL1EkMi2dT7PvxTsX137\nsEsuQcylltGEtRb67xvFBP8XhQZAEGw+u4S3EmtwWMwZixB45WQhj2Ncz5U0+w8V\ncp9DSqB1QheoGPBBI62jHle05kzG85ZKmLBgHE6HEGS8biIHpannM7dgI0cRH6i2\nF69N0rcbzK+NInUCAwEAAaOBhjCBgzAOBgNVHQ8BAf8EBAMCA6gwHQYDVR0lBBYw\nFAYIKwYBBQUHAwEGCCsGAQUFBwMCMB0GA1UdDgQWBBQelJT5fthHdbCyD5zaI4tw\n7mfp8zAfBgNVHSMEGDAWgBSuG6hyoOWoiGvSA3kqwo9DirS+pzASBgNVHREBAf8E\nCDAGhwR/AAABMA0GCSqGSIb3DQEBCwUAA4IBAQCmetSH5w835RbbyHZD8e3ClHzi\n210SrvzWkx3N0JcBOjs47jlLuqVTl0HRr2xMoIkErFbhPDBXARYV8eezhQ6G5M60\n8AwVsG56rCa1l0weK2JfnEWgkwXZ/zbpZ2yNkWatWNSHdlJwGp99JTSriQYNOnMG\nWvBDA8ukoOkIJd/a8+aXZBdUiAcFvlLWmX73pYGTlnQDiIqJvhrlkgCKPvzZqvV+\njtz7kCt9EfT6sN6Xcny7GusRBSs+XfEe8u10+mbud+ufE/QSJ2D3tTYrS6eGqpVD\nrezD8jS9PfZgQfHXVaphMADyw4flaSVxfJ/ZRFxXql3oJSuj02+VX6QsXex+\n-----END CERTIFICATE-----", + "leader_client_cert": "-----BEGIN CERTIFICATE-----\nMIIDNTCCAh2gAwIBAgIULkPFG+qu7tGv21Plc1sg4eGbMPkwDQYJKoZIhvcNAQEL\nBQAwFDESMBAGA1UEAxMJbG9jYWxob3N0MB4XDTE5MDYyNDIyMjgwNVoXDTI5MDYy\nMTIyMjgzNVowFDESMBAGA1UEAxMJbG9jYWxob3N0MIIBIjANBgkqhkiG9w0BAQEF\nAAOCAQ8AMIIBCgKCAQEAwszD+A5vWD8S1N632ElHA5Px2dk97wJBKNYc/7RPNptn\n+EOmMTXPfuA3LB92FoSMCR7ye3wvSTzyK9nqafS7U2tlOF4PJrJoNZyzrVwBVLXg\n7Pd8qQxnxbonc3bscWZuEfbFsugkPHgBtnSkyCffXKhhwM5LbJqmK5cfJRZZ0eRy\nwmOCQCJ8ZmN2KfjHiGSEw9v19CNtvFNLyfiTZZLO9M5n4dgainZZCs+vdKD7tSJf\nycwWiZ4ezOwLMIgxdbLYKVglbZsPcMVVPLTskmY8WiHUM6sy3HAbFQn20Rj7JGE6\nldR3NX80YtCMt8/d+xzBfxu4x8juxHCgZFGt3nUS0wIDAQABo38wfTAOBgNVHQ8B\nAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUrhuocqDlqIhr0gN5\nKsKPQ4q0vqcwHwYDVR0jBBgwFoAUrhuocqDlqIhr0gN5KsKPQ4q0vqcwGgYDVR0R\nBBMwEYIJbG9jYWxob3N0hwR/AAABMA0GCSqGSIb3DQEBCwUAA4IBAQBRno9NOaat\n8g1ma/6OxP1JUt1VRao4+t2GQTCJ697d2SmpHr8CYanMPog+QhDj/lderA/oS0V3\n2jruH9CyH0smFMIsLBZpnRIwdhTISbIXdU3Uvcd6nne/f7LiUUmqf8YS9SHxWPFq\nI72QvtPrsjYKCZwJsHZe071lYScjrjGnlUhhbrug2g6/ZMHJ7mndGE022zMn/XD/\njrrKE6fCDCjJ4PRrta7+G7BvsFHqMSQ+2/947TGohxW69cbNyDeiQVDQ5mpJUy2b\nnOCVVnq0nafSuvBTHCCLxjd7f+9TiB/B3qT8GA9V6LANDSdQ15MRIhpup/yosmqX\nl5goCY/j3bDh\n-----END CERTIFICATE-----", + "leader_client_key": "-----BEGIN RSA PRIVATE KEY-----\nMIIEpAIBAAKCAQEAp1ivqtTbW9h/ur9yk+KC0FyGoe8Zm+lsD0Nm5y5R1DSDigBd\nHJKFDyibOZk6Y7gDUYjeCrMcF49JiX7UhkLCBs8GTYIfsyGUwwg13CgQfojEWAc0\nGQ0roZvCcYvIovRLKbzyXLX6w8/r6WVLy5Y0q7kZw5scvKwPcJ7pBO3e6wM+LDRz\nGn8ovUSQyLZ1Ps+/FOxfXfuwSy5BzKWW0YS1FvrvG8UE/xeFBkAQbD67hLcSa3BY\nzBmLEHjlZCGPY1zPlTT7DxVyn0NKoHVCF6gY8EEjraMeV7TmTMbzlkqYsGAcTocQ\nZLxuIgelqeczt2AjRxEfqLYXr03StxvMr40idQIDAQABAoIBAHCOhhkw8hnklITX\nIAm34KSklylz2JW1eqkJfL0huogwigjYFciSBE0d0sn69fr8Wb8Nf8tSjSKLjbqd\nQ/TKEhbiSCr5yriBbb2AWDmr+OwisW1D6xaudRpN2Yrlqh1wkt2P6LPS8sehodtp\n9oEIloSqC1o1ii6czAXD3JckJzuJ66yoVyCo2oVC3NETujjJRhdRcNY0dYUGx47M\n+hQo7b4s79wlMFmccrgyJcKI7Ra3DtMrBIaVXm4WcjX2x4DduZX6L4mfG83uLWng\nhbvcEPKGamUErjPGYixKE5XOwgJT6Nzq/ZZJZpok6DbHBCtqvwwByWlfLzh8lc4o\nz+Pl5EECgYEA3pJXRM+SdVUCnWIpMFOAiNstOwz3nm0/c8GDdYYNq0ere1tKCVV0\nii+ujMQY8vEdRrp7fbqJEPJANyI6sM4Jc2nxMveFuBoEsEClZuE4KBFquW8CQU4R\nGNkzKF1W0GaTI5O4QDUag+lFG6TPCwZiejTIkt65o5bnSzGLgdC546sCgYEAwHr9\nlq9HytWkV9OLz0zbcAUEIrFAljnC32Mybsj8LzdSKIZ3wErf9Txh8zqZqMyhedxL\nOn17cpJAq5Vi71uXOaxnhkf7TPuRs8nBRRJfgyNHPXuXLkuWeuvXEe/PIC+nvOIX\nas0Ab0Pvx0fRGl4EkZ2pV9oDAEUezbVVZCoO8l8CgYEAp4p3YNfzwpj0d+5tXPBu\ngBakzJ+tQjewnP1dbLk1TuqLXjdQ2wfVyzOrbFEtCquPwy8bSICDLxt8VURR88eU\n+6kTJK+InBYR029GUtRUhmzd7qpugyQ14IOXa9ofQI8GUbCf8M1IoWWWXQHJzN3I\ngX98QHqiOU+d2k94WYb6dzMCgYA3E7p2oMdZShLRss3hzqtH/Zd2WeQSWIrjox3u\nR4Kp/Bl9UST5GDPHl7SrhcwsWgmmthusq/VkDmeE8aUyurGmJigla3mESMQjfwrX\nue8sti6PcEsNS0HPAKc1EbriCeDkkomC3RBPxk/ZZTp3YgnKpSOs6MxNCnpLAKVj\nmQlX3wKBgQCFYyYJdCKMoaoMrNjMM34sAfTqmZT4Hbxg9KM4OMDSxyvIi0ZaVcnB\nkzssvt0FOMucp4o7h8Iujt8xsgnBHwg81IV7WOw+ZwpUDAzgVc7+kCU6CLd2Q40j\n5uFnuRgiWeGm1aT4arNLWlJrDLSGbyrf59SlGJV1hmu/7SMaYIZHSQ==\n-----END RSA PRIVATE KEY-----" +} +``` +### Sample Request + +``` +$ curl \ + --header "X-Vault-Token: ..." \ + --request POST \ + --data @payload.json \ + http://127.0.0.1:8200/v1/sys/storage/raft/join +``` + +**Note:** Unseal the joining node immediately after this API is invoked. + +## Read Raft Configuration + +This endpoint returns the details of all the nodes in the raft cluster. + +| Method | Path | +| :--------------------------- | :---------------------------- | +| `GET` | `/sys/storage/raft/configuration` | + +### Sample Request + +``` +$ curl \ + --header "X-Vault-Token: ..." \ + http://127.0.0.1:8200/v1/sys/storage/raft/configuration +``` + +### Sample Response + +```json +{ + "request_id": "ca4b5a1d-38d6-e27e-e756-269521328a15", + "lease_id": "", + "lease_duration": 0, + "renewable": false, + "data": { + "config": { + "index": 24, + "servers": [ + { + "address": "127.0.0.1:8201", + "leader": true, + "node_id": "raft1", + "protocol_version": "\u0003", + "voter": true + }, + { + "address": "127.0.0.2:8201", + "leader": false, + "node_id": "raft2", + "protocol_version": "\u0003", + "voter": true + } + ] + } + }, + "warnings": null +} +``` + +## Remove a node from Raft cluster + +This endpoint removes a node from the raft cluster. + +| Method | Path | +| :--------------------------- | :--------------------- | +| `POST` | `/sys/storage/raft/remove-peer` | + +### Sample Payload + +```json +{ + "server_id": "raft1" +} +``` +### Sample Request + +``` +$ curl \ + --header "X-Vault-Token: ..." \ + --request POST \ + --data @payload.json \ + http://127.0.0.1:8200/v1/sys/storage/raft/remove-peer +``` + +## Take a snapshot of the Raft cluster + +This endpoint returns a snapshot of the current state of the raft cluster. The +snapshot is returned as binary data and should be redirected to a file. + +| Method | Path | +| :--------------------------- | :---------------------------- | +| `GET` | `/sys/storage/raft/snapshot` | + +### Sample Request + +``` +$ curl \ + --header "X-Vault-Token: ..." \ + --request GET \ + http://127.0.0.1:8200/v1/sys/storage/raft/snapshot > raft.snap +``` + +## Restore Raft using a snapshot + +Installs the provided snapshot, returning the cluster to the state defined in it. + +| Method | Path | +| :--------------------------- | :--------------------- | +| `POST` | `/sys/storage/raft/snapshot` | + + +### Sample Request + +``` +$ curl \ + --header "X-Vault-Token: ..." \ + --request POST \ + -- data-binary @raft.snap + http://127.0.0.1:8200/v1/sys/storage/raft/snapshot +``` + +## Force Restore Raft using a snapshot + +Installs the provided snapshot, returning the cluster to the state defined in +it. This is same as writing to `/sys/storage/raft/snapshot` except that this +bypasses checks ensuring the Autounseal or shamir keys are consistent with the +snapshot data. + +| Method | Path | +| :--------------------------- | :--------------------- | +| `POST` | `/sys/storage/raft/snapshot-force` | + +### Sample Request + +``` +$ curl \ + --header "X-Vault-Token: ..." \ + --request POST \ + --data-binary @raft.snap + http://127.0.0.1:8200/v1/sys/storage/raft/snapshot-force +``` diff --git a/website/source/docs/configuration/storage/raft.html.md b/website/source/docs/configuration/storage/raft.html.md new file mode 100644 index 0000000000..d3f1fe9bde --- /dev/null +++ b/website/source/docs/configuration/storage/raft.html.md @@ -0,0 +1,47 @@ +--- +layout: "docs" +page_title: "Raft - Storage Backends - Configuration" +sidebar_title: "Raft" +sidebar_current: "docs-configuration-storage-raft" +description: |- + + The Raft storage backend is used to persist Vault's data. Unlike all the other + storage backends, this backend does not operate from a single source for the + data. Instead all the nodes in a Vault cluster will have a replicated copy of + the entire data. The data is replicated across the nodes using the Raft + Consensus Algorithm. + +--- + +# Raft Storage Backend + +The Raft storage backend is used to persist Vault's data. Unlike other storage +backends, Raft storage does not operate from a single source of data. Instead +all the nodes in a Vault cluster will have a replicated copy of Vault's data. +Data gets replicated across the all the nodes via the [Raft Consensus +Algorithm][raft]. + + +- **High Availability** – the Raft storage backend supports high availability. + +- **HashiCorp Supported** – the Raft storage backend is officially supported + by HashiCorp. + +```hcl +storage "raft" { + path = "/path/to/raft/data" + node_id = "raft_node_1" +} +cluster_addr = "http://127.0.0.1:8201" +``` + +**Note:** When using the Raft storage backend, it is required to provide `cluster_addr` to indicate the address and port to be used for communication between the nodes in the Raft cluster. + +## `raft` Parameters + +- `path` `(string: "")` – The file system path where all the Vault data gets + stored. + +- `node_id` `(string: "")` - The identifier for the node in the Raft cluster. + +[raft]: https://raft.github.io/ "The Raft Consensus Algorithm" diff --git a/website/source/layouts/api.erb b/website/source/layouts/api.erb index 8974fd83d1..968a9e05c5 100644 --- a/website/source/layouts/api.erb +++ b/website/source/layouts/api.erb @@ -138,6 +138,12 @@ 'seal', 'seal-status', 'step-down', + { + category: 'storage', + content: [ + 'raft' + ] + }, 'tools', 'unseal', 'wrapping-lookup', diff --git a/website/source/layouts/docs.erb b/website/source/layouts/docs.erb index 92ace5b742..5698743b38 100644 --- a/website/source/layouts/docs.erb +++ b/website/source/layouts/docs.erb @@ -70,6 +70,7 @@ 'mssql', 'mysql', 'postgresql', + 'raft', 's3', 'swift', 'zookeeper'