From 6a5e4a83e4d055b10256d2f99e9881487073e933 Mon Sep 17 00:00:00 2001 From: Alessandro Boch Date: Fri, 24 Apr 2015 12:05:33 -0700 Subject: [PATCH] Provide Query API for Network and Endpoint - In NetworkController and Network respectively Signed-off-by: Alessandro Boch --- libnetwork/libnetwork_test.go | 98 +++++++++++++++++++++++++++++++++++ libnetwork/network.go | 74 ++++++++++++++++++++++++-- 2 files changed, 168 insertions(+), 4 deletions(-) diff --git a/libnetwork/libnetwork_test.go b/libnetwork/libnetwork_test.go index fdbead8017..a2359cca31 100644 --- a/libnetwork/libnetwork_test.go +++ b/libnetwork/libnetwork_test.go @@ -371,3 +371,101 @@ func TestNetworkEndpointsWalkers(t *testing.T) { t.Fatal(err) } } + +func TestControllerQuery(t *testing.T) { + defer netutils.SetupTestNetNS(t)() + controller := libnetwork.New() + netType := "bridge" + + option := options.Generic{} + err := controller.ConfigureNetworkDriver(netType, option) + if err != nil { + t.Fatal(err) + } + + // Create network 1 + net1, err := controller.NewNetwork(netType, "network1", "") + if err != nil { + t.Fatal(err) + } + + g := controller.NetworkByName("") + if g != nil { + t.Fatalf("NetworkByName() succeeded with invalid target name") + } + + g = controller.NetworkByID("") + if g != nil { + t.Fatalf("NetworkByID() succeeded with invalid target id: %v", g) + } + + g = controller.NetworkByID("network1") + if g != nil { + t.Fatalf("NetworkByID() succeeded with invalid target name") + } + + g = controller.NetworkByName("network1") + if g == nil { + t.Fatalf("NetworkByName() did not find the network") + } + if g != net1 { + t.Fatalf("NetworkByName() returned the wrong network") + } + + g = controller.NetworkByID(net1.ID()) + if net1 != g { + t.Fatalf("NetworkByID() returned unexpected element: %v", g) + } +} + +func TestNetworkQuery(t *testing.T) { + defer netutils.SetupTestNetNS(t)() + controller := libnetwork.New() + netType := "bridge" + + option := options.Generic{} + err := controller.ConfigureNetworkDriver(netType, option) + if err != nil { + t.Fatal(err) + } + + // Create network 1 and add 2 endpoint: ep11, ep12 + net1, err := controller.NewNetwork(netType, "network1", "") + if err != nil { + t.Fatal(err) + } + ep11, err := net1.CreateEndpoint("ep11", "sbox1", nil) + if err != nil { + t.Fatal(err) + } + ep12, err := net1.CreateEndpoint("ep12", "sbox2", nil) + if err != nil { + t.Fatal(err) + } + + e := net1.EndpointByName("ep11") + if ep11 != e { + t.Fatalf("EndpointByName() returned %v instead of %v", e, ep11) + } + + e = net1.EndpointByName("") + if e != nil { + t.Fatalf("EndpointByName(): expected nil, got %v", e) + } + + e = net1.EndpointByName("IamNotAnEndpoint") + if e != nil { + t.Fatalf("EndpointByName(): expected nil, got %v", e) + } + + e = net1.EndpointByID(ep12.ID()) + if ep12 != e { + t.Fatalf("EndpointByID() returned %v instead of %v", e, ep12) + } + + e = net1.EndpointByID("") + if e != nil { + t.Fatalf("EndpointByID(): expected nil, got %v", e) + } + +} diff --git a/libnetwork/network.go b/libnetwork/network.go index 4e2472cbb5..8b35ac3251 100644 --- a/libnetwork/network.go +++ b/libnetwork/network.go @@ -8,14 +8,14 @@ create network namespaces and allocate interfaces for containers to use. // This option is only needed for in-tree drivers. Plugins(in future) will get // their options through plugin infrastructure. option := options.Generic{} - driver, err := controller.NewNetworkDriver("bridge", option) + err := controller.NewNetworkDriver("bridge", option) if err != nil { return } netOptions := options.Generic{} // Create a network for containers to join. - network, err := controller.NewNetwork(driver, "network1", netOptions) + network, err := controller.NewNetwork("bridge", "network1", netOptions) if err != nil { return } @@ -62,6 +62,12 @@ type NetworkController interface { // WalkNetworks uses the provided function to walk the Network(s) managed by this controller. WalkNetworks(walker NetworkWalker) + + // NetworkByName returns the Network which has the passed name, if it exists otherwise nil is returned + NetworkByName(name string) Network + + // NetworkByID returns the Network which has the passed id, if it exists otherwise nil is returned + NetworkByID(id string) Network } // A Network represents a logical connectivity zone that containers may @@ -81,14 +87,20 @@ type Network interface { // Labels support will be added in the near future. CreateEndpoint(name string, sboxKey string, options interface{}) (Endpoint, error) + // Delete the network. + Delete() error + // Endpoints returns the list of Endpoint(s) in this network. Endpoints() []Endpoint // WalkEndpoints uses the provided function to walk the Endpoints WalkEndpoints(walker EndpointWalker) - // Delete the network. - Delete() error + // EndpointByName returns the Endpoint which has the passed name, if it exists otherwise nil is returned + EndpointByName(name string) Endpoint + + // EndpointByID returns the Endpoint which has the passed id, if it exists otherwise nil is returned + EndpointByID(id string) Endpoint } // NetworkWalker is a client provided function which will be used to walk the Networks. @@ -217,6 +229,33 @@ func (c *controller) WalkNetworks(walker NetworkWalker) { } } +func (c *controller) NetworkByName(name string) Network { + var n Network + + if name != "" { + s := func(current Network) bool { + if current.Name() == name { + n = current + return true + } + return false + } + + c.WalkNetworks(s) + } + + return n +} + +func (c *controller) NetworkByID(id string) Network { + c.Lock() + defer c.Unlock() + if n, ok := c.networks[types.UUID(id)]; ok { + return n + } + return nil +} + func (n *network) Name() string { return n.name } @@ -302,6 +341,33 @@ func (n *network) WalkEndpoints(walker EndpointWalker) { } } +func (n *network) EndpointByName(name string) Endpoint { + var e Endpoint + + if name != "" { + s := func(current Endpoint) bool { + if current.Name() == name { + e = current + return true + } + return false + } + + n.WalkEndpoints(s) + } + + return e +} + +func (n *network) EndpointByID(id string) Endpoint { + n.Lock() + defer n.Unlock() + if e, ok := n.endpoints[types.UUID(id)]; ok { + return e + } + return nil +} + func (ep *endpoint) ID() string { return string(ep.id) }