Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CNI compatible libnetwork drivers #1978

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ build-local:
@mkdir -p "bin"
go build -tags experimental -o "bin/dnet" ./cmd/dnet
go build -o "bin/docker-proxy" ./cmd/proxy

go build -o "bin/cniserver" ./cmd/cni_server
go build -o "bin/cnictl" ./cmd/dnet_cni/
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this needs to be statically built since you don't control the environment it will end up running in -- it is run in the context of the runtime (so maybe cri or docker, perhaps in a container) and not in a container/env supplied by libnetwork.

clean:
@echo "🐳 $@"
@if [ -d bin ]; then \
Expand Down
15 changes: 13 additions & 2 deletions api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -646,12 +646,17 @@ func procPublishService(c libnetwork.NetworkController, vars map[string]string,
setFctList = append(setFctList, libnetwork.CreateOptionMyAlias(str))
}

if sp.DisableResolution {
setFctList = append(setFctList, libnetwork.CreateOptionDisableResolution())
}

ep, err := n.CreateEndpoint(sp.Name, setFctList...)
if err != nil {
return "", endpointToService(convertNetworkError(err))
}
epResp := getEndpointInfo(ep)

return ep.ID(), &createdResponse
return epResp, &createdResponse
}

func procUnpublishService(c libnetwork.NetworkController, vars map[string]string, body []byte) (interface{}, *responseStatus) {
Expand Down Expand Up @@ -708,6 +713,13 @@ func procAttachBackend(c libnetwork.NetworkController, vars map[string]string, b
return nil, convertNetworkError(err)
}

if bk.SandboxKey != "" {
err = sb.SetKey(bk.SandboxKey)
if err != nil {
return nil, convertNetworkError(err)
}
}

return sb.Key(), &successResponse
}

Expand All @@ -727,7 +739,6 @@ func procDetachBackend(c libnetwork.NetworkController, vars map[string]string, b
if err != nil {
return nil, convertNetworkError(err)
}

return nil, &successResponse
}

