X-Git-Url: https://gerrit.o-ran-sc.org/r/gitweb?a=blobdiff_plain;f=internal%2Fcli%2Fhealthcheck.go;h=257bd5d1ed3c3a0b6666fdca5bc6db5a5f4f89b1;hb=6f724aa3950cdc01246351644348fdc0f6e9ca4a;hp=94467a9c946135170839fd0fab30308304506f6e;hpb=977a55ca96d5dba1c7f9273671747eaf9cd6f894;p=ric-plt%2Fsdlgo.git diff --git a/internal/cli/healthcheck.go b/internal/cli/healthcheck.go index 94467a9..257bd5d 100644 --- a/internal/cli/healthcheck.go +++ b/internal/cli/healthcheck.go @@ -23,30 +23,26 @@ package cli import ( - "bytes" "fmt" "gerrit.o-ran-sc.org/r/ric-plt/sdlgo/internal/sdlgoredis" "github.com/spf13/cobra" "os" + "text/tabwriter" ) -func NewHealthCheckCmd() *cobra.Command { - return newHealthCheckCmd(newDatabase) +func init() { + rootCmd.AddCommand(newHealthCheckCmd(newDatabase)) } func newHealthCheckCmd(dbCreateCb DbCreateCb) *cobra.Command { cmd := &cobra.Command{ Use: "healthcheck", - Short: "healthcheck - validates database healthiness", - Long: `healthcheck - validates database healthiness`, + Short: "Validate SDL database healthiness", + Long: `Validate SDL database healthiness`, + Args: cobra.ExactArgs(0), RunE: func(cmd *cobra.Command, args []string) error { - var buf bytes.Buffer - sdlgoredis.SetDbLogger(&buf) - out, err := runHealthCheck(dbCreateCb) - cmd.Println(out) - if err != nil { - cmd.PrintErrf("%s\n", buf.String()) - } + states, err := runHealthCheck(dbCreateCb) + printHealthStatus(cmd, states) return err }, } @@ -54,53 +50,113 @@ func newHealthCheckCmd(dbCreateCb DbCreateCb) *cobra.Command { return cmd } -func runHealthCheck(dbCreateCb DbCreateCb) (string, error) { +func runHealthCheck(dbCreateCb DbCreateCb) ([]sdlgoredis.DbState, error) { var anyErr error - var str string var states []sdlgoredis.DbState for _, dbInst := range dbCreateCb().Instances { - info, err := dbInst.State() + state, err := dbInst.State() if err != nil { - anyErr = fmt.Errorf("SDL CLI error: %v", err) + anyErr = err } - states = append(states, *info) + states = append(states, *state) } - str = writeStateResults(states) - return str, anyErr + return states, anyErr } -func writeStateResults(dbStates []sdlgoredis.DbState) string { - var str string +func printHealthStatus(cmd *cobra.Command, dbStates []sdlgoredis.DbState) { var anyErr error + w := tabwriter.NewWriter(cmd.OutOrStdout(), 6, 4, 3, ' ', 0) + fmt.Fprintln(w, "CLUSTER\tROLE\tADDRESS\tSTATUS\tERROR\t") + for i, dbState := range dbStates { if err := dbState.IsOnline(); err != nil { anyErr = err } - str = str + fmt.Sprintf(" SDL DB backend #%d\n", (i+1)) - mAddr := dbState.MasterDbState.GetAddress() - err := dbState.MasterDbState.IsOnline() - if err == nil { - str = str + fmt.Sprintf(" Master (%s): OK\n", mAddr) - } else { - str = str + fmt.Sprintf(" Master (%s): NOK\n", mAddr) - str = str + fmt.Sprintf(" %s\n", err.Error()) + + if err := printPrimaryHealthStatus(w, i, &dbState); err != nil { + anyErr = err + } + + if err := printReplicasHealthStatus(w, i, &dbState); err != nil { + anyErr = err } - if dbState.ReplicasDbState != nil { - for j, rInfo := range dbState.ReplicasDbState.States { - err := rInfo.IsOnline() - if err == nil { - str = str + fmt.Sprintf(" Replica #%d (%s): OK\n", (j+1), rInfo.GetAddress()) - } else { - str = str + fmt.Sprintf(" Replica #%d (%s): NOK\n", (j+1), rInfo.GetAddress()) - str = str + fmt.Sprintf(" %s\n", err.Error()) - } - } + + if err := printSentinelsHealthStatus(w, i, &dbState); err != nil { + anyErr = err } } if anyErr == nil { - str = fmt.Sprintf("Overall status: OK\n\n") + str + cmd.Println("Overall status: OK") + } else { + cmd.Println("Overall status: NOK") + } + cmd.Println("") + w.Flush() +} + +func printPrimaryHealthStatus(w *tabwriter.Writer, clusterID int, dbState *sdlgoredis.DbState) error { + addr := printAddress(dbState.PrimaryDbState.GetAddress()) + err := dbState.PrimaryDbState.IsOnline() + if err != nil { + fmt.Fprintf(w, "%d\t%s\t%s\t%s\t%s\t\n", clusterID, "primary", addr, "NOK", err.Error()) } else { - str = fmt.Sprintf("Overall status: NOK\n\n") + str + fmt.Fprintf(w, "%d\t%s\t%s\t%s\t%s\t\n", clusterID, "primary", addr, "OK", "") + } + return err +} + +func printReplicasHealthStatus(w *tabwriter.Writer, clusterID int, dbState *sdlgoredis.DbState) error { + var anyErr error + + if dbState.ReplicasDbState != nil { + if dbState.ConfigNodeCnt > len(dbState.ReplicasDbState.States)+1 { + err := fmt.Errorf("Configured DBAAS nodes %d but only 1 primary and %d replicas", + dbState.ConfigNodeCnt, len(dbState.ReplicasDbState.States)) + fmt.Fprintf(w, "%d\t%s\t%s\t%s\t%s\t\n", clusterID, "replica", "", "NOK", err.Error()) + anyErr = err + } + for _, state := range dbState.ReplicasDbState.States { + if err := printReplicaHealthStatus(w, clusterID, state); err != nil { + anyErr = err + } + } + } + return anyErr +} + +func printReplicaHealthStatus(w *tabwriter.Writer, clusterID int, dbState *sdlgoredis.ReplicaDbState) error { + addr := printAddress(dbState.GetAddress()) + err := dbState.IsOnline() + if err != nil { + fmt.Fprintf(w, "%d\t%s\t%s\t%s\t%s\t\n", clusterID, "replica", addr, "NOK", err.Error()) + } else { + fmt.Fprintf(w, "%d\t%s\t%s\t%s\t%s\t\n", clusterID, "replica", addr, "OK", "") + } + return err +} + +func printSentinelsHealthStatus(w *tabwriter.Writer, clusterID int, dbState *sdlgoredis.DbState) error { + var anyErr error + if dbState.SentinelsDbState != nil { + for _, state := range dbState.SentinelsDbState.States { + if err := printSentinelHealthStatus(w, clusterID, state); err != nil { + anyErr = err + } + } + } + return anyErr +} +func printSentinelHealthStatus(w *tabwriter.Writer, clusterID int, dbState *sdlgoredis.SentinelDbState) error { + err := dbState.IsOnline() + if err != nil { + fmt.Fprintf(w, "%d\t%s\t%s\t%s\t%s\t\n", clusterID, "sentinel", dbState.GetAddress(), "NOK", err.Error()) + } + return err +} + +func printAddress(address string) string { + if address == "" { + return "" } - return str + return address }