Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion pkg/cmd/worker/listening-tentacle/view/view.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ func NewCmdView(f factory.Factory) *cobra.Command {
$ %[1]s worker listening-tentacle view Machines-100
`, constants.ExecutableName),
RunE: func(c *cobra.Command, args []string) error {
opts := shared.NewViewOptions(flags, cmd.NewDependencies(f, c), args)
opts := shared.NewViewOptions(flags, cmd.NewDependencies(f, c), args, c)
return ViewRun(opts)
},
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/cmd/worker/polling-tentacle/view/view.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ func NewCmdView(f factory.Factory) *cobra.Command {
$ %[1]s worker polling-tentacle view Machines-100
`, constants.ExecutableName),
RunE: func(c *cobra.Command, args []string) error {
opts := shared.NewViewOptions(flags, cmd.NewDependencies(f, c), args)
opts := shared.NewViewOptions(flags, cmd.NewDependencies(f, c), args, c)
return ViewRun(opts)
},
}
Expand Down
5 changes: 4 additions & 1 deletion pkg/cmd/worker/shared/view.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"github.com/OctopusDeploy/cli/pkg/machinescommon"
"github.com/OctopusDeploy/cli/pkg/output"
"github.com/OctopusDeploy/go-octopusdeploy/v2/pkg/machines"
"github.com/spf13/cobra"
)

type ContributeEndpointCallback func(opts *ViewOptions, endpoint machines.IEndpoint) ([]*output.DataRow, error)
Expand All @@ -18,6 +19,7 @@ type ViewOptions struct {
*cmd.Dependencies
IdOrName string
*ViewFlags
Command *cobra.Command
}

func NewViewFlags() *ViewFlags {
Expand All @@ -26,11 +28,12 @@ func NewViewFlags() *ViewFlags {
}
}

func NewViewOptions(viewFlags *ViewFlags, dependencies *cmd.Dependencies, args []string) *ViewOptions {
func NewViewOptions(viewFlags *ViewFlags, dependencies *cmd.Dependencies, args []string, command *cobra.Command) *ViewOptions {
return &ViewOptions{
ViewFlags: viewFlags,
Dependencies: dependencies,
IdOrName: args[0],
Command: command,
}
}

Expand Down
2 changes: 1 addition & 1 deletion pkg/cmd/worker/ssh/view/view.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ func NewCmdView(f factory.Factory) *cobra.Command {
$ %[1]s worker ssh view Machines-100
`, constants.ExecutableName),
RunE: func(c *cobra.Command, args []string) error {
opts := shared.NewViewOptions(flags, cmd.NewDependencies(f, c), args)
opts := shared.NewViewOptions(flags, cmd.NewDependencies(f, c), args, c)
return ViewRun(opts)
},
}
Expand Down
174 changes: 165 additions & 9 deletions pkg/cmd/worker/view/view.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,18 @@ package view

import (
"fmt"
"strings"

"github.com/MakeNowJust/heredoc/v2"
"github.com/OctopusDeploy/cli/pkg/cmd"
listeningTentacle "github.com/OctopusDeploy/cli/pkg/cmd/worker/listening-tentacle/view"
pollingTentacle "github.com/OctopusDeploy/cli/pkg/cmd/worker/polling-tentacle/view"
"github.com/OctopusDeploy/cli/pkg/cmd/worker/shared"
ssh "github.com/OctopusDeploy/cli/pkg/cmd/worker/ssh/view"
"github.com/OctopusDeploy/cli/pkg/constants"
"github.com/OctopusDeploy/cli/pkg/factory"
"github.com/OctopusDeploy/cli/pkg/machinescommon"
"github.com/OctopusDeploy/cli/pkg/output"
"github.com/OctopusDeploy/cli/pkg/usage"
"github.com/OctopusDeploy/cli/pkg/util"
"github.com/OctopusDeploy/go-octopusdeploy/v2/pkg/machines"
"github.com/spf13/cobra"
)

Expand All @@ -28,7 +29,7 @@ func NewCmdView(f factory.Factory) *cobra.Command {
$ %[1]s worker view 'worker'
`, constants.ExecutableName),
RunE: func(c *cobra.Command, args []string) error {
return ViewRun(shared.NewViewOptions(flags, cmd.NewDependencies(f, c), args))
return ViewRun(shared.NewViewOptions(flags, cmd.NewDependencies(f, c), args, c))
},
}

