/
handler.go
130 lines (115 loc) · 3.7 KB
/
handler.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
/*
* Copyright © 2017-2018 Aeneas Rekkas <aeneas+oss@aeneas.io>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* @author Aeneas Rekkas <aeneas+oss@aeneas.io>
* @copyright 2017-2018 Aeneas Rekkas <aeneas+oss@aeneas.io>
* @license Apache-2.0
*/
package health
import (
"net/http"
"github.com/julienschmidt/httprouter"
"github.com/ory/herodot"
)
const (
AliveCheckPath = "/health/alive"
ReadyCheckPath = "/health/ready"
VersionPath = "/version"
)
type ReadyChecker func() error
type Handler struct {
H *herodot.JSONWriter
VersionString string
ReadyChecks map[string]ReadyChecker
}
func NewHandler(
h *herodot.JSONWriter,
version string,
readyChecks map[string]ReadyChecker,
) *Handler {
return &Handler{
H: h,
VersionString: version,
ReadyChecks: readyChecks,
}
}
func (h *Handler) SetRoutes(r *httprouter.Router) {
r.GET(AliveCheckPath, h.Alive)
r.GET(ReadyCheckPath, h.Ready)
r.GET(VersionPath, h.Version)
}
// swagger:route GET /health/alive health isInstanceAlive
//
// Check the Alive Status
//
// This endpoint returns a 200 status code when the HTTP server is up running.
// This status does currently not include checks whether the database connection is working.
// This endpoint does not require the `X-Forwarded-Proto` header when TLS termination is set.
//
// Be aware that if you are running multiple nodes of ORY Oathkeeper, the health status will never refer to the cluster state, only to a single instance.
//
// Responses:
// 200: healthStatus
// 500: genericError
func (h *Handler) Alive(rw http.ResponseWriter, r *http.Request, _ httprouter.Params) {
h.H.Write(rw, r, &swaggerHealthStatus{
Status: "ok",
})
}
// swagger:route GET /health/ready health isInstanceReady
//
// Check the Readiness Status
//
// This endpoint returns a 200 status code when the HTTP server is up running and the environment dependencies (e.g.
// the database) are responsive as well.
//
// This status does currently not include checks whether the database connection is working.
// This endpoint does not require the `X-Forwarded-Proto` header when TLS termination is set.
//
// Be aware that if you are running multiple nodes of ORY Oathkeeper, the health status will never refer to the cluster state, only to a single instance.
//
// Responses:
// 200: healthStatus
// 503: healthNotReadyStatus
func (h *Handler) Ready(rw http.ResponseWriter, r *http.Request, _ httprouter.Params) {
var notReady = swaggerNotReadyStatus{
Errors: map[string]string{},
}
for n, c := range h.ReadyChecks {
if err := c(); err != nil {
notReady.Errors[n] = err.Error()
}
}
if len(notReady.Errors) > 0 {
h.H.WriteCode(rw, r, http.StatusServiceUnavailable, notReady)
return
}
h.H.Write(rw, r, &swaggerHealthStatus{
Status: "ok",
})
}
// swagger:route GET /version version getVersion
//
// Get the version of Oathkeeper
//
// This endpoint returns the version as `{ "version": "VERSION" }`. The version is only correct with the prebuilt binary and not custom builds.
//
// Responses:
// 200: version
func (h *Handler) Version(rw http.ResponseWriter, r *http.Request, _ httprouter.Params) {
h.H.Write(rw, r, &swaggerVersion{
Version: h.VersionString,
})
}