Switchq and automation container's maas client updated to 2.0

Change-Id: I910ad20ca16b019788b920da79ed22a8ee825300
diff --git a/automation/maas-flow.go b/automation/maas-flow.go
index 02ccd8c..98c786b 100644
--- a/automation/maas-flow.go
+++ b/automation/maas-flow.go
@@ -27,7 +27,10 @@
 	maas "github.com/juju/gomaasapi"
 )
 
-const appName = "AUTOMATION"
+const (
+	appName        = "AUTOMATION"
+	maasApiVersion = "2.0"
+)
 
 type Config struct {
 	PowerHelperUser   string        `default:"cord" envconfig:"POWER_HELPER_USER" desc:"user when integrating with virtual box power mgmt"`
@@ -41,7 +44,6 @@
 	ApiKeyFile        string        `default:"/secrets/maas_api_key" envconfig:"MAAS_API_KEY_FILE" desc:"file to hold the secret"`
 	ShowApiKey        bool          `default:"false" envconfig:"MAAS_SHOW_API_KEY" desc:"Show API in clear text in logs"`
 	MaasUrl           string        `default:"http://localhost/MAAS" envconfig:"MAAS_URL" desc:"URL to access MAAS server"`
-	ApiVersion        string        `default:"1.0" envconfig:"MAAS_API_VERSION" desc:"API version to use with MAAS server"`
 	QueryInterval     time.Duration `default:"15s" envconfig:"MAAS_QUERY_INTERVAL" desc:"frequency to query MAAS service for nodes"`
 	PreviewOnly       bool          `default:"false" envconfig:"PREVIEW_ONLY" desc:"display actions that would be taken, but don't execute them"`
 	AlwaysRename      bool          `default:"true" envconfig:"ALWAYS_RENAME" desc:"attempt to rename hosts at every stage or workflow"`
@@ -71,7 +73,7 @@
 // fetchNodes do a HTTP GET to the MAAS server to query all the nodes
 func fetchNodes(client *maas.MAASObject) ([]MaasNode, error) {
 	nodeListing := client.GetSubObject("nodes")
-	listNodeObjects, err := nodeListing.CallGet("list", url.Values{})
+	listNodeObjects, err := nodeListing.CallGet("", url.Values{})
 	if checkWarn(err, "unable to get the list of all nodes: %s", err) {
 		return nil, err
 	}
@@ -208,7 +210,6 @@
 	    MAAS_SHOW_API_KEY:    %t
 	    MAAS_API_KEY:         %s
 	    MAAS_API_KEY_FILE:    %s
-	    MAAS_API_VERSION:     %s
 	    MAAS_QUERY_INTERVAL:  %s
 	    HOST_FILTER_SPEC:     %+v
 	    MAC_TO_NAME_MAPPINGS: %+v
@@ -219,7 +220,7 @@
 		config.PowerHelperUser, config.PowerHelperHost, config.PowerHelperScript,
 		config.ProvisionUrl, config.ProvisionTtl,
 		config.MaasUrl, config.ShowApiKey,
-		pubKey, config.ApiKeyFile, config.ApiVersion, config.QueryInterval,
+		pubKey, config.ApiKeyFile, config.QueryInterval,
 		filterPrefix+string(filterAsJson), mappingsPrefix+string(mappingsAsJson),
 		config.PreviewOnly, config.AlwaysRename,
 		config.LogLevel, config.LogFormat)
@@ -242,7 +243,7 @@
 		}
 	}
 
-	authClient, err := maas.NewAuthenticatedClient(config.MaasUrl, config.ApiKey, config.ApiVersion)
+	authClient, err := maas.NewAuthenticatedClient(config.MaasUrl, config.ApiKey, maasApiVersion)
 	checkError(err, "Unable to use specified client key, '%s', to authenticate to the MAAS server: %s",
 		pubKey, err)
 
