forked from lyft/cni-ipvlan-vpc-k8s
/
desc.go
97 lines (81 loc) · 1.93 KB
/
desc.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
package nl
import (
"fmt"
"io/ioutil"
"net"
"os"
"path/filepath"
"github.com/containernetworking/plugins/pkg/ns"
"github.com/vishvananda/netlink"
)
// BoundIP contains an IPNet / Label pair
type BoundIP struct {
*net.IPNet
Label string
}
func getIpsOnHandle(handle *netlink.Handle) ([]BoundIP, error) {
foundIps := []BoundIP{}
links, err := handle.LinkList()
if err != nil {
return nil, err
}
for _, link := range links {
addrs, err := handle.AddrList(link, netlink.FAMILY_V4)
if err != nil {
return nil, err
}
for _, addr := range addrs {
ip := *addr.IPNet
found := BoundIP{
&ip,
addr.Label,
}
foundIps = append(foundIps, found)
}
}
return foundIps, nil
}
// GetIPs returns IPs allocated to interfaces, in all namespaces
// TODO: Remove addresses on control plane interfaces, filters
func GetIPs() ([]BoundIP, error) {
var namespaces []string
files, err := ioutil.ReadDir("/var/run/netns/")
if err == nil {
for _, file := range files {
namespaces = append(namespaces,
filepath.Join("/var/run/netns", file.Name()))
}
}
// Check for running docker containers
containers, err := runningDockerContainers()
if err == nil {
dockerNamespaces := dockerNetworkNamespaces(containers)
namespaces = append(namespaces, dockerNamespaces...)
}
// First get all the IPs in the main namespace
handle, err := netlink.NewHandle()
if err != nil {
return nil, err
}
foundIps, err := getIpsOnHandle(handle)
if err != nil {
return nil, err
}
// Enter each namesapce, get handles
for _, nsPath := range namespaces {
err := ns.WithNetNSPath(nsPath, func(_ ns.NetNS) error {
handle, err = netlink.NewHandle()
if err != nil {
return err
}
defer handle.Delete()
newIps, err := getIpsOnHandle(handle)
foundIps = append(foundIps, newIps...)
return err
})
if err != nil {
fmt.Fprintf(os.Stderr, "Enumerating namespace failure %v", err)
}
}
return foundIps, nil
}