Merge branch 'acb-develop'
Add basic message page explaining why service has been turned off.
diff --git a/xos/configurations/cord-pod/Makefile b/xos/configurations/cord-pod/Makefile
index ff4f258..592f579 100644
--- a/xos/configurations/cord-pod/Makefile
+++ b/xos/configurations/cord-pod/Makefile
@@ -14,6 +14,9 @@
 	sudo docker-compose run xos python /opt/xos/tosca/run.py padmin@vicci.org /opt/xos/configurations/common/fixtures.yaml
 	sudo docker-compose run xos python /opt/xos/tosca/run.py padmin@vicci.org /root/setup/cord-vtn-vsg.yaml
 
+cord-ceilometer: ceilometer_custom_images cord
+	sudo docker-compose run xos python /opt/xos/tosca/run.py padmin@vicci.org /root/setup/ceilometer.yaml
+
 nodes.yaml:
 	export SETUPDIR=.; bash ../common/make-nodes-yaml.sh
 
@@ -26,6 +29,22 @@
 vtn_network_cfg_json:
 	export SETUPDIR=.; bash ./make-vtn-networkconfig-json.sh
 
+stop:
+	sudo MYIP=$(MYIP) docker-compose stop
+
+rm:
+	sudo MYIP=$(MYIP) docker-compose rm
+
+showlogs:
+	sudo MYIP=$(MYIP) docker-compose logs
+
+cleanup: stop rm
+	./cleanup.sh
+	bash -c "source ./admin-openrc.sh; nova list --all-tenants; neutron net-list"
+
+ceilometer_custom_images:
+	bash -c "source ./admin-openrc.sh; glance image-show ceilometer-trusty-server-multi-nic || ! mkdir -p ./images || ! wget http://www.vicci.org/cord/ceilometer-trusty-server-multi-nic.qcow2 -P ./images || glance image-create --name ceilometer-trusty-server-multi-nic --disk-format qcow2 --file ./images/ceilometer-trusty-server-multi-nic.qcow2 --container-format bare"
+
 .PHONY: local_containers
 local_containers:
 	cd ../../../containers/xos; make devel
diff --git a/xos/configurations/cord-pod/ceilometer.yaml b/xos/configurations/cord-pod/ceilometer.yaml
new file mode 100644
index 0000000..3b32345
--- /dev/null
+++ b/xos/configurations/cord-pod/ceilometer.yaml
@@ -0,0 +1,258 @@
+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:
+            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:
+            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/ceilometer/ceilometerservice/$id$/
+          kind: ceilometer
+          ceilometer_pub_sub_url: http://10.11.10.1:4455/
+          public_key: { get_artifact: [ SELF, pubkey, LOCAL_FILE] }
+      artifacts:
+          pubkey: /opt/xos/synchronizers/monitoring_channel/monitoring_channel_public_key
+
+#    service_sflow:
+#      type: tosca.nodes.SFlowService
+#      requirements:
+#      properties:
+#          view_url: /admin/ceilometer/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
+
+    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
+      properties:
+          default_flavor: m1.small
+
+#    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
+
+    my_ceilometer_tenant:
+      description: Ceilometer Service default Tenant
+      type: tosca.nodes.CeilometerTenant
+      requirements:
+          - provider_service:
+              node: service_ceilometer
+              relationship: tosca.relationships.MemberOfService
+       
+    # 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
+
+    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/xos/configurations/cord-pod/cleanup.sh b/xos/configurations/cord-pod/cleanup.sh
new file mode 100755
index 0000000..6ca58c2
--- /dev/null
+++ b/xos/configurations/cord-pod/cleanup.sh
@@ -0,0 +1,49 @@
+#!/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
diff --git a/xos/configurations/cord-pod/docker-compose.yml b/xos/configurations/cord-pod/docker-compose.yml
index 6f442af..a0fec91 100644
--- a/xos/configurations/cord-pod/docker-compose.yml
+++ b/xos/configurations/cord-pod/docker-compose.yml
@@ -62,16 +62,17 @@
 #    links:
 #        - xos_db
 
-#xos_synchronizer_monitoring_channel:
-#    image: xosproject/xos-synchronizer-openstack
-#    command: bash -c "sleep 120; python /opt/xos/synchronizers/monitoring_channel/monitoring_channel_synchronizer.py -C /opt/xos/synchronizers/monitoring_channel/monitoring_channel_synchronizer_config"
-#    labels:
-#        org.xosproject.kind: synchronizer
-#        org.xosproject.target: monitoring_channel
-#    links:
-#        - xos_db
-#    volumes:
-#        - ./id_rsa:/opt/xos/synchronizers/monitoring_channel/monitoring_channel_private_key:ro  # private key
+xos_synchronizer_monitoring_channel:
+    image: xosproject/xos-synchronizer-openstack
+    command: bash -c "sleep 120; python /opt/xos/synchronizers/monitoring_channel/monitoring_channel_synchronizer.py -C /root/setup/files/monitoring_channel_synchronizer_config"
+    labels:
+        org.xosproject.kind: synchronizer
+        org.xosproject.target: monitoring_channel
+    links:
+        - xos_db
+    volumes:
+        - .:/root/setup:ro
+        - ./id_rsa:/opt/xos/synchronizers/monitoring_channel/monitoring_channel_private_key:ro  # private key
 
 xos:
     command: python /opt/xos/manage.py runserver 0.0.0.0:80 --insecure --makemigrations
@@ -87,3 +88,4 @@
         - ../vtn/files/xos_vtn_config:/opt/xos/xos_configuration/xos_vtn_config:ro
         - ./id_rsa.pub:/opt/xos/synchronizers/onos/onos_key.pub:ro
         - ./id_rsa.pub:/opt/xos/synchronizers/vcpe/vcpe_public_key:ro