diff --git a/automation/node.go b/automation/node.go
index 99d1408..86c2d03 100644
--- a/automation/node.go
+++ b/automation/node.go
@@ -24,28 +24,37 @@
 
 // MAAS Node Statuses
 const (
-	Invalid             MaasNodeStatus = -1
-	New                 MaasNodeStatus = 0
-	Commissioning       MaasNodeStatus = 1
-	FailedCommissioning MaasNodeStatus = 2
-	Missing             MaasNodeStatus = 3
-	Ready               MaasNodeStatus = 4
-	Reserved            MaasNodeStatus = 5
-	Deployed            MaasNodeStatus = 6
-	Retired             MaasNodeStatus = 7
-	Broken              MaasNodeStatus = 8
-	Deploying           MaasNodeStatus = 9
-	Allocated           MaasNodeStatus = 10
-	FailedDeployment    MaasNodeStatus = 11
-	Releasing           MaasNodeStatus = 12
-	FailedReleasing     MaasNodeStatus = 13
-	DiskErasing         MaasNodeStatus = 14
-	FailedDiskErasing   MaasNodeStatus = 15
+	Invalid                  MaasNodeStatus = -1
+	New                      MaasNodeStatus = 0
+	Commissioning            MaasNodeStatus = 1
+	FailedCommissioning      MaasNodeStatus = 2
+	Missing                  MaasNodeStatus = 3
+	Ready                    MaasNodeStatus = 4
+	Reserved                 MaasNodeStatus = 5
+	Deployed                 MaasNodeStatus = 6
+	Retired                  MaasNodeStatus = 7
+	Broken                   MaasNodeStatus = 8
+	Deploying                MaasNodeStatus = 9
+	Allocated                MaasNodeStatus = 10
+	FailedDeployment         MaasNodeStatus = 11
+	Releasing                MaasNodeStatus = 12
+	FailedReleasing          MaasNodeStatus = 13
+	DiskErasing              MaasNodeStatus = 14
+	FailedDiskErasing        MaasNodeStatus = 15
+	RescueMode               MaasNodeStatus = 16
+	EnteringRescueMode       MaasNodeStatus = 17
+	FailedEnteringRescueMode MaasNodeStatus = 18
+	ExitingRescueMode        MaasNodeStatus = 19
+	FailedExitingRescueMode  MaasNodeStatus = 20
+	Testing                  MaasNodeStatus = 21
+	FailedTesting            MaasNodeStatus = 22
 )
 
 var names = []string{"New", "Commissioning", "FailedCommissioning", "Missing", "Ready", "Reserved",
 	"Deployed", "Retired", "Broken", "Deploying", "Allocated", "FailedDeployment",
-	"Releasing", "FailedReleasing", "DiskErasing", "FailedDiskErasing"}
+	"Releasing", "FailedReleasing", "DiskErasing", "FailedDiskErasing","RescueMode",
+	"EnteringRescueMode", "FailedEnteringRescueMode", "ExitingRescueMode", "FailedExitingRescueMode",
+	"Testing", "FailedTesting"}
 
 func (v MaasNodeStatus) String() string {
 	return names[v]
@@ -135,19 +144,18 @@
 
 // MACs get the MAC Addresses
 func (n *MaasNode) MACs() []string {
-	macsObj, _ := n.GetMap()["macaddress_set"]
-	macs, _ := macsObj.GetArray()
-	if len(macs) == 0 {
+	ifaceObj, _ := n.GetMap()["interface_set"]
+	ifaces, _ := ifaceObj.GetArray()
+	if len(ifaces) == 0 {
 		return []string{}
 	}
-	result := make([]string, len(macs))
-	for i, mac := range macs {
-		obj, _ := mac.GetMap()
-		addr, _ := obj["mac_address"]
-		s, _ := addr.GetString()
-		result[i] = s
+	result := make([]string, len(ifaces))
+	for i, iface := range ifaces {
+		obj, _ := iface.GetMap()
+		macAddressObj, _ := obj["mac_address"]
+		macAddress,_ := macAddressObj.GetString()
+		result[i] = macAddress
 	}
-
 	return result
 }
 
diff --git a/automation/state.go b/automation/state.go
index 8a2116f..372e4b8 100644
--- a/automation/state.go
+++ b/automation/state.go
@@ -79,7 +79,7 @@
 	"Deployed": {
 		"New":                 []Action{Reset, Commission},
 		"Deployed":            []Action{Provision, Done},
-		"Ready":               []Action{Reset, Aquire},
+		"Ready":               []Action{Reset, Allocate},
 		"Allocated":           []Action{Reset, Deploy},
 		"Retired":             []Action{Reset, AdminState},
 		"Reserved":            []Action{Reset, AdminState},
@@ -87,12 +87,14 @@
 		"DiskErasing":         []Action{Reset, Wait},
 		"Deploying":           []Action{Reset, Wait},
 		"Commissioning":       []Action{Reset, Wait},
+		"Testing"            : []Action{Reset, Wait},
 		"Missing":             []Action{Reset, Fail},
 		"FailedReleasing":     []Action{Reset, Fail},
 		"FailedDiskErasing":   []Action{Reset, Fail},
 		"FailedDeployment":    []Action{Reset, Fail},
 		"Broken":              []Action{Reset, Fail},
 		"FailedCommissioning": []Action{Reset, Fail},
+		"FailedTesting":       []Action{Reset, Fail},
 	},
 }
 
@@ -105,10 +107,14 @@
         (Commissioning)->(Ready)
         (Ready)->(Deploying)
         (Ready)->(Allocated)
+		(Allocated)->(Testing)
         (Allocated)->(Deploying)
+        (Testing)->(Deploying)
+		(Testing)->(FailedTesting)
         (Deploying)->(Deployed)
         (Deploying)->(FailedDeployment)
         (FailedDeployment)->(Broken)
+		(FailedTesting)->(Broken)
         (Deployed)->(Releasing)
         (Releasing)->(FailedReleasing)
         (FailedReleasing)->(Broken)
@@ -140,12 +146,11 @@
 	for _, mac := range macs {
 		if name, ok := options.Mappings[mac]; ok {
 			if current != name {
-				nodesObj := client.GetSubObject("nodes")
-				nodeObj := nodesObj.GetSubObject(node.ID())
+				machineObj := client.GetSubObject("machines").GetSubObject(node.ID())
 				log.Infof("RENAME '%s' to '%s'\n", node.Hostname(), name)
 
 				if !options.Preview {
-					nodeObj.Update(url.Values{"hostname": []string{name}})
+					machineObj.Update(url.Values{"hostname": []string{name}})
 				}
 			}
 		}
@@ -265,11 +270,10 @@
 	}
 
 	if !options.Preview {
-		nodesObj := client.GetSubObject("nodes")
-		myNode := nodesObj.GetSubObject(node.ID())
+		machineObj := client.GetSubObject("machines").GetSubObject(node.ID())
 		// Start the node with the trusty distro. This should really be looked up or
 		// a parameter default
-		_, err := myNode.CallPost("start", url.Values{"distro_series": []string{"trusty"}})
+		_, err := machineObj.CallPost("deploy", url.Values{"distro_series": []string{"xenial"}})
 		if err != nil {
 			log.Errorf("DEPLOY '%s' : '%s'", node.Hostname(), err)
 			return err
@@ -278,10 +282,11 @@
 	return nil
 }
 
-// Aquire aquire a machine to a specific operator
-var Aquire = func(client *maas.MAASObject, node MaasNode, options ProcessingOptions) error {
-	log.Infof("AQUIRE: %s", node.Hostname())
-	nodesObj := client.GetSubObject("nodes")
+// Acquire a machine to a specific operator
+// Acquire is renamed to allocate for maas 2.0
+var Allocate = func(client *maas.MAASObject, node MaasNode, options ProcessingOptions) error {
+	log.Infof("ALLOCATE: %s", node.Hostname())
+	machinesObj := client.GetSubObject("machines")
 
 	if options.AlwaysRename {
 		updateNodeName(client, node, options)
@@ -371,10 +376,10 @@
 				}
 			}
 		}
-		_, err = nodesObj.CallPost("acquire",
+		_, err = machinesObj.CallPost("allocate",
 			url.Values{"name": []string{node.Hostname()}})
 		if err != nil {
-			log.Errorf("AQUIRE '%s' : '%s'", node.Hostname(), err)
+			log.Errorf("ALLOCATE '%s' : '%s'", node.Hostname(), err)
 			return err
 		}
 	}
@@ -393,10 +398,9 @@
 		// Attempt to turn the node off
 		log.Infof("POWER DOWN: %s", node.Hostname())
 		if !options.Preview {
-			//POST /api/1.0/nodes/{system_id}/ op=stop
-			nodesObj := client.GetSubObject("nodes")
-			nodeObj := nodesObj.GetSubObject(node.ID())
-			_, err := nodeObj.CallPost("stop", url.Values{"stop_mode": []string{"soft"}})
+			//POST /api/2.0/machines/{system_id}/ op=stop
+			machineObj := client.GetSubObject("machines").GetSubObject(node.ID())
+			_, err := machineObj.CallPost("power_off", url.Values{"stop_mode": []string{"soft"}})
 			if err != nil {
 				log.Errorf("Commission '%s' : changing power start to off : '%s'", node.Hostname(), err)
 			}
@@ -407,12 +411,11 @@
 		// We are off so move to commissioning
 		log.Infof("COMISSION: %s", node.Hostname())
 		if !options.Preview {
-			nodesObj := client.GetSubObject("nodes")
-			nodeObj := nodesObj.GetSubObject(node.ID())
+			machineObj := client.GetSubObject("machines").GetSubObject(node.ID())
 
 			updateNodeName(client, node, options)
 
-			_, err := nodeObj.CallPost("commission", url.Values{})
+			_, err := machineObj.CallPost("commission", url.Values{})
 			if err != nil {
 				log.Errorf("Commission '%s' : '%s'", node.Hostname(), err)
 			}
@@ -450,7 +453,14 @@
 					"power_pass":    power.PowerPassword,
 					"power_address": power.PowerAddress,
 				}
-				node.UpdatePowerParameters(power.Name, params)
+				machineNodeObj := client.GetSubObject("machines").GetSubObject(node.ID())
+				machineObj, err := machineNodeObj.Get();
+				if err != nil {
+					log.Errorf("Unable to get %s machine object %s ",node.ID(),err)
+					return err
+				}
+				machineNode := MaasNode{machineObj}
+				machineNode.UpdatePowerParameters(power.Name, params)
 			default:
 				log.Warningf("Unsupported power type discovered '%s'", power.Name)
 			}
@@ -511,11 +521,11 @@
 
 // ProcessNode something
 func ProcessNode(client *maas.MAASObject, node MaasNode, options ProcessingOptions) error {
-	substatus, err := node.GetInteger("substatus")
+	status, err := node.GetInteger("status")
 	if err != nil {
 		return err
 	}
-	actions, err := findActions("Deployed", MaasNodeStatus(substatus).String())
+	actions, err := findActions("Deployed", MaasNodeStatus(status).String())
 	if err != nil {
 		return err
 	}
diff --git a/roles/maas/templates/automation-compose.yml.j2 b/roles/maas/templates/automation-compose.yml.j2
index 73f5c6e..3a9eb91 100644
--- a/roles/maas/templates/automation-compose.yml.j2
+++ b/roles/maas/templates/automation-compose.yml.j2
@@ -132,7 +132,6 @@
 {% endif %}
       - "AUTOMATION_LOG_FORMAT=text"
       - "AUTOMATION_LOG_LEVEL=warn"
-      - "AUTOMATION_MAAS_API_VERSION=1.0"
       - "AUTOMATION_MAAS_URL=http://{{ mgmt_ip_address.stdout }}/MAAS"
       - "AUTOMATION_QUERY_INTERVAL=30s"
       - "AUTOMATION_MAC_TO_NAME_MAPPINGS=@/mappings/mappings.json"
diff --git a/switchq/switchq.go b/switchq/switchq.go
index 7d3022b..4be1c31 100644
--- a/switchq/switchq.go
+++ b/switchq/switchq.go
@@ -30,7 +30,10 @@
 	"time"
 )
 
-const appName = "SWITCHQ"
+const(
+	appName        = "SWITCHQ"
+	massApiVersion = "2.0"
+)
 
 type Config struct {
 	VendorsURL      string `default:"file:///switchq/vendors.json" envconfig:"VENDORS_URL" desc:"URL that specifies supported vendor OUI information"`
@@ -383,7 +386,7 @@
 	if len(context.config.MaasURL) > 0 {
 
 		// Attempt to connect to MAAS
-		authClient, err := maas.NewAuthenticatedClient(context.config.MaasURL, context.config.MaasKey, "1.0")
+		authClient, err := maas.NewAuthenticatedClient(context.config.MaasURL, context.config.MaasKey, massApiVersion)
 		checkError(err, "Unable to connect to MAAS at '%s' : %s", context.config.MaasURL, err)
 
 		context.maasClient = maas.NewMAAS(*authClient)
diff --git a/switchq/sync.go b/switchq/sync.go
index 4452c6f..1e9e035 100644
--- a/switchq/sync.go
+++ b/switchq/sync.go
@@ -73,20 +73,21 @@
 		}
 		all[i].Name = name
 
-		mac_set_arr, err := device["macaddress_set"].GetArray()
-		if len(mac_set_arr) != 1 {
-			return nil, nil, fmt.Errorf("Expecting a single MAC address, recived %d", len(mac_set_arr))
+		iface_arr, err := device["interface_set"].GetArray()
+		if len(iface_arr) != 1 {
+			return nil, nil, fmt.Errorf("Expecting a single interface, recived %d", len(iface_arr))
 		}
 
-		mac_obj, err := mac_set_arr[0].GetMap()
+		iface_obj, err := iface_arr[0].GetMap()
 		if err != nil {
 			return nil, nil, err
 		}
 
-		mac, err := mac_obj["mac_address"].GetString()
+		mac, err := iface_obj["mac_address"].GetString()
 		if err != nil {
 			return nil, nil, err
 		}
+
 		mac = strings.ToUpper(mac)
 		all[i].MAC = mac
 
@@ -106,7 +107,7 @@
 	for list := range request {
 		// Get current device list and convert it to some maps for quick indexing
 		devices := c.maasClient.GetSubObject("devices")
-		deviceObjects, err := devices.CallGet("list", url.Values{})
+		deviceObjects, err := devices.CallGet("", url.Values{})
 		if err != nil {
 			log.Errorf("Unable to synchronize switches to MAAS, unable to get current devices : %s",
 				err)
@@ -230,7 +231,7 @@
 
 			// The device does not currently exist in MAAS, so add it
 			log.Infof("Adding device '%s (%s)' to MAAS", rec.Name, rec.MAC)
-			deviceObj, err := devices.CallPost("new", url.Values{
+			deviceObj, err := devices.CallPost("", url.Values{
 				"hostname":      []string{rec.Name},
 				"mac_addresses": []string{rec.MAC},
 			})