Expand All @@ -43,14 +44,169 @@ func ViewRun(opts *shared.ViewOptions) error {
return err
}

switch worker.Endpoint.GetCommunicationStyle() {
err = output.PrintResource(worker, opts.Command, output.Mappers[*machines.Worker]{
Json: func(w *machines.Worker) any {
return getWorkerAsJson(opts, w)
},
Table: output.TableDefinition[*machines.Worker]{
Header: []string{"NAME", "TYPE", "HEALTH", "STATUS", "WORKER POOLS", "ENDPOINT DETAILS"},
Row: func(w *machines.Worker) []string {
return getWorkerAsTableRow(opts, w)
},
},
Basic: func(w *machines.Worker) string {
return getWorkerAsBasic(opts, w)
},
})
if err != nil {
return err
}

if opts.WebFlags != nil && opts.WebFlags.Web.Value {
machinescommon.DoWebForWorkers(worker, opts.Dependencies, opts.WebFlags, getWorkerTypeDisplayName(worker.Endpoint.GetCommunicationStyle()))
}

return nil
}

type WorkerAsJson struct {
Id string `json:"Id"`
Name string `json:"Name"`
HealthStatus string `json:"HealthStatus"`
StatusSummary string `json:"StatusSummary"`
CommunicationStyle string `json:"CommunicationStyle"`
WorkerPools []string `json:"WorkerPools"`
EndpointDetails map[string]string `json:"EndpointDetails"`
WebUrl string `json:"WebUrl"`
}

func getWorkerAsJson(opts *shared.ViewOptions, worker *machines.Worker) WorkerAsJson {
workerPoolMap, _ := shared.GetWorkerPoolMap(opts)
workerPoolNames := resolveValues(worker.WorkerPoolIDs, workerPoolMap)

endpointDetails := getEndpointDetails(worker)

return WorkerAsJson{
Id: worker.GetID(),
Name: worker.Name,
HealthStatus: worker.HealthStatus,
StatusSummary: worker.StatusSummary,
CommunicationStyle: worker.Endpoint.GetCommunicationStyle(),
WorkerPools: workerPoolNames,
EndpointDetails: endpointDetails,
WebUrl: util.GenerateWebURL(opts.Host, worker.SpaceID, fmt.Sprintf("infrastructure/workers/%s/settings", worker.GetID())),
}
}

func getWorkerAsTableRow(opts *shared.ViewOptions, worker *machines.Worker) []string {
workerPoolMap, _ := shared.GetWorkerPoolMap(opts)
workerPoolNames := resolveValues(worker.WorkerPoolIDs, workerPoolMap)

endpointDetails := getEndpointDetails(worker)
endpointDetailsStr := formatEndpointDetailsForTable(endpointDetails)

return []string{
worker.Name,
getWorkerTypeDisplayName(worker.Endpoint.GetCommunicationStyle()),
getHealthStatusFormatted(worker.HealthStatus),
worker.StatusSummary,
strings.Join(workerPoolNames, ", "),
endpointDetailsStr,
}
}

func getWorkerAsBasic(opts *shared.ViewOptions, worker *machines.Worker) string {
var result strings.Builder

result.WriteString(fmt.Sprintf("%s %s\n", output.Bold(worker.Name), output.Dimf("(%s)", worker.GetID())))
result.WriteString(fmt.Sprintf("Health status: %s\n", getHealthStatusFormatted(worker.HealthStatus)))
result.WriteString(fmt.Sprintf("Current status: %s\n", worker.StatusSummary))
result.WriteString(fmt.Sprintf("Communication style: %s\n", getWorkerTypeDisplayName(worker.Endpoint.GetCommunicationStyle())))

workerPoolMap, _ := shared.GetWorkerPoolMap(opts)
workerPoolNames := resolveValues(worker.WorkerPoolIDs, workerPoolMap)
result.WriteString(fmt.Sprintf("Worker Pools: %s\n", output.FormatAsList(workerPoolNames)))

// Add endpoint-specific details
endpointDetails := getEndpointDetails(worker)
for key, value := range endpointDetails {
result.WriteString(fmt.Sprintf("%s: %s\n", key, value))
}

// Web URL
url := util.GenerateWebURL(opts.Host, worker.SpaceID, fmt.Sprintf("infrastructure/workers/%s/settings", worker.GetID()))
result.WriteString(fmt.Sprintf("\nView this worker in Octopus Deploy: %s\n", output.Blue(url)))

return result.String()
}