+        - ./id_rsa.pub:/opt/xos/synchronizers/monitoring_channel/monitoring_channel_public_key:ro
diff --git a/xos/configurations/cord-pod/files/monitoring_channel_synchronizer_config b/xos/configurations/cord-pod/files/monitoring_channel_synchronizer_config
new file mode 100644
index 0000000..fb3f22a
--- /dev/null
+++ b/xos/configurations/cord-pod/files/monitoring_channel_synchronizer_config
@@ -0,0 +1,43 @@
+
+[plc]
+name=plc
+deployment=VICCI
+
+[db]
+name=xos
+user=postgres
+password=password
+host=localhost
+port=5432
+
+[api]
+host=128.112.171.237
+port=8000
+ssl_key=None
+ssl_cert=None
+ca_ssl_cert=None
+ratelimit_enabled=0
+omf_enabled=0
+mail_support_address=support@localhost
+nova_enabled=True
+
+[observer]
+name=monitoring_channel
+dependency_graph=/opt/xos/synchronizers/monitoring_channel/model-deps
+steps_dir=/opt/xos/synchronizers/monitoring_channel/steps
+sys_dir=/opt/xos/synchronizers/monitoring_channel/sys
+deleters_dir=/opt/xos/synchronizers/monitoring_channel/deleters
+log_file=console
+driver=None
+pretend=False
+backoff_disabled=True
+save_ansible_output=True
+full_setup=True
+# For CORD_POD config, set proxy_ssh to True even on cloudlab
+proxy_ssh=True
+proxy_ssh_key=/root/setup/node_key
+proxy_ssh_user=root
+
+[feefie]
+client_id='vicci_dev_central'
+user_id='pl'
diff --git a/xos/configurations/cord/cord.yaml b/xos/configurations/cord/cord.yaml
index 4dea365..c708d8e 100644
--- a/xos/configurations/cord/cord.yaml
+++ b/xos/configurations/cord/cord.yaml
@@ -8,6 +8,12 @@
 topology_template:
   node_templates:
     # CORD Services
+    service_vtr:
+      type: tosca.nodes.Service
+      properties:
+          view_url: /admin/vtr/vtrservice/$id$/
+          kind: vTR
+
     service_volt:
       type: tosca.nodes.Service
       requirements:
diff --git a/xos/configurations/cord/docker-compose.yml b/xos/configurations/cord/docker-compose.yml
index bfb04b8..28eeeb4 100644
--- a/xos/configurations/cord/docker-compose.yml
+++ b/xos/configurations/cord/docker-compose.yml
@@ -69,6 +69,19 @@
     volumes:
         - ../setup/id_rsa:/opt/xos/synchronizers/monitoring_channel/monitoring_channel_private_key:ro  # private key
 
+xos_synchronizer_vtr:
+    image: xosproject/xos-synchronizer-openstack
+    command: bash -c "sleep 120; python /opt/xos/synchronizers/vtr/vtr-synchronizer.py -C /opt/xos/synchronizers/vtr/vtr_synchronizer_config"
+    labels:
+        org.xosproject.kind: synchronizer
+        org.xosproject.target: vtr
+    links:
+        - xos_db
+    extra_hosts:
+        - ctl:${MYIP}
+    volumes:
+        - ../setup/id_rsa:/opt/xos/synchronizers/vtr/vcpe_private_key:ro  # private key
+        - ../setup:/root/setup:ro
 
 # FUTURE
 #xos_swarm_synchronizer:
diff --git a/xos/core/admin.py b/xos/core/admin.py
index 910ee97..44fa06c 100644
--- a/xos/core/admin.py
+++ b/xos/core/admin.py
@@ -1554,7 +1554,6 @@
     extra = 0
     suit_classes = 'suit-tab suit-tab-admin-only'
     fields = ['controller', 'user', 'kuser_id']
-    readonly_fields=['controller']
 
 
 class UserAdmin(XOSAdminMixin, UserAdmin):
