Example #1
0
// traverse walks the keyspace and converts anything that looks like an entity
// into an entity and returns it as part of the array.
//
// traverse will log & skip errors to ensure bad data will not break this routine.
func (c *Client) traverse(node *client.Node, obj db.Entity) []db.Entity {
	entities := []db.Entity{}
	if node.Dir {
		for _, inner := range node.Nodes {
			entities = append(entities, c.traverse(inner, obj)...)
		}
	} else {
		copy := obj.Copy()

		doAppend := true

		if err := jsonio.Read(copy, []byte(node.Value)); err != nil {
			// This is kept this way so a buggy policy won't break listing all of them
			logrus.Errorf("Received error retrieving value at path %q during list: %v", node.Key, err)
			doAppend = false
		}

		if err := copy.SetKey(c.trimPath(node.Key)); err != nil {
			logrus.Error(err)
			doAppend = false
		}

		// same here. fire hooks to retrieve the full entity. only log but don't append on error.
		if copy.Hooks().PostGet != nil {
			if err := copy.Hooks().PostGet(c, copy); err != nil {
				logrus.Errorf("Error received trying to run fetch hooks during %q list: %v", node.Key, err)
				doAppend = false
			}
		}

		if doAppend {
			entities = append(entities, copy)
		}
	}

	return entities
}