diff --git a/cmd/harbor/root/cmd.go b/cmd/harbor/root/cmd.go index 7a3fbf3d..94c4f8a3 100644 --- a/cmd/harbor/root/cmd.go +++ b/cmd/harbor/root/cmd.go @@ -109,6 +109,7 @@ harbor help repositry.Repository(), user.User(), artifact.Artifact(), + HealthCommand(), ) return root diff --git a/cmd/harbor/root/health.go b/cmd/harbor/root/health.go new file mode 100644 index 00000000..9baf4dfa --- /dev/null +++ b/cmd/harbor/root/health.go @@ -0,0 +1,24 @@ +package root + +import ( + "github.com/goharbor/harbor-cli/pkg/api" + "github.com/spf13/cobra" + "github.com/goharbor/harbor-cli/pkg/views/health" +) + +func HealthCommand() *cobra.Command { + cmd := &cobra.Command{ + Use: "health", + Short: "Get the health status of Harbor components", + RunE: func(cmd *cobra.Command, args []string) error { + status, err := api.GetHealth() + if err != nil { + return err + } + health.PrintHealthStatus(status) + return nil + }, + } + + return cmd +} diff --git a/pkg/api/health_handler.go b/pkg/api/health_handler.go new file mode 100644 index 00000000..d8eceb37 --- /dev/null +++ b/pkg/api/health_handler.go @@ -0,0 +1,22 @@ +package api + +import ( + "fmt" + + "github.com/goharbor/go-client/pkg/sdk/v2.0/client/health" + "github.com/goharbor/harbor-cli/pkg/utils" +) + +func GetHealth() (*health.GetHealthOK, error) { + ctx, client, err := utils.ContextWithClient() + if err != nil { + return nil, err + } + + response, err := client.Health.GetHealth(ctx,&health.GetHealthParams{}) + if err != nil { + return nil, fmt.Errorf("error getting health status: %w", err) + } + + return response, nil +} diff --git a/pkg/views/health/view.go b/pkg/views/health/view.go new file mode 100644 index 00000000..31813d15 --- /dev/null +++ b/pkg/views/health/view.go @@ -0,0 +1,42 @@ +package health + +import ( + "fmt" + "os" + + "github.com/charmbracelet/bubbles/table" + "github.com/charmbracelet/bubbletea" + "github.com/goharbor/go-client/pkg/sdk/v2.0/client/health" + "github.com/goharbor/harbor-cli/pkg/views" + "github.com/goharbor/harbor-cli/pkg/views/base/tablelist" +) + +var columns = []table.Column{ + {Title: "Component", Width: 18}, + {Title: "Status", Width: 26}, +} + +func PrintHealthStatus(status *health.GetHealthOK) { + var rows []table.Row + fmt.Printf("Harbor Health Status:: %s\n", styleStatus(status.Payload.Status)) + for _, component := range status.Payload.Components { + rows = append(rows, table.Row{ + component.Name, + styleStatus(component.Status), + }) + } + + m := tablelist.NewModel(columns, rows, len(rows)) + + if _, err := tea.NewProgram(m).Run(); err != nil { + fmt.Println("Error running program:", err) + os.Exit(1) + } +} + +func styleStatus(status string) string { + if status == "healthy" { + return views.GreenStyle.Render(status) + } + return views.RedStyle.Render(status) +} \ No newline at end of file diff --git a/pkg/views/styles.go b/pkg/views/styles.go index 89efa04e..b00c92be 100644 --- a/pkg/views/styles.go +++ b/pkg/views/styles.go @@ -11,6 +11,8 @@ var ( SelectedItemStyle = lipgloss.NewStyle().PaddingLeft(2).Foreground(lipgloss.Color("170")) PaginationStyle = list.DefaultStyles().PaginationStyle.PaddingLeft(4) HelpStyle = list.DefaultStyles().HelpStyle.PaddingLeft(4).PaddingBottom(1) + RedStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("#FF0000")) + GreenStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("#04B575")) ) var BaseStyle = lipgloss.NewStyle().