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 {
|
if err != nil {
|
||||||
return
|
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
|
## Future
|
||||||
|
|
|
@ -1,7 +1,10 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
"github.com/docker/libnetwork"
|
"github.com/docker/libnetwork"
|
||||||
|
"github.com/docker/libnetwork/netutils"
|
||||||
"github.com/docker/libnetwork/pkg/options"
|
"github.com/docker/libnetwork/pkg/options"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -46,4 +49,14 @@ func main() {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
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.
|
// passing the network id and endpoint id.
|
||||||
DeleteEndpoint(nid, eid types.UUID) error
|
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 method is invoked when a Sandbox is attached to an endpoint.
|
||||||
Join(nid, eid types.UUID, sboxKey string, options map[string]interface{}) error
|
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
|
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.
|
// 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 {
|
func (d *driver) Join(nid, eid types.UUID, sboxKey string, options map[string]interface{}) error {
|
||||||
var err error
|
var err error
|
||||||
|
|
|
@ -72,6 +72,68 @@ func TestCreateFullOptions(t *testing.T) {
|
||||||
t.Fatalf("Failed to create bridge: %v", err)
|
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) {
|
func TestCreateLinkWithOptions(t *testing.T) {
|
||||||
defer netutils.SetupTestNetNS(t)()
|
defer netutils.SetupTestNetNS(t)()
|
||||||
|
|
||||||
|
|
|
@ -35,6 +35,10 @@ func (d *driver) DeleteEndpoint(nid, eid types.UUID) error {
|
||||||
return nil
|
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.
|
// 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 {
|
func (d *driver) Join(nid, eid types.UUID, sboxKey string, options map[string]interface{}) error {
|
||||||
return nil
|
return nil
|
||||||
|
|
|
@ -34,6 +34,9 @@ type Endpoint interface {
|
||||||
// SandboxInfo returns the sandbox information for this endpoint.
|
// SandboxInfo returns the sandbox information for this endpoint.
|
||||||
SandboxInfo() *sandbox.Info
|
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 and detaches this endpoint from the network.
|
||||||
Delete() error
|
Delete() error
|
||||||
}
|
}
|
||||||
|
@ -94,6 +97,10 @@ func (ep *endpoint) SandboxInfo() *sandbox.Info {
|
||||||
return ep.sandboxInfo.GetCopy()
|
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) {
|
func (ep *endpoint) processOptions(options ...EndpointOption) {
|
||||||
for _, opt := range options {
|
for _, opt := range options {
|
||||||
if opt != nil {
|
if opt != nil {
|
||||||
|
|
|
@ -131,6 +131,22 @@ func TestBridge(t *testing.T) {
|
||||||
t.Fatal(err)
|
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 {
|
if err := ep.Delete(); err != nil {
|
||||||
t.Fatal(err)
|
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 (
|
const (
|
||||||
// ICMP is for the ICMP ip protocol
|
// ICMP is for the ICMP ip protocol
|
||||||
ICMP = 1
|
ICMP = 1
|
||||||
|
|
Loading…
Add table
Reference in a new issue