Skip to content

Commit 24eea22

Browse files
committed
Add command 'gp ports list' to gitpod-cli
1 parent 1d4be66 commit 24eea22

File tree

3 files changed

+150
-0
lines changed

3 files changed

+150
-0
lines changed

components/gitpod-cli/cmd/ports.go

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// Copyright (c) 2022 Gitpod GmbH. All rights reserved.
2+
// Licensed under the GNU Affero General Public License (AGPL).
3+
// See License-AGPL.txt in the project root for license information.
4+
5+
package cmd
6+
7+
import (
8+
"github.com/gitpod-io/gitpod/gitpod-cli/cmd/ports"
9+
"github.com/spf13/cobra"
10+
)
11+
12+
// portsCmd represents the ports command
13+
var portsCmd = &cobra.Command{
14+
Use: "ports",
15+
Short: "Interact with workspace ports",
16+
Run: func(cmd *cobra.Command, args []string) {
17+
if len(args) == 0 {
18+
_ = cmd.Help()
19+
}
20+
},
21+
}
22+
23+
// listPortsCmd represents the ports list command
24+
var listPortsCmd = &cobra.Command{
25+
Use: "list",
26+
Short: "Lists the workspace ports and their state",
27+
Run: ports.ListPortsCmd,
28+
}
29+
30+
func init() {
31+
rootCmd.AddCommand(portsCmd)
32+
portsCmd.AddCommand(listPortsCmd)
33+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
// Copyright (c) 2022 Gitpod GmbH. All rights reserved.
2+
// Licensed under the GNU Affero General Public License (AGPL).
3+
// See License-AGPL.txt in the project root for license information.
4+
5+
package ports
6+
7+
import (
8+
"context"
9+
"fmt"
10+
"os"
11+
"time"
12+
13+
"github.com/gitpod-io/gitpod/gitpod-cli/pkg/supervisor"
14+
"github.com/gitpod-io/gitpod/supervisor/api"
15+
"github.com/spf13/cobra"
16+
17+
"github.com/olekukonko/tablewriter"
18+
)
19+
20+
func ListPortsCmd(cmd *cobra.Command, args []string) {
21+
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
22+
defer cancel()
23+
24+
conn := supervisor.Dial()
25+
client := api.NewStatusServiceClient(conn)
26+
27+
ports := supervisor.GetPortsList(ctx, client)
28+
29+
if len(ports) == 0 {
30+
fmt.Println("No ports detected")
31+
return
32+
}
33+
34+
table := tablewriter.NewWriter(os.Stdout)
35+
table.SetHeader([]string{"Port", "Status", "URL", "Name & Description"})
36+
table.SetBorders(tablewriter.Border{Left: true, Top: false, Right: true, Bottom: false})
37+
table.SetCenterSeparator("|")
38+
39+
for _, port := range ports {
40+
status := "not served"
41+
statusColor := tablewriter.FgHiBlackColor
42+
if port.Exposed == nil && port.Tunneled == nil {
43+
if port.AutoExposure == api.PortAutoExposure_failed {
44+
status = "failed to expose"
45+
statusColor = tablewriter.FgRedColor
46+
} else {
47+
status = "detecting..."
48+
statusColor = tablewriter.FgYellowColor
49+
}
50+
} else if port.Served {
51+
status = "open (" + port.Exposed.Visibility.String() + ")"
52+
if port.Exposed.Visibility == api.PortVisibility_public {
53+
statusColor = tablewriter.FgHiCyanColor
54+
} else {
55+
statusColor = tablewriter.FgHiWhiteColor
56+
}
57+
}
58+
59+
nameAndDescription := port.Name
60+
if len(port.Description) > 0 {
61+
if len(nameAndDescription) > 0 {
62+
nameAndDescription = fmt.Sprint(nameAndDescription, ": ", port.Description)
63+
} else {
64+
nameAndDescription = port.Description
65+
}
66+
}
67+
68+
table.Rich(
69+
[]string{fmt.Sprint(port.LocalPort), status, port.Exposed.Url, nameAndDescription},
70+
[]tablewriter.Colors{{}, {statusColor}, {}, {}},
71+
)
72+
}
73+
74+
table.Render()
75+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
// Copyright (c) 2022 Gitpod GmbH. All rights reserved.
2+
// Licensed under the GNU Affero General Public License (AGPL).
3+
// See License-AGPL.txt in the project root for license information.
4+
5+
package supervisor
6+
7+
import (
8+
"context"
9+
"io"
10+
11+
"github.com/gitpod-io/gitpod/supervisor/api"
12+
log "github.com/sirupsen/logrus"
13+
)
14+
15+
func GetPortsList(ctx context.Context, client api.StatusServiceClient) []*api.PortsStatus {
16+
listen, err := client.PortsStatus(ctx, &api.PortsStatusRequest{Observe: false})
17+
if err != nil {
18+
log.WithError(err).Error("Cannot list ports")
19+
}
20+
21+
portschan := make(chan []*api.PortsStatus)
22+
23+
go func() {
24+
for {
25+
resp, err := listen.Recv()
26+
if err != nil && err != io.EOF {
27+
panic(err)
28+
}
29+
30+
chunk := resp.GetPorts()
31+
32+
if chunk == nil {
33+
close(portschan)
34+
break
35+
} else {
36+
portschan <- chunk
37+
}
38+
}
39+
}()
40+
41+
return <-portschan
42+
}

0 commit comments

Comments
 (0)