1package cli
2
3import (
4 "context"
5 "fmt"
6 "io"
7 "strings"
8
9 "github.com/bnema/gordon/internal/adapters/in/cli/ui/components"
10 "github.com/bnema/gordon/internal/domain"
11 "github.com/spf13/cobra"
12)
13
14func newNetworksCmd() *cobra.Command {
15 cmd := &cobra.Command{
16 Use: "networks",
17 Short: "Inspect Gordon-managed networks",
18 }
19
20 cmd.AddCommand(newNetworksListCmd())
21
22 return cmd
23}
24
25func newNetworksListCmd() *cobra.Command {
26 var jsonOut bool
27
28 cmd := &cobra.Command{
29 Use: "list",
30 Short: "List Gordon-managed Docker networks",
31 Long: `Display Docker networks managed by Gordon, including which containers
32are connected to each network.
33
34Examples:
35 gordon networks list
36 gordon networks list --json
37 gordon networks list --remote https://gordon.mydomain.com --token $TOKEN`,
38 RunE: func(cmd *cobra.Command, _ []string) error {
39 ctx := cmd.Context()
40 handle, err := resolveControlPlane(configPath)
41 if err != nil {
42 return err
43 }
44 defer handle.close()
45 return runNetworksList(ctx, handle.plane, cmd.OutOrStdout(), jsonOut)
46 },
47 }
48
49 cmd.Flags().BoolVar(&jsonOut, "json", false, "Output as JSON")
50
51 return cmd
52}
53
54func runNetworksList(ctx context.Context, cp ControlPlane, out io.Writer, jsonOut bool) error {
55 networks, err := cp.ListNetworks(ctx)
56 if err != nil {
57 return fmt.Errorf("failed to list networks: %w", err)
58 }
59
60 if jsonOut {
61 result := make([]map[string]any, 0, len(networks))
62 for _, net := range networks {
63 if net == nil {
64 continue
65 }
66 result = append(result, map[string]any{
67 "name": net.Name,
68 "driver": net.Driver,
69 "containers": net.Containers,
70 })
71 }
72 return writeJSON(out, result)
73 }
74
75 if len(networks) == 0 {
76 return cliWriteLine(out, cliRenderMuted("No Gordon-managed networks found"))
77 }
78
79 if err := cliWriteLine(out, cliRenderTitle("Networks")); err != nil {
80 return err
81 }
82
83 return renderNetworksTable(out, networks)
84}
85
86func renderNetworksTable(out io.Writer, networks []*domain.NetworkInfo) error {
87 rows := make([][]string, 0, len(networks))
88 for _, net := range networks {
89 if net == nil {
90 continue
91 }
92 containers := strings.Join(net.Containers, ", ")
93 if containers == "" {
94 containers = "-"
95 }
96 if len(containers) > 40 {
97 containers = containers[:37] + "..."
98 }
99 rows = append(rows, []string{
100 net.Name,
101 net.Driver,
102 fmt.Sprintf("%d", len(net.Containers)),
103 containers,
104 })
105 }
106
107 table := components.NewTable(
108 components.WithColumns([]components.TableColumn{
109 {Title: "Name", Width: 25},
110 {Title: "Driver", Width: 10},
111 {Title: "Containers", Width: 12},
112 {Title: "Connected", Width: 40},
113 }),
114 components.WithRows(rows),
115 )
116
117 return cliWriteLine(out, table.View())
118}