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