Skip to content

Commit 2385db1

Browse files
committed
add MAC, IPv4, IPv6 addresses to nework inspect
Signed-off-by: Arjun Raja Yogidas <[email protected]>
1 parent 53e7b27 commit 2385db1

File tree

2 files changed

+102
-8
lines changed

2 files changed

+102
-8
lines changed

cmd/nerdctl/network/network_inspect_test.go

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -397,6 +397,63 @@ func TestNetworkInspect(t *testing.T) {
397397
}
398398
},
399399
},
400+
{
401+
Description: "Test container network details",
402+
Setup: func(data test.Data, helpers test.Helpers) {
403+
helpers.Ensure("network", "create", data.Identifier("test-network"))
404+
405+
// See https://github.com/containerd/nerdctl/issues/4322
406+
if runtime.GOOS == "windows" {
407+
time.Sleep(time.Second)
408+
}
409+
410+
// Create and start a container on this network
411+
helpers.Ensure("run", "-d", "--name", data.Identifier("test-container"),
412+
"--network", data.Identifier("test-network"),
413+
testutil.CommonImage, "sleep", nerdtest.Infinity)
414+
415+
// Get container ID for later use
416+
containerID := strings.Trim(helpers.Capture("inspect", data.Identifier("test-container"), "--format", "{{.Id}}"), "\n")
417+
data.Labels().Set("containerID", containerID)
418+
},
419+
Cleanup: func(data test.Data, helpers test.Helpers) {
420+
helpers.Anyhow("rm", "-f", data.Identifier("test-container"))
421+
helpers.Anyhow("network", "remove", data.Identifier("test-network"))
422+
},
423+
Command: func(data test.Data, helpers test.Helpers) test.TestableCommand {
424+
return helpers.Command("network", "inspect", data.Identifier("test-network"))
425+
},
426+
Expected: func(data test.Data, helpers test.Helpers) *test.Expected {
427+
return &test.Expected{
428+
Output: func(stdout string, t tig.T) {
429+
var dc []dockercompat.Network
430+
err := json.Unmarshal([]byte(stdout), &dc)
431+
assert.NilError(t, err, "Unable to unmarshal output")
432+
assert.Equal(t, 1, len(dc), "Expected exactly one network")
433+
434+
network := dc[0]
435+
assert.Equal(t, network.Name, data.Identifier("test-network"))
436+
assert.Equal(t, 1, len(network.Containers), "Expected exactly one container")
437+
438+
// Get the container details
439+
containerID := data.Labels().Get("containerID")
440+
container := network.Containers[containerID]
441+
442+
// Test container name
443+
assert.Equal(t, container.Name, data.Identifier("test-container"))
444+
445+
// Test IPv4 address field exists in response
446+
assert.Assert(t, true, "IPv4Address field exists: %q", container.IPv4Address)
447+
448+
// Test MAC address field exists in response
449+
assert.Assert(t, true, "MacAddress field exists: %q", container.MacAddress)
450+
451+
// Test IPv6 address field exists in response
452+
assert.Assert(t, true, "IPv6Address field exists: %q", container.IPv6Address)
453+
},
454+
}
455+
},
456+
},
400457
}
401458

402459
testCase.Run(t)

pkg/inspecttypes/dockercompat/dockercompat.go

Lines changed: 45 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -929,9 +929,9 @@ type Network struct {
929929
type EndpointResource struct {
930930
Name string `json:"Name"`
931931
// EndpointID string `json:"EndpointID"`
932-
// MacAddress string `json:"MacAddress"`
933-
// IPv4Address string `json:"IPv4Address"`
934-
// IPv6Address string `json:"IPv6Address"`
932+
MacAddress string `json:"MacAddress"`
933+
IPv4Address string `json:"IPv4Address"`
934+
IPv6Address string `json:"IPv6Address"`
935935
}
936936

937937
type structuredCNI struct {
@@ -975,13 +975,50 @@ func NetworkFromNative(n *native.Network) (*Network, error) {
975975

976976
res.Containers = make(map[string]EndpointResource)
977977
for _, container := range n.Containers {
978-
res.Containers[container.ID] = EndpointResource{
978+
endpoint := EndpointResource{
979979
Name: container.Labels[labels.Name],
980-
// EndpointID: container.EndpointID,
981-
// MacAddress: container.MacAddress,
982-
// IPv4Address: container.IPv4Address,
983-
// IPv6Address: container.IPv6Address,
984980
}
981+
982+
// Extract network information from container's NetNS if available
983+
if container.Process != nil && container.Process.NetNS != nil {
984+
for _, x := range container.Process.NetNS.Interfaces {
985+
if x.Interface.Flags&net.FlagLoopback != 0 {
986+
continue
987+
}
988+
if x.Interface.Flags&net.FlagUp == 0 {
989+
continue
990+
}
991+
992+
// Set MAC address
993+
endpoint.MacAddress = x.HardwareAddr
994+
995+
// Extract IPv4 and IPv6 addresses
996+
for _, a := range x.Addrs {
997+
ip, _, err := net.ParseCIDR(a)
998+
if err != nil {
999+
continue
1000+
}
1001+
if ip.IsLoopback() || ip.IsLinkLocalUnicast() {
1002+
continue
1003+
}
1004+
1005+
// Check for IPv4
1006+
if ip4 := ip.To4(); ip4 != nil {
1007+
endpoint.IPv4Address = ip4.String()
1008+
} else if ip6 := ip.To16(); ip6 != nil {
1009+
// It's IPv6
1010+
endpoint.IPv6Address = ip6.String()
1011+
}
1012+
}
1013+
1014+
// Use the primary interface if available, otherwise use the first valid interface
1015+
if x.Index == container.Process.NetNS.PrimaryInterface || endpoint.IPv4Address != "" {
1016+
break
1017+
}
1018+
}
1019+
}
1020+
1021+
res.Containers[container.ID] = endpoint
9851022
}
9861023

9871024
return &res, nil

0 commit comments

Comments
 (0)