mirror of
https://github.com/optim-enterprises-bv/vault.git
synced 2025-11-01 19:17:58 +00:00
Change uninit/sealed status codes from health endpoint
This commit is contained in:
@@ -73,9 +73,14 @@ func getSysHealth(core *vault.Core, r *http.Request) (int, *HealthResponse, erro
|
|||||||
// Check if being a standby is allowed for the purpose of a 200 OK
|
// Check if being a standby is allowed for the purpose of a 200 OK
|
||||||
_, standbyOK := r.URL.Query()["standbyok"]
|
_, standbyOK := r.URL.Query()["standbyok"]
|
||||||
|
|
||||||
// FIXME: Change the sealed code to http.StatusServiceUnavailable at some
|
uninitCode := http.StatusNotImplemented
|
||||||
// point
|
if code, found, ok := fetchStatusCode(r, "uninitcode"); !ok {
|
||||||
sealedCode := http.StatusInternalServerError
|
return http.StatusBadRequest, nil, nil
|
||||||
|
} else if found {
|
||||||
|
uninitCode = code
|
||||||
|
}
|
||||||
|
|
||||||
|
sealedCode := http.StatusServiceUnavailable
|
||||||
if code, found, ok := fetchStatusCode(r, "sealedcode"); !ok {
|
if code, found, ok := fetchStatusCode(r, "sealedcode"); !ok {
|
||||||
return http.StatusBadRequest, nil, nil
|
return http.StatusBadRequest, nil, nil
|
||||||
} else if found {
|
} else if found {
|
||||||
@@ -108,7 +113,7 @@ func getSysHealth(core *vault.Core, r *http.Request) (int, *HealthResponse, erro
|
|||||||
code := activeCode
|
code := activeCode
|
||||||
switch {
|
switch {
|
||||||
case !init:
|
case !init:
|
||||||
code = http.StatusInternalServerError
|
code = uninitCode
|
||||||
case sealed:
|
case sealed:
|
||||||
code = sealedCode
|
code = sealedCode
|
||||||
case !standbyOK && standby:
|
case !standbyOK && standby:
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestSysHealth_get(t *testing.T) {
|
func TestSysHealth_get(t *testing.T) {
|
||||||
core, _, root := vault.TestCoreUnsealed(t)
|
core := vault.TestCore(t)
|
||||||
ln, addr := TestServer(t, core)
|
ln, addr := TestServer(t, core)
|
||||||
defer ln.Close()
|
defer ln.Close()
|
||||||
|
|
||||||
@@ -23,6 +23,68 @@ func TestSysHealth_get(t *testing.T) {
|
|||||||
|
|
||||||
var actual map[string]interface{}
|
var actual map[string]interface{}
|
||||||
expected := map[string]interface{}{
|
expected := map[string]interface{}{
|
||||||
|
"initialized": false,
|
||||||
|
"sealed": true,
|
||||||
|
"standby": true,
|
||||||
|
}
|
||||||
|
testResponseStatus(t, resp, 501)
|
||||||
|
testResponseBody(t, resp, &actual)
|
||||||
|
expected["server_time_utc"] = actual["server_time_utc"]
|
||||||
|
expected["version"] = actual["version"]
|
||||||
|
if actual["cluster_name"] == nil {
|
||||||
|
delete(expected, "cluster_name")
|
||||||
|
} else {
|
||||||
|
expected["cluster_name"] = actual["cluster_name"]
|
||||||
|
}
|
||||||
|
if actual["cluster_id"] == nil {
|
||||||
|
delete(expected, "cluster_id")
|
||||||
|
} else {
|
||||||
|
expected["cluster_id"] = actual["cluster_id"]
|
||||||
|
}
|
||||||
|
if !reflect.DeepEqual(actual, expected) {
|
||||||
|
t.Fatalf("bad: expected:%#v\nactual:%#v", expected, actual)
|
||||||
|
}
|
||||||
|
|
||||||
|
key, _ := vault.TestCoreInit(t, core)
|
||||||
|
resp, err = http.Get(addr + "/v1/sys/health")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("err: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
actual = map[string]interface{}{}
|
||||||
|
expected = map[string]interface{}{
|
||||||
|
"initialized": true,
|
||||||
|
"sealed": true,
|
||||||
|
"standby": true,
|
||||||
|
}
|
||||||
|
testResponseStatus(t, resp, 503)
|
||||||
|
testResponseBody(t, resp, &actual)
|
||||||
|
expected["server_time_utc"] = actual["server_time_utc"]
|
||||||
|
expected["version"] = actual["version"]
|
||||||
|
if actual["cluster_name"] == nil {
|
||||||
|
delete(expected, "cluster_name")
|
||||||
|
} else {
|
||||||
|
expected["cluster_name"] = actual["cluster_name"]
|
||||||
|
}
|
||||||
|
if actual["cluster_id"] == nil {
|
||||||
|
delete(expected, "cluster_id")
|
||||||
|
} else {
|
||||||
|
expected["cluster_id"] = actual["cluster_id"]
|
||||||
|
}
|
||||||
|
if !reflect.DeepEqual(actual, expected) {
|
||||||
|
t.Fatalf("bad: expected:%#v\nactual:%#v", expected, actual)
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err := vault.TestCoreUnseal(core, vault.TestKeyCopy(key)); err != nil {
|
||||||
|
t.Fatalf("unseal err: %s", err)
|
||||||
|
}
|
||||||
|
resp, err = http.Get(addr + "/v1/sys/health")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("err: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
actual = map[string]interface{}{}
|
||||||
|
expected = map[string]interface{}{
|
||||||
"initialized": true,
|
"initialized": true,
|
||||||
"sealed": false,
|
"sealed": false,
|
||||||
"standby": false,
|
"standby": false,
|
||||||
@@ -45,44 +107,14 @@ func TestSysHealth_get(t *testing.T) {
|
|||||||
t.Fatalf("bad: expected:%#v\nactual:%#v", expected, actual)
|
t.Fatalf("bad: expected:%#v\nactual:%#v", expected, actual)
|
||||||
}
|
}
|
||||||
|
|
||||||
core.Seal(root)
|
|
||||||
|
|
||||||
resp, err = http.Get(addr + "/v1/sys/health")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("err: %s", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
actual = map[string]interface{}{}
|
|
||||||
expected = map[string]interface{}{
|
|
||||||
"initialized": true,
|
|
||||||
"sealed": true,
|
|
||||||
"standby": false,
|
|
||||||
}
|
|
||||||
testResponseStatus(t, resp, 500)
|
|
||||||
testResponseBody(t, resp, &actual)
|
|
||||||
expected["server_time_utc"] = actual["server_time_utc"]
|
|
||||||
expected["version"] = actual["version"]
|
|
||||||
if actual["cluster_name"] == nil {
|
|
||||||
delete(expected, "cluster_name")
|
|
||||||
} else {
|
|
||||||
expected["cluster_name"] = actual["cluster_name"]
|
|
||||||
}
|
|
||||||
if actual["cluster_id"] == nil {
|
|
||||||
delete(expected, "cluster_id")
|
|
||||||
} else {
|
|
||||||
expected["cluster_id"] = actual["cluster_id"]
|
|
||||||
}
|
|
||||||
if !reflect.DeepEqual(actual, expected) {
|
|
||||||
t.Fatalf("bad: expected:%#v\nactual:%#v", expected, actual)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSysHealth_customcodes(t *testing.T) {
|
func TestSysHealth_customcodes(t *testing.T) {
|
||||||
core, _, root := vault.TestCoreUnsealed(t)
|
core := vault.TestCore(t)
|
||||||
ln, addr := TestServer(t, core)
|
ln, addr := TestServer(t, core)
|
||||||
defer ln.Close()
|
defer ln.Close()
|
||||||
|
|
||||||
queryurl, err := url.Parse(addr + "/v1/sys/health?sealedcode=503&activecode=202")
|
queryurl, err := url.Parse(addr + "/v1/sys/health?uninitcode=581&sealedcode=523&activecode=202")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("err: %s", err)
|
t.Fatalf("err: %s", err)
|
||||||
}
|
}
|
||||||
@@ -93,11 +125,11 @@ func TestSysHealth_customcodes(t *testing.T) {
|
|||||||
|
|
||||||
var actual map[string]interface{}
|
var actual map[string]interface{}
|
||||||
expected := map[string]interface{}{
|
expected := map[string]interface{}{
|
||||||
"initialized": true,
|
"initialized": false,
|
||||||
"sealed": false,
|
"sealed": true,
|
||||||
"standby": false,
|
"standby": true,
|
||||||
}
|
}
|
||||||
testResponseStatus(t, resp, 202)
|
testResponseStatus(t, resp, 581)
|
||||||
testResponseBody(t, resp, &actual)
|
testResponseBody(t, resp, &actual)
|
||||||
|
|
||||||
expected["server_time_utc"] = actual["server_time_utc"]
|
expected["server_time_utc"] = actual["server_time_utc"]
|
||||||
@@ -116,12 +148,7 @@ func TestSysHealth_customcodes(t *testing.T) {
|
|||||||
t.Fatalf("bad: expected:%#v\nactual:%#v", expected, actual)
|
t.Fatalf("bad: expected:%#v\nactual:%#v", expected, actual)
|
||||||
}
|
}
|
||||||
|
|
||||||
core.Seal(root)
|
key, _ := vault.TestCoreInit(t, core)
|
||||||
|
|
||||||
queryurl, err = url.Parse(addr + "/v1/sys/health?sealedcode=503&activecode=202")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("err: %s", err)
|
|
||||||
}
|
|
||||||
resp, err = http.Get(queryurl.String())
|
resp, err = http.Get(queryurl.String())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("err: %s", err)
|
t.Fatalf("err: %s", err)
|
||||||
@@ -131,9 +158,42 @@ func TestSysHealth_customcodes(t *testing.T) {
|
|||||||
expected = map[string]interface{}{
|
expected = map[string]interface{}{
|
||||||
"initialized": true,
|
"initialized": true,
|
||||||
"sealed": true,
|
"sealed": true,
|
||||||
|
"standby": true,
|
||||||
|
}
|
||||||
|
testResponseStatus(t, resp, 523)
|
||||||
|
testResponseBody(t, resp, &actual)
|
||||||
|
|
||||||
|
expected["server_time_utc"] = actual["server_time_utc"]
|
||||||
|
expected["version"] = actual["version"]
|
||||||
|
if actual["cluster_name"] == nil {
|
||||||
|
delete(expected, "cluster_name")
|
||||||
|
} else {
|
||||||
|
expected["cluster_name"] = actual["cluster_name"]
|
||||||
|
}
|
||||||
|
if actual["cluster_id"] == nil {
|
||||||
|
delete(expected, "cluster_id")
|
||||||
|
} else {
|
||||||
|
expected["cluster_id"] = actual["cluster_id"]
|
||||||
|
}
|
||||||
|
if !reflect.DeepEqual(actual, expected) {
|
||||||
|
t.Fatalf("bad: expected:%#v\nactual:%#v", expected, actual)
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err := vault.TestCoreUnseal(core, vault.TestKeyCopy(key)); err != nil {
|
||||||
|
t.Fatalf("unseal err: %s", err)
|
||||||
|
}
|
||||||
|
resp, err = http.Get(queryurl.String())
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("err: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
actual = map[string]interface{}{}
|
||||||
|
expected = map[string]interface{}{
|
||||||
|
"initialized": true,
|
||||||
|
"sealed": false,
|
||||||
"standby": false,
|
"standby": false,
|
||||||
}
|
}
|
||||||
testResponseStatus(t, resp, 503)
|
testResponseStatus(t, resp, 202)
|
||||||
testResponseBody(t, resp, &actual)
|
testResponseBody(t, resp, &actual)
|
||||||
expected["server_time_utc"] = actual["server_time_utc"]
|
expected["server_time_utc"] = actual["server_time_utc"]
|
||||||
expected["version"] = actual["version"]
|
expected["version"] = actual["version"]
|
||||||
|
|||||||
@@ -44,7 +44,14 @@ description: |-
|
|||||||
<span class="param">sealedcode</span>
|
<span class="param">sealedcode</span>
|
||||||
<span class="param-flags">optional</span>
|
<span class="param-flags">optional</span>
|
||||||
A query parameter provided to indicate the status code that should
|
A query parameter provided to indicate the status code that should
|
||||||
be returned for a sealed node instead of the default of `500`
|
be returned for a sealed node instead of the default of `503`
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<span class="param">uninitcode</span>
|
||||||
|
<span class="param-flags">optional</span>
|
||||||
|
A query parameter provided to indicate the status code that should
|
||||||
|
be returned for an uninitialized Vault instead of the default of
|
||||||
|
`501`
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</dd>
|
</dd>
|
||||||
|
|||||||
@@ -18,6 +18,22 @@ able to form an HA cluster. If following our [general upgrade
|
|||||||
instructions](https://www.vaultproject.io/docs/install/upgrade.html) this will
|
instructions](https://www.vaultproject.io/docs/install/upgrade.html) this will
|
||||||
not be an issue.
|
not be an issue.
|
||||||
|
|
||||||
|
## Health Endpoint Status Code Changes
|
||||||
|
|
||||||
|
Prior to 0.6.1, the health endpoint would return a `500` (Internal Server
|
||||||
|
Error) for both a sealed and uninitialized state. In both states this was
|
||||||
|
confusing, since it was hard to tell, based on the status code, an actual
|
||||||
|
internal error from Vault from a Vault that was simply uninitialized or sealed,
|
||||||
|
not to mention differentiating between those two states.
|
||||||
|
|
||||||
|
In 0.6.1, a sealed Vault will return a `503` (Service Unavailable) status code.
|
||||||
|
As before, this can be adjusted with the `sealedcode` query parameter. An
|
||||||
|
uninitialized Vault will return a `501` (Not Implemented) status code. This can
|
||||||
|
be adjusted with the `uninitcode` query parameter.
|
||||||
|
|
||||||
|
This removes ambiguity/confusion and falls more in line with the intention of
|
||||||
|
each status code (including `500`).
|
||||||
|
|
||||||
## Root Token Creation Restrictions
|
## Root Token Creation Restrictions
|
||||||
|
|
||||||
Root tokens (tokens with the `root` policy) can no longer be created except by
|
Root tokens (tokens with the `root` policy) can no longer be created except by
|
||||||
|
|||||||
Reference in New Issue
Block a user