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},
})