-
Notifications
You must be signed in to change notification settings - Fork 360
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
cmd: Add health check commands #319
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Awesome! Just some documentation things. Also, I think these command should exit with a status code of 1 if the check fails!
var healthAliveCmd = &cobra.Command{ | ||
Use: "alive", | ||
Short: "Command for checking alive status", | ||
Run: func(cmd *cobra.Command, args []string) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add a long description here, with at least one example, showcasing how to use this command.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, you should add a warning:
If the target endpoint runs behind a Load Balancer, this command will effectively test the health of the Load Balancer, not the actual ORY Oathkeeper deployment.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added the Load Balancer warning to the parent health
command since that is where the endpoint
flag is declared.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Most devs do not read the "top level" command docs, only the specific docs. It makes sense to have the note in all three!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
|
||
r, err := client.API.IsInstanceAlive(api.NewIsInstanceAliveParams()) | ||
cmdx.Must(err, "%s", err) | ||
fmt.Println(cmdx.FormatResponse(r.Payload)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this command should exit with an error code of 1 if the instance is not yet alive. Any response from the server that has a status code of != 200
means that this instance is not alive yet.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added explicit exit codes in all cases now. cmdx.Must(err, "%s", err)
will exit 1 if there was an error e.g. a 404 response. If no error, it will exit 1 if r.Payload.Status != "ok"
. Otherwise, exit 0
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah right, I forgot that the API will return an error if the code is not 200. We should still print out the received status code, which will make it easier to debug :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The error status code is printed in the error message. For example:
$ oathkeeper health -e http://localhost:4456/bad ready
> unknown error (status 404): {resp:0xc0028aee10}
I can't find any way to get a reference to the StatusCode based on the what the internal API client returns.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can type assert the error with runtime.APIError
and then you have access to the Response, code, and so on, so e.g.
if apiErr, ok := err.(*runtime.APIError); ok {
// ...
} else {
// ...
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
however, I think it's ok as it is at the moment!
@@ -0,0 +1,26 @@ | |||
package cmd |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please apply the comments from health_alive
here as well!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
Co-Authored-By: hackerman <[email protected]>
Co-Authored-By: hackerman <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for the changes, a few last things and then we're good to go! :)
var healthAliveCmd = &cobra.Command{ | ||
Use: "alive", | ||
Short: "Command for checking alive status", | ||
Run: func(cmd *cobra.Command, args []string) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Most devs do not read the "top level" command docs, only the specific docs. It makes sense to have the note in all three!
cmd/health_ready.go
Outdated
if r.Payload.Status != "ok" { | ||
os.Exit(1) | ||
} | ||
os.Exit(0) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No need for os.Exit(0)
, this is always the case!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I removed the explicit exit 0 for both
fmt.Println(cmdx.FormatResponse(r.Payload)) | ||
// When healthy, ORY Oathkeeper always returns a status of "ok" | ||
if r.Payload.Status != "ok" { | ||
os.Exit(1) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There should be an error message here. Something like:
fmt.Printf("The endpoint does not appear to be healthy, received HTTP Status Code %d and status %s\n", r.StatusCode, r.Payload.Status)
(I think the status code is r.StatusCode
).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The HTTP StatusCode doesn't appear to be available. The internal API client returns the following struct
type IsInstanceReadyOK struct {
Payload *models.SwaggerHealthStatus
}
If the HTTP status code isn't a 200, it will be printed as an error and the process will exit 1 which is handled by cmdx.Must(err, "%s", err)
. Otherwise, the Payload is always printed so you can see the payload status
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, you're right!
Thank you! |
Thanks for all your help reviewing! Does this mean I get to chat in the #contibutors channel now? ;) |
Credit where credit is due ;) You're now able to write in the contributors channel! |
Co-Authored-By: hackerman <[email protected]>
Related issue
Proposed changes
Add health check commands to the oathkeeper CLI.
motivation:
Support for Docker
HEALTHCHECK
Docker's
HEALTHCHECK
instruction executes a command e.g.CMD curl -f http://localhost/ || exit 1
in the container to determine the health status of the container. The exit code of the command determines the health status. The possible exit codes are:Rather than using
curl
(which is not available in the official oathkeeper image) to query the oathkeeper api, we can query the api using oathkeeper's CLI. This has a few advantages:curl
See this blog post for more details.
example usage:
In keeping with the conventions already in place by the
rules
command, the newhealth
command has the following usageoathkeeper health -e <endpoint> alive
for checking livenessoathkeeper health -e <endpoint> ready
for checking readinessChecklist
vulnerability. If this pull request addresses a security vulnerability, I
confirm that I got green light (please contact
[email protected]) from the maintainers to push
the changes.
developer guide (if appropriate)
Further comments