initial commit

Change-Id: I5063800f2ddaf90a350325a9186479c25f90f8e1
diff --git a/roles/onos-fabric/files/bin/minify b/roles/onos-fabric/files/bin/minify
new file mode 100755
index 0000000..b91023c
--- /dev/null
+++ b/roles/onos-fabric/files/bin/minify
@@ -0,0 +1,29 @@
+#!/bin/bash
+
+PROG=$(basename $0)
+
+usage() {
+    echo "$PROG: [options]"
+    echo ""
+    echo "    -h | --help       display this message"
+}
+
+FILE=
+while [ $# -gt 0 ]; do
+    case $1 in
+        -h|--help)
+            usage
+            exit
+            ;;
+        *)
+            FILE=$1
+            ;;
+    esac
+    shift
+done
+
+if [ "$FILE x" == " x" ]; then
+    sed -e 's|//.*$||g' -e '/^\s*$/d' # <&0
+else
+    cat $FILE | sed -e 's|//.*$||g' -e '/^\s*$/d'
+fi
diff --git a/roles/onos-fabric/files/bin/onos-cfg-delete b/roles/onos-fabric/files/bin/onos-cfg-delete
new file mode 100755
index 0000000..4404b5c
--- /dev/null
+++ b/roles/onos-fabric/files/bin/onos-cfg-delete
@@ -0,0 +1,4 @@
+#!/bin/bash
+
+curl -slL -X DELETE --header "Accept: application/json" "http://karaf:karaf@localhost:8181/onos/v1/network/configuration" $*
+
diff --git a/roles/onos-fabric/files/bin/onos-cfg-get b/roles/onos-fabric/files/bin/onos-cfg-get
new file mode 100755
index 0000000..8d0cabf
--- /dev/null
+++ b/roles/onos-fabric/files/bin/onos-cfg-get
@@ -0,0 +1,4 @@
+#!/bin/bash
+
+curl -sLl -X GET --header "Accept: application/json" "http://karaf:karaf@localhost:8181/onos/v1/network/configuration" | python -m json.tool
+
diff --git a/roles/onos-fabric/files/bin/onos-cfg-post b/roles/onos-fabric/files/bin/onos-cfg-post
new file mode 100755
index 0000000..328b8b0
--- /dev/null
+++ b/roles/onos-fabric/files/bin/onos-cfg-post
@@ -0,0 +1,3 @@
+#!/bin/bash
+
+cat $1 | sed -e 's|//.*$||g' -e '/^\s*$/d' | curl -slL -X POST --header "Content-Type: application/json" --header "Accept: application/json" -d "@-" "http://karaf:karaf@localhost:8181/onos/v1/network/configuration"
diff --git a/roles/onos-fabric/files/bin/ping-test.sh b/roles/onos-fabric/files/bin/ping-test.sh
new file mode 100755
index 0000000..d7b894e
--- /dev/null
+++ b/roles/onos-fabric/files/bin/ping-test.sh
@@ -0,0 +1,10 @@
+#!/bin/bash
+
+HOSTS="10.3.1.1 10.3.1.2 10.3.2.1 10.3.2.2 10.3.1.254 10.3.2.254 192.168.10.1 8.8.8.8"
+
+ME=$(ifconfig | grep "10\.3\.[0-9]\.[0-9]" | sed -e 's/.*addr:\(10\.3\.[0-9]\.[0-9]\).*/\1/g' 2> /dev/null) 
+echo "FROM: $ME"
+for TO in $HOSTS; do
+    T=$(ping -q -c 1 -W 1 -I eth0 $TO | grep rtt | awk '{print $4}' | sed -e 's|/| |g') #sed -e 's|r| |')
+    echo  "$TO: $T" | awk '{printf("    %-15s %-7s\n", $1, $2, $3, $4)}'
+done
diff --git a/roles/onos-fabric/files/bin/restart-vms.sh b/roles/onos-fabric/files/bin/restart-vms.sh
new file mode 100755
index 0000000..ef14e5f
--- /dev/null
+++ b/roles/onos-fabric/files/bin/restart-vms.sh
@@ -0,0 +1,39 @@
+#!/bin/bash
+
+function verify {
+    local L=$1
+    for i in $L; do
+        grep $i /etc/bind/maas/dhcp_harvest.inc > /dev/null 2>&1
+        if [ $? -ne 0 ]; then
+            echo "0"
+            return
+        fi
+    done
+    echo "1"
+}
+
+for i in $(uvt-kvm list); do
+    virsh start $i
+done
+
+LIST=$(uvt-kvm list)
+CNT=$(uvt-kvm list | wc -l)
+# plus 4 for the switches
+
+RETRY=5
+VERIFIED=0
+while [ $VERIFIED -ne 1 -a $RETRY -gt 0 ]; do
+    echo "INFO: Waiting for VMs to start"
+    sleep 5
+    curl -slL -XPOST http://127.0.0.1:8954/harvest >> /dev/null
+    VERIFIED=$(verify $LIST)
+    RETRY=$(expr $RETRY - 1)
+    echo "INFO: Verifing all VMs started"
+done
+
+if [ $VERIFIED -ne 1 ]; then
+    echo "ERROR: Likely VMs did not all boot correctly"
+    exit 1
+else
+    echo "INFO: Looks like all VM started correctly"
+fi
diff --git a/roles/onos-fabric/meta/main.yml b/roles/onos-fabric/meta/main.yml
new file mode 100644
index 0000000..bf39d8c
--- /dev/null
+++ b/roles/onos-fabric/meta/main.yml
@@ -0,0 +1,15 @@
+---
+galaxy_info:
+  author: Ciena Blueplanet
+  description: Docker Engine and Docker Compose
+  company: Ciena Blueplanet
+  license: Apache 2.0
+  min_ansible_version: 2.0
+  platforms:
+    - name: Ubuntu
+      versions:
+        - trusty
+  galaxy_tags:
+    - development
+    - system
+dependencies: []
diff --git a/roles/onos-fabric/tasks/main.yml b/roles/onos-fabric/tasks/main.yml
new file mode 100644
index 0000000..b2bccc5
--- /dev/null
+++ b/roles/onos-fabric/tasks/main.yml
@@ -0,0 +1,45 @@
+---
+- name: User Local bin directory
+  file:
+    path={{ ansible_env.HOME }}/bin
+    state=directory
+    owner=ubuntu
+    group=ubuntu
+    mode=0755
+
+- name: Copy Utility Commands
+  copy:
+    src=files/bin/{{ item }}
+    dest={{ ansible_env.HOME }}/bin
+    owner=ubuntu
+    group=ubuntu
+    mode=0755
+  with_items:
+    - minify
+    - onos-cfg-get
+    - onos-cfg-post
+    - onos-cfg-delete
+    - ping-test.sh
+
+- name: Include Utility Commands in User Path
+  lineinfile:
+    dest={{ ansible_env.HOME }}/.bashrc
+    line="PATH=$HOME/bin:$PATH"
+    state=present
+    insertafter=EOF
+
+- name: Custom ONOS
+  unarchive:
+    src=files/onos-1.6.0.ubuntu.tar.gz
+    dest={{ ansible_env.HOME }}
+    owner=ubuntu
+    group=ubuntu
+
+- name: ONOS Fabric Configuration
+  template:
+    src=templates/fabric-network-config.json.j2
+    dest={{ ansible_env.HOME }}/fabric-network.config.json
+    owner=ubuntu
+    group=ubuntu
+    mode=0644
+    
diff --git a/roles/onos-fabric/templates/fabric-network-config.json.j2 b/roles/onos-fabric/templates/fabric-network-config.json.j2
new file mode 100644
index 0000000..f39cf60
--- /dev/null
+++ b/roles/onos-fabric/templates/fabric-network-config.json.j2
@@ -0,0 +1,218 @@
+// This is a commented JSON data file. The comments must stripped from the
+// file before passing it to a JSON parser. This can be done various way
+// including the JavaScript JSON.minify() function or a simple sed script
+// such as "catting" this file through sed -e '|s//.*$||g'.
+
+
+// This file represents the network configuration for the cord demo pod number
+// two (2).
+{
+    "ports" : {
+
+        // Leaf-1/port-1 connected to cord-r2-s1/eth0
+        "of:0000000000000021/1" : {
+            "interfaces" : [
+                {
+                    "ips" : [ "10.3.1.254/24" ] // Represents a fake gateway
+                                                // for this subnet. ONOS will
+                                                // ARP this and respond.
+                }
+            ]
+        },
+
+        // Leaf-1/port-2 connected to cord-r2-s2/eth0
+        "of:0000000000000021/2" : {
+            "interfaces" : [
+                {
+                    "ips" : [ "10.3.1.254/24" ] // Represents a fake gateway
+                                                // for this subnet. ONOS will
+                                                // ARP this and respond.
+                },
+                {
+                    "vlan" : "1000" // cross-connect s-tag 1000 to Tibit OLT
+                },
+                // Need to specify the public IP for the vSG
+                {
+                    "ips" : [ "10.3.1.130/32" ] // vSG public IP address /32
+                }
+            ]
+        },
+
+	// Leaf-1/port-129 connected to Tibit OLT
+        // The physical port is port 25, but we are using a break out cable and thus the switch
+        // create virtual ports
+        "of:0000000000000021/129" : {
+            "interfaces" : [
+                {
+                    "name" : "tibit-olt", // unused
+                    "vlan" : "1000" // cross-connect s-tag 42 to vSG
+                }
+            ]
+        },
+
+        // Leaf-2/port-3 connected to cord-r2-s3/eth0
+        "of:0000000000000022/3" : {
+            "interfaces" : [
+                {
+                    "ips" : [ "10.3.2.254/24" ] // Represents a fake gateway
+                                                // for this subnet. ONOS will
+                                                // ARP this and respond.
+                }
+            ]
+        },
+
+        // Leaf-2/port-4 connected to cord-r2-s4/eth0
+        "of:0000000000000022/4" : {
+            "interfaces" : [
+                {
+                    "ips" : [ "10.3.2.254/24" ] // Represents a fake gateway
+                                                // for this subnet. ONOS will
+                                                // ARP this and respond.
+                }
+            ]
+        }
+    },
+
+    "devices" : {
+        "of:0000000000000021" : {
+            "segmentrouting" : {
+                "name" : "leaf-1",
+                "nodeSid" : 101,
+                "routerIp" : "10.3.1.254",
+                "routerMac" : "cc:37:ab:7c:b9:d6",
+                "isEdgeRouter" : true,
+                "adjacencySids" : []
+            }
+        },
+        "of:0000000000000022" : {
+            "segmentrouting" : {
+                "name" : "leaf-2",
+                "nodeSid" : 102,
+                "routerIp" : "10.3.2.254",
+                "routerMac" : "cc:37:ab:7c:ba:da",
+                "isEdgeRouter" : true,
+                "adjacencySids" : []
+            }
+        },
+        "of:0000000000000011" : {
+            "segmentrouting" : {
+                "name" : "spine-1",
+                "nodeSid" : 103,
+                "routerIp" : "10.2.30.1",
+                "routerMac" : "cc:37:ab:7c:be:68",
+                "isEdgeRouter" : false,
+                "adjacencySids" : []
+            }
+        },
+        "of:0000000000000012" : {
+            "segmentrouting" : {
+                "name" : "spine-2",
+                "nodeSid" : 104,
+                "routerIp" : "10.2.30.2",
+                "routerMac" : "cc:37:ab:7c:bf:ee",
+                "isEdgeRouter" : false,
+                "adjacencySids" : []
+            }
+        }
+    },
+    "links": {
+        // spine 1/1 connected to leaf 1/31
+        "of:0000000000000011/1-of:0000000000000021/31": {
+            "basic": {}
+        },
+
+        // spine 1/2 connected to leaf 2/31
+        "of:0000000000000011/2-of:0000000000000022/31": {
+            "basic": {}
+        },
+
+        // spine 2/1 connected to leaf 1/32
+        "of:0000000000000012/1-of:0000000000000021/32": {
+            "basic": {}
+        },
+
+        // spine 2/2 connected to leaf 2/32
+        "of:0000000000000012/2-of:0000000000000022/32": {
+            "basic": {}
+        },
+
+        // leaf 1/31 connected to spine 1/1
+        "of:0000000000000021/31-of:0000000000000011/1": {
+            "basic": {}
+        },
+
+        // leaf 1/32 connected to spine 2/1
+        "of:0000000000000021/32-of:0000000000000012/1": {
+            "basic": {}
+        },
+
+        // leaf 2/31 connected to spine 1/2
+        "of:0000000000000022/31-of:0000000000000011/2": {
+            "basic": {}
+        },
+
+        // leaf 2/23 connected to spine 2/2
+        "of:0000000000000022/32-of:0000000000000012/2": {
+            "basic": {}
+        }
+    },
+    "hosts" : {
+        // cord-r2-s1 iface eth0
+        "3c:fd:fe:9e:93:10/-1" : {
+            "basic": {
+                "ips": ["10.3.1.1"],                  // host IP on fabric
+                "location": "of:0000000000000021/1"   // link back to fabric leaf-1/port-1
+            }
+        },
+
+        // cord-r2-s2 iface eth0
+        "3c:fd:fe:9e:8a:88/-1" : {
+            "basic": {
+                "ips": ["10.3.1.2"],                 // host IP on fabric
+                "location": "of:0000000000000021/2"  // link back to fabric leaf-1/port-2
+            }
+        },
+
+       // fa:16:3e:94:7e:c5
+       // fa:16:3e:94:7e:c5
+       // OLD: 02:42:0a:03:01:82
+
+        "fa:16:3e:94:7e:c5/-1" : { // vSG1
+            "basic": {
+                "ips": ["10.3.1.130"], // vSG1 public IP address
+                "location": "of:0000000000000001/5"
+            }
+        },
+
+	// OLD: 02:42:0a:03:01:83
+        "fa:16:3e:91:82:6a/-1" : { // vSG1 VM
+            "basic" : {
+                "ips": ["10.3.1.131"],
+                "location": "of:0000000000000001/5"
+             }
+         },
+
+        // cord-r2-s3 iface eth0
+        "3c:fd:fe:9e:94:98/-1" : {
+            "basic": {
+                "ips": ["10.3.2.1"],                 // host IP on fabric
+                "location": "of:0000000000000022/3"  // link back to fabric leaf-2/port-3
+            }
+        },
+
+        // cord-r2-s4 iface eth0
+        "3c:fd:fe:9e:97:98/-1" : {
+            "basic": {
+                "ips": ["10.3.2.2"],                 // host IP on fabric
+                "location": "of:0000000000000022/4"  // link back to fabric leaf-2/port-4
+            }
+        }
+    },
+    "apps" : {
+        "org.onosproject.core" : {
+            "core" : {
+                "linkDiscoveryMode" : "STRICT" // enable strict link validation
+            }    
+        }
+    }
+}
diff --git a/roles/onos-fabric/vars/main.yml b/roles/onos-fabric/vars/main.yml
new file mode 100644
index 0000000..457d453
--- /dev/null
+++ b/roles/onos-fabric/vars/main.yml
@@ -0,0 +1,20 @@
+---
+fabric:
+  network: 10.6.1
+  spine1:
+    of_id: of:0000000000000011
+  spine2:
+    of_id: of:0000000000000012
+  leaf1:
+    of_id: of:0000000000000021
+  leaf2:
+    of_id: of:0000000000000022
+  hosts:
+    cord-r6-s1:
+      mac: 3c:fd:fe:9e:94:30
+      ip: 10.6.1.1
+      location:
+        leaf: 1
+        port: 1
+  
+