Add networks panel
parent
17fcdb2b20
commit
ce95ddea2a
@ -0,0 +1,54 @@
|
|||||||
|
package commands
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
dockerTypes "github.com/docker/docker/api/types"
|
||||||
|
"github.com/docker/docker/api/types/filters"
|
||||||
|
"github.com/docker/docker/client"
|
||||||
|
"github.com/sirupsen/logrus"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Network : A docker Network
|
||||||
|
type Network struct {
|
||||||
|
Name string
|
||||||
|
Network dockerTypes.NetworkResource
|
||||||
|
Client *client.Client
|
||||||
|
OSCommand *OSCommand
|
||||||
|
Log *logrus.Entry
|
||||||
|
DockerCommand LimitedDockerCommand
|
||||||
|
}
|
||||||
|
|
||||||
|
// RefreshNetworks gets the networks and stores them
|
||||||
|
func (c *DockerCommand) RefreshNetworks() ([]*Network, error) {
|
||||||
|
networks, err := c.Client.NetworkList(context.Background(), dockerTypes.NetworkListOptions{})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
ownNetworks := make([]*Network, len(networks))
|
||||||
|
|
||||||
|
for i, network := range networks {
|
||||||
|
ownNetworks[i] = &Network{
|
||||||
|
Name: network.Name,
|
||||||
|
Network: network,
|
||||||
|
Client: c.Client,
|
||||||
|
OSCommand: c.OSCommand,
|
||||||
|
Log: c.Log,
|
||||||
|
DockerCommand: c,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ownNetworks, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// PruneNetworks prunes networks
|
||||||
|
func (c *DockerCommand) PruneNetworks() error {
|
||||||
|
_, err := c.Client.NetworksPrune(context.Background(), filters.Args{})
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove removes the network
|
||||||
|
func (v *Network) Remove() error {
|
||||||
|
return v.Client.NetworkRemove(context.Background(), v.Name)
|
||||||
|
}
|
@ -0,0 +1,179 @@
|
|||||||
|
package gui
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
"github.com/fatih/color"
|
||||||
|
"github.com/jesseduffield/gocui"
|
||||||
|
"github.com/jesseduffield/lazydocker/pkg/commands"
|
||||||
|
"github.com/jesseduffield/lazydocker/pkg/config"
|
||||||
|
"github.com/jesseduffield/lazydocker/pkg/gui/panels"
|
||||||
|
"github.com/jesseduffield/lazydocker/pkg/gui/presentation"
|
||||||
|
"github.com/jesseduffield/lazydocker/pkg/gui/types"
|
||||||
|
"github.com/jesseduffield/lazydocker/pkg/tasks"
|
||||||
|
"github.com/jesseduffield/lazydocker/pkg/utils"
|
||||||
|
"github.com/samber/lo"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (gui *Gui) getNetworksPanel() *panels.SideListPanel[*commands.Network] {
|
||||||
|
return &panels.SideListPanel[*commands.Network]{
|
||||||
|
ContextState: &panels.ContextState[*commands.Network]{
|
||||||
|
GetMainTabs: func() []panels.MainTab[*commands.Network] {
|
||||||
|
return []panels.MainTab[*commands.Network]{
|
||||||
|
{
|
||||||
|
Key: "config",
|
||||||
|
Title: gui.Tr.ConfigTitle,
|
||||||
|
Render: gui.renderNetworkConfig,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
GetItemContextCacheKey: func(network *commands.Network) string {
|
||||||
|
return "networks-" + network.Name
|
||||||
|
},
|
||||||
|
},
|
||||||
|
ListPanel: panels.ListPanel[*commands.Network]{
|
||||||
|
List: panels.NewFilteredList[*commands.Network](),
|
||||||
|
View: gui.Views.Networks,
|
||||||
|
},
|
||||||
|
NoItemsMessage: gui.Tr.NoNetworks,
|
||||||
|
Gui: gui.intoInterface(),
|
||||||
|
// we're sorting these networks based on whether they have labels defined,
|
||||||
|
// because those are the ones you typically care about.
|
||||||
|
// Within that, we also sort them alphabetically
|
||||||
|
Sort: func(a *commands.Network, b *commands.Network) bool {
|
||||||
|
return a.Name < b.Name
|
||||||
|
},
|
||||||
|
GetTableCells: presentation.GetNetworkDisplayStrings,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (gui *Gui) renderNetworkConfig(network *commands.Network) tasks.TaskFunc {
|
||||||
|
return gui.NewSimpleRenderStringTask(func() string { return gui.networkConfigStr(network) })
|
||||||
|
}
|
||||||
|
|
||||||
|
func (gui *Gui) networkConfigStr(network *commands.Network) string {
|
||||||
|
padding := 15
|
||||||
|
output := ""
|
||||||
|
output += utils.WithPadding("ID: ", padding) + network.Network.ID + "\n"
|
||||||
|
output += utils.WithPadding("Name: ", padding) + network.Name + "\n"
|
||||||
|
output += utils.WithPadding("Driver: ", padding) + network.Network.Driver + "\n"
|
||||||
|
output += utils.WithPadding("Scope: ", padding) + network.Network.Scope + "\n"
|
||||||
|
output += utils.WithPadding("EnabledIPV6: ", padding) + strconv.FormatBool(network.Network.EnableIPv6) + "\n"
|
||||||
|
output += utils.WithPadding("Internal: ", padding) + strconv.FormatBool(network.Network.Internal) + "\n"
|
||||||
|
output += utils.WithPadding("Attachable: ", padding) + strconv.FormatBool(network.Network.Attachable) + "\n"
|
||||||
|
output += utils.WithPadding("Ingress: ", padding) + strconv.FormatBool(network.Network.Ingress) + "\n"
|
||||||
|
|
||||||
|
output += utils.WithPadding("Containers: ", padding)
|
||||||
|
if len(network.Network.Containers) > 0 {
|
||||||
|
output += "\n"
|
||||||
|
for _, v := range network.Network.Containers {
|
||||||
|
output += utils.FormatMapItem(padding, v.Name, v.EndpointID)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
output += "none\n"
|
||||||
|
}
|
||||||
|
|
||||||
|
output += "\n"
|
||||||
|
output += utils.WithPadding("Labels: ", padding) + utils.FormatMap(padding, network.Network.Labels) + "\n"
|
||||||
|
output += utils.WithPadding("Options: ", padding) + utils.FormatMap(padding, network.Network.Options)
|
||||||
|
|
||||||
|
return output
|
||||||
|
}
|
||||||
|
|
||||||
|
func (gui *Gui) reloadNetworks() error {
|
||||||
|
if err := gui.refreshStateNetworks(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return gui.Panels.Networks.RerenderList()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (gui *Gui) refreshStateNetworks() error {
|
||||||
|
networks, err := gui.DockerCommand.RefreshNetworks()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
gui.Panels.Networks.SetItems(networks)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (gui *Gui) handleNetworksRemoveMenu(g *gocui.Gui, v *gocui.View) error {
|
||||||
|
network, err := gui.Panels.Networks.GetSelectedItem()
|
||||||
|
if err != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type removeNetworkOption struct {
|
||||||
|
description string
|
||||||
|
command string
|
||||||
|
}
|
||||||
|
|
||||||
|
options := []*removeNetworkOption{
|
||||||
|
{
|
||||||
|
description: gui.Tr.Remove,
|
||||||
|
command: utils.WithShortSha("docker network rm " + network.Name),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
menuItems := lo.Map(options, func(option *removeNetworkOption, _ int) *types.MenuItem {
|
||||||
|
return &types.MenuItem{
|
||||||
|
LabelColumns: []string{option.description, color.New(color.FgRed).Sprint(option.command)},
|
||||||
|
OnPress: func() error {
|
||||||
|
return gui.WithWaitingStatus(gui.Tr.RemovingStatus, func() error {
|
||||||
|
if err := network.Remove(); err != nil {
|
||||||
|
return gui.createErrorPanel(err.Error())
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
},
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return gui.Menu(CreateMenuOptions{
|
||||||
|
Title: "",
|
||||||
|
Items: menuItems,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (gui *Gui) handlePruneNetworks() error {
|
||||||
|
return gui.createConfirmationPanel(gui.Tr.Confirm, gui.Tr.ConfirmPruneNetworks, func(g *gocui.Gui, v *gocui.View) error {
|
||||||
|
return gui.WithWaitingStatus(gui.Tr.PruningStatus, func() error {
|
||||||
|
err := gui.DockerCommand.PruneNetworks()
|
||||||
|
if err != nil {
|
||||||
|
return gui.createErrorPanel(err.Error())
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
}, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (gui *Gui) handleNetworksCustomCommand(g *gocui.Gui, v *gocui.View) error {
|
||||||
|
network, err := gui.Panels.Networks.GetSelectedItem()
|
||||||
|
if err != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
commandObject := gui.DockerCommand.NewCommandObject(commands.CommandObject{
|
||||||
|
Network: network,
|
||||||
|
})
|
||||||
|
|
||||||
|
customCommands := gui.Config.UserConfig.CustomCommands.Networks
|
||||||
|
|
||||||
|
return gui.createCustomCommandMenu(customCommands, commandObject)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (gui *Gui) handleNetworksBulkCommand(g *gocui.Gui, v *gocui.View) error {
|
||||||
|
baseBulkCommands := []config.CustomCommand{
|
||||||
|
{
|
||||||
|
Name: gui.Tr.PruneNetworks,
|
||||||
|
InternalFunction: gui.handlePruneNetworks,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
bulkCommands := append(baseBulkCommands, gui.Config.UserConfig.BulkCommands.Networks...)
|
||||||
|
commandObject := gui.DockerCommand.NewCommandObject(commands.CommandObject{})
|
||||||
|
|
||||||
|
return gui.createBulkCommandMenu(bulkCommands, commandObject)
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
package presentation
|
||||||
|
|
||||||
|
import "github.com/jesseduffield/lazydocker/pkg/commands"
|
||||||
|
|
||||||
|
func GetNetworkDisplayStrings(network *commands.Network) []string {
|
||||||
|
return []string{network.Network.Driver, network.Name}
|
||||||
|
}
|
Loading…
Reference in New Issue