add support for a consul backing store for trackig provisioned state
diff --git a/automation/tracker.go b/automation/tracker.go
index 9f38b23..e299a68 100644
--- a/automation/tracker.go
+++ b/automation/tracker.go
@@ -3,9 +3,11 @@
 import (
 	"encoding/json"
 	"github.com/fzzy/radix/redis"
+	consul "github.com/hashicorp/consul/api"
 	"log"
 	"net/url"
 	"os"
+	"strings"
 )
 
 type ProvisionState int8
@@ -48,6 +50,46 @@
 	Clear(key string) error
 }
 
+type ConsulTracker struct {
+	client *consul.Client
+	kv     *consul.KV
+}
+
+func (c *ConsulTracker) Get(key string) (*TrackerRecord, error) {
+	pair, _, err := c.kv.Get(key, nil)
+	if err != nil {
+		return nil, err
+	}
+
+	if pair == nil {
+		var record TrackerRecord
+		record.State = Unprovisioned
+		return &record, nil
+	}
+
+	var record TrackerRecord
+	err = json.Unmarshal([]byte(pair.Value), &record)
+	if err != nil {
+		return nil, err
+	}
+	return &record, nil
+}
+
+func (c *ConsulTracker) Set(key string, record *TrackerRecord) error {
+	data, err := json.Marshal(record)
+	if err != nil {
+		return err
+	}
+	pair := &consul.KVPair{Key: key, Value: data}
+	_, err = c.kv.Put(pair, nil)
+	return err
+}
+
+func (c *ConsulTracker) Clear(key string) error {
+	_, err := c.kv.Delete(key, nil)
+	return err
+}
+
 // RedisTracker redis implementation of the tracker interface
 type RedisTracker struct {
 	client *redis.Client
@@ -77,7 +119,11 @@
 }
 
 func (t *RedisTracker) Set(key string, record *TrackerRecord) error {
-	reply := t.client.Cmd("set", key, true)
+	data, err := json.Marshal(record)
+	if err != nil {
+		return err
+	}
+	reply := t.client.Cmd("set", key, data)
 	return reply.Err
 }
 
@@ -114,8 +160,14 @@
 //            depends on the environment. If a link to a redis instance is defined then this will
 //            be used, else an in memory version will be used.
 func NewTracker() Tracker {
-	// Check the environment to see if we are linked to a redis DB
-	if os.Getenv("AUTODB_ENV_REDIS_VERSION") != "" {
+	driver := os.Getenv("AUTODB_DRIVER")
+	if driver == "" {
+		log.Printf("[info] No driver specified, defaulting to in memeory persistence driver")
+		driver = "MEMORY"
+	}
+
+	switch strings.ToUpper(driver) {
+	case "REDIS":
 		tracker := new(RedisTracker)
 		if spec := os.Getenv("AUTODB_PORT"); spec != "" {
 			port, err := url.Parse(spec)
@@ -124,14 +176,27 @@
 			checkError(err, "[error] unable to connect to redis database : '%s' : %s", port, err)
 			log.Println("[info] Using REDIS to track provisioning status of nodes")
 			return tracker
-		} else {
-			log.Fatalf("[error] looks like we are configured for REDIS, but no PORT defined in environment")
 		}
+		log.Fatalf("[error] No connection specified to REDIS server")
+	case "CONSUL":
+		var err error
+		config := consul.Config{
+			Address: "autodb:8500",
+			Scheme:  "http",
+		}
+		tracker := new(ConsulTracker)
+		tracker.client, err = consul.NewClient(&config)
+		checkError(err, "[error] unable to connect to redis server : 'autodb:8500' : %s", err)
+		log.Println("[info] Using Consul to track provisioning status of nodes")
+		tracker.kv = tracker.client.KV()
+		return tracker
+	case "MEMORY":
+		tracker := new(MemoryTracker)
+		tracker.data = make(map[string]TrackerRecord)
+		log.Println("[info] Using memory based structures to track provisioning status of nodes")
+		return tracker
+	default:
+		log.Fatalf("[error] Unknown persistance driver specified, '%s'", driver)
 	}
-
-	// Else fallback to an in memory tracker
-	tracker := new(MemoryTracker)
-	tracker.data = make(map[string]TrackerRecord)
-	log.Println("[info] Using memory based structures to track provisioning status of nodes")
-	return tracker
+	return nil
 }