Skip to content

Commit

Permalink
Merge pull request #21860 from Luap99/network-inspect
Browse files Browse the repository at this point in the history
podman network inspect: include running containers
  • Loading branch information
openshift-merge-bot[bot] authored Feb 28, 2024
2 parents 031e7a1 + 5952486 commit 275dbc5
Show file tree
Hide file tree
Showing 15 changed files with 155 additions and 65 deletions.
2 changes: 1 addition & 1 deletion cmd/podman/common/completion.go
Original file line number Diff line number Diff line change
Expand Up @@ -1298,7 +1298,7 @@ func getEntityType(cmd *cobra.Command, args []string, o interface{}) interface{}
}
// network logic
if networks, _ := getNetworks(cmd, args[0], completeDefault); len(networks) > 0 {
return &types.Network{}
return &entities.NetworkInspectReport{}
}
return o
}
Expand Down
3 changes: 1 addition & 2 deletions cmd/podman/networks/inspect.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package network

import (
"github.com/containers/common/libnetwork/types"
"github.com/containers/podman/v5/cmd/podman/common"
"github.com/containers/podman/v5/cmd/podman/inspect"
"github.com/containers/podman/v5/cmd/podman/registry"
Expand Down Expand Up @@ -33,7 +32,7 @@ func init() {

formatFlagName := "format"
flags.StringVarP(&inspectOpts.Format, formatFlagName, "f", "", "Pretty-print network to JSON or using a Go template")
_ = networkinspectCommand.RegisterFlagCompletionFunc(formatFlagName, common.AutocompleteFormat(&types.Network{}))
_ = networkinspectCommand.RegisterFlagCompletionFunc(formatFlagName, common.AutocompleteFormat(&entities.NetworkInspectReport{}))
}

func networkInspect(_ *cobra.Command, args []string) error {
Expand Down
2 changes: 2 additions & 0 deletions docs/source/markdown/podman-network-inspect.1.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ Pretty-print networks to JSON or using a Go template.

| **Placeholder** | **Description** |
|--------------------|-------------------------------------------|
| .Containers ... | Running containers on this network. |
| .Created ... | Timestamp when the network was created |
| .DNSEnabled | Network has dns enabled (boolean) |
| .Driver | Network driver |
Expand All @@ -25,6 +26,7 @@ Pretty-print networks to JSON or using a Go template.
| .IPv6Enabled | Network has ipv6 subnet (boolean) |
| .Labels ... | Network labels |
| .Name | Network name |
| .Network ... | Nested Network type |
| .NetworkDNSServers | Array of DNS servers used in this network |
| .NetworkInterface | Name of the network interface on the host |
| .Options ... | Network options |
Expand Down
43 changes: 7 additions & 36 deletions pkg/api/handlers/compat/networks.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,36 +22,6 @@ import (
"github.com/sirupsen/logrus"
)

type containerNetStatus struct {
name string
id string
status map[string]nettypes.StatusBlock
}

func getContainerNetStatuses(rt *libpod.Runtime) ([]containerNetStatus, error) {
cons, err := rt.GetAllContainers()
if err != nil {
return nil, err
}
statuses := make([]containerNetStatus, 0, len(cons))
for _, con := range cons {
status, err := con.GetNetworkStatus()
if err != nil {
if errors.Is(err, define.ErrNoSuchCtr) || errors.Is(err, define.ErrCtrRemoved) {
continue
}
return nil, err
}

statuses = append(statuses, containerNetStatus{
id: con.ID(),
name: con.Name(),
status: status,
})
}
return statuses, nil
}

func normalizeNetworkName(rt *libpod.Runtime, name string) (string, bool) {
if name == nettypes.BridgeNetworkDriver {
return rt.Network().DefaultNetworkName(), true
Expand Down Expand Up @@ -86,7 +56,8 @@ func InspectNetwork(w http.ResponseWriter, r *http.Request) {
utils.NetworkNotFound(w, name, err)
return
}
statuses, err := getContainerNetStatuses(runtime)
ic := abi.ContainerEngine{Libpod: runtime}
statuses, err := ic.GetContainerNetStatuses()
if err != nil {
utils.InternalServerError(w, err)
return
Expand All @@ -95,10 +66,10 @@ func InspectNetwork(w http.ResponseWriter, r *http.Request) {
utils.WriteResponse(w, http.StatusOK, report)
}

func convertLibpodNetworktoDockerNetwork(runtime *libpod.Runtime, statuses []containerNetStatus, network *nettypes.Network, changeDefaultName bool) *types.NetworkResource {
func convertLibpodNetworktoDockerNetwork(runtime *libpod.Runtime, statuses []abi.ContainerNetStatus, network *nettypes.Network, changeDefaultName bool) *types.NetworkResource {
containerEndpoints := make(map[string]types.EndpointResource, len(statuses))
for _, st := range statuses {
if netData, ok := st.status[network.Name]; ok {
if netData, ok := st.Status[network.Name]; ok {
ipv4Address := ""
ipv6Address := ""
macAddr := ""
Expand All @@ -116,12 +87,12 @@ func convertLibpodNetworktoDockerNetwork(runtime *libpod.Runtime, statuses []con
break
}
containerEndpoint := types.EndpointResource{
Name: st.name,
Name: st.Name,
MacAddress: macAddr,
IPv4Address: ipv4Address,
IPv6Address: ipv6Address,
}
containerEndpoints[st.id] = containerEndpoint
containerEndpoints[st.ID] = containerEndpoint
}
}
ipamConfigs := make([]dockerNetwork.IPAMConfig, 0, len(network.Subnets))
Expand Down Expand Up @@ -192,7 +163,7 @@ func ListNetworks(w http.ResponseWriter, r *http.Request) {
utils.InternalServerError(w, err)
return
}
statuses, err := getContainerNetStatuses(runtime)
statuses, err := ic.GetContainerNetStatuses()
if err != nil {
utils.InternalServerError(w, err)
return
Expand Down
2 changes: 1 addition & 1 deletion pkg/api/handlers/swagger/responses.go
Original file line number Diff line number Diff line change
Expand Up @@ -434,7 +434,7 @@ type networkRmResponse struct {
// swagger:response
type networkInspectResponse struct {
// in:body
Body types.Network
Body entities.NetworkInspectReport
}

// Network list
Expand Down
4 changes: 2 additions & 2 deletions pkg/bindings/network/network.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,8 @@ func Update(ctx context.Context, netNameOrID string, options *UpdateOptions) err
}

// Inspect returns information about a network configuration
func Inspect(ctx context.Context, nameOrID string, _ *InspectOptions) (types.Network, error) {
var net types.Network
func Inspect(ctx context.Context, nameOrID string, _ *InspectOptions) (entitiesTypes.NetworkInspectReport, error) {
var net entitiesTypes.NetworkInspectReport
conn, err := bindings.GetClient(ctx)
if err != nil {
return net, err
Expand Down
2 changes: 1 addition & 1 deletion pkg/domain/entities/engine_container.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ type ContainerEngine interface { //nolint:interfacebloat
NetworkUpdate(ctx context.Context, networkname string, options NetworkUpdateOptions) error
NetworkDisconnect(ctx context.Context, networkname string, options NetworkDisconnectOptions) error
NetworkExists(ctx context.Context, networkname string) (*BoolReport, error)
NetworkInspect(ctx context.Context, namesOrIds []string, options InspectOptions) ([]netTypes.Network, []error, error)
NetworkInspect(ctx context.Context, namesOrIds []string, options InspectOptions) ([]NetworkInspectReport, []error, error)
NetworkList(ctx context.Context, options NetworkListOptions) ([]netTypes.Network, error)
NetworkPrune(ctx context.Context, options NetworkPruneOptions) ([]*NetworkPruneReport, error)
NetworkReload(ctx context.Context, names []string, options NetworkReloadOptions) ([]*NetworkReloadReport, error)
Expand Down
3 changes: 3 additions & 0 deletions pkg/domain/entities/network.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,3 +82,6 @@ type NetworkPruneReport = entitiesTypes.NetworkPruneReport
type NetworkPruneOptions struct {
Filters map[string][]string
}

type NetworkInspectReport = entitiesTypes.NetworkInspectReport
type NetworkContainerInfo = entitiesTypes.NetworkContainerInfo
14 changes: 14 additions & 0 deletions pkg/domain/entities/types/network.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,17 @@ type NetworkRmReport struct {
type NetworkCreateReport struct {
Name string
}

type NetworkInspectReport struct {
commonTypes.Network

Containers map[string]NetworkContainerInfo `json:"containers"`
}

type NetworkContainerInfo struct {
// Name of the container
Name string `json:"name"`

// Interfaces configured for this container with their addresses
Interfaces map[string]commonTypes.NetInterface `json:"interfaces,omitempty"`
}
58 changes: 55 additions & 3 deletions pkg/domain/infra/abi/network.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,13 @@ func (ic *ContainerEngine) NetworkList(ctx context.Context, options entities.Net
return nets, err
}

func (ic *ContainerEngine) NetworkInspect(ctx context.Context, namesOrIds []string, options entities.InspectOptions) ([]types.Network, []error, error) {
func (ic *ContainerEngine) NetworkInspect(ctx context.Context, namesOrIds []string, options entities.InspectOptions) ([]entities.NetworkInspectReport, []error, error) {
var errs []error
networks := make([]types.Network, 0, len(namesOrIds))
statuses, err := ic.GetContainerNetStatuses()
if err != nil {
return nil, nil, fmt.Errorf("failed to get network status for containers: %w", err)
}
networks := make([]entities.NetworkInspectReport, 0, len(namesOrIds))
for _, name := range namesOrIds {
net, err := ic.Libpod.Network().NetworkInspect(name)
if err != nil {
Expand All @@ -77,7 +81,22 @@ func (ic *ContainerEngine) NetworkInspect(ctx context.Context, namesOrIds []stri
return nil, nil, fmt.Errorf("inspecting network %s: %w", name, err)
}
}
networks = append(networks, net)
containerMap := make(map[string]entities.NetworkContainerInfo)
for _, st := range statuses {
// Make sure to only show the info for the correct network
if sb, ok := st.Status[net.Name]; ok {
containerMap[st.ID] = entities.NetworkContainerInfo{
Name: st.Name,
Interfaces: sb.Interfaces,
}
}
}

netReport := entities.NetworkInspectReport{
Network: net,
Containers: containerMap,
}
networks = append(networks, netReport)
}
return networks, errs, nil
}
Expand Down Expand Up @@ -243,3 +262,36 @@ func (ic *ContainerEngine) createDanglingFilterFunc(wantDangling bool) (types.Fi
return wantDangling
}, nil
}

type ContainerNetStatus struct {
// Name of the container
Name string
// ID of the container
ID string
// Status contains the net status, the key is the network name
Status map[string]types.StatusBlock
}

func (ic *ContainerEngine) GetContainerNetStatuses() ([]ContainerNetStatus, error) {
cons, err := ic.Libpod.GetAllContainers()
if err != nil {
return nil, err
}
statuses := make([]ContainerNetStatus, 0, len(cons))
for _, con := range cons {
status, err := con.GetNetworkStatus()
if err != nil {
if errors.Is(err, define.ErrNoSuchCtr) || errors.Is(err, define.ErrCtrRemoved) {
continue
}
return nil, err
}

statuses = append(statuses, ContainerNetStatus{
ID: con.ID(),
Name: con.Name(),
Status: status,
})
}
return statuses, nil
}
4 changes: 2 additions & 2 deletions pkg/domain/infra/tunnel/network.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@ func (ic *ContainerEngine) NetworkList(ctx context.Context, opts entities.Networ
return network.List(ic.ClientCtx, options)
}

func (ic *ContainerEngine) NetworkInspect(ctx context.Context, namesOrIds []string, opts entities.InspectOptions) ([]types.Network, []error, error) {
func (ic *ContainerEngine) NetworkInspect(ctx context.Context, namesOrIds []string, opts entities.InspectOptions) ([]entities.NetworkInspectReport, []error, error) {
var (
reports = make([]types.Network, 0, len(namesOrIds))
reports = make([]entities.NetworkInspectReport, 0, len(namesOrIds))
errs = []error{}
)
options := new(network.InspectOptions)
Expand Down
19 changes: 10 additions & 9 deletions test/e2e/network_create_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"net"

"github.com/containers/common/libnetwork/types"
"github.com/containers/podman/v5/pkg/domain/entities"
. "github.com/containers/podman/v5/test/utils"
"github.com/containers/storage/pkg/stringid"
. "github.com/onsi/ginkgo/v2"
Expand Down Expand Up @@ -32,7 +33,7 @@ var _ = Describe("Podman network create", func() {
Expect(inspect).Should(ExitCleanly())

// JSON the network configuration into something usable
var results []types.Network
var results []entities.NetworkInspectReport
err := json.Unmarshal([]byte(inspect.OutputToString()), &results)
Expect(err).ToNot(HaveOccurred())
Expect(results).To(HaveLen(1))
Expand Down Expand Up @@ -84,7 +85,7 @@ var _ = Describe("Podman network create", func() {
Expect(inspect).Should(ExitCleanly())

// JSON the network configuration into something usable
var results []types.Network
var results []entities.NetworkInspectReport
err := json.Unmarshal([]byte(inspect.OutputToString()), &results)
Expect(err).ToNot(HaveOccurred())
Expect(results).To(HaveLen(1))
Expand Down Expand Up @@ -125,7 +126,7 @@ var _ = Describe("Podman network create", func() {
Expect(inspect).Should(ExitCleanly())

// JSON the network configuration into something usable
var results []types.Network
var results []entities.NetworkInspectReport
err := json.Unmarshal([]byte(inspect.OutputToString()), &results)
Expect(err).ToNot(HaveOccurred())
Expect(results).To(HaveLen(1))
Expand Down Expand Up @@ -168,7 +169,7 @@ var _ = Describe("Podman network create", func() {
Expect(inspect).Should(ExitCleanly())

// JSON the network configuration into something usable
var results []types.Network
var results []entities.NetworkInspectReport
err := json.Unmarshal([]byte(inspect.OutputToString()), &results)
Expect(err).ToNot(HaveOccurred())
Expect(results).To(HaveLen(1))
Expand Down Expand Up @@ -213,7 +214,7 @@ var _ = Describe("Podman network create", func() {
Expect(inspect).Should(ExitCleanly())

// JSON the network configuration into something usable
var results []types.Network
var results []entities.NetworkInspectReport
err := json.Unmarshal([]byte(inspect.OutputToString()), &results)
Expect(err).ToNot(HaveOccurred())
Expect(results).To(HaveLen(1))
Expand Down Expand Up @@ -254,7 +255,7 @@ var _ = Describe("Podman network create", func() {
Expect(inspect).Should(ExitCleanly())

// JSON the network configuration into something usable
var results []types.Network
var results []entities.NetworkInspectReport
err := json.Unmarshal([]byte(inspect.OutputToString()), &results)
Expect(err).ToNot(HaveOccurred())
Expect(results).To(HaveLen(1))
Expand Down Expand Up @@ -284,7 +285,7 @@ var _ = Describe("Podman network create", func() {
Expect(inspect).Should(ExitCleanly())

// JSON the network configuration into something usable
var results []types.Network
var results []entities.NetworkInspectReport
err := json.Unmarshal([]byte(inspect.OutputToString()), &results)
Expect(err).ToNot(HaveOccurred())
Expect(results).To(HaveLen(1))
Expand Down Expand Up @@ -323,7 +324,7 @@ var _ = Describe("Podman network create", func() {
Expect(inspect).Should(ExitCleanly())

// JSON the network configuration into something usable
var results []types.Network
var results []entities.NetworkInspectReport
err := json.Unmarshal([]byte(inspect.OutputToString()), &results)
Expect(err).ToNot(HaveOccurred())
Expect(results).To(HaveLen(1))
Expand Down Expand Up @@ -711,7 +712,7 @@ var _ = Describe("Podman network create", func() {
Expect(inspect).Should(ExitCleanly())

// JSON the network configuration into something usable
var results []types.Network
var results []entities.NetworkInspectReport
err := json.Unmarshal([]byte(inspect.OutputToString()), &results)
Expect(err).ToNot(HaveOccurred())
Expect(results).To(HaveLen(1))
Expand Down
Loading

0 comments on commit 275dbc5

Please sign in to comment.