2020-06-15 10:04:08 +00:00
|
|
|
package cmd
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"fmt"
|
2020-12-26 13:11:49 +00:00
|
|
|
"os"
|
|
|
|
|
2020-06-15 10:04:08 +00:00
|
|
|
"github.com/spf13/cobra"
|
2020-12-26 13:11:49 +00:00
|
|
|
"gitlab.com/inetmock/inetmock/internal/format"
|
|
|
|
"gitlab.com/inetmock/inetmock/internal/rpc"
|
2020-06-15 10:04:08 +00:00
|
|
|
"google.golang.org/grpc"
|
|
|
|
)
|
|
|
|
|
|
|
|
var (
|
|
|
|
healthCmd = &cobra.Command{
|
|
|
|
Use: "health",
|
|
|
|
Short: "health is the entry point for all health check related commands",
|
|
|
|
}
|
|
|
|
|
|
|
|
generalHealthCmd = &cobra.Command{
|
|
|
|
Use: "general",
|
|
|
|
Short: "get the health in a more general way i.e. exit code 0 if healthy, exit codes unequal 0 if somethings wrong",
|
|
|
|
Long: `
|
|
|
|
Exit code 1 means the server is still initializing
|
|
|
|
Exit code 2 means any component is unhealthy
|
|
|
|
Exit code 10 means an error occurred while opening a connection to the API socket
|
|
|
|
|
|
|
|
The output contains information about each component and it's health state.
|
|
|
|
`,
|
|
|
|
Run: runGeneralHealth,
|
|
|
|
}
|
|
|
|
|
|
|
|
containerHealthCmd = &cobra.Command{
|
|
|
|
Use: "container",
|
|
|
|
Short: "get the health in a container compatible way i.e. exit code 0 if okay otherwise exit code 1",
|
|
|
|
Run: runContainerHealth,
|
|
|
|
}
|
|
|
|
)
|
|
|
|
|
|
|
|
type printableHealthInfo struct {
|
2020-06-23 12:54:08 +00:00
|
|
|
Component string
|
|
|
|
State string
|
|
|
|
Message string
|
2020-06-15 10:04:08 +00:00
|
|
|
}
|
|
|
|
|
2020-06-23 12:54:08 +00:00
|
|
|
func fromComponentsHealth(componentsHealth map[string]*rpc.ComponentHealth) (componentsInfo []printableHealthInfo) {
|
|
|
|
for componentName, component := range componentsHealth {
|
|
|
|
componentsInfo = append(componentsInfo, printableHealthInfo{
|
|
|
|
Component: componentName,
|
|
|
|
State: component.State.String(),
|
|
|
|
Message: component.Message,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
func getHealthResult() (healthResp *rpc.HealthResponse, err error) {
|
2020-06-15 10:04:08 +00:00
|
|
|
var conn *grpc.ClientConn
|
|
|
|
|
|
|
|
if conn, err = grpc.Dial(inetMockSocketPath, grpc.WithInsecure()); err != nil {
|
2020-06-23 12:54:08 +00:00
|
|
|
return
|
2020-06-15 10:04:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
var healthClient = rpc.NewHealthClient(conn)
|
|
|
|
ctx, _ := context.WithTimeout(context.Background(), grpcTimeout)
|
2020-06-23 12:54:08 +00:00
|
|
|
healthResp, err = healthClient.GetHealth(ctx, &rpc.HealthRequest{})
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
func runGeneralHealth(_ *cobra.Command, _ []string) {
|
2020-06-15 10:04:08 +00:00
|
|
|
var healthResp *rpc.HealthResponse
|
2020-06-23 12:54:08 +00:00
|
|
|
var err error
|
2020-06-15 10:04:08 +00:00
|
|
|
|
2020-06-23 12:54:08 +00:00
|
|
|
if healthResp, err = getHealthResult(); err != nil {
|
2020-06-15 10:04:08 +00:00
|
|
|
fmt.Printf("Failed to get health information: %v", err)
|
|
|
|
os.Exit(1)
|
|
|
|
}
|
|
|
|
|
2020-06-23 12:54:08 +00:00
|
|
|
printable := fromComponentsHealth(healthResp.ComponentsHealth)
|
|
|
|
|
2020-06-15 10:04:08 +00:00
|
|
|
writer := format.Writer(outputFormat, os.Stdout)
|
2020-06-23 12:54:08 +00:00
|
|
|
if err = writer.Write(printable); err != nil {
|
2020-06-15 10:04:08 +00:00
|
|
|
fmt.Printf("Error occurred during writing response values: %v\n", err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func runContainerHealth(_ *cobra.Command, _ []string) {
|
2020-06-23 12:54:08 +00:00
|
|
|
if healthResp, err := getHealthResult(); err != nil {
|
|
|
|
fmt.Printf("Failed to get health information: %v", err)
|
|
|
|
os.Exit(1)
|
|
|
|
} else if healthResp.OverallHealthState != rpc.HealthState_HEALTHY {
|
|
|
|
fmt.Println("Overall health state is not healthy")
|
|
|
|
os.Exit(1)
|
|
|
|
}
|
2020-06-15 10:04:08 +00:00
|
|
|
}
|