Merge "Added example to load a custom dashboard in the system"
diff --git a/cord-pod-ansible/Makefile b/cord-pod-ansible/Makefile
index 80bb48c..c09cb62 100644
--- a/cord-pod-ansible/Makefile
+++ b/cord-pod-ansible/Makefile
@@ -16,5 +16,17 @@
 rm: stop
 	ansible-playbook -i inventory/local --connection=local -e "config_dir=$(CONFIG_DIR)" cord-pod-rm-playbook.yaml
 
+cleanup: rm
+	scripts/cleanup.sh
+
 local_containers:
 	ansible-playbook -i inventory/local --connection=local -e "config_dir=$(CONFIG_DIR)" local-containers-playbook.yaml
+
+cord-subscriber:
+	ansible-playbook -i inventory/local --connection=local -e "config_dir=$(CONFIG_DIR)" test-subscriber-playbook.yaml
+
+cord-monitoringservice:
+	ansible-playbook -i inventory/local --connection=local -e "config_dir=$(CONFIG_DIR)" monitoring-playbook.yaml
+
+exampleservice:
+	ansible-playbook -i inventory/local --connection=local -e "config_dir=$(CONFIG_DIR)" exampleservice-playbook.yaml
diff --git a/cord-pod-ansible/base-config-2x2 b/cord-pod-ansible/base-config-2x2
deleted file mode 100644
index bc6c95b..0000000
--- a/cord-pod-ansible/base-config-2x2
+++ /dev/null
@@ -1,139 +0,0 @@
-{
-    "ports" : {
-    "of:0000cc37ab6180ca/5" : {
-        "interfaces" : [
-            {
-                "ips" : [ "10.6.1.254/24" ]
-            }
-        ]
-    },
-    "of:0000cc37ab6182d2/5" : {
-        "interfaces" : [
-            {
-                "ips" : [ "10.6.2.254/24" ]
-            }
-        ]
-    },
-    "of:0000cc37ab6182d2/32" : {
-        "interfaces" : [
-            {
-                "name" : "internet-router",
-                "ips" : [ "10.231.254.202/30" ],
-                "mac" : "00:16:3e:4b:5a:04"
-            }
-        ],
-        "pimInterface" : {
-            "interfaceName" : "internet-router",
-            "enabled" : true,
-            "helloInterval" : 1,
-            "holdTime" : 3,
-            "propagationDelay" : 500,
-            "overrideInterval" : 2500
-         }
-    }
-    },
-    "devices" : {
-        "of:0000cc37ab6180ca" : {
-            "segmentrouting" : {
-                "name" : "Leaf-R1",
-                "nodeSid" : 101,
-                "routerIp" : "10.6.0.8",
-                "routerMac" : "00:00:00:00:01:80",
-                "isEdgeRouter" : true,
-                "adjacencySids" : []
-            }
-        },
-        "of:0000cc37ab6182d2" : {
-            "segmentrouting" : {
-                "name" : "Leaf-R2",
-                "nodeSid" : 102,
-                "routerIp" : "10.6.0.11",
-                "routerMac" : "00:00:00:00:02:80",
-                "isEdgeRouter" : true,
-                "adjacencySids" : []
-            }
-        },
-        "of:0000cc37ab618048" : {
-            "segmentrouting" : {
-                "name" : "Spine-R1",
-                "nodeSid" : 103,
-                "routerIp" : "10.6.0.18",
-                "routerMac" : "00:00:01:00:11:80",
-                "isEdgeRouter" : false,
-                "adjacencySids" : []
-            }
-        },
-        "of:0000cc37ab617ec2" : {
-            "segmentrouting" : {
-                "name" : "Spine-R2",
-                "nodeSid" : 104,
-                "routerIp" : "10.6.0.17",
-                "routerMac" : "00:00:01:00:22:80",
-                "isEdgeRouter" : false,
-                "adjacencySids" : []
-            }
-        }
-    },
-    "links" : {
-        "of:0000cc37ab6180ca/1-of:0000cc37ab618048/1" : {
-            "basic" : {}
-        },
-        "of:0000cc37ab6180ca/3-of:0000cc37ab617ec2/1" : {
-            "basic" : {}
-        },
-        "of:0000cc37ab6182d2/1-of:0000cc37ab618048/3" : {
-            "basic" : {}
-        },
-        "of:0000cc37ab6182d2/3-of:0000cc37ab617ec2/3" : {
-            "basic" : {}
-        },
-        "of:0000cc37ab618048/1-of:0000cc37ab6180ca/1" : {
-            "basic" : {}
-        },
-        "of:0000cc37ab617ec2/1-of:0000cc37ab6180ca/3" : {
-            "basic" : {}
-        },
-        "of:0000cc37ab618048/3-of:0000cc37ab6182d2/1" : {
-            "basic" : {}
-        },
-        "of:0000cc37ab617ec2/3-of:0000cc37ab6182d2/3" : {
-            "basic" : {}
-        }
-    },
-    "apps" : {
-        "org.onosproject.core" : {
-            "core" : {
-                "linkDiscoveryMode" : "STRICT"
-            },
-            "multicast": {
-                "ingressVlan": "None",
-                "egressVlan": "None"
-            }
-        },
-        "org.onosproject.segmentrouting" : {
-            "segmentrouting" : {
-                "vRouterMacs" : [
-                    "a4:23:05:34:56:78", "a4:23:05:34:56:79"
-                ],
-                "vRouterId" : "of:0000cc37ab6182d2",
-                "suppressSubnet" : [
-                    "of:0000cc37ab6182d2/31", "of:0000cc37ab6182d2/32"
-                ],
-                "suppressHostByProvider" : [
-                    "org.onosproject.provider.host"
-                ],
-                "suppressHostByPort" : [
-                    "of:0000cc37ab6182d2/31", "of:0000cc37ab6182d2/32"
-                ]
-            }
-        },
-        "org.onosproject.router" : {
-            "router" : {
-                "controlPlaneConnectPoint" : "of:0000cc37ab6182d2/31",
-                "ospfEnabled" : "true",
-                "pimEnabled" : "true",
-                "interfaces" : [ "internet-router" ]
-            }
-        }
-    }
-}
diff --git a/cord-pod-ansible/cord-pod-playbook.yaml b/cord-pod-ansible/cord-pod-playbook.yaml
index c8512c4..7b92361 100644
--- a/cord-pod-ansible/cord-pod-playbook.yaml
+++ b/cord-pod-ansible/cord-pod-playbook.yaml
@@ -4,6 +4,7 @@
   hosts: head
   tasks:
     - include_vars: vars/cord-pod_defaults.yml