func getHealthStatusFormatted(status string) string {
switch status {
case "Healthy":
return output.Green(status)
case "Unhealthy":
return output.Red(status)
case "HasWarnings":
return output.Yellow("Has Warnings")
case "Unavailable":
return output.Dim(status)
default:
return status
}
}

func getWorkerTypeDisplayName(communicationStyle string) string {
switch communicationStyle {
case "TentaclePassive":
return listeningTentacle.ViewRun(opts)
return "Listening Tentacle"
case "TentacleActive":
return pollingTentacle.ViewRun(opts)
return "Polling Tentacle"
case "Ssh":
return ssh.ViewRun(opts)
return "SSH"
default:
return communicationStyle
}
}

func getEndpointDetails(worker *machines.Worker) map[string]string {
details := make(map[string]string)

switch endpoint := worker.Endpoint.(type) {
case *machines.ListeningTentacleEndpoint:
details["URI"] = endpoint.URI.String()
if endpoint.TentacleVersionDetails != nil {
details["Tentacle version"] = endpoint.TentacleVersionDetails.Version
}
case *machines.PollingTentacleEndpoint:
if endpoint.TentacleVersionDetails != nil {
details["Tentacle version"] = endpoint.TentacleVersionDetails.Version
}
case *machines.SSHEndpoint:
details["URI"] = endpoint.URI.String()
if endpoint.DotNetCorePlatform != "" {
details["Platform"] = endpoint.DotNetCorePlatform
}
}

return fmt.Errorf("unsupported worker '%s'", worker.Endpoint.GetCommunicationStyle())
return details
}

func formatEndpointDetailsForTable(details map[string]string) string {
var parts []string
for key, value := range details {
parts = append(parts, fmt.Sprintf("%s: %s", key, value))
}
return strings.Join(parts, "; ")
}

func resolveValues(keys []string, lookup map[string]string) []string {
var result []string
for _, key := range keys {
if value, exists := lookup[key]; exists {
result = append(result, value)
} else {
result = append(result, key)
}
}
return result
}
2 changes: 1 addition & 1 deletion pkg/cmd/workerpool/dynamic/view/view.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ func NewCmdView(f factory.Factory) *cobra.Command {
$ %[1]s worker-pool dynamic view 'Hosted Workers'
`, constants.ExecutableName),
RunE: func(c *cobra.Command, args []string) error {
return ViewRun(shared.NewViewOptions(flags, cmd.NewDependencies(f, c), args))
return ViewRun(shared.NewViewOptions(flags, cmd.NewDependencies(f, c), args, c))
},
}

Expand Down
5 changes: 4 additions & 1 deletion pkg/cmd/workerpool/shared/view.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"github.com/OctopusDeploy/cli/pkg/machinescommon"
"github.com/OctopusDeploy/cli/pkg/output"
"github.com/OctopusDeploy/go-octopusdeploy/v2/pkg/workerpools"
"github.com/spf13/cobra"
)

type ContributeDetailsCallback func(opts *ViewOptions, workerPool workerpools.IWorkerPool) ([]*output.DataRow, error)
Expand All @@ -18,6 +19,7 @@ type ViewOptions struct {
*cmd.Dependencies
IdOrName string
*ViewFlags
Command *cobra.Command
}

func NewViewFlags() *ViewFlags {
Expand All @@ -26,11 +28,12 @@ func NewViewFlags() *ViewFlags {
}
}

func NewViewOptions(viewFlags *ViewFlags, dependencies *cmd.Dependencies, args []string) *ViewOptions {
func NewViewOptions(viewFlags *ViewFlags, dependencies *cmd.Dependencies, args []string, command *cobra.Command) *ViewOptions {
return &ViewOptions{
ViewFlags: viewFlags,
Dependencies: dependencies,
IdOrName: args[0],
Command: command,
}
}

Expand Down
2 changes: 1 addition & 1 deletion pkg/cmd/workerpool/static/view/view.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ func NewCmdView(f factory.Factory) *cobra.Command {
$ %[1]s worker-pool static view 'windows workers'
`, constants.ExecutableName),
RunE: func(c *cobra.Command, args []string) error {
return ViewRun(shared.NewViewOptions(flags, cmd.NewDependencies(f, c), args))
return ViewRun(shared.NewViewOptions(flags, cmd.NewDependencies(f, c), args, c))
},
}

Expand Down
Loading
Loading