Expand Down
8 changes: 6 additions & 2 deletions api/api_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -821,11 +821,15 @@ func TestProcPublishUnpublishService(t *testing.T) {
if err != nil {
t.Fatal(err)
}
si, errRsp := procPublishService(c, vars, b)
sv, errRsp := procPublishService(c, vars, b)
if errRsp != &createdResponse {
t.Fatalf("Unexpected failure: %v", errRsp)
}
sid := i2s(si)
ep, ok := sv.(endpointInfo)
if !ok {
panic(fmt.Sprintf("Failed for %v", sv))
}
sid := ep.ID

vars[urlEpID] = ""
_, errRsp = procUnpublishService(c, vars, nil)
Expand Down
66 changes: 60 additions & 6 deletions api/types.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
package api

import "github.com/docker/libnetwork/types"
import (
"net"

"github.com/docker/libnetwork"
"github.com/docker/libnetwork/types"
)

/***********
Resources
Expand Down Expand Up @@ -72,15 +77,17 @@ type sandboxCreate struct {

// endpointJoin represents the expected body of the "join endpoint" or "leave endpoint" http request messages
type endpointJoin struct {
SandboxID string `json:"sandbox_id"`
Aliases []string `json:"aliases"`
SandboxID string `json:"sandbox_id"`
Aliases []string `json:"aliases"`
SandboxKey string `json:"sandbox_key"`
}

// servicePublish represents the body of the "publish service" http request message
type servicePublish struct {
Name string `json:"name"`
MyAliases []string `json:"my_aliases"`
Network string `json:"network_name"`
Name string `json:"name"`
MyAliases []string `json:"my_aliases"`
Network string `json:"network_name"`
DisableResolution bool `json:"disable_resolution"`
}

// serviceDelete represents the body of the "unpublish service" http request message
Expand All @@ -89,8 +96,55 @@ type serviceDelete struct {
Force bool `json:"force"`
}

// endpointInfo represents the endpoint info for https response message on endpoint creation
type endpointInfo struct {
ID string `json:"id"`
Address net.IPNet `json:"address"`
AddressIPv6 net.IPNet `json:"address_ipv6"`
MacAddress net.HardwareAddr `json:"mac_address"`
Gateway net.IP `json:"gateway"`
GatewayIPv6 net.IP `json:"gateway_ipv6"`
}

// extraHost represents the extra host object
type extraHost struct {
Name string `json:"name"`
Address string `json:"address"`
}

// SandboxMetadata holds the metadata related to sandox (config)
type SandboxMetadata struct {
ContainerID string `json:"container_id"`
HostName string `json:"host_name"`
DomainName string `json:"domain_name"`
HostsPath string `json:"hosts_path"`
ResolvConfPath string `json:"resolv_conf_path"`
DNS []string `json:"dns"`
ExtraHosts []extraHost `json:"extra_hosts"`
UseExternalKey bool `json:"use_external_key"`
UseDefaultSandbox bool `json:"use_default_sandbox"`
ExposedPorts []types.TransportPort `json:"exposed_ports"`
PortMapping []types.PortBinding `json:"port_mapping"`
ExternalKey string `json:"external_key"`
}

func getEndpointInfo(ep libnetwork.Endpoint) endpointInfo {
epInfo := endpointInfo{ID: ep.ID()}

if ipv4 := ep.Info().Iface().Address(); ipv4 != nil {
epInfo.Address = *ipv4
}
if ipv6 := ep.Info().Iface().AddressIPv6(); ipv6 != nil {
epInfo.AddressIPv6 = *ipv6
}
if mac := ep.Info().Iface().MacAddress(); mac != nil {
epInfo.MacAddress = mac
}
if gw := ep.Info().Gateway(); gw != nil {
epInfo.Gateway = gw
}
if gw6 := ep.Info().GatewayIPv6(); gw6 != nil {
epInfo.GatewayIPv6 = gw6
}
return epInfo
}
4 changes: 2 additions & 2 deletions client/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ var mockContainerID = "2a3456789"
var mockSandboxID = "2b3456789"

func setupMockHTTPCallback() {
var list []networkResource
nw := networkResource{Name: mockNwName, ID: mockNwID}
var list []NetworkResource
nw := NetworkResource{Name: mockNwName, ID: mockNwID}
mockNwJSON, _ = json.Marshal(nw)
list = append(list, nw)
mockNwListJSON, _ = json.Marshal(list)
Expand Down
12 changes: 6 additions & 6 deletions client/network.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,9 +71,9 @@ func (cli *NetworkCli) CmdNetworkCreate(chain string, args ...string) error {
}
}

var icList []ipamConf
var icList []IPAMConf
if *flSubnet != "" {
ic := ipamConf{
ic := IPAMConf{
PreferredPool: *flSubnet,
}

Expand All @@ -85,7 +85,7 @@ func (cli *NetworkCli) CmdNetworkCreate(chain string, args ...string) error {
}

// Construct network create request body
nc := networkCreate{Name: cmd.Arg(0), NetworkType: *flDriver, ID: *flID, IPv4Conf: icList, DriverOpts: driverOpts, NetworkOpts: networkOpts}
nc := NetworkCreate{Name: cmd.Arg(0), NetworkType: *flDriver, ID: *flID, IPv4Conf: icList, DriverOpts: driverOpts, NetworkOpts: networkOpts}
obj, _, err := readBody(cli.call("POST", "/networks", nc, nil))
if err != nil {
return err
Expand Down Expand Up @@ -137,7 +137,7 @@ func (cli *NetworkCli) CmdNetworkLs(chain string, args ...string) error {
*last = 1
}

var networkResources []networkResource
var networkResources []NetworkResource
err = json.Unmarshal(obj, &networkResources)
if err != nil {
return err
Expand Down Expand Up @@ -189,7 +189,7 @@ func (cli *NetworkCli) CmdNetworkInfo(chain string, args ...string) error {
if err != nil {
return err
}
networkResource := &networkResource{}
networkResource := &NetworkResource{}
if err := json.NewDecoder(bytes.NewReader(obj)).Decode(networkResource); err != nil {
return err
}
Expand Down Expand Up @@ -222,7 +222,7 @@ func lookupNetworkID(cli *NetworkCli, nameID string) (string, error) {
return "", fmt.Errorf("name query failed for %s due to : statuscode(%d) %v", nameID, statusCode, string(obj))
}

var list []*networkResource
var list []*NetworkResource
err = json.Unmarshal(obj, &list)
if err != nil {
return "", err
Expand Down
16 changes: 8 additions & 8 deletions client/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ func lookupServiceID(cli *NetworkCli, nwName, svNameID string) (string, error) {
if err != nil {
return "", err
}
var nwList []networkResource
var nwList []NetworkResource
if err = json.Unmarshal(obj, &nwList); err != nil {
return "", err
}
Expand All @@ -45,7 +45,7 @@ func lookupServiceID(cli *NetworkCli, nwName, svNameID string) (string, error) {
if err != nil {
return "", err
}
networkResource := &networkResource{}
networkResource := &NetworkResource{}
if err := json.NewDecoder(bytes.NewReader(obj)).Decode(networkResource); err != nil {
return "", err
}
Expand Down Expand Up @@ -173,19 +173,19 @@ func (cli *NetworkCli) CmdServicePublish(chain string, args ...string) error {
}

sn, nn := parseServiceName(cmd.Arg(0))
sc := serviceCreate{Name: sn, Network: nn, MyAliases: flAlias.GetAll()}
sc := ServiceCreate{Name: sn, Network: nn, MyAliases: flAlias.GetAll()}
obj, _, err := readBody(cli.call("POST", "/services", sc, nil))
if err != nil {
return err
}

var replyID string
err = json.Unmarshal(obj, &replyID)
var ep EndpointInfo
err = json.Unmarshal(obj, &ep)
if err != nil {
return err
}

fmt.Fprintf(cli.out, "%s\n", replyID)
fmt.Fprintf(cli.out, "%s\n", ep.ID)
return nil
}

Expand All @@ -205,7 +205,7 @@ func (cli *NetworkCli) CmdServiceUnpublish(chain string, args ...string) error {
return err
}

sd := serviceDelete{Name: sn, Force: *force}
sd := ServiceDelete{Name: sn, Force: *force}
_, _, err = readBody(cli.call("DELETE", "/services/"+serviceID, sd, nil))

return err
Expand Down Expand Up @@ -350,7 +350,7 @@ func (cli *NetworkCli) CmdServiceAttach(chain string, args ...string) error {
return err
}

nc := serviceAttach{SandboxID: sandboxID, Aliases: flAlias.GetAll()}
nc := ServiceAttach{SandboxID: sandboxID, Aliases: flAlias.GetAll()}

_, _, err = readBody(cli.call("POST", "/services/"+serviceID+"/backend", nc, nil))

Expand Down
55 changes: 37 additions & 18 deletions client/types.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
package client

import "github.com/docker/libnetwork/types"
import (
"net"

"github.com/docker/libnetwork/types"
)

/***********
Resources
************/

// networkResource is the body of the "get network" http response message
type networkResource struct {
// NetworkResource is the body of the "get network" http response message
type NetworkResource struct {
Name string `json:"name"`
ID string `json:"id"`
Type string `json:"type"`
Expand All @@ -31,40 +35,44 @@ type SandboxResource struct {
/***********
Body types
************/
type ipamConf struct {

// IPAMConf is the ipam configution used during network create
type IPAMConf struct {
PreferredPool string
SubPool string
Gateway string
AuxAddresses map[string]string
}

// networkCreate is the expected body of the "create network" http request message
type networkCreate struct {
// NetworkCreate is the expected body of the "create network" http request message
type NetworkCreate struct {
Name string `json:"name"`
ID string `json:"id"`
NetworkType string `json:"network_type"`
IPv4Conf []ipamConf `json:"ipv4_configuration"`
IPv4Conf []IPAMConf `json:"ipv4_configuration"`
DriverOpts map[string]string `json:"driver_opts"`
NetworkOpts map[string]string `json:"network_opts"`
}

// serviceCreate represents the body of the "publish service" http request message
type serviceCreate struct {
Name string `json:"name"`
MyAliases []string `json:"my_aliases"`
Network string `json:"network_name"`
// ServiceCreate represents the body of the "publish service" http request message
type ServiceCreate struct {
Name string `json:"name"`
MyAliases []string `json:"my_aliases"`
Network string `json:"network_name"`
DisableResolution bool `json:"disable_resolution"`
}

// serviceDelete represents the body of the "unpublish service" http request message
type serviceDelete struct {
// ServiceDelete represents the body of the "unpublish service" http request message
type ServiceDelete struct {
Name string `json:"name"`
Force bool `json:"force"`
}

// serviceAttach represents the expected body of the "attach/detach sandbox to/from service" http request messages
type serviceAttach struct {
SandboxID string `json:"sandbox_id"`
Aliases []string `json:"aliases"`
// ServiceAttach represents the expected body of the "attach/detach sandbox to/from service" http request messages
type ServiceAttach struct {
SandboxID string `json:"sandbox_id"`
Aliases []string `json:"aliases"`
SandboxKey string `json:"sandbox_key"`
}

// SandboxCreate is the body of the "post /sandboxes" http request message
Expand All @@ -76,6 +84,7 @@ type SandboxCreate struct {
ResolvConfPath string `json:"resolv_conf_path"`
DNS []string `json:"dns"`
ExtraHosts []extraHost `json:"extra_hosts"`
UseExternalKey bool `json:"use_external_key"`
UseDefaultSandbox bool `json:"use_default_sandbox"`
ExposedPorts []types.TransportPort `json:"exposed_ports"`
PortMapping []types.PortBinding `json:"port_mapping"`
Expand All @@ -94,3 +103,13 @@ type sandboxParentUpdate struct {
Name string `json:"name"`
Address string `json:"address"`
}

// EndpointInfo contants the endpoint info for http response message on endpoint creation
type EndpointInfo struct {
ID string `json:"id"`
Address net.IPNet `json:"address"`
AddressIPv6 net.IPNet `json:"address_ipv6"`
MacAddress net.HardwareAddr `json:"mac_address"`
Gateway net.IP `json:"gateway"`
GatewayIPv6 net.IP `json:"gateway_ipv6"`
}
Loading