+    - include_vars: vars/cord-stack_defaults.yml
 
 - name: Prerequisites
   hosts: head
diff --git a/cord-pod-ansible/exampleservice-playbook.yaml b/cord-pod-ansible/exampleservice-playbook.yaml
new file mode 100644
index 0000000..87d4719
--- /dev/null
+++ b/cord-pod-ansible/exampleservice-playbook.yaml
@@ -0,0 +1,20 @@
+---
+
+- name: Include vars
+  hosts: head
+  tasks:
+    - include_vars: vars/cord-pod_defaults.yml
+    - include_vars: vars/exampleservice_defaults.yml
+
+- name: Onboarding
+  hosts: head
+  roles:
+    - onboarding
+
+- name: Configuration
+  hosts: head
+  roles:
+    - config
+  tags:
+    - config
+
diff --git a/cord-pod-ansible/images/README.md b/cord-pod-ansible/images/README.md
new file mode 100644
index 0000000..aca55a9
--- /dev/null
+++ b/cord-pod-ansible/images/README.md
@@ -0,0 +1,5 @@
+# VM images for XOS
+
+Any Cloud image files placed in this directory (with suffix .img) will be automatically
+imported by XOS and added to Glance (OpenStack's image repository).  For instance, the image
+`trusty-server-multi-nic.img` will be imported with name `trusty-server-multi-nic`.
diff --git a/cord-pod-ansible/monitoring-playbook.yaml b/cord-pod-ansible/monitoring-playbook.yaml
new file mode 100644
index 0000000..144d399
--- /dev/null
+++ b/cord-pod-ansible/monitoring-playbook.yaml
@@ -0,0 +1,25 @@
+---
+
+- name: Include vars
+  hosts: head
+  tasks:
+    - include_vars: vars/cord-pod_defaults.yml
+    - include_vars: vars/monitoring_defaults.yml
+
+- name: Download images
+  hosts: head
+  roles:
+    - download_images
+
+- name: Onboarding
+  hosts: head
+  roles:
+    - onboarding
+
+- name: Configuration
+  hosts: head
+  roles:
+    - config
+  tags:
+    - config
+
diff --git a/cord-pod-ansible/monitoringservice.yaml b/cord-pod-ansible/monitoringservice.yaml
new file mode 100644
index 0000000..b076057
--- /dev/null
+++ b/cord-pod-ansible/monitoringservice.yaml
@@ -0,0 +1,313 @@
+tosca_definitions_version: tosca_simple_yaml_1_0
+
+description: Setup CORD-related services -- vOLT, vCPE, vBNG.
+
+imports:
+   - custom_types/xos.yaml
+
+node_types:
+    tosca.nodes.SFlowService:
+        derived_from: tosca.nodes.Root
+        description: >
+            XOS SFlow Collection Service
+        capabilities:
+            scalable:
+                type: tosca.capabilities.Scalable
+            service:
+                type: tosca.capabilities.xos.Service
+        properties:
+            no-delete:
+                type: boolean
+                default: false
+                description: Do not allow Tosca to delete this object
+            no-create:
+                type: boolean
+                default: false
+                description: Do not allow Tosca to create this object
+            no-update:
+                type: boolean
+                default: false
+                description: Do not allow Tosca to update this object
+            kind:
+                type: string
+                default: generic
+                description: Type of service.
+            view_url:
+                type: string
+                required: false
+                description: URL to follow when icon is clicked in the Service Directory.
+            icon_url:
+                type: string
+                required: false
+                description: ICON to display in the Service Directory.
+            enabled:
+                type: boolean
+                default: true
+            published:
+                type: boolean
+                default: true
+                description: If True then display this Service in the Service Directory.
+            public_key:
+                type: string
+                required: false
+                description: Public key to install into Instances to allows Services to SSH into them.
+            private_key_fn:
+                type: string
+                required: false
+                description: Location of private key file
+            versionNumber:
+                type: string
+                required: false
+                description: Version number of Service.
+            sflow_port:
+              type: integer
+              required: false
+              default: 6343
+              description: sFlow listening port
+            sflow_api_port:
+              type: integer
+              required: false
+              default: 33333
+              description: sFlow publish subscribe api listening port
+
+    tosca.nodes.CeilometerService:
+        derived_from: tosca.nodes.Root
+        description: >
+            XOS Ceilometer Service
+        capabilities:
+            scalable:
+                type: tosca.capabilities.Scalable
+            service:
+                type: tosca.capabilities.xos.Service
+        properties:
+            no-delete:
+                type: boolean
+                default: false
+                description: Do not allow Tosca to delete this object
+            no-create:
+                type: boolean
+                default: false
+                description: Do not allow Tosca to create this object
+            no-update:
+                type: boolean
+                default: false
+                description: Do not allow Tosca to update this object
+            kind:
+                type: string
+                default: generic
+                description: Type of service.
+            view_url:
+                type: string
+                required: false
+                description: URL to follow when icon is clicked in the Service Directory.
+            icon_url:
+                type: string
+                required: false
+                description: ICON to display in the Service Directory.
+            enabled:
+                type: boolean
+                default: true
+            published:
+                type: boolean
+                default: true
+                description: If True then display this Service in the Service Directory.
+            public_key:
+                type: string
+                required: false
+                description: Public key to install into Instances to allows Services to SSH into them.
+            private_key_fn:
+                type: string
+                required: false
+                description: Location of private key file
+            versionNumber:
+                type: string
+                required: false
+                description: Version number of Service.
+            ceilometer_pub_sub_url:
+                type: string
+                required: false
+                description: REST URL of ceilometer PUB/SUB component
+
+    tosca.nodes.CeilometerTenant:
+        derived_from: tosca.nodes.Root
+        description: >
+            CORD: A Tenant of the Ceilometer Service.
+        properties:
+            kind:
+                type: string
+                default: generic
+                description: Kind of tenant
+
+topology_template:
+  node_templates:
+    service_ceilometer:
+      type: tosca.nodes.CeilometerService
+      requirements:
+      properties:
+          view_url: /admin/monitoring/ceilometerservice/$id$/
+          kind: ceilometer
+          ceilometer_pub_sub_url: http://10.11.10.1:4455/
+          public_key: { get_artifact: [ SELF, pubkey, LOCAL_FILE] }
+          private_key_fn: /opt/xos/services/monitoring/keys/monitoringservice_rsa
+      artifacts:
+          pubkey: /opt/xos/services/monitoring/keys/monitoringservice_rsa.pub
+
+#    service_sflow:
+#      type: tosca.nodes.SFlowService
+#      requirements:
+#      properties:
+#          view_url: /admin/monitoring/sflowservice/$id$/
+#          kind: sflow
+#          sflow_port: 6343
+#          sflow_api_port: 33333
+
+    Private:
+      type: tosca.nodes.NetworkTemplate
+
+    management:
+      type: tosca.nodes.network.Network.XOS
+      properties:
+          no-create: true
+          no-delete: true
+          no-update: true
+
+#    ceilometer_network:
+#      type: tosca.nodes.network.Network.XOS
+#      properties:
+#          ip_version: 4
+#          labels: ceilometer_client_access
+#      requirements:
+#          - network_template:
+#              node: Private
+#              relationship: tosca.relationships.UsesNetworkTemplate
+#          - owner:
+#              node: mysite_ceilometer
+#              relationship: tosca.relationships.MemberOfSlice
+#          - connection:
+#              node: mysite_ceilometer
+#              relationship: tosca.relationships.ConnectsToSlice
+
+    mysite:
+      type: tosca.nodes.Site
+
+    trusty-server-multi-nic:
+      type: tosca.nodes.Image
+
+    ceilometer-trusty-server-multi-nic:
+      type: tosca.nodes.Image
+
+    ceilometer-service-trusty-server-multi-nic:
+      type: tosca.nodes.Image
+
+    m1.small:
+      type: tosca.nodes.Flavor
+
+    mysite_ceilometer:
+      description: Ceilometer Proxy Slice
+      type: tosca.nodes.Slice
+      requirements:
+          - ceilometer_service:
+              node: service_ceilometer
+              relationship: tosca.relationships.MemberOfService
+          - site:
+              node: mysite
+              relationship: tosca.relationships.MemberOfSite
+          - default_image:
+                node: ceilometer-trusty-server-multi-nic
+                relationship: tosca.relationships.DefaultImage
+          - management:
+              node: management
+              relationship: tosca.relationships.ConnectsToNetwork
+          - m1.small:
+              node: m1.small
+              relationship: tosca.relationships.DefaultFlavor
+
+    # Virtual machines
+    ceilometer_service_instance:
+      type: tosca.nodes.Compute
+      capabilities:
+        # Host container properties
+        host:
+         properties:
+           num_cpus: 1
+           disk_size: 20 GB
+           mem_size: 2 GB
+      requirements:
+          - slice:
+                node: mysite_ceilometer
+                relationship: tosca.relationships.MemberOfSlice
+          - image:
+                node: ceilometer-service-trusty-server-multi-nic
+                relationship: tosca.relationships.UsesImage
+
+#    mysite_sflow:
+#      description: Slice for sFlow service
+#      type: tosca.nodes.Slice
+#      requirements:
+#          - sflow_service:
+#              node: service_sflow
+#              relationship: tosca.relationships.MemberOfService
+#          - site:
+#              node: mysite
+#              relationship: tosca.relationships.MemberOfSite
+
+# MOVING this section to monitoringtenant.yaml
+#    my_ceilometer_tenant:
+#      description: Ceilometer Service default Tenant
+#      type: tosca.nodes.CeilometerTenant
+#      requirements:
+#          - provider_service:
+#              node: service_ceilometer
+#              relationship: tosca.relationships.MemberOfService
+#          - dependency:
+#              node: ceilometer_service_instance
+#              relationship: tosca.relationships.DependsOn
+       
+    # Virtual machines
+#    sflow_service_instance:
+#      type: tosca.nodes.Compute
+#      capabilities:
+#        # Host container properties
+#        host:
+#         properties:
+#           num_cpus: 1
+#           disk_size: 10 GB
+#           mem_size: 4 MB
+#        # Guest Operating System properties
+#        os:
+#          properties:
+#            # host Operating System image properties
+#            architecture: x86_64
+#            type: linux
+#            distribution: Ubuntu
+#            version: 14.10
+#      requirements:
+#          - slice:
+#                node: mysite_sflow
+#                relationship: tosca.relationships.MemberOfSlice
+
+# MOVING the below sections to monitoringtenant.yaml
+#    Ceilometer:
+#      type: tosca.nodes.DashboardView
+#      properties:
+#          url: template:xosCeilometerDashboard
+#    Tenant:
+#      type: tosca.nodes.DashboardView
+#      properties:
+#          no-create: true
+#          no-update: true
+#          no-delete: true
+#
+#    padmin@vicci.org:
+#      type: tosca.nodes.User
+#      properties:
+#          firstname: XOS
+#          lastname: admin
+#          is_admin: true
+#      requirements:
+#          - tenant_dashboard:
+#              node: Tenant
+#              relationship: tosca.relationships.UsesDashboard
+#          - ceilometer_dashboard:
+#              node: Ceilometer
+#              relationship: tosca.relationships.UsesDashboard
diff --git a/cord-pod-ansible/monitoringtenant.yaml b/cord-pod-ansible/monitoringtenant.yaml
new file mode 100644
index 0000000..37cda64
--- /dev/null
+++ b/cord-pod-ansible/monitoringtenant.yaml
@@ -0,0 +1,182 @@
+tosca_definitions_version: tosca_simple_yaml_1_0
+
+description: Setup CORD-related services -- vOLT, vCPE, vBNG.
+
+imports:
+   - custom_types/xos.yaml
+
+node_types:
+#FIXME: See if we can avoid redefining the below types again in this file by moving to common file
+    tosca.nodes.SFlowService:
+        derived_from: tosca.nodes.Root
+        description: >
+            XOS SFlow Collection Service
+        capabilities:
+            scalable:
+                type: tosca.capabilities.Scalable
+            service:
+                type: tosca.capabilities.xos.Service
+        properties:
+            no-delete:
+                type: boolean
+                default: false
+                description: Do not allow Tosca to delete this object
+            no-create:
+                type: boolean
+                default: false
+                description: Do not allow Tosca to create this object
+            no-update:
+                type: boolean
+                default: false
+                description: Do not allow Tosca to update this object
+            kind:
+                type: string
+                default: generic
+                description: Type of service.
+            view_url:
+                type: string
+                required: false
+                description: URL to follow when icon is clicked in the Service Directory.
+            icon_url:
+                type: string
+                required: false
+                description: ICON to display in the Service Directory.
+            enabled:
+                type: boolean
+                default: true
+            published:
+                type: boolean
+                default: true
+                description: If True then display this Service in the Service Directory.
+            public_key:
+                type: string
+                required: false
+                description: Public key to install into Instances to allows Services to SSH into them.
+            private_key_fn:
+                type: string
+                required: false
+                description: Location of private key file
+            versionNumber:
+                type: string
+                required: false
+                description: Version number of Service.
+            sflow_port:
+              type: integer
+              required: false
+              default: 6343
+              description: sFlow listening port
+            sflow_api_port:
+              type: integer
+              required: false
+              default: 33333
+              description: sFlow publish subscribe api listening port
+
+    tosca.nodes.CeilometerService:
+        derived_from: tosca.nodes.Root
+        description: >
+            XOS Ceilometer Service
+        capabilities:
+            scalable:
+                type: tosca.capabilities.Scalable
+            service:
+                type: tosca.capabilities.xos.Service
+        properties:
+            no-delete:
+                type: boolean
+                default: false
+                description: Do not allow Tosca to delete this object
+            no-create:
+                type: boolean
+                default: false
+                description: Do not allow Tosca to create this object
+            no-update:
+                type: boolean
+                default: false
+                description: Do not allow Tosca to update this object
+            kind:
+                type: string
+                default: generic
+                description: Type of service.
+            view_url:
+                type: string
+                required: false
+                description: URL to follow when icon is clicked in the Service Directory.
+            icon_url:
+                type: string
+                required: false
+                description: ICON to display in the Service Directory.
+            enabled:
+                type: boolean
+                default: true
+            published:
+                type: boolean
+                default: true
+                description: If True then display this Service in the Service Directory.
+            public_key:
+                type: string
+                required: false
+                description: Public key to install into Instances to allows Services to SSH into them.
+            private_key_fn:
+                type: string
+                required: false
+                description: Location of private key file
+            versionNumber:
+                type: string
+                required: false
+                description: Version number of Service.
+            ceilometer_pub_sub_url:
+                type: string
+                required: false
+                description: REST URL of ceilometer PUB/SUB component
+
+    tosca.nodes.CeilometerTenant:
+        derived_from: tosca.nodes.Root
+        description: >
+            CORD: A Tenant of the Ceilometer Service.
+        properties:
+            kind:
+                type: string
+                default: generic
+                description: Kind of tenant
+
+topology_template:
+  node_templates:
+    service_ceilometer:
+      type: tosca.nodes.CeilometerService
+      properties:
+          no-create: true
+          no-update: true
+          no-delete: true
+
+    my_ceilometer_tenant:
+      description: Ceilometer Service default Tenant
+      type: tosca.nodes.CeilometerTenant
+      requirements:
+          - provider_service:
+              node: service_ceilometer
+              relationship: tosca.relationships.MemberOfService
+       
+    Ceilometer:
+      type: tosca.nodes.DashboardView
+      properties:
+          url: template:xosCeilometerDashboard
+    Tenant:
+      type: tosca.nodes.DashboardView
+      properties:
+          no-create: true
+          no-update: true
+          no-delete: true
+
+    padmin@vicci.org:
+      type: tosca.nodes.User
+      properties:
+          firstname: XOS
+          lastname: admin
+          is_admin: true
+      requirements:
+          - tenant_dashboard:
+              node: Tenant
+              relationship: tosca.relationships.UsesDashboard
+          - ceilometer_dashboard:
+              node: Ceilometer
+              relationship: tosca.relationships.UsesDashboard
diff --git a/cord-pod-ansible/pod-exampleservice.yaml b/cord-pod-ansible/pod-exampleservice.yaml
new file mode 100644
index 0000000..0182a59
--- /dev/null
+++ b/cord-pod-ansible/pod-exampleservice.yaml
@@ -0,0 +1,94 @@
+tosca_definitions_version: tosca_simple_yaml_1_0
+
+description: Setup the ExampleService on the pod
+
+imports:
+   - custom_types/xos.yaml
+   - custom_types/exampleservice.yaml
+
+topology_template:
+  node_templates:
+
+    Private:
+      type: tosca.nodes.NetworkTemplate
+
+    management:
+      type: tosca.nodes.network.Network.XOS
+      properties:
+          no-create: true
+          no-delete: true
+          no-update: true
+
+    service#vrouter:
+      type: tosca.nodes.Service
+      properties:
+          no-create: true
+          no-delete: true
+          no-update: true
+
+    exampleservice-public:
+      type: tosca.nodes.network.Network
+      properties:
+          ip_version: 4
+      requirements:
+          - network_template:
+              node: Private
+              relationship: tosca.relationships.UsesNetworkTemplate
+          - owner:
+              node: mysite_exampleservice
+              relationship: tosca.relationships.MemberOfSlice
+          - connection:
+              node: mysite_exampleservice
+              relationship: tosca.relationships.ConnectsToSlice
+          - vrouter_tenant:
+              node: service#vrouter
+              relationship: tosca.relationships.TenantOfService
+
+    mysite:
+      type: tosca.nodes.Site
+
+    trusty-server-multi-nic:
+      type: tosca.nodes.Image
+
+    mysite_exampleservice:
+      description: This slice holds the ExampleService
+      type: tosca.nodes.Slice
+      properties:
+          network: noauto
+      requirements:
+          - site:
+              node: mysite
+              relationship: tosca.relationships.MemberOfSite
+          - management:
+              node: management
+              relationship: tosca.relationships.ConnectsToNetwork
+          - exmapleserver:
+              node: service#exampleservice
+              relationship: tosca.relationships.MemberOfService
+          - image:
+              node: trusty-server-multi-nic
+              relationship: tosca.relationships.DefaultImage
+
+    service#exampleservice:
+      type: tosca.nodes.ExampleService
+      requirements:
+          - management:
+              node: management
+              relationship: tosca.relationships.UsesNetwork
+      properties:
+          view_url: /admin/exampleservice/exampleservice/$id$/
+          kind: exampleservice
+          public_key: { get_artifact: [ SELF, pubkey, LOCAL_FILE] }
+          private_key_fn: /opt/xos/services/exampleservice/keys/exampleservice_rsa
+          service_message: hello
+      artifacts:
+          pubkey: /opt/xos/services/exampleservice/keys/exampleservice_rsa.pub
+
+    tenant#exampletenant1:
+        type: tosca.nodes.ExampleTenant
+        properties:
+            tenant_message: world
+        requirements:
+          - tenant:
+              node: service#exampleservice
+              relationship: tosca.relationships.TenantOfService
diff --git a/cord-pod-ansible/roles/buildconfig/tasks/main.yml b/cord-pod-ansible/roles/buildconfig/tasks/main.yml
index 26907d3..338dd4b 100644
--- a/cord-pod-ansible/roles/buildconfig/tasks/main.yml
+++ b/cord-pod-ansible/roles/buildconfig/tasks/main.yml
@@ -9,5 +9,8 @@
 - name: make vtn-external.yaml
   shell: export SETUPDIR={{ setup_dir }}; bash {{ config_dir }}/scripts/make-vtn-external-yaml.sh
 
+- name: copy network-cfg-quickstart.json from fabric service repo
+  copy: src="{{ xos_services_dir }}/fabric/config/network-cfg-quickstart.json" dest="{{ setup_dir }}"
+
 - name: make fabric.yaml
   shell: export SETUPDIR={{ setup_dir }}; bash {{ config_dir }}/scripts/make-fabric-yaml.sh
diff --git a/cord-pod-ansible/roles/config/tasks/main.yml b/cord-pod-ansible/roles/config/tasks/main.yml
index 3016471..d418765 100644
--- a/cord-pod-ansible/roles/config/tasks/main.yml
+++ b/cord-pod-ansible/roles/config/tasks/main.yml
@@ -1,9 +1,5 @@
 ---
 
-- name: run config recipe {{ item.name }}
-  xostosca:
-     port={{ ui_port }}
-     username={{ bootstrap_user }}
-     password={{ bootstrap_password }}
-     recipe={{ lookup('file', item.yaml) }}
+- name: run config recipes
+  include: run_config.yml
   with_items: "{{ config_recipes | default([]) }}"
diff --git a/cord-pod-ansible/roles/config/tasks/run_config.yml b/cord-pod-ansible/roles/config/tasks/run_config.yml
new file mode 100644
index 0000000..cfb64fc
--- /dev/null
+++ b/cord-pod-ansible/roles/config/tasks/run_config.yml
@@ -0,0 +1,12 @@
+- set_fact: recipe="{{ item }}"
+
+- name: run config recipe {{ recipe.name }}
+  xostosca:
+     port={{ ui_port }}
+     username={{ bootstrap_user }}
+     password={{ bootstrap_password }}
+     recipe={{ lookup('file', recipe.yaml) }}
+
+- name: post-recipe delay
+  pause: seconds="{{ recipe.post_delay }}"
+  when: recipe.post_delay is defined
diff --git a/cord-pod-ansible/scripts/cleanup.sh b/cord-pod-ansible/scripts/cleanup.sh
new file mode 100755
index 0000000..704cacb
--- /dev/null
+++ b/cord-pod-ansible/scripts/cleanup.sh
@@ -0,0 +1,50 @@
+#!/bin/bash
+
+function cleanup_network {
+  NETWORK=$1
+  SUBNETS=`neutron net-show $NETWORK | grep -i subnets | awk '{print $4}'`
+  if [[ $SUBNETS != "" ]]; then
+      PORTS=`neutron port-list | grep -i $SUBNETS | awk '{print $2}'`
+      for PORT in $PORTS; do
+          echo "Deleting port $PORT"
+          neutron port-delete $PORT
+      done
+  fi
+  neutron net-delete $NETWORK
+}
+
+source ./admin-openrc.sh
+
+echo "Deleting VMs"
+# Delete all VMs
+VMS=$( nova list --all-tenants|grep mysite|awk '{print $2}' )
+for VM in $VMS
+do
+    nova delete $VM
+done
+
+echo "Waiting 5 seconds..."
+sleep 5
+
+cleanup_network lan_network
+cleanup_network wan_network
+cleanup_network mysite_vcpe-private
+cleanup_network mysite_vsg-access
+cleanup_network management
+
+echo "Deleting networks"
+# Delete all networks beginning with mysite_
+NETS=$( neutron net-list --all-tenants|grep mysite|awk '{print $2}' )
+for NET in $NETS
+do
+    neutron net-delete $NET
+done
+
+neutron net-delete lan_network || true
+neutron net-delete subscriber_network || true
+neutron net-delete public_network || true
+neutron net-delete hpc_client_network || true
+neutron net-delete ceilometer_network || true
+neutron net-delete management || true
+neutron net-delete mysite_vsg-access || true
+neutron net-delete exampleservice-public || true
diff --git a/cord-pod-ansible/scripts/make-fabric-yaml.sh b/cord-pod-ansible/scripts/make-fabric-yaml.sh
index 7c4cfd7..b52ba82 100644
--- a/cord-pod-ansible/scripts/make-fabric-yaml.sh
+++ b/cord-pod-ansible/scripts/make-fabric-yaml.sh
@@ -24,7 +24,7 @@
           replaces: service_ONOS_Fabric
           rest_onos/v1/network/configuration/: { get_artifact: [ SELF, fabric_network_cfg_json, LOCAL_FILE ] }
       artifacts:
-          fabric_network_cfg_json: /root/setup/base-config-2x2
+          fabric_network_cfg_json: /root/setup/network-cfg-quickstart.json
 
     service#fabric:
       type: tosca.nodes.FabricService
diff --git a/cord-pod-ansible/test-subscriber-playbook.yaml b/cord-pod-ansible/test-subscriber-playbook.yaml
new file mode 100644
index 0000000..d9215d6
--- /dev/null
+++ b/cord-pod-ansible/test-subscriber-playbook.yaml
@@ -0,0 +1,15 @@
+---
+
+- name: Include vars
+  hosts: head
+  tasks:
+    - include_vars: vars/cord-pod_defaults.yml
+    - include_vars: vars/cord-test-subscriber_defaults.yml
+
+- name: Configuration
+  hosts: head
+  roles:
+    - config
+  tags:
+    - config
+
diff --git a/cord-pod-ansible/vars/cord-pod_defaults.yml b/cord-pod-ansible/vars/cord-pod_defaults.yml
index dcba503..2b51288 100644
--- a/cord-pod-ansible/vars/cord-pod_defaults.yml
+++ b/cord-pod-ansible/vars/cord-pod_defaults.yml
@@ -21,34 +21,4 @@
 bootstrap_user: "padmin@vicci.org"
 bootstrap_password: "letmein"
 
-synchronizers_yml: "{{ config_dir }}/synchronizers.yaml"
-
-onboard_keys:
-  - { name: "vsg_rsa", private_fn: "{{ config_dir }}/id_rsa", public_fn: "{{ config_dir }}/id_rsa.pub" }
-  - { name: "volt_rsa", private_fn: "{{ config_dir }}/id_rsa", public_fn: "{{ config_dir }}/id_rsa.pub" }
-  - { name: "onos_rsa", private_fn: "{{ config_dir }}/id_rsa", public_fn: "{{ config_dir }}/id_rsa.pub" }
-
-onboard_services:
- - { name: "vrouter", yaml: "{{ xos_services_dir }}/vrouter/xos/vrouter-onboard.yaml" }
- - { name: "volt", yaml: "{{ xos_services_dir }}/olt/xos/volt-onboard.yaml" }
- - { name: "vsg", yaml: "{{ xos_services_dir }}/vsg/xos/vsg-onboard.yaml" }
- - { name: "vtr", yaml: "{{ xos_services_dir }}/vtn/xos/vtn-onboard.yaml" }
- - { name: "onos", yaml: "{{ xos_services_dir }}/onos-service/xos/onos-onboard.yaml" }
- - { name: "fabric", yaml: "{{ xos_services_dir }}/fabric/xos/fabric-onboard.yaml" }
- - { name: "vtr", yaml: "{{ xos_services_dir }}/vtr/xos/vtr-onboard.yaml" }
-
-images:
- - { name: "vsg-1.0", filename: "vsg-1.0.img", url: "http://www.vicci.org/cord/vsg-1.0.img" }
-
-config_recipes:
- - { name: "setup", yaml: "{{ setup_dir }}/setup.yaml" }
- - { name: "nodes", yaml: "{{ setup_dir }}/nodes.yaml" }
- - { name: "images", yaml: "{{ setup_dir }}/images.yaml" }
- - { name: "vtn-external", yaml: "{{ setup_dir }}/vtn-external.yaml" }
- - { name: "fabric", yaml: "{{ setup_dir }}/fabric.yaml" }
- - { name: "mgmt-net", yaml: "{{ setup_dir }}/mgmt-net.yaml" }
- - { name: "cord-services", yaml: "{{ setup_dir }}/cord-services.yaml" }
- - { name: "cord-volt-devices", yaml: "{{ setup_dir }}/cord-volt-devices.yaml" }
- - { name: "cord-test-subscriber", yaml: "{{ setup_dir }}/cord-test-subscriber.yaml" }
-
 
diff --git a/cord-pod-ansible/vars/cord-stack_defaults.yml b/cord-pod-ansible/vars/cord-stack_defaults.yml
new file mode 100644
index 0000000..f804679
--- /dev/null
+++ b/cord-pod-ansible/vars/cord-stack_defaults.yml
@@ -0,0 +1,31 @@
+---
+
+synchronizers_yml: "{{ config_dir }}/synchronizers.yaml"
+
+onboard_keys:
+  - { name: "vsg_rsa", private_fn: "{{ config_dir }}/id_rsa", public_fn: "{{ config_dir }}/id_rsa.pub" }
+  - { name: "volt_rsa", private_fn: "{{ config_dir }}/id_rsa", public_fn: "{{ config_dir }}/id_rsa.pub" }
+  - { name: "onos_rsa", private_fn: "{{ config_dir }}/id_rsa", public_fn: "{{ config_dir }}/id_rsa.pub" }
+
+onboard_services:
+ - { name: "vrouter", yaml: "{{ xos_services_dir }}/vrouter/xos/vrouter-onboard.yaml" }
+ - { name: "volt", yaml: "{{ xos_services_dir }}/olt/xos/volt-onboard.yaml" }
+ - { name: "vsg", yaml: "{{ xos_services_dir }}/vsg/xos/vsg-onboard.yaml" }
+ - { name: "vtr", yaml: "{{ xos_services_dir }}/vtn/xos/vtn-onboard.yaml" }
+ - { name: "onos", yaml: "{{ xos_services_dir }}/onos-service/xos/onos-onboard.yaml" }
+ - { name: "fabric", yaml: "{{ xos_services_dir }}/fabric/xos/fabric-onboard.yaml" }
+ - { name: "vtr", yaml: "{{ xos_services_dir }}/vtr/xos/vtr-onboard.yaml" }
+
+images:
+ - { name: "vsg-1.1", filename: "vsg-1.1.img", url: "http://www.vicci.org/cord/vsg-1.1.img" }
+
+config_recipes:
+ - { name: "setup", yaml: "{{ setup_dir }}/setup.yaml" }
+ - { name: "nodes", yaml: "{{ setup_dir }}/nodes.yaml" }
+ - { name: "images", yaml: "{{ setup_dir }}/images.yaml", post_delay: 120 }
+ - { name: "vtn-external", yaml: "{{ setup_dir }}/vtn-external.yaml" }
+ - { name: "fabric", yaml: "{{ setup_dir }}/fabric.yaml", post_delay: 30 }
+ - { name: "mgmt-net", yaml: "{{ setup_dir }}/mgmt-net.yaml"}
+ - { name: "cord-services", yaml: "{{ setup_dir }}/cord-services.yaml" }
+ - { name: "cord-volt-devices", yaml: "{{ setup_dir }}/cord-volt-devices.yaml" }
+
diff --git a/cord-pod-ansible/vars/cord-test-subscriber_defaults.yml b/cord-pod-ansible/vars/cord-test-subscriber_defaults.yml
new file mode 100644
index 0000000..ce93a3e
--- /dev/null
+++ b/cord-pod-ansible/vars/cord-test-subscriber_defaults.yml
@@ -0,0 +1,3 @@
+config_recipes:
+ - { name: "cord-test-subscriber", yaml: "{{ setup_dir }}/cord-test-subscriber.yaml", post_delay: 30 }
+ - { name: "vtn-external", yaml: "{{ setup_dir }}/vtn-external.yaml" }
diff --git a/cord-pod-ansible/vars/exampleservice_defaults.yml b/cord-pod-ansible/vars/exampleservice_defaults.yml
new file mode 100644
index 0000000..a3d986c
--- /dev/null
+++ b/cord-pod-ansible/vars/exampleservice_defaults.yml
@@ -0,0 +1,10 @@
+---
+
+onboard_keys:
+  - { name: "exampleservice_rsa", private_fn: "{{ config_dir }}/id_rsa", public_fn: "{{ config_dir }}/id_rsa.pub" }
+
+onboard_services:
+  - { name: "exampleservice", yaml: "{{ xos_services_dir }}/exampleservice/xos/exampleservice-onboard.yaml" }
+
+config_recipes:
+  - { name: "pod-exampleservice", yaml: "{{ setup_dir }}/pod-exampleservice.yaml" }
diff --git a/cord-pod-ansible/vars/monitoring_defaults.yml b/cord-pod-ansible/vars/monitoring_defaults.yml
new file mode 100644
index 0000000..4e1e8d2
--- /dev/null
+++ b/cord-pod-ansible/vars/monitoring_defaults.yml
@@ -0,0 +1,15 @@
+---
+
+onboard_keys:
+  - { name: "monitoringservice_rsa", private_fn: "{{ config_dir }}/id_rsa", public_fn: "{{ config_dir }}/id_rsa.pub" }
+
+onboard_services:
+ - { name: "monitoring", yaml: "{{ xos_services_dir }}/monitoring/xos/monitoring-onboard.yaml" }
+
+images:
+ - { name: "ceilometer-trusty-server-multi-nic", filename: "ceilometer-trusty-server-multi-nic.compressed.qcow2", url: "http://www.vicci.org/cord/ceilometer-trusty-server-multi-nic.compressed.qcow2" }
+
+config_recipes:
+ - { name: "monitoringservice", yaml: "{{ setup_dir }}/monitoringservice.yaml" }
+ - { name: "monitoringtenant", yaml: "{{ setup_dir }}/monitoringtenant.yaml" }
+
diff --git a/cord-pod/Makefile b/cord-pod/Makefile
index 898d34c..bf5016b 100644
--- a/cord-pod/Makefile
+++ b/cord-pod/Makefile
@@ -84,6 +84,7 @@
 	$(RUN_TOSCA) vtn-external.yaml
 
 fabric: fabric.yaml
+	cp ../../xos_services/fabric/config/network-cfg-quickstart.json .
 	$(RUN_TOSCA) fabric.yaml
 
 cord: vsg_custom_images
@@ -173,8 +174,8 @@
 	#TODO: Add logic for service VM custom image (ceilometer-service-trusty-server-multi-nic)
 	bash -c "source ./admin-openrc.sh; glance image-show ceilometer-trusty-server-multi-nic || glance image-create --name ceilometer-trusty-server-multi-nic --disk-format qcow2 --file ./images/ceilometer-trusty-server-multi-nic.compressed.qcow2 --container-format bare"
 
-vsg_custom_images: images/vsg-1.0.img
-	bash -c "source ./admin-openrc.sh; glance image-show vsg-1.0 || glance image-create --name vsg-1.0 --disk-format qcow2 --file ./images/vsg-1.0.img --container-format bare"
+vsg_custom_images: images/vsg-1.1.img
+	bash -c "source ./admin-openrc.sh; glance image-show vsg-1.1 || glance image-create --name vsg-1.1 --disk-format qcow2 --file ./images/vsg-1.1.img --container-format bare"
 
 images/ceilometer-trusty-server-multi-nic.img: images
 	bash -c "source ../setup/admin-openrc.sh; glance image-show ceilometer-trusty-server-multi-nic || wget http://www.vicci.org/cord/ceilometer-trusty-server-multi-nic.compressed.qcow2 -P ./images"
@@ -183,8 +184,8 @@
 	#TODO: Add logic for service VM custom image (ceilometer-service-trusty-server-multi-nic) once image is uploaded into vicci portal
 	#bash -c "source ../setup/admin-openrc.sh; glance image-show ceilometer-service-trusty-server-multi-nic || wget http://www.vicci.org/cord/ceilometer-service-trusty-server-multi-nic.compressed.qcow2 -P ./images"
 
-images/vsg-1.0.img: images
-	[ -s images/vsg-1.0.img ] || wget http://www.vicci.org/cord/vsg-1.0.img -P ./images
+images/vsg-1.1.img: images
+	[ -s images/vsg-1.1.img ] || wget http://www.vicci.org/cord/vsg-1.1.img -P ./images
 
 images:
 	mkdir -p ./images
diff --git a/cord-pod/base-config-2x2 b/cord-pod/base-config-2x2
deleted file mode 100644
index bc6c95b..0000000
--- a/cord-pod/base-config-2x2
+++ /dev/null
@@ -1,139 +0,0 @@
-{
-    "ports" : {
-    "of:0000cc37ab6180ca/5" : {
-        "interfaces" : [
-            {
-                "ips" : [ "10.6.1.254/24" ]
-            }
-        ]
-    },
-    "of:0000cc37ab6182d2/5" : {
-        "interfaces" : [
-            {
-                "ips" : [ "10.6.2.254/24" ]
-            }
-        ]
-    },
-    "of:0000cc37ab6182d2/32" : {
-        "interfaces" : [
-            {
-                "name" : "internet-router",
-                "ips" : [ "10.231.254.202/30" ],
-                "mac" : "00:16:3e:4b:5a:04"
-            }
-        ],
-        "pimInterface" : {
-            "interfaceName" : "internet-router",
-            "enabled" : true,
-            "helloInterval" : 1,
-            "holdTime" : 3,
-            "propagationDelay" : 500,
-            "overrideInterval" : 2500
-         }
-    }
-    },
-    "devices" : {
-        "of:0000cc37ab6180ca" : {
-            "segmentrouting" : {
-                "name" : "Leaf-R1",
-                "nodeSid" : 101,
-                "routerIp" : "10.6.0.8",
-                "routerMac" : "00:00:00:00:01:80",
-                "isEdgeRouter" : true,
-                "adjacencySids" : []
-            }
-        },
-        "of:0000cc37ab6182d2" : {
-            "segmentrouting" : {
-                "name" : "Leaf-R2",
-                "nodeSid" : 102,
-                "routerIp" : "10.6.0.11",
-                "routerMac" : "00:00:00:00:02:80",
-                "isEdgeRouter" : true,
-                "adjacencySids" : []
-            }
-        },
-        "of:0000cc37ab618048" : {
-            "segmentrouting" : {
-                "name" : "Spine-R1",
-                "nodeSid" : 103,
-                "routerIp" : "10.6.0.18",
-                "routerMac" : "00:00:01:00:11:80",
-                "isEdgeRouter" : false,
-                "adjacencySids" : []
-            }
-        },
-        "of:0000cc37ab617ec2" : {
-            "segmentrouting" : {
-                "name" : "Spine-R2",
-                "nodeSid" : 104,
-                "routerIp" : "10.6.0.17",
-                "routerMac" : "00:00:01:00:22:80",
-                "isEdgeRouter" : false,
-                "adjacencySids" : []
-            }
-        }
-    },
-    "links" : {
-        "of:0000cc37ab6180ca/1-of:0000cc37ab618048/1" : {
-            "basic" : {}
-        },
-        "of:0000cc37ab6180ca/3-of:0000cc37ab617ec2/1" : {
-            "basic" : {}
-        },
-        "of:0000cc37ab6182d2/1-of:0000cc37ab618048/3" : {
-            "basic" : {}
-        },
-        "of:0000cc37ab6182d2/3-of:0000cc37ab617ec2/3" : {
-            "basic" : {}
-        },
-        "of:0000cc37ab618048/1-of:0000cc37ab6180ca/1" : {
-            "basic" : {}
-        },
-        "of:0000cc37ab617ec2/1-of:0000cc37ab6180ca/3" : {
-            "basic" : {}
-        },
-        "of:0000cc37ab618048/3-of:0000cc37ab6182d2/1" : {
-            "basic" : {}
-        },
-        "of:0000cc37ab617ec2/3-of:0000cc37ab6182d2/3" : {
-            "basic" : {}
-        }
-    },
-    "apps" : {
-        "org.onosproject.core" : {
-            "core" : {
-                "linkDiscoveryMode" : "STRICT"
-            },
-            "multicast": {
-                "ingressVlan": "None",
-                "egressVlan": "None"
-            }
-        },
-        "org.onosproject.segmentrouting" : {
-            "segmentrouting" : {
-                "vRouterMacs" : [
-                    "a4:23:05:34:56:78", "a4:23:05:34:56:79"
-                ],
-                "vRouterId" : "of:0000cc37ab6182d2",
-                "suppressSubnet" : [
-                    "of:0000cc37ab6182d2/31", "of:0000cc37ab6182d2/32"
-                ],
-                "suppressHostByProvider" : [
-                    "org.onosproject.provider.host"
-                ],
-                "suppressHostByPort" : [
-                    "of:0000cc37ab6182d2/31", "of:0000cc37ab6182d2/32"
-                ]
-            }
-        },
-        "org.onosproject.router" : {
-            "router" : {
-                "controlPlaneConnectPoint" : "of:0000cc37ab6182d2/31",
-                "ospfEnabled" : "true",
-                "pimEnabled" : "true",
-                "interfaces" : [ "internet-router" ]
-            }
-        }
-    }
-}
diff --git a/cord-pod/cord-services.yaml b/cord-pod/cord-services.yaml
index 66b69ff..725af7c 100644
--- a/cord-pod/cord-services.yaml
+++ b/cord-pod/cord-services.yaml
@@ -126,7 +126,7 @@
           no-delete: true
           no-update: true
 
-    image#vsg-1.0:
+    image#vsg-1.1:
       type: tosca.nodes.Image
 
     mysite:
@@ -168,5 +168,5 @@
               node: management
               relationship: tosca.relationships.ConnectsToNetwork
           - image:
-              node: image#vsg-1.0
+              node: image#vsg-1.1
               relationship: tosca.relationships.DefaultImage
diff --git a/cord-pod/make-fabric-yaml.sh b/cord-pod/make-fabric-yaml.sh
index 7c4cfd7..b52ba82 100644
--- a/cord-pod/make-fabric-yaml.sh
+++ b/cord-pod/make-fabric-yaml.sh
@@ -24,7 +24,7 @@
           replaces: service_ONOS_Fabric
           rest_onos/v1/network/configuration/: { get_artifact: [ SELF, fabric_network_cfg_json, LOCAL_FILE ] }
       artifacts:
-          fabric_network_cfg_json: /root/setup/base-config-2x2
+          fabric_network_cfg_json: /root/setup/network-cfg-quickstart.json
 
     service#fabric:
       type: tosca.nodes.FabricService