Browse Source

Fix etcd implementation of getNetworks()

etcd itself returns networks in a different format than the code and
the testcases expected.  Fix up the code and testcases to match what
etcd returns.

Fixes: d9d89f6bde8dfeb8af252f39ee70e2ecfc379eee (subnet: add infrastructure and tests for network watches)
Dan Williams 9 years ago
parent
commit
40737d1ab1
2 changed files with 37 additions and 6 deletions
  1. 6 3
      subnet/etcd.go
  2. 31 3
      subnet/mock_registry.go

+ 6 - 3
subnet/etcd.go

@@ -462,9 +462,12 @@ func (m *EtcdManager) getNetworks(ctx context.Context) ([]string, uint64, error)
 
 	if err == nil {
 		for _, node := range resp.Node.Nodes {
-			netname, err := m.parseNetworkKey(node.Key)
-			if err == nil {
-				networks = append(networks, netname)
+			// Look for '/config' on the child nodes
+			for _, child := range node.Nodes {
+				netname, err := m.parseNetworkKey(child.Key)
+				if err == nil {
+					networks = append(networks, netname)
+				}
 			}
 		}
 

+ 31 - 3
subnet/mock_registry.go

@@ -234,6 +234,13 @@ func (msr *MockSubnetRegistry) expireSubnet(network, sn string) {
 	}
 }
 
+func configKeyToNetworkKey(configKey string) string {
+	if !strings.HasSuffix(configKey, "/config") {
+		return ""
+	}
+	return strings.TrimSuffix(configKey, "/config")
+}
+
 func (msr *MockSubnetRegistry) getNetworks(ctx context.Context) (*etcd.Response, error) {
 	var keys []string
 	for k := range msr.networks {
@@ -241,13 +248,34 @@ func (msr *MockSubnetRegistry) getNetworks(ctx context.Context) (*etcd.Response,
 	}
 	sort.Strings(keys)
 
-	networks := &etcd.Node{Key: networkKeyPrefix, Value: "", ModifiedIndex: msr.index, Nodes: make([]*etcd.Node, 0, len(keys))}
+	// mimic etcd by returning a multi-level response where each top-level
+	// node is a network node, and each network node has a single child
+	// 'config' node.  eg:
+	//
+	//  /coreos.com/network
+	//     /coreos.com/network/blue
+	//        /coreos.com/network/blue/config
+	//     /coreos.com/network/red
+	//        /coreos.com/network/red/config
+	//
+	toplevel := &etcd.Node{Key: networkKeyPrefix, Value: "", ModifiedIndex: msr.index, Nodes: make([]*etcd.Node, 0, len(keys))}
 	for _, k := range keys {
-		networks.Nodes = append(networks.Nodes, msr.networks[k])
+		netKey := configKeyToNetworkKey(msr.networks[k].Key)
+		if netKey == "" {
+			continue
+		}
+		network := &etcd.Node{
+			Key:           netKey,
+			Value:         "",
+			ModifiedIndex: msr.index,
+			Nodes:         []*etcd.Node{msr.networks[k]},
+		}
+
+		toplevel.Nodes = append(toplevel.Nodes, network)
 	}
 
 	return &etcd.Response{
-		Node:  networks,
+		Node:  toplevel,
 		Index: msr.index,
 	}, nil
 }