diff --git a/xos/core/xoslib/methods/truckroll.py b/xos/core/xoslib/methods/truckroll.py
new file mode 100644
index 0000000..ca59866
--- /dev/null
+++ b/xos/core/xoslib/methods/truckroll.py
@@ -0,0 +1,90 @@
+from rest_framework.decorators import api_view
+from rest_framework.response import Response
+from rest_framework.reverse import reverse
+from rest_framework import serializers
+from rest_framework import generics
+from rest_framework import status
+from core.models import *
+from django.forms import widgets
+from services.cord.models import CordSubscriberRoot
+from services.vtr.models import VTRTenant, VTRService
+from plus import PlusSerializerMixin
+from xos.apibase import XOSListCreateAPIView, XOSRetrieveUpdateDestroyAPIView, XOSPermissionDenied
+
+if hasattr(serializers, "ReadOnlyField"):
+    # rest_framework 3.x
+    ReadOnlyField = serializers.ReadOnlyField
+else:
+    # rest_framework 2.x
+    ReadOnlyField = serializers.Field
+
+def get_default_vtr_service():
+    vtr_services = VTRService.get_service_objects().all()
+    if vtr_services:
+        return vtr_services[0].id
+    return None
+
+class VTRTenantIdSerializer(serializers.ModelSerializer, PlusSerializerMixin):
+        id = ReadOnlyField()
+        target_id = serializers.IntegerField()
+        test = serializers.CharField()
+        argument = serializers.CharField(required=False)
+        provider_service = serializers.PrimaryKeyRelatedField(queryset=VTRService.get_service_objects().all(), default=get_default_vtr_service)
+        result = serializers.CharField(required=False)
+        backend_status = ReadOnlyField()
+
+        humanReadableName = serializers.SerializerMethodField("getHumanReadableName")
+        is_synced = serializers.SerializerMethodField("isSynced")
+
+        class Meta:
+            model = VTRTenant
+            fields = ('humanReadableName', 'id', 'provider_service', 'target_id', 'test', 'argument', 'result', 'is_synced', 'backend_status' )
+
+        def getHumanReadableName(self, obj):
+            return obj.__unicode__()
+
+        def isSynced(self, obj):
+            return (obj.enacted is not None) and (obj.enacted >= obj.updated)
+
+class VTRTenantList(XOSListCreateAPIView):
+    serializer_class = VTRTenantIdSerializer
+
+    method_kind = "list"
+    method_name = "truckroll"
+
+    def get_queryset(self):
+        queryset = VTRTenant.get_tenant_objects().select_related().all()
+
+        test = self.request.QUERY_PARAMS.get('test', None)
+        if test is not None:
+            ids = [x.id for x in queryset if x.get_attribute("test", None)==test]
+            queryset = queryset.filter(id__in=ids)
+
+        return queryset
+
+    def post(self, request, format=None):
+        data = request.DATA
+
+        existing_obj = None
+#        for obj in VTRTenant.get_tenant_objects().all():
+#            if (obj.tesst == data.get("test", None)) and (obj.target == data.get("target", None))):
+#               existing_obj = obj
+
+        if existing_obj:
+            serializer = VTRTenantIdSerializer(existing_obj)
+            headers = self.get_success_headers(serializer.data)
+            return Response( serializer.data, status=status.HTTP_200_OK )
+
+        return super(VTRTenantList, self).post(request, format)
+
+class VTRTenantDetail(XOSRetrieveUpdateDestroyAPIView):
+    serializer_class = VTRTenantIdSerializer
+    queryset = VTRTenant.get_tenant_objects().select_related().all()
+
+    method_kind = "detail"
+    method_name = "truckroll"
+
+
+
+
+
diff --git a/xos/services/ceilometer/models.py b/xos/services/ceilometer/models.py
index d8fb0fa..5285bd7 100644
--- a/xos/services/ceilometer/models.py
+++ b/xos/services/ceilometer/models.py
@@ -88,10 +88,11 @@
         for ns in self.instance.ports.all():
             if "private" in ns.network.name.lower():
                 addresses["private"] = (ns.ip, ns.mac)
-            elif "nat" in ns.network.name.lower():
+            elif ("nat" in ns.network.name.lower()) or ("management" in ns.network.name.lower()):
                 addresses["nat"] = (ns.ip, ns.mac)
-            elif "ceilometer_client_access" in ns.network.labels.lower():
-                addresses["ceilometer"] = (ns.ip, ns.mac)
+            #TODO: Do we need this client_access_network. Revisit in VTN context
+            #elif "ceilometer_client_access" in ns.network.labels.lower():
+            #    addresses["ceilometer"] = (ns.ip, ns.mac)
         return addresses
 
     @property
@@ -165,7 +166,7 @@
 
     @property
     def ceilometer_url(self):
-        if not self.ceilometer_ip:
+        if not self.private_ip:
             return None
         return "http://" + self.private_ip + ":" + str(self.ceilometer_port) + "/"
 
