Modifying Jenkinsfile to enable automated fabric provisioning

Change-Id: I916bbb42f0cbdceaeaade3d66d7bdfa5c7d703d2
diff --git a/Jenkinsfile b/Jenkinsfile
index 28232e7..96d2287 100644
--- a/Jenkinsfile
+++ b/Jenkinsfile
@@ -74,7 +74,7 @@
                     sh 'vagrant ssh -c "cd /cord/build; ./gradlew -PtargetReg=${headNodeIP}:5000 -PdeployConfig=config/pod-configs/${podConfigFileName} deploy" corddev'
                 }
 
-            stage ("Power cycle compute nodes") {
+                stage ("Power cycle compute nodes") {
                     parallel(
                         compute_1: {
                             sh 'ipmitool -U ${computeNode1IPMIUser} -P ${computeNode1IPMIPass} -H ${computeNode1IPMIIP} power cycle'
@@ -91,7 +91,7 @@
                     timeout(time: 45) {
                         waitUntil {
                             try {
-                                num = runHeadCmd("maas pod-maas nodes list | grep Deployed | wc -l").trim()
+                                num = runHeadCmd("maas pod-maas nodes list | grep -i deployed | wc -l").trim()
                                 return num == '2'
                             } catch (exception) {
                                 return false
@@ -114,6 +114,66 @@
                     }
                 }
 
+                def fabricConfExists = true
+                try {
+                    print "${fabricMACs}"
+                } catch (err) {
+                    fabricConfExists = false
+                }
+                if (fabricConfExists) {
+                    def fabric_macs = multiStringToArray("${fabricMACs}")
+                    def fabric_ips = multiStringToArray("${fabricIPs}")
+
+                    stage("Reserve IPs for fabric switches and restart maas-dhcp service") {
+                        for(int i=0; i < fabric_macs.length; i++) {
+                            def append = "";
+                            if (i!=0) {
+                                append = "-a";
+                            }
+                            def str = createMACIPbindingStr(i+1, fabric_macs[i], fabric_ips[i])
+                            runHeadCmd("echo -e $str '|' sudo tee $append /etc/dhcp/dhcpd.reservations > /dev/null")
+                        }
+                        runHeadCmd("sudo restart maas-dhcpd")
+                        runHeadCmd("cord harvest go")
+                    }
+
+                    stage ("Wait for fabric switches to get deployed") {
+                        for(int i=0; i < fabric_ips.length; i++) {
+                            runFabricCmd("${fabric_ips[i]}", "sudo onl-onie-boot-mode install")
+                            runFabricCmd("${fabric_ips[i]}", "sudo reboot")
+                        }
+                        timeout(time: 45) {
+                            waitUntil {
+                                try {
+                                    def harvestCompleted = runHeadCmd("cord harvest list '|' grep -i fabric '|' wc -l").trim()
+                                    return harvestCompleted == fabric_macs.length.toString()
+                                } catch (exception) {
+                                    return false
+                                }
+                            }
+                        }
+                    }
+
+                    stage ("Wait for fabric switches to be provisioned") {
+                        timeout(time:45) {
+                            waitUntil {
+                                try {
+                                    def provCompleted = 0
+                                    for(int i=0; i < fabric_ips.length; i++) {
+                                        def count = runHeadCmd("cord prov list '|' grep -i ${fabric_ips[i]} '|' grep -i complete '|' wc -l").trim()
+                                        print "Count: ${count}"
+                                        provCompleted = provCompleted + count.toInteger()
+                                        print "New prov completed: ${provCompleted}"
+                                    }
+                                    return provCompleted == fabric_ips.length
+                                } catch (exception) {
+                                    return false
+                                }
+                            }
+                        }
+                    }
+                }
+
                 stage ("Trigger Build") {
                     url = 'https://jenkins.opencord.org/job/release-build/job/' + params.branch + '/build'
                     httpRequest authentication: 'auto-release', httpMode: 'POST', url: url, validResponseCodes: '201'
@@ -129,7 +189,6 @@
             }
             echo "RESULT: ${currentBuild.result}"
        }
-
     }
 }
 
@@ -148,21 +207,31 @@
  * Returns a string used to bind IPs and MAC addresses, substituting the values
  * given.
  *
- * @param mac the MAC address to substitute
- * @param ip the IP address to substitute
+ * @param counter the counter used to generate the host name
+ * @param mac     the MAC address to substitute
+ * @param ip      the IP address to substitute
  */
-def createMACIPbindingStr(mac, ip) {
-    return """host ${mac} {
-hardware ethernet ${mac};
-fixed-address ${ip};
-}"""
+def createMACIPbindingStr(counter, mac, ip) {
+    return """\\'host fabric${counter} {'\n'hardware ethernet ${mac}';''\n'fixed-address ${ip}';''\n'}\\'"""
 }
 
 /**
  * Runs a command on the head node.
  *
  * @param command the command to run on the head node
+ * @return the output of the command
  */
 def runHeadCmd(command) {
     return sh(returnStdout: true, script: "sshpass -p ${headNodePass} ssh -oStrictHostKeyChecking=no -l ${headNodeUser} ${headNodeIP} ${command}")
 }
+
+/**
+ * Runs a command on a fabric switch.
+ *
+ * @param ip             the mgmt IP of the fabric switch, reachable from the head node
+ * @param fabric_command the command to run on the fabric switch
+ * @return the output of the command
+ */
+def runFabricCmd(ip, command) {
+    return runHeadCmd("sshpass -p ${fabricPass} ssh -oStrictHostKeyChecking=no -l ${fabricUser} ${ip} ${command}")
+}
\ No newline at end of file