From 9729c980bbd89507a61dc192fe1db380ce137548 Mon Sep 17 00:00:00 2001 From: benPearce1 Date: Fri, 15 May 2026 11:41:50 +1000 Subject: [PATCH 1/3] fix: added azure default worker pool to deployment-target view command --- pkg/cmd/target/shared/view.go | 13 +++++++++ pkg/cmd/target/view/view.go | 54 +++++++++++++++++++++++++++++++---- 2 files changed, 62 insertions(+), 5 deletions(-) diff --git a/pkg/cmd/target/shared/view.go b/pkg/cmd/target/shared/view.go index f1bbe3ca..76573fa0 100644 --- a/pkg/cmd/target/shared/view.go +++ b/pkg/cmd/target/shared/view.go @@ -2,6 +2,7 @@ package shared import ( "fmt" + "github.com/OctopusDeploy/cli/pkg/cmd" "github.com/OctopusDeploy/cli/pkg/machinescommon" "github.com/OctopusDeploy/cli/pkg/output" @@ -142,6 +143,18 @@ func GetEnvironmentMap(opts *ViewOptions) (map[string]string, error) { return environmentMap, nil } +func GetWorkerPoolMap(opts *ViewOptions) (map[string]string, error) { + workerPoolMap := make(map[string]string) + allWorkerPools, err := opts.Client.WorkerPools.GetAll() + if err != nil { + return nil, err + } + for _, wp := range allWorkerPools { + workerPoolMap[wp.ID] = wp.Name + } + return workerPoolMap, nil +} + func GetTenantMap(opts *ViewOptions) (map[string]string, error) { tenantMap := make(map[string]string) allEnvs, err := opts.Client.Tenants.GetAll() diff --git a/pkg/cmd/target/view/view.go b/pkg/cmd/target/view/view.go index fa270f95..8baeb705 100644 --- a/pkg/cmd/target/view/view.go +++ b/pkg/cmd/target/view/view.go @@ -46,10 +46,13 @@ func ViewRun(opts *shared.ViewOptions) error { return output.PrintResource(target, opts.Command, output.Mappers[*machines.DeploymentTarget]{ Json: func(t *machines.DeploymentTarget) any { + if target.Endpoint.GetCommunicationStyle() == "AzureWebApp" { + return getAzureDeploymentTargetAsJson(opts, t) + } return getDeploymentTargetAsJson(opts, t) }, Table: output.TableDefinition[*machines.DeploymentTarget]{ - Header: []string{"NAME", "TYPE", "HEALTH", "ENVIRONMENTS", "ROLES", "TENANTS", "TENANT TAGS", "ENDPOINT DETAILS"}, + Header: []string{"NAME", "TYPE", "HEALTH", "ENVIRONMENTS", "ROLES", "TENANTS", "TENANT TAGS", "ENDPOINT DETAILS", "DEFAULT WORKER POOL"}, Row: func(t *machines.DeploymentTarget) []string { return getDeploymentTargetAsTableRow(opts, t) }, @@ -74,6 +77,11 @@ type DeploymentTargetAsJson struct { WebUrl string `json:"WebUrl"` } +type AzureDeploymentTargetAsJson struct { + DeploymentTargetAsJson + DefaultWorkerPool string `json:"DefaultWorkerPool"` +} + func getDeploymentTargetAsJson(opts *shared.ViewOptions, target *machines.DeploymentTarget) DeploymentTargetAsJson { environmentMap, _ := shared.GetEnvironmentMap(opts) tenantMap, _ := shared.GetTenantMap(opts) @@ -81,7 +89,7 @@ func getDeploymentTargetAsJson(opts *shared.ViewOptions, target *machines.Deploy environments := resolveValues(target.EnvironmentIDs, environmentMap) tenants := resolveValues(target.TenantIDs, tenantMap) - endpointDetails := getEndpointDetails(target) + endpointDetails := getEndpointDetails(target, opts) return DeploymentTargetAsJson{ Id: target.GetID(), @@ -98,6 +106,17 @@ func getDeploymentTargetAsJson(opts *shared.ViewOptions, target *machines.Deploy } } +func getAzureDeploymentTargetAsJson(opts *shared.ViewOptions, target *machines.DeploymentTarget) AzureDeploymentTargetAsJson { + deploymentTargetAsJson := getDeploymentTargetAsJson(opts, target) + workerPool := resolveDefaultWorkerPool(target, opts) + var azureTargetAsJson = AzureDeploymentTargetAsJson{ + DeploymentTargetAsJson: deploymentTargetAsJson, + DefaultWorkerPool: workerPool, + } + return azureTargetAsJson + +} + func getDeploymentTargetAsTableRow(opts *shared.ViewOptions, target *machines.DeploymentTarget) []string { environmentMap, _ := shared.GetEnvironmentMap(opts) environments := resolveValues(target.EnvironmentIDs, environmentMap) @@ -120,7 +139,7 @@ func getDeploymentTargetAsTableRow(opts *shared.ViewOptions, target *machines.De } // Handle endpoint details - endpointDetails := getEndpointDetails(target) + endpointDetails := getEndpointDetails(target, opts) var endpointDetailsStr strings.Builder first := true for key, value := range endpointDetails { @@ -135,6 +154,8 @@ func getDeploymentTargetAsTableRow(opts *shared.ViewOptions, target *machines.De endpointDetailsString = "-" } + workerPool := resolveDefaultWorkerPool(target, opts) + return []string{ output.Bold(target.Name), targetType, @@ -144,6 +165,7 @@ func getDeploymentTargetAsTableRow(opts *shared.ViewOptions, target *machines.De tenants, tenantTags, endpointDetailsString, + workerPool, } } @@ -203,7 +225,7 @@ func getDeploymentTargetAsBasic(opts *shared.ViewOptions, target *machines.Deplo result.WriteString(fmt.Sprintf("Type: %s\n", output.Cyan(targetType))) // Add endpoint-specific details - endpointDetails := getEndpointDetails(target) + endpointDetails := getEndpointDetails(target, opts) for key, value := range endpointDetails { result.WriteString(fmt.Sprintf("%s: %s\n", key, value)) } @@ -232,6 +254,15 @@ func getDeploymentTargetAsBasic(opts *shared.ViewOptions, target *machines.Deplo result.WriteString("Tenant Tags: None\n") } + // default worker pool + if target.Endpoint.GetCommunicationStyle() == "AzureWebApp" { + workerPool := resolveDefaultWorkerPool(target, opts) + if workerPool == "" { + workerPool = "None" + } + result.WriteString(fmt.Sprintf("Default Worker Pool: %s\n", workerPool)) + } + // Web URL url := util.GenerateWebURL(opts.Host, target.SpaceID, fmt.Sprintf("infrastructure/machines/%s/settings", target.GetID())) result.WriteString(fmt.Sprintf("\nView this deployment target in Octopus Deploy: %s\n", output.Blue(url))) @@ -256,7 +287,7 @@ func resolveValues(keys []string, lookup map[string]string) []string { return values } -func getEndpointDetails(target *machines.DeploymentTarget) map[string]string { +func getEndpointDetails(target *machines.DeploymentTarget, opts *shared.ViewOptions) map[string]string { details := make(map[string]string) switch target.Endpoint.GetCommunicationStyle() { @@ -299,3 +330,16 @@ func getEndpointDetails(target *machines.DeploymentTarget) map[string]string { return details } + +func resolveDefaultWorkerPool(target *machines.DeploymentTarget, opts *shared.ViewOptions) string { + if endpoint, ok := target.Endpoint.(*machines.AzureWebAppEndpoint); ok { + if endpoint.DefaultWorkerPoolID != "" { + workerPoolMap, _ := shared.GetWorkerPoolMap(opts) + return resolveValues([]string{endpoint.DefaultWorkerPoolID}, workerPoolMap)[0] + } else { + return "" + } + } + + return "N/A" +} From bb5d7c5eac28ff27f74f98ccc8adcf608e10485e Mon Sep 17 00:00:00 2001 From: benPearce1 Date: Fri, 15 May 2026 11:54:03 +1000 Subject: [PATCH 2/3] fix: added default worker pool to deployment-target azure-web-app view command --- pkg/cmd/target/shared/view.go | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/pkg/cmd/target/shared/view.go b/pkg/cmd/target/shared/view.go index 76573fa0..80adb7c2 100644 --- a/pkg/cmd/target/shared/view.go +++ b/pkg/cmd/target/shared/view.go @@ -88,6 +88,15 @@ func ViewRun(opts *ViewOptions, contributeEndpoint ContributeEndpointCallback, d data = append(data, output.NewDataRow("Tenant Tags", "None")) } + if endpoint, ok := target.Endpoint.(*machines.AzureWebAppEndpoint); ok { + workerPoolName := "None" + if endpoint.DefaultWorkerPoolID != "" { + workerPoolMap, _ := GetWorkerPoolMap(opts) + workerPoolName = resolveValues([]string{endpoint.DefaultWorkerPoolID}, workerPoolMap)[0] + } + data = append(data, output.NewDataRow("Default Worker Pool", workerPoolName)) + } + t := output.NewTable(opts.Out) for _, row := range data { t.AddRow(row.Name, row.Value) From cce945ec3c6ce11da5443bdfde08aca489aeab81 Mon Sep 17 00:00:00 2001 From: benPearce1 Date: Wed, 20 May 2026 16:35:39 +1000 Subject: [PATCH 3/3] Extended default worker pool display to all targets implementing IRunOnWorker interface cleaned up duplicated code between target list and view commands --- go.mod | 2 +- go.sum | 4 +- pkg/cmd/target/list/list.go | 65 +++------------ pkg/cmd/target/shared/json.go | 61 ++++++++++++++ pkg/cmd/target/shared/target.go | 48 ++++++++++- pkg/cmd/target/shared/view.go | 41 ++++++---- pkg/cmd/target/view/view.go | 137 ++++++-------------------------- pkg/cmd/tenant/list/list.go | 2 +- pkg/cmd/tenant/shared/shared.go | 2 +- pkg/cmd/tenant/view/view.go | 2 +- 10 files changed, 175 insertions(+), 189 deletions(-) create mode 100644 pkg/cmd/target/shared/json.go diff --git a/go.mod b/go.mod index 6fddc442..a2f4f3ac 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,7 @@ require ( github.com/AlecAivazis/survey/v2 v2.3.7 github.com/MakeNowJust/heredoc/v2 v2.0.1 github.com/OctopusDeploy/go-octodiff v1.0.0 - github.com/OctopusDeploy/go-octopusdeploy/v2 v2.108.0 + github.com/OctopusDeploy/go-octopusdeploy/v2 v2.108.1 github.com/bmatcuk/doublestar/v4 v4.4.0 github.com/briandowns/spinner v1.19.0 github.com/google/uuid v1.3.0 diff --git a/go.sum b/go.sum index 232b3b40..56c25587 100644 --- a/go.sum +++ b/go.sum @@ -46,8 +46,8 @@ github.com/Netflix/go-expect v0.0.0-20220104043353-73e0943537d2 h1:+vx7roKuyA63n github.com/Netflix/go-expect v0.0.0-20220104043353-73e0943537d2/go.mod h1:HBCaDeC1lPdgDeDbhX8XFpy1jqjK0IBG8W5K+xYqA0w= github.com/OctopusDeploy/go-octodiff v1.0.0 h1:U+ORg6azniwwYo+O44giOw6TiD5USk8S4VDhOQ0Ven0= github.com/OctopusDeploy/go-octodiff v1.0.0/go.mod h1:Mze0+EkOWTgTmi8++fyUc6r0aLZT7qD9gX+31t8MmIU= -github.com/OctopusDeploy/go-octopusdeploy/v2 v2.108.0 h1:hUnkq49u3gRiZSisRF9L86gPygKK4qS9LMoO5ADTGKI= -github.com/OctopusDeploy/go-octopusdeploy/v2 v2.108.0/go.mod h1:VkTXDoIPbwGFi5+goo1VSwFNdMVo784cVtJdKIEvfus= +github.com/OctopusDeploy/go-octopusdeploy/v2 v2.108.1 h1:THcIJGQyhhzSx8/b7ibYnyFlwktF8/U+xwXfC373N1U= +github.com/OctopusDeploy/go-octopusdeploy/v2 v2.108.1/go.mod h1:VkTXDoIPbwGFi5+goo1VSwFNdMVo784cVtJdKIEvfus= github.com/bmatcuk/doublestar/v4 v4.4.0 h1:LmAwNwhjEbYtyVLzjcP/XeVw4nhuScHGkF/XWXnvIic= github.com/bmatcuk/doublestar/v4 v4.4.0/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc= github.com/briandowns/spinner v1.19.0 h1:s8aq38H+Qju89yhp89b4iIiMzMm8YN3p6vGpwyh/a8E= diff --git a/pkg/cmd/target/list/list.go b/pkg/cmd/target/list/list.go index 1b28b5c6..89f365dc 100644 --- a/pkg/cmd/target/list/list.go +++ b/pkg/cmd/target/list/list.go @@ -55,46 +55,32 @@ func ListRun(opts *ListOptions) error { return err } - type TargetAsJson struct { - Id string `json:"Id"` - Name string `json:"Name"` - Type string `json:"Type"` - Roles []string `json:"Roles"` - Environments []Entity `json:"Environments"` - Tenants []Entity `json:"Tenants"` - TenantTags []string `json:"TenantTags"` + environmentMap, err := shared.GetEnvironmentMap(opts.Client) + if err != nil { + return err } - environmentMap, err := GetEnvironmentMap(opts) + tenantMap, err := shared.GetTenantMap(opts.Client) if err != nil { return err } - tenantMap, err := GetTenantMap(opts) + workerPoolMap, err := shared.GetWorkerPoolMap(opts.Client) if err != nil { return err } return output.PrintArray(allTargets, opts.Command, output.Mappers[*machines.DeploymentTarget]{ Json: func(item *machines.DeploymentTarget) any { - environments := resolveEntities(item.EnvironmentIDs, environmentMap) - tenants := resolveEntities(item.TenantIDs, tenantMap) - return TargetAsJson{ - Id: item.GetID(), - Name: item.Name, - Type: machinescommon.CommunicationStyleToDeploymentTargetTypeMap[item.Endpoint.GetCommunicationStyle()], - Roles: item.Roles, - Environments: environments, - Tenants: tenants, - TenantTags: item.TenantTags, - } + return shared.GetDeploymentTargetAsJson(opts.Dependencies, item) }, Table: output.TableDefinition[*machines.DeploymentTarget]{ - Header: []string{"NAME", "TYPE", "ROLES", "ENVIRONMENTS", "TENANTS", "TAGS"}, + Header: []string{"NAME", "TYPE", "ROLES", "ENVIRONMENTS", "TENANTS", "TAGS", "DEFAULT WORKER POOL"}, Row: func(item *machines.DeploymentTarget) []string { environmentNames := resolveValues(item.EnvironmentIDs, environmentMap) tenantNames := resolveValues(item.TenantIDs, tenantMap) - return []string{output.Bold(item.Name), machinescommon.CommunicationStyleToDescriptionMap[item.Endpoint.GetCommunicationStyle()], output.FormatAsList(item.Roles), output.FormatAsList(environmentNames), output.FormatAsList(tenantNames), output.FormatAsList(item.TenantTags)} + workerPool := shared.ResolveDefaultWorkerPool(item, workerPoolMap, "None") + return []string{output.Bold(item.Name), machinescommon.CommunicationStyleToDescriptionMap[item.Endpoint.GetCommunicationStyle()], output.FormatAsList(item.Roles), output.FormatAsList(environmentNames), output.FormatAsList(tenantNames), output.FormatAsList(item.TenantTags), workerPool} }, }, Basic: func(item *machines.DeploymentTarget) string { @@ -110,36 +96,3 @@ func resolveValues(keys []string, lookup map[string]string) []string { } return values } - -func resolveEntities(keys []string, lookup map[string]string) []Entity { - var entities []Entity - for _, k := range keys { - entities = append(entities, Entity{Id: k, Name: lookup[k]}) - } - - return entities -} - -func GetEnvironmentMap(opts *ListOptions) (map[string]string, error) { - environmentMap := make(map[string]string) - allEnvs, err := opts.Client.Environments.GetAll() - if err != nil { - return nil, err - } - for _, e := range allEnvs { - environmentMap[e.GetID()] = e.GetName() - } - return environmentMap, nil -} - -func GetTenantMap(opts *ListOptions) (map[string]string, error) { - tenantMap := make(map[string]string) - allEnvs, err := opts.Client.Tenants.GetAll() - if err != nil { - return nil, err - } - for _, e := range allEnvs { - tenantMap[e.GetID()] = e.Name - } - return tenantMap, nil -} diff --git a/pkg/cmd/target/shared/json.go b/pkg/cmd/target/shared/json.go new file mode 100644 index 00000000..464ee3fe --- /dev/null +++ b/pkg/cmd/target/shared/json.go @@ -0,0 +1,61 @@ +package shared + +import ( + "fmt" + + "github.com/OctopusDeploy/cli/pkg/cmd" + "github.com/OctopusDeploy/cli/pkg/util" + "github.com/OctopusDeploy/go-octopusdeploy/v2/pkg/machines" +) + +type DeploymentTargetAsJson struct { + Id string `json:"Id"` + Name string `json:"Name"` + HealthStatus string `json:"HealthStatus"` + StatusSummary string `json:"StatusSummary"` + CommunicationStyle string `json:"CommunicationStyle"` + Environments []string `json:"Environments"` + Roles []string `json:"Roles"` + Tenants []string `json:"Tenants"` + TenantTags []string `json:"TenantTags"` + EndpointDetails map[string]string `json:"EndpointDetails"` + WebUrl string `json:"WebUrl"` +} + +type DeploymentTargetWithWorkerPool struct { + DeploymentTargetAsJson + DefaultWorkerPool string `json:"DefaultWorkerPool"` +} + +func GetDeploymentTargetAsJson(deps *cmd.Dependencies, target *machines.DeploymentTarget) any { + environmentMap, _ := GetEnvironmentMap(deps.Client) + tenantMap, _ := GetTenantMap(deps.Client) + + environments := resolveValues(target.EnvironmentIDs, environmentMap) + tenants := resolveValues(target.TenantIDs, tenantMap) + + endpointDetails := GetEndpointDetails(target) + + targetJson := DeploymentTargetAsJson{ + Id: target.GetID(), + Name: target.Name, + HealthStatus: target.HealthStatus, + StatusSummary: target.StatusSummary, + CommunicationStyle: target.Endpoint.GetCommunicationStyle(), + Environments: environments, + Roles: target.Roles, + Tenants: tenants, + TenantTags: target.TenantTags, + EndpointDetails: endpointDetails, + WebUrl: util.GenerateWebURL(deps.Host, target.SpaceID, fmt.Sprintf("infrastructure/machines/%s/settings", target.GetID())), + } + + if workerEndpoint, ok := target.Endpoint.(machines.IRunsOnAWorker); ok { + return DeploymentTargetWithWorkerPool{ + DeploymentTargetAsJson: targetJson, + DefaultWorkerPool: workerEndpoint.GetDefaultWorkerPoolID(), + } + } + + return targetJson +} diff --git a/pkg/cmd/target/shared/target.go b/pkg/cmd/target/shared/target.go index 99ad7a22..6dd8cb85 100644 --- a/pkg/cmd/target/shared/target.go +++ b/pkg/cmd/target/shared/target.go @@ -1,10 +1,12 @@ package shared import ( + "fmt" + "math" + "github.com/OctopusDeploy/cli/pkg/cmd" "github.com/OctopusDeploy/go-octopusdeploy/v2/pkg/client" "github.com/OctopusDeploy/go-octopusdeploy/v2/pkg/machines" - "math" ) type GetTargetsCallback func() ([]*machines.DeploymentTarget, error) @@ -38,3 +40,47 @@ func GetAllTargets(client client.Client, query machines.MachinesQuery) ([]*machi } return res.Items, nil } + +func GetEndpointDetails(target *machines.DeploymentTarget) map[string]string { + details := make(map[string]string) + + switch target.Endpoint.GetCommunicationStyle() { + case "AzureWebApp": + if endpoint, ok := target.Endpoint.(*machines.AzureWebAppEndpoint); ok { + webApp := endpoint.WebAppName + if endpoint.WebAppSlotName != "" { + webApp = fmt.Sprintf("%s/%s", webApp, endpoint.WebAppSlotName) + } + details["Web App"] = webApp + } + case "Kubernetes": + if endpoint, ok := target.Endpoint.(*machines.KubernetesEndpoint); ok { + details["Authentication Type"] = endpoint.Authentication.GetAuthenticationType() + } + case "Ssh": + if endpoint, ok := target.Endpoint.(*machines.SSHEndpoint); ok { + details["URI"] = endpoint.URI.String() + runtime := "Mono" + if endpoint.DotNetCorePlatform != "" { + runtime = endpoint.DotNetCorePlatform + } + details["Runtime architecture"] = runtime + } + case "TentaclePassive": + if endpoint, ok := target.Endpoint.(*machines.ListeningTentacleEndpoint); ok { + details["URI"] = endpoint.URI.String() + details["Tentacle version"] = endpoint.TentacleVersionDetails.Version + } + case "TentacleActive": + if endpoint, ok := target.Endpoint.(*machines.PollingTentacleEndpoint); ok { + details["URI"] = endpoint.URI.String() + details["Tentacle version"] = endpoint.TentacleVersionDetails.Version + } + case "None": + // Cloud regions typically don't have additional endpoint details + case "OfflineDrop", "StepPackage", "AzureCloudService", "AzureServiceFabricCluster": + // These endpoints don't have specific details we can easily extract + } + + return details +} diff --git a/pkg/cmd/target/shared/view.go b/pkg/cmd/target/shared/view.go index 80adb7c2..f40427fc 100644 --- a/pkg/cmd/target/shared/view.go +++ b/pkg/cmd/target/shared/view.go @@ -7,6 +7,7 @@ import ( "github.com/OctopusDeploy/cli/pkg/machinescommon" "github.com/OctopusDeploy/cli/pkg/output" "github.com/OctopusDeploy/cli/pkg/util" + "github.com/OctopusDeploy/go-octopusdeploy/v2/pkg/client" "github.com/OctopusDeploy/go-octopusdeploy/v2/pkg/machines" "github.com/spf13/cobra" ) @@ -61,7 +62,7 @@ func ViewRun(opts *ViewOptions, contributeEndpoint ContributeEndpointCallback, d } } - environmentMap, err := GetEnvironmentMap(opts) + environmentMap, err := GetEnvironmentMap(opts.Client) if err != nil { return err } @@ -71,7 +72,7 @@ func ViewRun(opts *ViewOptions, contributeEndpoint ContributeEndpointCallback, d data = append(data, output.NewDataRow("Roles", output.FormatAsList(target.Roles))) if !util.Empty(target.TenantIDs) { - tenantMap, err := GetTenantMap(opts) + tenantMap, err := GetTenantMap(opts.Client) if err != nil { return err } @@ -88,11 +89,11 @@ func ViewRun(opts *ViewOptions, contributeEndpoint ContributeEndpointCallback, d data = append(data, output.NewDataRow("Tenant Tags", "None")) } - if endpoint, ok := target.Endpoint.(*machines.AzureWebAppEndpoint); ok { + if runsOnAWorker, ok := target.Endpoint.(machines.IRunsOnAWorker); ok { workerPoolName := "None" - if endpoint.DefaultWorkerPoolID != "" { - workerPoolMap, _ := GetWorkerPoolMap(opts) - workerPoolName = resolveValues([]string{endpoint.DefaultWorkerPoolID}, workerPoolMap)[0] + if runsOnAWorker.GetDefaultWorkerPoolID() != "" { + workerPoolMap, _ := GetWorkerPoolMap(opts.Client) + workerPoolName = resolveValues([]string{runsOnAWorker.GetDefaultWorkerPoolID()}, workerPoolMap)[0] } data = append(data, output.NewDataRow("Default Worker Pool", workerPoolName)) } @@ -101,9 +102,9 @@ func ViewRun(opts *ViewOptions, contributeEndpoint ContributeEndpointCallback, d for _, row := range data { t.AddRow(row.Name, row.Value) } - t.Print() + _ = t.Print() - fmt.Fprintf(opts.Out, "\n") + _, _ = fmt.Fprintf(opts.Out, "\n") machinescommon.DoWebForTargets(target, opts.Dependencies, opts.WebFlags, description) return nil } @@ -140,9 +141,9 @@ func getHealthStatus(target *machines.DeploymentTarget) string { } } -func GetEnvironmentMap(opts *ViewOptions) (map[string]string, error) { +func GetEnvironmentMap(client *client.Client) (map[string]string, error) { environmentMap := make(map[string]string) - allEnvs, err := opts.Client.Environments.GetAll() + allEnvs, err := client.Environments.GetAll() if err != nil { return nil, err } @@ -152,9 +153,9 @@ func GetEnvironmentMap(opts *ViewOptions) (map[string]string, error) { return environmentMap, nil } -func GetWorkerPoolMap(opts *ViewOptions) (map[string]string, error) { +func GetWorkerPoolMap(client *client.Client) (map[string]string, error) { workerPoolMap := make(map[string]string) - allWorkerPools, err := opts.Client.WorkerPools.GetAll() + allWorkerPools, err := client.WorkerPools.GetAll() if err != nil { return nil, err } @@ -164,9 +165,9 @@ func GetWorkerPoolMap(opts *ViewOptions) (map[string]string, error) { return workerPoolMap, nil } -func GetTenantMap(opts *ViewOptions) (map[string]string, error) { +func GetTenantMap(client *client.Client) (map[string]string, error) { tenantMap := make(map[string]string) - allEnvs, err := opts.Client.Tenants.GetAll() + allEnvs, err := client.Tenants.GetAll() if err != nil { return nil, err } @@ -183,3 +184,15 @@ func resolveValues(keys []string, lookup map[string]string) []string { } return values } + +func ResolveDefaultWorkerPool(target *machines.DeploymentTarget, workerPoolMap map[string]string, emptyValue string) string { + if endpoint, ok := target.Endpoint.(machines.IRunsOnAWorker); ok { + if endpoint.GetDefaultWorkerPoolID() != "" { + return resolveValues([]string{endpoint.GetDefaultWorkerPoolID()}, workerPoolMap)[0] + } else { + return emptyValue + } + } + + return "N/A" +} diff --git a/pkg/cmd/target/view/view.go b/pkg/cmd/target/view/view.go index 8baeb705..6074eb7e 100644 --- a/pkg/cmd/target/view/view.go +++ b/pkg/cmd/target/view/view.go @@ -44,17 +44,18 @@ func ViewRun(opts *shared.ViewOptions) error { return err } + environmentMap, _ := shared.GetEnvironmentMap(opts.Client) + workerPoolMap, _ := shared.GetWorkerPoolMap(opts.Client) + tenantMap, _ := shared.GetTenantMap(opts.Client) + return output.PrintResource(target, opts.Command, output.Mappers[*machines.DeploymentTarget]{ Json: func(t *machines.DeploymentTarget) any { - if target.Endpoint.GetCommunicationStyle() == "AzureWebApp" { - return getAzureDeploymentTargetAsJson(opts, t) - } - return getDeploymentTargetAsJson(opts, t) + return getDeploymentTargetAsJson(opts.Dependencies, t, environmentMap, tenantMap, workerPoolMap) }, Table: output.TableDefinition[*machines.DeploymentTarget]{ Header: []string{"NAME", "TYPE", "HEALTH", "ENVIRONMENTS", "ROLES", "TENANTS", "TENANT TAGS", "ENDPOINT DETAILS", "DEFAULT WORKER POOL"}, Row: func(t *machines.DeploymentTarget) []string { - return getDeploymentTargetAsTableRow(opts, t) + return getDeploymentTargetAsTableRow(opts, t, environmentMap, tenantMap, workerPoolMap) }, }, Basic: func(t *machines.DeploymentTarget) string { @@ -63,35 +64,13 @@ func ViewRun(opts *shared.ViewOptions) error { }) } -type DeploymentTargetAsJson struct { - Id string `json:"Id"` - Name string `json:"Name"` - HealthStatus string `json:"HealthStatus"` - StatusSummary string `json:"StatusSummary"` - CommunicationStyle string `json:"CommunicationStyle"` - Environments []string `json:"Environments"` - Roles []string `json:"Roles"` - Tenants []string `json:"Tenants"` - TenantTags []string `json:"TenantTags"` - EndpointDetails map[string]string `json:"EndpointDetails"` - WebUrl string `json:"WebUrl"` -} - -type AzureDeploymentTargetAsJson struct { - DeploymentTargetAsJson - DefaultWorkerPool string `json:"DefaultWorkerPool"` -} - -func getDeploymentTargetAsJson(opts *shared.ViewOptions, target *machines.DeploymentTarget) DeploymentTargetAsJson { - environmentMap, _ := shared.GetEnvironmentMap(opts) - tenantMap, _ := shared.GetTenantMap(opts) - +func getDeploymentTargetAsJson(deps *cmd.Dependencies, target *machines.DeploymentTarget, environmentMap map[string]string, tenantMap map[string]string, workerPoolMap map[string]string) any { environments := resolveValues(target.EnvironmentIDs, environmentMap) tenants := resolveValues(target.TenantIDs, tenantMap) - endpointDetails := getEndpointDetails(target, opts) + endpointDetails := shared.GetEndpointDetails(target) - return DeploymentTargetAsJson{ + targetJson := shared.DeploymentTargetAsJson{ Id: target.GetID(), Name: target.Name, HealthStatus: target.HealthStatus, @@ -102,32 +81,27 @@ func getDeploymentTargetAsJson(opts *shared.ViewOptions, target *machines.Deploy Tenants: tenants, TenantTags: target.TenantTags, EndpointDetails: endpointDetails, - WebUrl: util.GenerateWebURL(opts.Host, target.SpaceID, fmt.Sprintf("infrastructure/machines/%s/settings", target.GetID())), + WebUrl: util.GenerateWebURL(deps.Host, target.SpaceID, fmt.Sprintf("infrastructure/machines/%s/settings", target.GetID())), } -} -func getAzureDeploymentTargetAsJson(opts *shared.ViewOptions, target *machines.DeploymentTarget) AzureDeploymentTargetAsJson { - deploymentTargetAsJson := getDeploymentTargetAsJson(opts, target) - workerPool := resolveDefaultWorkerPool(target, opts) - var azureTargetAsJson = AzureDeploymentTargetAsJson{ - DeploymentTargetAsJson: deploymentTargetAsJson, - DefaultWorkerPool: workerPool, + if workerEndpoint, ok := target.Endpoint.(machines.IRunsOnAWorker); ok { + return shared.DeploymentTargetWithWorkerPool{ + DeploymentTargetAsJson: targetJson, + DefaultWorkerPool: workerEndpoint.GetDefaultWorkerPoolID(), + } } - return azureTargetAsJson + return targetJson } -func getDeploymentTargetAsTableRow(opts *shared.ViewOptions, target *machines.DeploymentTarget) []string { - environmentMap, _ := shared.GetEnvironmentMap(opts) +func getDeploymentTargetAsTableRow(opts *shared.ViewOptions, target *machines.DeploymentTarget, environmentMap map[string]string, tenantMap map[string]string, workerPoolMap map[string]string) []string { environments := resolveValues(target.EnvironmentIDs, environmentMap) - healthStatus := getHealthStatusFormatted(target.HealthStatus) targetType := getTargetTypeDisplayName(target.Endpoint.GetCommunicationStyle()) // Handle tenants tenants := "None" if !util.Empty(target.TenantIDs) { - tenantMap, _ := shared.GetTenantMap(opts) tenantNames := resolveValues(target.TenantIDs, tenantMap) tenants = strings.Join(tenantNames, ", ") } @@ -139,7 +113,7 @@ func getDeploymentTargetAsTableRow(opts *shared.ViewOptions, target *machines.De } // Handle endpoint details - endpointDetails := getEndpointDetails(target, opts) + endpointDetails := shared.GetEndpointDetails(target) var endpointDetailsStr strings.Builder first := true for key, value := range endpointDetails { @@ -154,7 +128,7 @@ func getDeploymentTargetAsTableRow(opts *shared.ViewOptions, target *machines.De endpointDetailsString = "-" } - workerPool := resolveDefaultWorkerPool(target, opts) + workerPool := shared.ResolveDefaultWorkerPool(target, workerPoolMap, "") return []string{ output.Bold(target.Name), @@ -225,13 +199,13 @@ func getDeploymentTargetAsBasic(opts *shared.ViewOptions, target *machines.Deplo result.WriteString(fmt.Sprintf("Type: %s\n", output.Cyan(targetType))) // Add endpoint-specific details - endpointDetails := getEndpointDetails(target, opts) + endpointDetails := shared.GetEndpointDetails(target) for key, value := range endpointDetails { result.WriteString(fmt.Sprintf("%s: %s\n", key, value)) } // Environments - environmentMap, _ := shared.GetEnvironmentMap(opts) + environmentMap, _ := shared.GetEnvironmentMap(opts.Client) environments := resolveValues(target.EnvironmentIDs, environmentMap) result.WriteString(fmt.Sprintf("Environments: %s\n", output.FormatAsList(environments))) @@ -240,7 +214,7 @@ func getDeploymentTargetAsBasic(opts *shared.ViewOptions, target *machines.Deplo // Tenants if !util.Empty(target.TenantIDs) { - tenantMap, _ := shared.GetTenantMap(opts) + tenantMap, _ := shared.GetTenantMap(opts.Client) tenants := resolveValues(target.TenantIDs, tenantMap) result.WriteString(fmt.Sprintf("Tenants: %s\n", output.FormatAsList(tenants))) } else { @@ -255,13 +229,9 @@ func getDeploymentTargetAsBasic(opts *shared.ViewOptions, target *machines.Deplo } // default worker pool - if target.Endpoint.GetCommunicationStyle() == "AzureWebApp" { - workerPool := resolveDefaultWorkerPool(target, opts) - if workerPool == "" { - workerPool = "None" - } - result.WriteString(fmt.Sprintf("Default Worker Pool: %s\n", workerPool)) - } + workerPoolMap, _ := shared.GetWorkerPoolMap(opts.Client) + workerPool := shared.ResolveDefaultWorkerPool(target, workerPoolMap, "None") + result.WriteString(fmt.Sprintf("Default Worker Pool: %s\n", workerPool)) // Web URL url := util.GenerateWebURL(opts.Host, target.SpaceID, fmt.Sprintf("infrastructure/machines/%s/settings", target.GetID())) @@ -286,60 +256,3 @@ func resolveValues(keys []string, lookup map[string]string) []string { } return values } - -func getEndpointDetails(target *machines.DeploymentTarget, opts *shared.ViewOptions) map[string]string { - details := make(map[string]string) - - switch target.Endpoint.GetCommunicationStyle() { - case "AzureWebApp": - if endpoint, ok := target.Endpoint.(*machines.AzureWebAppEndpoint); ok { - webApp := endpoint.WebAppName - if endpoint.WebAppSlotName != "" { - webApp = fmt.Sprintf("%s/%s", webApp, endpoint.WebAppSlotName) - } - details["Web App"] = webApp - } - case "Kubernetes": - if endpoint, ok := target.Endpoint.(*machines.KubernetesEndpoint); ok { - details["Authentication Type"] = endpoint.Authentication.GetAuthenticationType() - } - case "Ssh": - if endpoint, ok := target.Endpoint.(*machines.SSHEndpoint); ok { - details["URI"] = endpoint.URI.String() - runtime := "Mono" - if endpoint.DotNetCorePlatform != "" { - runtime = endpoint.DotNetCorePlatform - } - details["Runtime architecture"] = runtime - } - case "TentaclePassive": - if endpoint, ok := target.Endpoint.(*machines.ListeningTentacleEndpoint); ok { - details["URI"] = endpoint.URI.String() - details["Tentacle version"] = endpoint.TentacleVersionDetails.Version - } - case "TentacleActive": - if endpoint, ok := target.Endpoint.(*machines.PollingTentacleEndpoint); ok { - details["URI"] = endpoint.URI.String() - details["Tentacle version"] = endpoint.TentacleVersionDetails.Version - } - case "None": - // Cloud regions typically don't have additional endpoint details - case "OfflineDrop", "StepPackage", "AzureCloudService", "AzureServiceFabricCluster": - // These endpoints don't have specific details we can easily extract - } - - return details -} - -func resolveDefaultWorkerPool(target *machines.DeploymentTarget, opts *shared.ViewOptions) string { - if endpoint, ok := target.Endpoint.(*machines.AzureWebAppEndpoint); ok { - if endpoint.DefaultWorkerPoolID != "" { - workerPoolMap, _ := shared.GetWorkerPoolMap(opts) - return resolveValues([]string{endpoint.DefaultWorkerPoolID}, workerPoolMap)[0] - } else { - return "" - } - } - - return "N/A" -} diff --git a/pkg/cmd/tenant/list/list.go b/pkg/cmd/tenant/list/list.go index b6cf67e9..e0fbbece 100644 --- a/pkg/cmd/tenant/list/list.go +++ b/pkg/cmd/tenant/list/list.go @@ -42,7 +42,7 @@ func listRun(cmd *cobra.Command, f factory.Factory) error { return err } - environmentMap, err := shared.GetEnvironmentMap(client, allTenants) + environmentMap, err := shared.GetEnvironmentMapForTenants(client, allTenants) if err != nil { return err } diff --git a/pkg/cmd/tenant/shared/shared.go b/pkg/cmd/tenant/shared/shared.go index cedd9100..e5c90d44 100644 --- a/pkg/cmd/tenant/shared/shared.go +++ b/pkg/cmd/tenant/shared/shared.go @@ -42,7 +42,7 @@ func ResolveEntities(keys []string, lookup map[string]string) ([]output.IdAndNam return entities, nil } -func GetEnvironmentMap(client *client.Client, tenants []*tenants.Tenant) (map[string]string, error) { +func GetEnvironmentMapForTenants(client *client.Client, tenants []*tenants.Tenant) (map[string]string, error) { var environmentIds []string for _, t := range tenants { for p := range t.ProjectEnvironments { diff --git a/pkg/cmd/tenant/view/view.go b/pkg/cmd/tenant/view/view.go index 77d9fc9a..e63465e7 100644 --- a/pkg/cmd/tenant/view/view.go +++ b/pkg/cmd/tenant/view/view.go @@ -89,7 +89,7 @@ func viewRun(opts *ViewOptions, cmd *cobra.Command) error { return err } - environmentMap, err := shared.GetEnvironmentMap(opts.Client, []*tenants.Tenant{tenant}) + environmentMap, err := shared.GetEnvironmentMapForTenants(opts.Client, []*tenants.Tenant{tenant}) if err != nil { return err }