// Returns the node created and its creation response // Don't need to check for intermediate directories here as that was already done // by the thing calling makeNode() func (me *mockEtcd) makeNode(path []string, value string, isDir bool, ttl time.Duration) (*etcd.Node, *etcd.Response, error) { var child *etcd.Node var resp *etcd.Response var ok bool node := me.nodes["/"] for i, part := range path { node, ok = me.nodes[part] if !ok { me.index += 1 if i < len(path)-1 { // intermediate node child = me.newNode(part, "", true) } else { // Final node exp := time.Now().Add(ttl) child = me.newNode(part, value, isDir) child.Expiration = &exp resp = &etcd.Response{ Action: "create", Node: me.copyNode(child, false), Index: child.CreatedIndex, } me.sendEvent(resp) } me.nodes[child.Key] = child node = child } } return node, resp, nil }
// Removes a node and all children func (me *mockEtcd) deleteNode(node *etcd.Node, parent *etcd.Node, recursive bool) (*etcd.Response, error) { for _, child := range me.nodes { if isChild, directChild := isChild(node, child); isChild { if recursive == false { return nil, me.newError(etcd.ErrorCodeDirNotEmpty, "Key %s not empty", node.Key) } if directChild { me.deleteNode(child, node, true) me.index += 1 node.ModifiedIndex = me.index } } } me.index += 1 resp := &etcd.Response{ Action: "delete", Node: me.copyNode(node, false), Index: me.index, } me.sendEvent(resp) delete(me.nodes, node.Key) return resp, nil }
// nodeToAgentAdvert takes a etcd Node representing an AgentAdvert and returns an AgentAdvert func nodeToAgentAdvert(node *client.Node, expectedUUID string) (*defs.AgentAdvert, error) { adv := new(defs.AgentAdvert) // Marshal API data into object err := json.Unmarshal([]byte(node.Value), adv) if err != nil { log.Error("Failed to unmarshal json into agent advertisement") return nil, err } // We want to use the TTLDuration field from etcd for simplicity adv.Expires = node.TTLDuration() // The etcd key should always match the inner JSON if expectedUUID != adv.Uuid { return nil, errors.New("UUID in etcd does not match inner JSON text") } return adv, nil }