diff --git a/xos/services/cord/rest_examples/add_truckroll.sh b/xos/services/cord/rest_examples/add_truckroll.sh
new file mode 100755
index 0000000..ac092fa
--- /dev/null
+++ b/xos/services/cord/rest_examples/add_truckroll.sh
@@ -0,0 +1,11 @@
+#!/bin/bash
+
+source ./config.sh
+
+TARGET_ID=1
+TEST=ping
+ARGUMENT=128.112.139.30
+
+echo curl "-H \"Accept: application/json; indent=4\" -H \"Content-Type: application/json\" -u $AUTH -X POST -d \"{\\\"target_id\\\": \\\"$TARGET_ID\\\", \\\"test\\\": \\\"$TEST\\\", \\\"argument\\\": \\\"$ARGUMENT\\\"}\" $HOST/xoslib/truckroll/"
+
+curl -H "Accept: application/json; indent=4" -H "Content-Type: application/json" -u $AUTH -X POST -d "{\"target_id\": \"$TARGET_ID\", \"test\": \"$TEST\", \"argument\": \"$ARGUMENT\"}" $HOST/xoslib/truckroll/
diff --git a/xos/services/cord/rest_examples/list_truckrolls.sh b/xos/services/cord/rest_examples/list_truckrolls.sh
new file mode 100755
index 0000000..7aeaa4c
--- /dev/null
+++ b/xos/services/cord/rest_examples/list_truckrolls.sh
@@ -0,0 +1,5 @@
+#!/bin/bash
+
+source ./config.sh
+
+curl -H "Accept: application/json; indent=4" -H "Content-Type: application/json" -u $AUTH $HOST/xoslib/truckroll/  
diff --git a/xos/services/vtr/__init__.py b/xos/services/vtr/__init__.py
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/xos/services/vtr/__init__.py
@@ -0,0 +1 @@
+
diff --git a/xos/services/vtr/admin.py b/xos/services/vtr/admin.py
new file mode 100644
index 0000000..12b48af
--- /dev/null
+++ b/xos/services/vtr/admin.py
@@ -0,0 +1,102 @@
+from django.contrib import admin
+
+from services.cord.models import *
+from django import forms
+from django.utils.safestring import mark_safe
+from django.contrib.auth.admin import UserAdmin
+from django.contrib.admin.widgets import FilteredSelectMultiple
+from django.contrib.auth.forms import ReadOnlyPasswordHashField
+from django.contrib.auth.signals import user_logged_in
+from django.utils import timezone
+from django.contrib.contenttypes import generic
+from suit.widgets import LinkedSelect
+from core.admin import ServiceAppAdmin,SliceInline,ServiceAttrAsTabInline, ReadOnlyAwareAdmin, XOSTabularInline, ServicePrivilegeInline, TenantRootTenantInline, TenantRootPrivilegeInline
+from core.middleware import get_request
+
+from services.vtr.models import *
+from services.cord.models import CordSubscriberRoot
+
+from functools import update_wrapper
+from django.contrib.admin.views.main import ChangeList
+from django.core.urlresolvers import reverse
+from django.contrib.admin.utils import quote
+
+class VTRServiceAdmin(ReadOnlyAwareAdmin):
+    model = VTRService
+    verbose_name = "vTR Service"
+    verbose_name_plural = "vTR Service"
+    list_display = ("backend_status_icon", "name", "enabled")
+    list_display_links = ('backend_status_icon', 'name', )
+    fieldsets = [(None, {'fields': ['backend_status_text', 'name','enabled','versionNumber', 'description',"view_url","icon_url" ], 'classes':['suit-tab suit-tab-general']})]
+    readonly_fields = ('backend_status_text', )
+    inlines = [SliceInline,ServiceAttrAsTabInline,ServicePrivilegeInline]
+
+    extracontext_registered_admins = True
+
+    user_readonly_fields = ["name", "enabled", "versionNumber", "description"]
+
+    suit_form_tabs =(('general', 'vTR Service Details'),
+        ('administration', 'Administration'),
+        ('slices','Slices'),
+        ('serviceattrs','Additional Attributes'),
+        ('serviceprivileges','Privileges'),
+    )
+
+    suit_form_includes = (('vtradmin.html', 'top', 'administration'),
+                           ) #('hpctools.html', 'top', 'tools') )
+
+    def queryset(self, request):
+        return VTRService.get_service_objects_by_user(request.user)
+
+class VTRTenantForm(forms.ModelForm):
+    simple_attributes = {"test": None,
+                         "argument": None,
+                         "result": None,
+                         "target": None}
+    test = forms.ChoiceField(choices=VTRTenant.TEST_CHOICES, required=True)
+    argument = forms.CharField(required=False)
+    result = forms.CharField(required=False, widget=forms.Textarea(attrs={'rows': 10, 'cols': 80, 'class': 'input-xxlarge'}))
+    target = forms.ModelChoiceField(queryset=CordSubscriberRoot.objects.all())
+
+    def __init__(self,*args,**kwargs):
+        super (VTRTenantForm,self ).__init__(*args,**kwargs)
+        self.fields['provider_service'].queryset = VTRService.get_service_objects().all()
+        if self.instance:
+            # fields for the attributes
+            self.fields['test'].initial = self.instance.test
+            self.fields['argument'].initial = self.instance.argument
+            self.fields['target'].initial = self.instance.target
+            self.fields['result'].initial = self.instance.result
+        if (not self.instance) or (not self.instance.pk):
+            # default fields for an 'add' form
+            self.fields['kind'].initial = VTR_KIND
+            if VTRService.get_service_objects().exists():
+               self.fields["provider_service"].initial = VTRService.get_service_objects().all()[0]
+
+    def save(self, commit=True):
+        self.instance.test = self.cleaned_data.get("test")
+        self.instance.argument = self.cleaned_data.get("argument")
+        self.instance.target = self.cleaned_data.get("target")
+        self.instance.result = self.cleaned_data.get("result")
+        return super(VTRTenantForm, self).save(commit=commit)
+
+    class Meta:
+        model = VTRTenant
+
+class VTRTenantAdmin(ReadOnlyAwareAdmin):
+    list_display = ('backend_status_icon', 'id', 'target', 'test', 'argument' )
+    list_display_links = ('backend_status_icon', 'id')
+    fieldsets = [ (None, {'fields': ['backend_status_text', 'kind', 'provider_service', # 'subscriber_root', 'service_specific_id', 'service_specific_attribute',
+                                     'target', 'test', 'argument', 'result'],
+                          'classes':['suit-tab suit-tab-general']})]
+    readonly_fields = ('backend_status_text', 'service_specific_attribute')
+    form = VTRTenantForm
+
+    suit_form_tabs = (('general','Details'),)
+
+    def queryset(self, request):
+        return VTRTenant.get_tenant_objects_by_user(request.user)
+
+admin.site.register(VTRService, VTRServiceAdmin)
+admin.site.register(VTRTenant, VTRTenantAdmin)
+
diff --git a/xos/services/vtr/models.py b/xos/services/vtr/models.py
new file mode 100644
index 0000000..1181faf
--- /dev/null
+++ b/xos/services/vtr/models.py
@@ -0,0 +1,86 @@
+from django.db import models
+from core.models import Service, PlCoreBase, Slice, Instance, Tenant, TenantWithContainer, Node, Image, User, Flavor, Subscriber, NetworkParameter, NetworkParameterType, Port, AddressPool
+from core.models.plcorebase import StrippedCharField
+import os
+from django.db import models, transaction
+from django.forms.models import model_to_dict
+from django.db.models import Q
+from operator import itemgetter, attrgetter, methodcaller
+from core.models import Tag
+from core.models.service import LeastLoadedNodeScheduler
+from services.cord.models import CordSubscriberRoot
+import traceback
+from xos.exceptions import *
+from xos.config import Config
+
+class ConfigurationError(Exception):
+    pass
+
+VTR_KIND = "vTR"
+
+CORD_USE_VTN = getattr(Config(), "networking_use_vtn", False)
+
+# -------------------------------------------
+# VOLT
+# -------------------------------------------
+
+class VTRService(Service):
+    KIND = VTR_KIND
+
+    class Meta:
+        app_label = "vtr"
+        verbose_name = "vTR Service"
+        proxy = True
+
+class VTRTenant(Tenant):
+    class Meta:
+        proxy = True
+
+    KIND = VTR_KIND
+
+    TEST_CHOICES = ( ("ping", "Ping"), ("traceroute", "Trace Route"), ("tcpdump", "Tcp Dump") )
+
+    simple_attributes = ( ("test", None),
+                          ("argument", None),
+                          ("result", None),
+                          ("target_id", None) )
+
+    sync_attributes = ( 'test', 'argument' )
+
+    def __init__(self, *args, **kwargs):
+        vtr_services = VTRService.get_service_objects().all()
+        if vtr_services:
+            self._meta.get_field("provider_service").default = vtr_services[0].id
+        super(VTRTenant, self).__init__(*args, **kwargs)
+
+    @property
+    def target(self):
+        if getattr(self, "cached_target", None):
+            return self.cached_target
+        target_id=self.target_id
+        if not target_id:
+            return None
+        users=CordSubscriberRoot.objects.filter(id=target_id)
+        if not users:
+            return None
+        user=users[0]
+        self.cached_target = users[0]
+        return user
+
+    @target.setter
+    def target(self, value):
+        if value:
+            value = value.id
+        if (value != self.get_attribute("target_id", None)):
+            self.cached_target=None
+        self.target_id = value
+
+    def save(self, *args, **kwargs):
+        super(VTRTenant, self).save(*args, **kwargs)
+
+    def delete(self, *args, **kwargs):
+        super(VTRTenant, self).delete(*args, **kwargs)
+
+
+VTRTenant.setup_simple_attributes()
+
diff --git a/xos/services/vtr/templates/vtradmin.html b/xos/services/vtr/templates/vtradmin.html
new file mode 100644
index 0000000..e8a33bc
--- /dev/null
+++ b/xos/services/vtr/templates/vtradmin.html
@@ -0,0 +1,6 @@
+<div class = "row text-center">
+    <div class="col-xs-12">
+        <a href="/admin/vtr/vtrtenant/">vTR Tenants</a>
+    </div>
+</div>
+
diff --git a/xos/synchronizers/vtr/files/run_tcpdump.sh b/xos/synchronizers/vtr/files/run_tcpdump.sh
new file mode 100644
index 0000000..ed75bf0
--- /dev/null
+++ b/xos/synchronizers/vtr/files/run_tcpdump.sh
@@ -0,0 +1,9 @@
+#! /bin/bash
+INTERFACE=$1
+tcpdump -n -e -i $INTERFACE -c 100 &
+PID_TCPDUMP=$!
+curl http://www.xosproject.org/ &> /dev/null &
+PID_CURL=$!
+sleep 30s
+kill $PID_TCPDUMP
+kill $PIUD_CURL
diff --git a/xos/synchronizers/vtr/model-deps b/xos/synchronizers/vtr/model-deps
new file mode 100644
index 0000000..0967ef4
--- /dev/null
+++ b/xos/synchronizers/vtr/model-deps
@@ -0,0 +1 @@
+{}
diff --git a/xos/synchronizers/vtr/run-vtn.sh b/xos/synchronizers/vtr/run-vtn.sh
new file mode 100755
index 0000000..b2f9518
--- /dev/null
+++ b/xos/synchronizers/vtr/run-vtn.sh
@@ -0,0 +1,4 @@
+export XOS_DIR=/opt/xos
+cp /root/setup/node_key $XOS_DIR/synchronizers/vtr/node_key
+chmod 0600 $XOS_DIR/synchronizers/vtr/node_key
+python vtr-synchronizer.py  -C $XOS_DIR/synchronizers/vtr/vtn_vtr_synchronizer_config
diff --git a/xos/synchronizers/vtr/run.sh b/xos/synchronizers/vtr/run.sh
new file mode 100755
index 0000000..388fdf9
--- /dev/null
+++ b/xos/synchronizers/vtr/run.sh
@@ -0,0 +1,2 @@
+export XOS_DIR=/opt/xos
+python vtr-synchronizer.py  -C $XOS_DIR/synchronizers/vtr/vtr_synchronizer_config
diff --git a/xos/synchronizers/vtr/steps/sync_vtrtenant.py b/xos/synchronizers/vtr/steps/sync_vtrtenant.py
new file mode 100644
index 0000000..bf07d4a
--- /dev/null
+++ b/xos/synchronizers/vtr/steps/sync_vtrtenant.py
@@ -0,0 +1,150 @@
+import os
+import socket
+import sys
+import base64
+import time
+from django.db.models import F, Q
+from xos.config import Config
+from synchronizers.base.syncstep import SyncStep
+from synchronizers.base.ansible import run_template_ssh
+from synchronizers.base.SyncInstanceUsingAnsible import SyncInstanceUsingAnsible
+from core.models import Service, Slice, Tag
+from services.cord.models import VSGService, VSGTenant, VOLTTenant, CordSubscriberRoot
+from services.vtr.models import VTRService, VTRTenant
+from services.hpc.models import HpcService, CDNPrefix
+from xos.logger import Logger, logging
+
+# hpclibrary will be in steps/..
+parentdir = os.path.join(os.path.dirname(__file__),"..")
+sys.path.insert(0,parentdir)
+
+logger = Logger(level=logging.INFO)
+
+CORD_USE_VTN = getattr(Config(), "networking_use_vtn", False)
+
+class SyncVTRTenant(SyncInstanceUsingAnsible):
+    provides=[VTRTenant]
+    observes=VTRTenant
+    requested_interval=0
+    template_name = "sync_vtrtenant.yaml"
+    service_key_name = "/opt/xos/synchronizers/vtr/vcpe_private_key"
+
+    def __init__(self, *args, **kwargs):
+        super(SyncVTRTenant, self).__init__(*args, **kwargs)
+
+    def fetch_pending(self, deleted):
+        if (not deleted):
+            objs = VTRTenant.get_tenant_objects().filter(Q(enacted__lt=F('updated')) | Q(enacted=None),Q(lazy_blocked=False))
+        else:
+            objs = VTRTenant.get_deleted_tenant_objects()
+
+        return objs
+
+    def get_vtr_service(self, o):
+        if not o.provider_service:
+            return None
+
+        vtrs = VTRService.get_service_objects().filter(id=o.provider_service.id)
+        if not vtrs:
+            return None
+
+        return vtrs[0]
+
+    def get_vcpe_service(self, o):
+        if o.target:
+            # o.target is a CordSubscriberRoot
+            if o.target.volt and o.target.volt.vcpe:
+                vcpes = VSGService.get_service_objects().filter(id=o.target.volt.vcpe.provider_service.id)
+                if not vcpes:
+                    return None
+                return vcpes[0]
+        return None
+
+    def get_instance(self, o):
+        if o.target and o.target.volt and o.target.volt.vcpe:
+            return o.target.volt.vcpe.instance
+        else:
+            return None
+
+    def get_extra_attributes(self, o):
+        vtr_service = self.get_vtr_service(o)
+        vcpe_service = self.get_vcpe_service(o)
+
+        if not vcpe_service:
+            raise Exception("No vcpeservice")
+
+        instance = self.get_instance(o)
+
+        if not instance:
+            raise Exception("No instance")
+
+        s_tags = []
+        c_tags = []
+        if o.target and o.target.volt:
+            s_tags.append(o.target.volt.s_tag)
+            c_tags.append(o.target.volt.c_tag)
+
+        wan_vm_ip=""
+        wan_vm_mac=""
+        tags = Tag.select_by_content_object(instance).filter(name="vm_wan_addr")
+        if tags:
+            parts=tags[0].value.split(",")
+            if len(parts)!=3:
+                raise Exception("vm_wan_addr tag is malformed: %s" % value)
+            wan_vm_ip = parts[1]
+            wan_vm_mac = parts[2]
+        else:
+            if CORD_USE_VTN:
+                raise Exception("no vm_wan_addr tag for instance %s" % instance)
+
+        fields = {"s_tags": s_tags,
+                "c_tags": c_tags,
+                "isolation": instance.isolation,
+                "wan_container_gateway_mac": vcpe_service.wan_container_gateway_mac,
+                "wan_container_gateway_ip": vcpe_service.wan_container_gateway_ip,
+                "wan_container_netbits": vcpe_service.wan_container_netbits,
+                "wan_vm_mac": wan_vm_mac,
+                "wan_vm_ip": wan_vm_ip,
+                "container_name": "vcpe-%s-%s" % (s_tags[0], c_tags[0]),
+                "dns_servers": [x.strip() for x in vcpe_service.dns_servers.split(",")],
+
+                "result_fn": "%s-vcpe-%s-%s" % (o.test, s_tags[0], c_tags[0]) }
+
+        # add in the sync_attributes that come from the SubscriberRoot object
+
+        if o.target and hasattr(o.target, "sync_attributes"):
+            for attribute_name in o.target.sync_attributes:
+                fields[attribute_name] = getattr(o.target, attribute_name)
+
+        for attribute_name in o.sync_attributes:
+            fields[attribute_name] = getattr(o,attribute_name)
+
+        return fields
+
+    def sync_fields(self, o, fields):
+        # the super causes the playbook to be run
+
+        super(SyncVTRTenant, self).sync_fields(o, fields)
+
+    def run_playbook(self, o, fields):
+        o.result = ""
+
+        result_fn = os.path.join("/opt/xos/synchronizers/vtr/result", fields["result_fn"])
+        if os.path.exists(result_fn):
+            os.remove(result_fn)
+
+        instance = self.get_instance(o)
+        if instance.isolation in ["container", "container_vm"]:
+            super(SyncVTRTenant, self).run_playbook(o, fields, "sync_vtrtenant_new.yaml")
+        else:
+            if CORD_USE_VTN:
+                super(SyncVTRTenant, self).run_playbook(o, fields, template_name="sync_vtrtenant_vtn.yaml")
+            else:
+                super(SyncVTRTenant, self).run_playbook(o, fields)
+
+        if os.path.exists(result_fn):
+            o.result = open(result_fn).read()
+
+
+    def delete_record(self, m):
+        pass
diff --git a/xos/synchronizers/vtr/steps/sync_vtrtenant.yaml b/xos/synchronizers/vtr/steps/sync_vtrtenant.yaml
new file mode 100644
index 0000000..ddcfa57
--- /dev/null
+++ b/xos/synchronizers/vtr/steps/sync_vtrtenant.yaml
@@ -0,0 +1,90 @@
+---
+- hosts: {{ instance_name }}
+  #gather_facts: False
+  connection: ssh
+  user: ubuntu
+  sudo: yes
+  vars:
+      container_name: {{ container_name }}
+      wan_container_ip: {{ wan_container_ip }}
+      wan_container_netbits: {{ wan_container_netbits }}
+      wan_container_mac: {{ wan_container_mac }}
+      wan_container_gateway_ip: {{ wan_container_gateway_ip }}
+      wan_vm_ip: {{ wan_vm_ip }}
+      wan_vm_mac: {{ wan_vm_mac }}
+
+      scope: vm
+      test: {{ test }}
+      argument: {{ argument }}
+      result_file: {{ result_fn }}
+
+
+  tasks:
+  - name: Remove any old result file
+    shell: rm -f /tmp/{{ result_fn }}
+
+  - name: Copy run_tcpdump.sh to VM
+    copy: src=/opt/xos/synchronizers/vtr/files/run_tcpdump.sh dest=/root/run_tcpdump.sh mode=0755
+    when: (test=="tcpdump")
+
+
+# -----------------
+# scope == VM
+# -----------------
+
+  - name: Send the pings from VM
+    shell: ping -c 10 {{ argument }} 2>&1 > /tmp/{{ result_fn }}
+    ignore_errors: yes
+    when: (scope=="vm") and (test=="ping")
+
+  - name: Install traceroute
+    apt: name=traceroute state=present
+    when: (scope=="vm") and (test=="traceroute")
+
+  - name: Send traceroute from VM
+    shell: traceroute {{ argument }} 2>&1 > /tmp/{{ result_fn }}
+    ignore_errors: yes
+    when: (scope=="vm") and (test=="traceroute")
+
+  - name: Run tcpdump for 30 seconds on VM
+    shell: /root/run_tcpdump.sh {{ argument }} 2>&1 > /tmp/{{ result_fn }}
+    ignore_errors: yes
+    when: (scope=="vm") and (test=="tcpdump")
+
+# ------------------
+# scope == container
+# ------------------
+
+  - name: Send the pings from Container
+    shell: docker exec {{ container_name }} ping -c 10 {{ argument }} 2>&1 > /tmp/{{ result_fn }}
+    ignore_errors: yes
+    when: (scope=="container") and (test=="ping")
+
+  - name: Install traceroute into Container
+    shell: docker exec {{ container_name }} apt-get -y install traceroute
+    when: (scope=="container") and (test=="traceroute")
+
+  - name: Send traceroute from Container
+    shell: docker exec {{ container_name }} traceroute {{ argument }} 2>&1 > /tmp/{{ result_fn }}
+    ignore_errors: yes
+    when: (scope=="container") and (test=="traceroute")
+
+  - name: Copy run_tcpdump.sh to container
+    command: docker cp /root/run_tcpdump.sh {{ container_name }}:/root/run_tcpdump.sh
+    when: (scope=="container") and (test=="tcpdump")
+
+  - name: Run tcpdump for 30 seconds from Container
+    shell: docker exec {{ container_name }} /root/run_tcpdump.sh {{ argument }} 2>&1 > /tmp/{{ result_fn }}
+    ignore_errors: yes
+    when: (scope=="container") and (test=="tcpdump")
+
+# ------------------
+# scope == *
+# ------------------
+
+  - name: Fetch the result
+    fetch: src=/tmp/{{ result_fn }} dest=/opt/xos/synchronizers/vtr/result/{{ result_fn }} flat=yes
+
+
+
+
diff --git a/xos/synchronizers/vtr/steps/sync_vtrtenant_vtn.yaml b/xos/synchronizers/vtr/steps/sync_vtrtenant_vtn.yaml
new file mode 100644
index 0000000..d2e6ef7
--- /dev/null
+++ b/xos/synchronizers/vtr/steps/sync_vtrtenant_vtn.yaml
@@ -0,0 +1,30 @@
+---
+- hosts: {{ instance_name }}
+  #gather_facts: False
+  connection: ssh
+  user: ubuntu
+  sudo: yes
+  vars:
+      container_name: {{ container_name }}
+      wan_container_ip: {{ wan_container_ip }}
+      wan_container_netbits: {{ wan_container_netbits }}
+      wan_container_mac: {{ wan_container_mac }}
+      wan_container_gateway_ip: {{ wan_container_gateway_ip }}
+      wan_vm_ip: {{ wan_vm_ip }}
+      wan_vm_mac: {{ wan_vm_mac }}
+
+      test: {{ test }}
+      argument: {{ argument }}
+      result_file: {{ result_fn }}
+
+
+  tasks:
+{% if test=="ping" %}
+  - name: Send the pings
+    shell: rm -f /tmp/{{ result_fn }}
+    shell: ping -c 10 {{ argument }} > /tmp/{{ result_fn }}
+
+  - name: Fetch the ping result
+    fetch: src=/tmp/{{ result_fn }} dest=/opt/xos/synchronizers/vtr/result/{{ result_fn }} flat=yes
+{% endif %}
+
diff --git a/xos/synchronizers/vtr/vtn_vtr_synchronizer_config b/xos/synchronizers/vtr/vtn_vtr_synchronizer_config
new file mode 100644
index 0000000..2c9140a
--- /dev/null
+++ b/xos/synchronizers/vtr/vtn_vtr_synchronizer_config
@@ -0,0 +1,47 @@
+
+[plc]
+name=plc
+deployment=VICCI
+
+[db]
+name=xos
+user=postgres
+password=password
+host=localhost
+port=5432
+
+[api]
+host=128.112.171.237
+port=8000
+ssl_key=None
+ssl_cert=None
+ca_ssl_cert=None
+ratelimit_enabled=0
+omf_enabled=0
+mail_support_address=support@localhost
+nova_enabled=True
+
+[observer]
+name=vtr
+dependency_graph=/opt/xos/synchronizers/vtr/model-deps
+steps_dir=/opt/xos/synchronizers/vtr/steps
+sys_dir=/opt/xos/synchronizers/vtr/sys
+deleters_dir=/opt/xos/synchronizers/vtr/deleters
+log_file=console
+#/var/log/hpc.log
+driver=None
+pretend=False
+backoff_disabled=True
+save_ansible_output=True
+# set proxy_ssh to false on cloudlab
+full_setup=True
+proxy_ssh=True
+proxy_ssh_key=/opt/xos/synchronizers/vtr/node_key
+proxy_ssh_user=root
+
+[networking]
+use_vtn=True
+
+[feefie]
+client_id='vicci_dev_central'
+user_id='pl'
diff --git a/xos/synchronizers/vtr/vtr-synchronizer.py b/xos/synchronizers/vtr/vtr-synchronizer.py
new file mode 100755
index 0000000..84bec4f
--- /dev/null
+++ b/xos/synchronizers/vtr/vtr-synchronizer.py
@@ -0,0 +1,11 @@
+#!/usr/bin/env python
+
+# This imports and runs ../../xos-observer.py
+
+import importlib
+import os
+import sys
+observer_path = os.path.join(os.path.dirname(os.path.realpath(__file__)),"../../synchronizers/base")
+sys.path.append(observer_path)
+mod = importlib.import_module("xos-synchronizer")
+mod.main()
diff --git a/xos/synchronizers/vtr/vtr_synchronizer_config b/xos/synchronizers/vtr/vtr_synchronizer_config
new file mode 100644
index 0000000..51bf25a
--- /dev/null
+++ b/xos/synchronizers/vtr/vtr_synchronizer_config
@@ -0,0 +1,41 @@
+
+[plc]
+name=plc
+deployment=VICCI
+
+[db]
+name=xos
+user=postgres
+password=password
+host=localhost
+port=5432
+
+[api]
+host=128.112.171.237
+port=8000
+ssl_key=None
+ssl_cert=None
+ca_ssl_cert=None
+ratelimit_enabled=0
+omf_enabled=0
+mail_support_address=support@localhost
+nova_enabled=True
+
+[observer]
+name=vtr
+dependency_graph=/opt/xos/synchronizers/vtr/model-deps
+steps_dir=/opt/xos/synchronizers/vtr/steps
+sys_dir=/opt/xos/synchronizers/vtr/sys
+deleters_dir=/opt/xos/synchronizers/vtr/deleters
+log_file=console
+driver=None
+pretend=False
+backoff_disabled=True
+save_ansible_output=True
+# set proxy_ssh to false on cloudlab
+proxy_ssh=False
+full_setup=True
+
+[feefie]
+client_id='vicci_dev_central'
+user_id='pl'
diff --git a/xos/tools/xos-manage b/xos/tools/xos-manage
index 4783bf5..5410f37 100755
--- a/xos/tools/xos-manage
+++ b/xos/tools/xos-manage
@@ -146,6 +146,7 @@
     python ./manage.py makemigrations ceilometer
     python ./manage.py makemigrations helloworldservice_complete
     python ./manage.py makemigrations onos
