mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
Provide API to retrieve Endpoint operational data
- from the driver Signed-off-by: Alessandro Boch <aboch@docker.com>
This commit is contained in:
parent
76ac418c43
commit
56741e7d60
9 changed files with 193 additions and 0 deletions
|
@ -61,6 +61,17 @@ There are many networking solutions available to suit a broad range of use-cases
|
|||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// libentwork client can check the endpoint's operational data via the Info() API
|
||||
epInfo, err := ep.Info()
|
||||
mapData, ok := epInfo[options.PortMap]
|
||||
if ok {
|
||||
portMapping, ok := mapData.([]netutils.PortBinding)
|
||||
if ok {
|
||||
fmt.Printf("Current port mapping for endpoint %s: %v", ep.Name(), portMapping)
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
## Future
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/docker/libnetwork"
|
||||
"github.com/docker/libnetwork/netutils"
|
||||
"github.com/docker/libnetwork/pkg/options"
|
||||
)
|
||||
|
||||
|
@ -46,4 +49,14 @@ func main() {
|
|||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// libentwork client can check the endpoint's operational data via the Info() API
|
||||
epInfo, err := ep.Info()
|
||||
mapData, ok := epInfo[options.PortMap]
|
||||
if ok {
|
||||
portMapping, ok := mapData.([]netutils.PortBinding)
|
||||
if ok {
|
||||
fmt.Printf("Current port mapping for endpoint %s: %v", ep.Name(), portMapping)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -40,6 +40,9 @@ type Driver interface {
|
|||
// passing the network id and endpoint id.
|
||||
DeleteEndpoint(nid, eid types.UUID) error
|
||||
|
||||
// EndpointInfo retrieves from the driver the operational data related to the specified endpoint
|
||||
EndpointInfo(nid, eid types.UUID) (map[string]interface{}, error)
|
||||
|
||||
// Join method is invoked when a Sandbox is attached to an endpoint.
|
||||
Join(nid, eid types.UUID, sboxKey string, options map[string]interface{}) error
|
||||
|
||||
|
|
|
@ -573,6 +573,46 @@ func (d *driver) DeleteEndpoint(nid, eid types.UUID) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (d *driver) EndpointInfo(nid, eid types.UUID) (map[string]interface{}, error) {
|
||||
// Get the network handler and make sure it exists
|
||||
d.Lock()
|
||||
n := d.network
|
||||
d.Unlock()
|
||||
if n == nil {
|
||||
return nil, driverapi.ErrNoNetwork
|
||||
}
|
||||
|
||||
// Sanity check
|
||||
n.Lock()
|
||||
if n.id != nid {
|
||||
n.Unlock()
|
||||
return nil, InvalidNetworkIDError(nid)
|
||||
}
|
||||
n.Unlock()
|
||||
|
||||
// Check if endpoint id is good and retrieve correspondent endpoint
|
||||
ep, err := n.getEndpoint(eid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if ep == nil {
|
||||
return nil, driverapi.ErrNoEndpoint
|
||||
}
|
||||
|
||||
m := make(map[string]interface{})
|
||||
|
||||
if ep.portMapping != nil {
|
||||
// Return a copy of the operational data
|
||||
pmc := make([]netutils.PortBinding, 0, len(ep.portMapping))
|
||||
for _, pm := range ep.portMapping {
|
||||
pmc = append(pmc, pm.GetCopy())
|
||||
}
|
||||
m[options.PortMap] = pmc
|
||||
}
|
||||
|
||||
return m, nil
|
||||
}
|
||||
|
||||
// Join method is invoked when a Sandbox is attached to an endpoint.
|
||||
func (d *driver) Join(nid, eid types.UUID, sboxKey string, options map[string]interface{}) error {
|
||||
var err error
|
||||
|
|
|
@ -72,6 +72,68 @@ func TestCreateFullOptions(t *testing.T) {
|
|||
t.Fatalf("Failed to create bridge: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestQueryEndpointInfo(t *testing.T) {
|
||||
defer netutils.SetupTestNetNS(t)()
|
||||
|
||||
_, d := New()
|
||||
|
||||
config := &Configuration{
|
||||
BridgeName: DefaultBridgeName,
|
||||
EnableIPTables: true,
|
||||
EnableICC: false,
|
||||
}
|
||||
genericOption := make(map[string]interface{})
|
||||
genericOption[options.GenericData] = config
|
||||
|
||||
if err := d.Config(genericOption); err != nil {
|
||||
t.Fatalf("Failed to setup driver config: %v", err)
|
||||
}
|
||||
|
||||
err := d.CreateNetwork("net1", nil)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create bridge: %v", err)
|
||||
}
|
||||
|
||||
portMappings := getPortMapping()
|
||||
epOptions := make(map[string]interface{})
|
||||
epOptions[options.PortMap] = portMappings
|
||||
|
||||
_, err = d.CreateEndpoint("net1", "ep1", epOptions)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create an endpoint : %s", err.Error())
|
||||
}
|
||||
|
||||
dd := d.(*driver)
|
||||
ep, _ := dd.network.endpoints["ep1"]
|
||||
data, err := d.EndpointInfo(dd.network.id, ep.id)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to ask for endpoint operational data: %v", err)
|
||||
}
|
||||
pmd, ok := data[options.PortMap]
|
||||
if !ok {
|
||||
t.Fatalf("Endpoint operational data does not contain port mapping data")
|
||||
}
|
||||
pm, ok := pmd.([]netutils.PortBinding)
|
||||
if !ok {
|
||||
t.Fatalf("Unexpected format for port mapping in endpoint operational data")
|
||||
}
|
||||
if len(ep.portMapping) != len(pm) {
|
||||
t.Fatalf("Incomplete data for port mapping in endpoint operational data")
|
||||
}
|
||||
for i, pb := range ep.portMapping {
|
||||
if !pb.Equal(&pm[i]) {
|
||||
t.Fatalf("Unexpected data for port mapping in endpoint operational data")
|
||||
}
|
||||
}
|
||||
|
||||
// Cleanup as host ports are there
|
||||
err = releasePorts(ep)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to release mapped ports: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCreateLinkWithOptions(t *testing.T) {
|
||||
defer netutils.SetupTestNetNS(t)()
|
||||
|
||||
|
|
|
@ -35,6 +35,10 @@ func (d *driver) DeleteEndpoint(nid, eid types.UUID) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (d *driver) EndpointInfo(nid, eid types.UUID) (map[string]interface{}, error) {
|
||||
return make(map[string]interface{}, 0), nil
|
||||
}
|
||||
|
||||
// Join method is invoked when a Sandbox is attached to an endpoint.
|
||||
func (d *driver) Join(nid, eid types.UUID, sboxKey string, options map[string]interface{}) error {
|
||||
return nil
|
||||
|
|
|
@ -34,6 +34,9 @@ type Endpoint interface {
|
|||
// SandboxInfo returns the sandbox information for this endpoint.
|
||||
SandboxInfo() *sandbox.Info
|
||||
|
||||
// Info returns a collection of operational data related to this endpoint retrieved from the driver
|
||||
Info() (map[string]interface{}, error)
|
||||
|
||||
// Delete and detaches this endpoint from the network.
|
||||
Delete() error
|
||||
}
|
||||
|
@ -94,6 +97,10 @@ func (ep *endpoint) SandboxInfo() *sandbox.Info {
|
|||
return ep.sandboxInfo.GetCopy()
|
||||
}
|
||||
|
||||
func (ep *endpoint) Info() (map[string]interface{}, error) {
|
||||
return ep.network.driver.EndpointInfo(ep.network.id, ep.id)
|
||||
}
|
||||
|
||||
func (ep *endpoint) processOptions(options ...EndpointOption) {
|
||||
for _, opt := range options {
|
||||
if opt != nil {
|
||||
|
|
|
@ -131,6 +131,22 @@ func TestBridge(t *testing.T) {
|
|||
t.Fatal(err)
|
||||
}
|
||||
|
||||
epInfo, err := ep.Info()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
pmd, ok := epInfo[options.PortMap]
|
||||
if !ok {
|
||||
t.Fatalf("Could not find expected info in endpoint data")
|
||||
}
|
||||
pm, ok := pmd.([]netutils.PortBinding)
|
||||
if !ok {
|
||||
t.Fatalf("Unexpected format for port mapping in endpoint operational data")
|
||||
}
|
||||
if len(pm) != 3 {
|
||||
t.Fatalf("Incomplete data for port mapping in endpoint operational data")
|
||||
}
|
||||
|
||||
if err := ep.Delete(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
|
|
@ -83,6 +83,43 @@ func (p *PortBinding) GetCopy() PortBinding {
|
|||
}
|
||||
}
|
||||
|
||||
// Equal checks if this instance of PortBinding is equal to the passed one
|
||||
func (p *PortBinding) Equal(o *PortBinding) bool {
|
||||
if p == o {
|
||||
return true
|
||||
}
|
||||
|
||||
if o == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
if p.Proto != o.Proto || p.Port != o.Port || p.HostPort != o.HostPort {
|
||||
return false
|
||||
}
|
||||
|
||||
if p.IP != nil {
|
||||
if !p.IP.Equal(o.IP) {
|
||||
return false
|
||||
}
|
||||
} else {
|
||||
if o.IP != nil {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
if p.HostIP != nil {
|
||||
if !p.HostIP.Equal(o.HostIP) {
|
||||
return false
|
||||
}
|
||||
} else {
|
||||
if o.HostIP != nil {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
const (
|
||||
// ICMP is for the ICMP ip protocol
|
||||
ICMP = 1
|
||||
|
|
Loading…
Add table
Reference in a new issue