Implement `CreateNetwork` and `DeleteNetwork`
parent
bd8e73f41a
commit
f8a70d5222
@ -1,12 +1,35 @@
|
||||
github.com/containous/traefik v1.7.24 h1:iFkoJBpQUQh1URdblBjbh32Wav8Ctl/WjLtAtvBzHis=
|
||||
github.com/containous/traefik v1.7.24/go.mod h1:epDRqge3JzKOhlSWzOpNYEEKXmM6yfN5tPzDGKk3ljo=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/docker/distribution v2.7.1+incompatible h1:a5mlkVzth6W5A4fOsS3D2EO5BUmsJpcB+cRlLU7cSug=
|
||||
github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
||||
github.com/docker/docker v1.13.1 h1:IkZjBSIc8hBjLpqeAbeE5mca5mNgeatLHBy3GO78BWo=
|
||||
github.com/docker/docker v1.13.1/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||
github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ=
|
||||
github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec=
|
||||
github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw=
|
||||
github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
|
||||
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/sirupsen/logrus v1.6.0 h1:UBcNElsrwanuuMsnGSlYmtmgbb23qDR5dG+6X6Oo89I=
|
||||
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/vishvananda/netlink v1.1.0 h1:1iyaYNBLmP6L0220aDnYQpo1QEV4t4hJ+xEEhhJH8j0=
|
||||
github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE=
|
||||
github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df h1:OviZH7qLw/7ZovXvuNyL3XQl8UFofeikI1NW1Gypu7k=
|
||||
github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/net v0.0.0-20200513185701-a91f0712d120 h1:EZ3cVSzKOlJxAd8e8YAJ7no8nNypTxexh/YE/xW3ZEY=
|
||||
golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190422165155-953cdadca894 h1:Cz4ceDQGXuKRnVBDTS23GTn/pU5OE2C0WrNTOYK1Uuc=
|
||||
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190606203320-7fc4e5ec1444/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9 h1:YTzHMGlqJu67/uEo1lBv0n3wBXhXNeUbB1XfN2vmTm0=
|
||||
golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
|
@ -0,0 +1,96 @@
|
||||
package plugin
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
"github.com/vishvananda/netlink"
|
||||
"golang.org/x/sys/unix"
|
||||
|
||||
dTypes "github.com/docker/docker/api/types"
|
||||
)
|
||||
|
||||
// CLIOptionsKey is the key used in create network options by the CLI for custom options
|
||||
const CLIOptionsKey string = "com.docker.network.generic"
|
||||
|
||||
var (
|
||||
// ErrIPAM indicates an unsupported IPAM driver was used
|
||||
ErrIPAM = errors.New("only the null IPAM driver is supported")
|
||||
// ErrBridge indicates that a bridge is unavailable for use
|
||||
ErrBridge = errors.New("bridge not found or already in use by Docker")
|
||||
)
|
||||
|
||||
// CreateNetwork "creates" a new DHCP network (just checks if the provided bridge exists and the null IPAM driver is
|
||||
// used)
|
||||
func (p *Plugin) CreateNetwork(r CreateNetworkRequest) error {
|
||||
for _, d := range r.IPv4Data {
|
||||
if d.AddressSpace != "null" || d.Pool != "0.0.0.0/0" {
|
||||
return ErrIPAM
|
||||
}
|
||||
}
|
||||
|
||||
links, err := netlink.LinkList()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to retrieve list of network interfaces: %w", err)
|
||||
}
|
||||
|
||||
nets, err := p.docker.NetworkList(context.Background(), dTypes.NetworkListOptions{})
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to retrieve list of networks from Docker: %w", err)
|
||||
}
|
||||
|
||||
found := false
|
||||
for _, l := range links {
|
||||
attrs := l.Attrs()
|
||||
if l.Type() != "bridge" || attrs.Name != r.Options.Generic.Bridge {
|
||||
continue
|
||||
}
|
||||
|
||||
v4Addrs, err := netlink.AddrList(l, unix.AF_INET)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to retrieve IPv4 addresses for %v: %w", attrs.Name, err)
|
||||
}
|
||||
v6Addrs, err := netlink.AddrList(l, unix.AF_INET6)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to retrieve IPv6 addresses for %v: %w", attrs.Name, err)
|
||||
}
|
||||
addrs := append(v4Addrs, v6Addrs...)
|
||||
|
||||
// Make sure the addresses on this bridge aren't used by another network
|
||||
for _, n := range nets {
|
||||
for _, c := range n.IPAM.Config {
|
||||
_, cidr, err := net.ParseCIDR(c.Subnet)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to parse subnet %v on Docker network %v: %w", c.Subnet, n.ID, err)
|
||||
}
|
||||
|
||||
for _, linkAddr := range addrs {
|
||||
if linkAddr.IPNet.Contains(cidr.IP) || cidr.Contains(linkAddr.IP) {
|
||||
return ErrBridge
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
found = true
|
||||
break
|
||||
}
|
||||
if !found {
|
||||
return ErrBridge
|
||||
}
|
||||
|
||||
log.WithFields(log.Fields{
|
||||
"network": r.NetworkID,
|
||||
"bridge": r.Options.Generic.Bridge,
|
||||
"ipv6": r.Options.Generic.IPv6,
|
||||
}).Info("Creating network")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeleteNetwork "deletes" a DHCP network (does nothing, the bridge is managed by the user)
|
||||
func (p *Plugin) DeleteNetwork() error {
|
||||
return nil
|
||||
}
|
Loading…
Reference in New Issue