+    python ./manage.py makemigrations vtr
     #python ./manage.py makemigrations servcomp
 }
 
diff --git a/xos/tosca/README.md b/xos/tosca/README.md
index 98f0aaf..b0a654a 100644
--- a/xos/tosca/README.md
+++ b/xos/tosca/README.md
@@ -6,8 +6,8 @@
 as follows:
 
  * custom_types -- Defines schema for XOS-specific models.
-   * `.m4` files are source.
-   * `.yaml` files are generated.
+   * `.m4` source files
+   * `.yaml` generated files
  * definitions -- Defines schema for TOSCA's base models.
- * resources -- Translates TOSCA specification to Django API.
- * sample -- Example TOSCA models.
+ * resources -- Translates TOSCA to Django API.
+ * sample -- Example TOSCA specifications.
diff --git a/xos/tosca/custom_types/xos.m4 b/xos/tosca/custom_types/xos.m4
index 9773822..bb919e2 100644
--- a/xos/tosca/custom_types/xos.m4
+++ b/xos/tosca/custom_types/xos.m4
@@ -866,6 +866,9 @@
         derived_from: tosca.relationships.Root
         valid_target_types: [ tosca.capabilities.xos.NodeLabel ]
 
+    tosca.relationships.DependsOn:
+        derived_from: tosca.relationships.Root
+
     tosca.capabilities.xos.Service:
         derived_from: tosca.capabilities.Root
         description: An XOS Service
diff --git a/xos/tosca/custom_types/xos.yaml b/xos/tosca/custom_types/xos.yaml
index 21e8b8b..530e534 100644
--- a/xos/tosca/custom_types/xos.yaml
+++ b/xos/tosca/custom_types/xos.yaml
@@ -1178,6 +1178,9 @@
         derived_from: tosca.relationships.Root
         valid_target_types: [ tosca.capabilities.xos.NodeLabel ]
 
+    tosca.relationships.DependsOn:
+        derived_from: tosca.relationships.Root
+
     tosca.capabilities.xos.Service:
         derived_from: tosca.capabilities.Root
         description: An XOS Service
diff --git a/xos/xos/settings.py b/xos/xos/settings.py
index 8764b80..5c6c0cb 100644
--- a/xos/xos/settings.py
+++ b/xos/xos/settings.py
@@ -180,6 +180,7 @@
     'services.ceilometer',
     'services.requestrouter',
     'services.syndicate_storage',
+    'services.vtr',
     'geoposition',
     'rest_framework_swagger',
 )