Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 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: getHealthStatusFormatted(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