Merge pull request #115 from teone/master

JS Styleguide and Unit tests on XOSlib
diff --git a/Dockerfile b/Dockerfile
index 5d945a9..b69b7fd 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,4 +1,4 @@
-FROM       ubuntu:14.04.2
+FROM       ubuntu:14.04.3
 MAINTAINER Andy Bavier <acb@cs.princeton.edu>
 
 # XXX Workaround for docker bug:
diff --git a/xos/configurations/common/Makefile.cloudlab b/xos/configurations/common/Makefile.cloudlab
index 5712765..cf3d731 100644
--- a/xos/configurations/common/Makefile.cloudlab
+++ b/xos/configurations/common/Makefile.cloudlab
@@ -1,3 +1,6 @@
+MYFLATLANIF:=$(shell netstat -i |grep "flat"|awk '{print $$1}' )
+MYFLATLANIP:=$(shell ifconfig $(MYFLATLANIF) | grep "inet addr" | awk -F: '{print $$2}' | awk '{print $$1}' )
+
 all: prereqs admin-openrc flat_name nodes_yaml public_key private_key
 
 prereqs:
@@ -5,6 +8,8 @@
 
 admin-openrc:
 	sudo cat /root/setup/admin-openrc.sh > admin-openrc.sh
+	sudo cat /root/setup/settings > controller_settings
+	echo 'CONTROLLER_FLAT_LAN_IP=$(MYFLATLANIP)' >> controller_settings
 
 flat_name:
 	sudo bash -c "source /root/setup/admin-openrc.sh ; neutron net-list" |grep flat|awk '{printf "%s",$$4}' > flat_net_name
diff --git a/xos/configurations/common/cloudlab.yaml b/xos/configurations/common/cloudlab.yaml
index 807d931..a0beeeb 100644
--- a/xos/configurations/common/cloudlab.yaml
+++ b/xos/configurations/common/cloudlab.yaml
@@ -42,9 +42,13 @@
           admin_user: { get_script_env: [ SELF, adminrc, OS_USERNAME, LOCAL_FILE] }
           admin_password: { get_script_env: [ SELF, adminrc, OS_PASSWORD, LOCAL_FILE] }
           admin_tenant: { get_script_env: [ SELF, adminrc, OS_TENANT_NAME, LOCAL_FILE] }
+          rabbit_user: { get_script_env: [ SELF, controller_settings, RABBIT_USER, LOCAL_FILE] }
+          rabbit_password: { get_script_env: [ SELF, controller_settings, RABBIT_PASS, LOCAL_FILE] }
+          rabbit_host: { get_script_env: [ SELF, controller_settings, CONTROLLER_FLAT_LAN_IP, LOCAL_FILE] }
           domain: Default
       artifacts:
           adminrc: /root/setup/admin-openrc.sh
+          controller_settings: /root/setup/controller_settings
 
     mysite:
       type: tosca.nodes.Site
diff --git a/xos/configurations/cord/Dockerfile.cord b/xos/configurations/cord/Dockerfile.cord
index a21c7d0..f4be3b2 100644
--- a/xos/configurations/cord/Dockerfile.cord
+++ b/xos/configurations/cord/Dockerfile.cord
@@ -1,16 +1,21 @@
 RUN mkdir -p /root/setup
 ADD xos/configurations/common/admin-openrc.sh /root/setup/
+ADD xos/configurations/common/controller_settings /root/setup/
 ADD xos/configurations/common/flat_net_name /root/setup/
 ADD xos/configurations/common/cloudlab-nodes.yaml /opt/xos/configurations/commmon/
 ADD xos/configurations/common/id_rsa.pub /root/setup/padmin_public_key
 ADD xos/configurations/common/id_rsa.pub /opt/xos/observers/vcpe/vcpe_public_key
 ADD xos/configurations/common/id_rsa /opt/xos/observers/vcpe/vcpe_private_key
+ADD xos/configurations/common/id_rsa.pub /opt/xos/observers/monitoring_channel/monitoring_channel_public_key
+ADD xos/configurations/common/id_rsa /opt/xos/observers/monitoring_channel/monitoring_channel_private_key
 ADD xos/configurations/common/id_rsa.pub /opt/xos/observers/onos/onos_key.pub
 ADD xos/configurations/common/id_rsa /opt/xos/observers/onos/onos_key
 ADD xos/observers/vcpe/supervisor/vcpe-observer.conf /etc/supervisor/conf.d/
 ADD xos/observers/vbng/supervisor/vbng-observer.conf /etc/supervisor/conf.d/
 ADD xos/observers/onos/supervisor/onos-observer.conf /etc/supervisor/conf.d/
+ADD xos/observers/monitoring_channel/supervisor/monitoring_channel_observer.conf /etc/supervisor/conf.d/
 RUN sed -i 's/proxy_ssh=True/proxy_ssh=False/' /opt/xos/observers/vcpe/vcpe_observer_config
+RUN sed -i 's/proxy_ssh=True/proxy_ssh=False/' /opt/xos/observers/monitoring_channel/monitoring_channel_observer_config
 
 CMD /usr/bin/make -C /opt/xos/configurations/cord -f Makefile.inside; /bin/bash
 
diff --git a/xos/configurations/cord/Makefile.inside b/xos/configurations/cord/Makefile.inside
index a4bb5f1..c412f25 100644
--- a/xos/configurations/cord/Makefile.inside
+++ b/xos/configurations/cord/Makefile.inside
@@ -5,6 +5,7 @@
 	python /opt/xos/tosca/run.py padmin@vicci.org /opt/xos/configurations/common/cloudlab.yaml
 	python /opt/xos/tosca/run.py padmin@vicci.org /opt/xos/configurations/common/cloudlab-nodes.yaml
 	python /opt/xos/tosca/run.py padmin@vicci.org /opt/xos/configurations/cord/cord.yaml
+	python /opt/xos/tosca/run.py padmin@vicci.org /opt/xos/configurations/cord/ceilometer.yaml
 
 run_develserver:
 	cd /opt/xos; python manage.py runserver 0.0.0.0:8000 --insecure
diff --git a/xos/configurations/cord/ceilometer.yaml b/xos/configurations/cord/ceilometer.yaml
new file mode 100644
index 0000000..b660ba1
--- /dev/null
+++ b/xos/configurations/cord/ceilometer.yaml
@@ -0,0 +1,78 @@
+tosca_definitions_version: tosca_simple_yaml_1_0
+
+description: Setup CORD-related services -- vOLT, vCPE, vBNG.
+
+imports:
+   - custom_types/xos.yaml
+
+topology_template:
+  node_templates:
+    service_ceilometer:
+      type: tosca.nodes.Service
+      requirements:
+      properties:
+          view_url: /admin/ceilometer/ceilometerservice/$id$/
+          kind: ceilometer
+#          public_key: { get_artifact: [ SELF, pubkey, LOCAL_FILE] }
+#      artifacts:
+#          pubkey: /opt/xos/observers/vcpe/vcpe_public_key
+
+
+    Private:
+      type: tosca.nodes.NetworkTemplate
+
+    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
+
+    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
+
+    Ceilometer:
+      type: tosca.nodes.DashboardView
+      properties:
+          url: http:/xosmetering/
+
+    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
\ No newline at end of file
diff --git a/xos/configurations/cord/cord.yaml b/xos/configurations/cord/cord.yaml
index c66f7bc..e9a6291 100644
--- a/xos/configurations/cord/cord.yaml
+++ b/xos/configurations/cord/cord.yaml
@@ -50,6 +50,15 @@
       artifacts:
           pubkey: /opt/xos/observers/onos/onos_key.pub
 
+#
+# To actually bring up the vBNG app
+# - Set up the dataplane using the ansible script
+# - Log into the vBNG ONOS and run 'devices' to get switch dpID
+# - Change the dpID values in vBNG ONOS app in XOS GUI
+# - (Synchronizer should copy the files to ONOS container immediately)
+# - Log into service_ONOS_vBNG VM and restart ONOS Docker container
+#   (Should roll this step into a Synchronizer)
+#
     vBNG_ONOS_app:
       type: tosca.nodes.ONOSvBNGApp
       requirements:
@@ -64,7 +73,7 @@
           config_network-cfg.json: >
             {
               "ports" : {
-                "of:00000000000000a1/1" : {
+                "of:0000000000000001/1" : {
                   "interfaces" : [
                     {
                       "ips"  : [ "10.0.1.253/24" ],
@@ -72,10 +81,10 @@
                     }
                   ]
                 },
-                "of:00000000000000a5/2" : {
+                "of:0000000000000001/2" : {
                   "interfaces" : [
                     {
-                      "ips"  : [ "10.254.0.1/24" ],
+                      "ips"  : [ "10.254.0.2/24" ],
                       "mac"  : "00:00:00:00:00:98"
                     }
                   ]
@@ -90,7 +99,11 @@
                 "nextHopIpAddress" : "10.254.0.1",
                 "publicFacingMac" : "00:00:00:00:00:66",
                 "xosIpAddress" : "10.11.10.1",
-                "xosRestPort" : "9999"
+                "xosRestPort" : "9999",
+                "hosts" : {
+                    "cp-1.devel.xos-pg0.clemson.cloudlab.us" : "of:0000000000000001/1",
+                    "cp-2.devel.xos-pg0.clemson.cloudlab.us" : "of:0000000000000001/1"
+                }
             }
 
     service_ONOS_vOLT:
diff --git a/xos/configurations/cord/dataplane/ansible.cfg b/xos/configurations/cord/dataplane/ansible.cfg
new file mode 100644
index 0000000..9100590
--- /dev/null
+++ b/xos/configurations/cord/dataplane/ansible.cfg
@@ -0,0 +1,4 @@
+[defaults]
+remote_user = ubuntu
+private_key_file = ~/.ssh/id_rsa
+host_key_checking = false
\ No newline at end of file
diff --git a/xos/configurations/cord/dataplane/dataplane.yaml b/xos/configurations/cord/dataplane/dataplane.yaml
new file mode 100644
index 0000000..d74246d
--- /dev/null
+++ b/xos/configurations/cord/dataplane/dataplane.yaml
@@ -0,0 +1,96 @@
+---
+- hosts: switch_vbng
+  sudo: yes
+  vars:
+    controller_ip: "{{ hostvars['onos_vbng']['ansible_ssh_host'] }}"
+    controller_port: 6653
+  tags:
+  - vbng
+  tasks:
+  - name: Fix /etc/hosts
+    lineinfile:
+      dest=/etc/hosts
+      regexp="127.0.0.1 localhost"
+      line="127.0.0.1 localhost {{ ansible_hostname }}"
+
+  - name: Install packages
+    apt: name={{ item }}
+      state=latest
+      update_cache=yes
+    with_items:
+    - openvswitch-switch
+    - python-netifaces
+
+  - name: Create br-vbng
+    openvswitch_bridge:
+      bridge=br-vbng
+      state=present
+
+  - name: Find wan_network interface
+    script: scripts/if_from_ip.py {{ wan_ip }}
+    register: wan_net
+
+  - name: Find public_network interface
+    script: scripts/if_from_ip.py {{ public_ip }}
+    register: public_net
+
+  - name: Hook up wan-network to br-vbng
+    openvswitch_port:
+      bridge=br-vbng
+      port={{ wan_net.stdout }}
+      state=present
+
+  - name: Hook up public-network to OvS
+    openvswitch_port:
+      bridge=br-vbng
+      port={{ public_net.stdout }}
+      state=present
+
+  - name: Add controller to switch
+    command: /usr/bin/ovs-vsctl set-controller br-vbng tcp:{{ controller_ip }}:{{ controller_port }}
+
+- hosts: switch_volt
+  sudo: yes
+  vars:
+    controller_ip: "{{ hostvars['onos_volt']['ansible_ssh_host'] }}"
+    controller_port: 6653
+  tags:
+  - volt
+  tasks:
+
+  - name: Fix /etc/hosts
+    lineinfile:
+      dest=/etc/hosts
+      regexp="127.0.0.1 localhost"
+      line="127.0.0.1 localhost {{ ansible_hostname }}"
+
+  - name: Install packages
+    apt: name={{ item }} state=present update_cache=yes
+    with_items:
+    - git
+    - python-netifaces
+
+  - name: Checkout the Mininet repo
+    git: repo=https://github.com/mininet/mininet.git
+      dest=/tmp/mininet
+
+  - name: Install the CPqD switch using Mininet install script
+    shell: /tmp/mininet/util/install.sh -3f
+      creates=/usr/local/bin/ofdatapath
+    ignore_errors: true
+
+  - name: Find subscriber_network interface
+    script: scripts/if_from_ip.py {{ subscriber_ip }}
+    register: subscriber_net
+
+  - name: Find lan_network interface
+    script: scripts/if_from_ip.py {{ lan_ip }}
+    register: lan_net
+
+  - name: Run the datapath
+    command: /usr/local/bin/ofdatapath -i {{ subscriber_net.stdout_lines[0] }},{{ lan_net.stdout_lines[0] }} punix:/tmp/s1 -d 000000000001 --no-slicing -D -P
+      creates=/usr/local/var/run/ofdatapath.pid
+
+  - name: Run the control program
+    command: /usr/local/bin/ofprotocol unix:/tmp/s1 tcp:{{ controller_ip }}:{{ controller_port }} --fail=closed --listen=punix:/tmp/s1.listen -D -P
+      creates=/usr/local/var/run/ofprotocol.pid
diff --git a/xos/configurations/cord/dataplane/generate.sh b/xos/configurations/cord/dataplane/generate.sh
new file mode 100755
index 0000000..360ed67
--- /dev/null
+++ b/xos/configurations/cord/dataplane/generate.sh
@@ -0,0 +1,18 @@
+#!/bin/bash
+# set -x
+
+source ~/admin-openrc.sh
+
+get_ip () {
+    LABEL=$1
+    NETWORK=$2
+    nova list --all-tenants|grep $LABEL|sed "s/^.*$NETWORK=//g"|sed 's/; .*$//g'|awk '{print $1}'
+}
+
+cat <<EOF
+onos_vbng    ansible_ssh_host=$( get_ip mysite_onos_vbng flat-lan-1-net)
+switch_vbng  ansible_ssh_host=$( get_ip mysite_vbng flat-lan-1-net) wan_ip=$( get_ip mysite_vbng wan_network) public_ip=$( get_ip mysite_vbng tun0-net )
+
+onos_volt    ansible_ssh_host=$( get_ip mysite_onos_volt flat-lan-1-net)
+switch_volt  ansible_ssh_host=$( get_ip mysite_volt flat-lan-1-net) subscriber_ip=$( get_ip mysite_volt subscriber_network) lan_ip=$( get_ip mysite_volt lan_network) vcpe_lan_ip=$( get_ip mysite_vcpe lan_network)
+EOF
diff --git a/xos/configurations/cord/dataplane/scripts/if_from_ip.py b/xos/configurations/cord/dataplane/scripts/if_from_ip.py
new file mode 100644
index 0000000..be1da48
--- /dev/null
+++ b/xos/configurations/cord/dataplane/scripts/if_from_ip.py
@@ -0,0 +1,14 @@
+#!/usr/bin/python
+
+import sys
+import netifaces
+
+def main (argv):
+    addr = argv[0]
+    for iface in netifaces.interfaces():
+        addrs = netifaces.ifaddresses(iface)
+        if 2 in addrs and addrs[2][0]['addr'] == addr:
+            print iface
+    
+if __name__ == "__main__":
+    main(sys.argv[1:])
diff --git a/xos/configurations/opencloud/Dockerfile b/xos/configurations/opencloud/Dockerfile
index 5a4db61..3f8fc9d 100644
--- a/xos/configurations/opencloud/Dockerfile
+++ b/xos/configurations/opencloud/Dockerfile
@@ -1,9 +1,6 @@
-FROM       ubuntu:14.04.2
+FROM       ubuntu:14.04.3
 MAINTAINER Andy Bavier <acb@cs.princeton.edu>
 
-# Set environment variables.
-ENV HOME /root
-
 # XXX Workaround for docker bug:
 # https://github.com/docker/docker/issues/6345
 # Kernel 3.15 breaks docker, uss the line below as a workaround
@@ -12,87 +9,80 @@
 # XXX End workaround
 
 # Install.
-RUN DEBIAN_FRONTEND=noninteractive apt-get update && apt-get install -y \
-    curl \
+RUN apt-get update && apt-get install -y \
     git \
-    geoip-database \
+    postgresql \
+    python-psycopg2 \
     graphviz \
     graphviz-dev \
-    libgeoip1 \
     libxslt1.1 \
     libxslt1-dev \
-    libyaml-dev \
-    nginx \
-    openssh-client \
-    python-dev \
-    pkg-config \
-    postgresql \
-    python-crypto \
-    python-httplib2>=0.9.1 \
-    python-jinja2 \
-    python-paramiko \
     python-pip \
-    python-psycopg2 \
-    python-pycurl \
-    python-setuptools \
-    python-yaml \
-    python-keystoneclient \
-    python-novaclient \
-    python-neutronclient \
-    python-glanceclient \
-    python-ceilometerclient \
-    supervisor \
     tar \
-    wget 
+    gcc \
+    python-httplib2 \
+    geoip-database \
+    libgeoip1 \
+    wget \
+    curl \
+    python-dev \
+    libyaml-dev \
+    pkg-config \
+    python-pycurl
 
-RUN pip install \
-    django==1.7 \
-    djangorestframework==2.4.4 \
-    markdown  \ 
-    pyyaml \ 
-    django-filter \
-    lxml \
-    netaddr \
-    pytz \
-    django-timezones \
-    requests \
-    django-crispy-forms \
-    django-geoposition \
-    django-extensions \
-    django-suit \
-    django-bitfield \
-    django-ipware \
-    django-encrypted-fields \
-    django_rest_swagger \
-    python-keyczar \
-    pygraphviz \
-    dnslib \
-    uwsgi
+RUN pip install django==1.7
+RUN pip install djangorestframework==2.4.4
+RUN pip install markdown  # Markdown support for the browseable API.
+RUN pip install pyyaml    # YAML content-type support.
+RUN pip install django-filter  # Filtering support
+RUN pip install lxml  # XML manipulation library
+RUN pip install netaddr # IP Addr library
+RUN pip install pytz
+RUN pip install django-timezones
+RUN pip install requests
+RUN pip install django-crispy-forms
+RUN pip install django-geoposition
+RUN pip install django-extensions
+RUN pip install django-suit
+RUN pip install django-bitfield
+RUN pip install django-ipware
+RUN pip install django-encrypted-fields
+RUN pip install python-keyczar
+RUN pip install pygraphviz
+RUN pip install dnslib
 
+RUN DEBIAN_FRONTEND=noninteractive apt-get install -y python-keystoneclient
+RUN DEBIAN_FRONTEND=noninteractive apt-get install -y python-novaclient
+RUN DEBIAN_FRONTEND=noninteractive apt-get install -y python-neutronclient
+RUN DEBIAN_FRONTEND=noninteractive apt-get install -y python-glanceclient
+RUN DEBIAN_FRONTEND=noninteractive apt-get install -y python-ceilometerclient
+
+RUN pip install django_rest_swagger
+
+RUN DEBIAN_FRONTEND=noninteractive apt-get install -y python-setuptools
+RUN easy_install django_evolution
+RUN easy_install python_gflags
 RUN easy_install --upgrade httplib2
-
-RUN easy_install \
-    django_evolution \
-    python_gflags \
-    google_api_python_client \
-    httplib2.ca_certs_locater
-
+RUN easy_install google_api_python_client
+RUN easy_install httplib2.ca_certs_locater
 
 # Install custom Ansible
+RUN DEBIAN_FRONTEND=noninteractive apt-get install -y python-crypto
+RUN DEBIAN_FRONTEND=noninteractive apt-get install -y python-yaml
+RUN DEBIAN_FRONTEND=noninteractive apt-get install -y openssh-client
+RUN DEBIAN_FRONTEND=noninteractive apt-get install -y python-paramiko
+RUN DEBIAN_FRONTEND=noninteractive apt-get install -y python-jinja2
+RUN DEBIAN_FRONTEND=noninteractive apt-get install -y python-httplib2
 RUN git clone -b release1.8.2 git://github.com/ansible/ansible.git /opt/ansible
 RUN git clone -b release1.8.2 git://github.com/ansible/ansible-modules-extras.git /opt/ansible/lib/ansible/modules/extras
 RUN git clone -b release1.8.2 git://github.com/ansible/ansible-modules-extras.git /opt/ansible/v2/ansible/modules/extras
 RUN git clone git://github.com/sb98052/ansible-modules-core.git /opt/ansible/lib/ansible/modules/core
 RUN git clone git://github.com/sb98052/ansible-modules-core.git /opt/ansible/v2/ansible/modules/core
-# git clone uses cached copy, doesn't pick up latest
-RUN git -C /opt/ansible pull
-RUN git -C /opt/ansible/lib/ansible/modules/core pull
-RUN git -C /opt/ansible/v2/ansible/modules/core pull
 ADD ansible-hosts /etc/ansible/hosts
 
+ADD http://code.jquery.com/jquery-1.9.1.min.js /usr/local/lib/python2.7/dist-packages/suit/static/suit/js/
 
 # For Observer
-ADD http://code.jquery.com/jquery-1.9.1.min.js /usr/local/lib/python2.7/dist-packages/suit/static/suit/js/
 RUN git clone git://git.planet-lab.org/fofum.git /tmp/fofum
 RUN cd /tmp/fofum; python setup.py install
 RUN rm -rf /tmp/fofum
@@ -107,8 +97,15 @@
 # Get XOS
 RUN git clone git://github.com/open-cloud/xos.git /tmp/xos && mv /tmp/xos/xos /opt/
 
-RUN chmod +x /opt/xos/scripts/opencloud
+# Supervisor
+RUN DEBIAN_FRONTEND=noninteractive apt-get install -y supervisor
+RUN cp /tmp/xos/observer.conf /etc/supervisor/conf.d/
 
+# Initscript is broken in Ubuntu
+#ADD observer-initscript /etc/init.d/xosobserver
+
+RUN chmod +x /opt/xos/scripts/opencloud
+RUN chmod +x /opt/xos/configurations/opencloud/run_opencloud
 RUN /opt/xos/scripts/opencloud genkeys
 
 # Workaround for AUFS issue
@@ -125,19 +122,23 @@
 # Cruft to workaround problems with migrations, should go away...
 RUN /opt/xos/scripts/opencloud remigrate
 
+# git clone uses cached copy, doesn't pick up latest
+RUN git -C /opt/ansible pull
+RUN git -C /opt/ansible/lib/ansible/modules/core pull
+RUN git -C /opt/ansible/v2/ansible/modules/core pull
 
 # install Tosca engine
 RUN apt-get install -y m4
 RUN pip install python-dateutil
 RUN bash /opt/xos/tosca/install_tosca.sh
 
-# configure nginx
-RUN cp /opt/xos/nginx/xos.conf /etc/nginx/sites-enabled/default
-
-# Supervisor configuration
-RUN cp /opt/xos/configurations/opencloud/supervisord.conf  /etc/supervisor/conf.d/xos-all.conf
-
 EXPOSE 8000
 
+# Set environment variables.
+ENV HOME /root
+
+# Define working directory.
+WORKDIR /root
+
 # Define default command.
-CMD /usr/bin/supervisord -c /etc/supervisor/conf.d/xos-all.conf
+CMD /opt/xos/configurations/opencloud/run_opencloud
diff --git a/xos/configurations/opencloud/Dockerfile.alpha b/xos/configurations/opencloud/Dockerfile.alpha
new file mode 100644
index 0000000..dc4c927
--- /dev/null
+++ b/xos/configurations/opencloud/Dockerfile.alpha
@@ -0,0 +1,143 @@
+FROM       ubuntu:14.04.3
+MAINTAINER Andy Bavier <acb@cs.princeton.edu>
+
+# Set environment variables.
+ENV HOME /root
+
+# XXX Workaround for docker bug:
+# https://github.com/docker/docker/issues/6345
+# Kernel 3.15 breaks docker, uss the line below as a workaround
+# until there is a fix
+RUN ln -s -f /bin/true /usr/bin/chfn
+# XXX End workaround
+
+# Install.
+RUN DEBIAN_FRONTEND=noninteractive apt-get update && apt-get install -y \
+    curl \
+    git \
+    geoip-database \
+    graphviz \
+    graphviz-dev \
+    libgeoip1 \
+    libxslt1.1 \
+    libxslt1-dev \
+    libyaml-dev \
+    m4 \
+    nginx \
+    openssh-client \
+    python-dev \
+    pkg-config \
+    postgresql \
+    python-crypto \
+    python-httplib2>=0.9.1 \
+    python-jinja2 \
+    python-paramiko \
+    python-pip \
+    python-psycopg2 \
+    python-pycurl \
+    python-setuptools \
+    python-yaml \
+    python-keystoneclient \
+    python-novaclient \
+    python-neutronclient \
+    python-glanceclient \
+    python-ceilometerclient \
+    supervisor \
+    tar \
+    wget 
+
+RUN pip install \
+    django==1.7 \
+    djangorestframework==2.4.4 \
+    markdown  \ 
+    pyyaml \ 
+    django-filter \
+    lxml \
+    netaddr \
+    pytz \
+    django-timezones \
+    requests \
+    django-crispy-forms \
+    django-geoposition \
+    django-extensions \
+    django-suit \
+    django-bitfield \
+    django-ipware \
+    django-encrypted-fields \
+    django_rest_swagger \
+    python-dateutil \
+    python-keyczar \
+    pygraphviz \
+    dnslib \
+    uwsgi
+
+RUN easy_install --upgrade httplib2
+
+RUN easy_install \
+    django_evolution \
+    python_gflags \
+    google_api_python_client \
+    httplib2.ca_certs_locater
+
+
+# Install custom Ansible
+RUN git clone -b release1.8.2 git://github.com/ansible/ansible.git /opt/ansible
+RUN git clone -b release1.8.2 git://github.com/ansible/ansible-modules-extras.git /opt/ansible/lib/ansible/modules/extras
+RUN git clone -b release1.8.2 git://github.com/ansible/ansible-modules-extras.git /opt/ansible/v2/ansible/modules/extras
+RUN git clone git://github.com/sb98052/ansible-modules-core.git /opt/ansible/lib/ansible/modules/core
+RUN git clone git://github.com/sb98052/ansible-modules-core.git /opt/ansible/v2/ansible/modules/core
+# git clone uses cached copy, doesn't pick up latest
+RUN git -C /opt/ansible pull
+RUN git -C /opt/ansible/lib/ansible/modules/core pull
+RUN git -C /opt/ansible/v2/ansible/modules/core pull
+ADD ansible-hosts /etc/ansible/hosts
+
+
+# For Observer
+ADD http://code.jquery.com/jquery-1.9.1.min.js /usr/local/lib/python2.7/dist-packages/suit/static/suit/js/
+RUN git clone git://git.planet-lab.org/fofum.git /tmp/fofum
+RUN cd /tmp/fofum; python setup.py install
+RUN rm -rf /tmp/fofum
+
+RUN mkdir -p /usr/local/share /bin
+ADD http://phantomjs.googlecode.com/files/phantomjs-1.7.0-linux-x86_64.tar.bz2 /usr/local/share/
+RUN tar jxvf /usr/local/share/phantomjs-1.7.0-linux-x86_64.tar.bz2 -C /usr/local/share/
+RUN rm -f /usr/local/share/phantomjs-1.7.0-linux-x86_64.tar.bz2
+RUN ln -s /usr/local/share/phantomjs-1.7.0-linux-x86_64 /usr/local/share/phantomjs
+RUN ln -s /usr/local/share/phantomjs/bin/phantomjs /bin/phantomjs
+
+# Get XOS
+RUN git clone git://github.com/open-cloud/xos.git /tmp/xos && mv /tmp/xos/xos /opt/
+
+RUN chmod +x /opt/xos/scripts/opencloud
+
+RUN /opt/xos/scripts/opencloud genkeys
+
+# Workaround for AUFS issue
+# https://github.com/docker/docker/issues/783#issuecomment-56013588
+RUN mkdir /etc/ssl/private-copy; mv /etc/ssl/private/* /etc/ssl/private-copy/; rm -r /etc/ssl/private; mv /etc/ssl/private-copy /etc/ssl/private; chmod -R 0700 /etc/ssl/private; chown -R postgres /etc/ssl/private
+
+# Set postgres password to match default value in settings.py
+RUN service postgresql start && sudo -u postgres psql -c "alter user postgres with password 'password';"
+
+# Turn DEBUG on so that devel server will serve static files
+#    (not necessary if --insecure is passed to 'manage.py runserver')
+# RUN sed -i 's/DEBUG = False/DEBUG = True/' /opt/xos/xos/settings.py
+
+# Cruft to workaround problems with migrations, should go away...
+RUN /opt/xos/scripts/opencloud remigrate
+
+
+# install Tosca engine
+RUN bash /opt/xos/tosca/install_tosca.sh
+
+# configure nginx
+RUN cp /opt/xos/nginx/xos.conf /etc/nginx/sites-enabled/default
+
+# Supervisor configuration
+RUN cp /opt/xos/configurations/opencloud/supervisord.conf  /etc/supervisor/conf.d/xos-all.conf
+
+EXPOSE 8000
+
+# Define default command.
+CMD /usr/bin/supervisord -c /etc/supervisor/conf.d/xos-all.conf
diff --git a/xos/configurations/opencloud/Makefile b/xos/configurations/opencloud/Makefile
index ab88aea..d7708b3 100644
--- a/xos/configurations/opencloud/Makefile
+++ b/xos/configurations/opencloud/Makefile
@@ -1,16 +1,17 @@
-RUNNING_CONTAINER:=$(shell sudo docker ps|grep "opencloud-server"|awk '{print $$NF}')
+CONTAINER_NAME:=opencloud-server
+TOSCA_CONFIG_PATH:=/opt/xos/configurations/opencloud/opencloud.yaml
 
 .PHONY: build
 build: ; docker build --rm -t opencloud .
 
 .PHONY: run
-run: ; docker run --rm  --name opencloud-server opencloud
+run: ; docker run --rm  --name ${CONTAINER_NAME} -p 80:8000 opencloud
 
 .PHONY: runtosca
-runtosca: ; docker exec -it $RUNNING_CONTAINER /usr/bin/python /opt/xos/tosca/run.py padmin@vicci.org $TOSCA_CONFIG_PATH
+runtosca: ; docker exec -it ${CONTAINER_NAME} /usr/bin/python /opt/xos/tosca/run.py padmin@vicci.org ${TOSCA_CONFIG_PATH}
 
 .PHONY: stop
-stop: ; docker stop opencloud-server
+stop: ; docker stop ${CONTAINER_NAME}
 
 .PHONY: rmcontainer
-rmcontainer: ; docker rm opencloud-server
+rmcontainer: ; docker rm ${CONTAINER_NAME}
diff --git a/xos/configurations/opencloud/Makefile.inside b/xos/configurations/opencloud/Makefile.inside
deleted file mode 100644
index 43ad235..0000000
--- a/xos/configurations/opencloud/Makefile.inside
+++ /dev/null
@@ -1,2 +0,0 @@
-run_tosca:
-	python /opt/xos/tosca/run.py padmin@vicci.org opencloud.yaml
diff --git a/xos/configurations/opencloud/opencloud.yaml b/xos/configurations/opencloud/opencloud.yaml
index f6d33a2..15142a6 100644
--- a/xos/configurations/opencloud/opencloud.yaml
+++ b/xos/configurations/opencloud/opencloud.yaml
@@ -1,7 +1,6 @@
 tosca_definitions_version: tosca_simple_yaml_1_0
 
-description: >
-    * Adds OpenCloud Sites, Deployments, and Controllers.
+description: Adds OpenCloud Sites, Deployments, and Controllers.
 
 imports:
    - custom_types/xos.yaml
@@ -188,7 +187,7 @@
           admin_tenant: admin
           domain: Default
 
-   backbone-wdc:
+    backbone-wdc:
       type: tosca.nodes.Controller
       requirements:
           - deployment:
@@ -203,11 +202,26 @@
           admin_tenant: admin
           domain: Default
 
+    campus-arizona:
+      type: tosca.nodes.Controller
+      requirements:
+          - deployment:
+              node: campus
+              relationship: tosca.relationships.ControllerDeployment
+      properties:
+          backend_type: OpenStack
+          version: Juno
+          auth_url: http://localhost:35357/v2.0/
+          admin_user: admin
+          admin_password: admin
+          admin_tenant: admin
+          domain: Default
+
     campus-princeton:
       type: tosca.nodes.Controller
       requirements:
           - deployment:
-              node: backbone
+              node: campus
               relationship: tosca.relationships.ControllerDeployment
       properties:
           backend_type: OpenStack
@@ -222,7 +236,7 @@
       type: tosca.nodes.Controller
       requirements:
           - deployment:
-              node: backbone
+              node: campus
               relationship: tosca.relationships.ControllerDeployment
       properties:
           backend_type: OpenStack
@@ -237,7 +251,7 @@
       type: tosca.nodes.Controller
       requirements:
           - deployment:
-              node: backbone
+              node: campus
               relationship: tosca.relationships.ControllerDeployment
       properties:
           backend_type: OpenStack
@@ -252,7 +266,7 @@
       type: tosca.nodes.Controller
       requirements:
           - deployment:
-              node: backbone
+              node: campus
               relationship: tosca.relationships.ControllerDeployment
       properties:
           backend_type: OpenStack
@@ -267,7 +281,7 @@
       type: tosca.nodes.Controller
       requirements:
           - deployment:
-              node: backbone
+              node: campus
               relationship: tosca.relationships.ControllerDeployment
       properties:
           backend_type: OpenStack
@@ -282,7 +296,7 @@
       type: tosca.nodes.Controller
       requirements:
           - deployment:
-              node: backbone
+              node: campus
               relationship: tosca.relationships.ControllerDeployment
       properties:
           backend_type: OpenStack
@@ -297,7 +311,7 @@
       type: tosca.nodes.Controller
       requirements:
           - deployment:
-              node: backbone
+              node: campus
               relationship: tosca.relationships.ControllerDeployment
       properties:
           backend_type: OpenStack
@@ -363,7 +377,7 @@
                relationship: tosca.relationships.SiteDeployment
                requirements:
                    - controller:
-                       node: backbone-kas
+                       node: backbone-kan
                        relationship: tosca.relationships.UsesController
 
     i2-lax:
@@ -436,7 +450,7 @@
                        node: backbone-sng
                        relationship: tosca.relationships.UsesController
 
-   i2-wdc:
+    i2-wdc:
       type: tosca.nodes.Site
       properties:
           display_name: I2-wdc
@@ -567,7 +581,7 @@
       type: tosca.nodes.User
       requirements:
           - site:
-              node: campus_princeton
+              node: princeton
               relationship: tosca.relationships.MemberOfSite
       properties:
           is_admin: true
diff --git a/xos/configurations/opencloud/run_opencloud b/xos/configurations/opencloud/run_opencloud
new file mode 100644
index 0000000..f37e8c3
--- /dev/null
+++ b/xos/configurations/opencloud/run_opencloud
@@ -0,0 +1,17 @@
+#! /bin/bash
+
+function wait_postgres {
+    sudo -u postgres psql -c '\q'
+    while [[ "$?" != "0" ]]; do
+        echo Waiting for postgres to start
+        sleep 1
+        sudo -u postgres psql -c '\q'
+    done
+}
+
+cd /tmp
+service postgresql start
+wait_postgres
+service supervisor start
+cd /opt/xos
+python manage.py runserver 0.0.0.0:8000 --insecure
diff --git a/xos/configurations/opencloud/supervisord.conf b/xos/configurations/opencloud/supervisord.conf
index 1fe737d..98b4a0a 100644
--- a/xos/configurations/opencloud/supervisord.conf
+++ b/xos/configurations/opencloud/supervisord.conf
@@ -2,6 +2,12 @@
 nodaemon=true
 logfile=/var/log/supervisord.log
 
+[program:postgresql]
+autorestart=true
+command=/usr/lib/postgresql/9.3/bin/postgres -D /var/lib/postgresql/9.3/main -c config_file=/etc/postgresql/9.3/main/postgresql.conf
+stderr_logfile=/var/log/supervisor/postgresql.err.log
+stdout_logfile=/var/log/supervisor/postgresql.out.log
+
 [program:observer]
 autorestart=true
 command=python /opt/xos/xos-observer.py
diff --git a/xos/openstack_observer/steps/sync_container.py b/xos/openstack_observer/steps/sync_container.py
index c6ac936..a5880f0 100644
--- a/xos/openstack_observer/steps/sync_container.py
+++ b/xos/openstack_observer/steps/sync_container.py
@@ -41,14 +41,45 @@
     def get_node_key(self, node):
         return "/opt/xos/node-key"
 
+    def get_instance_port(self, container_port):
+        print container_port
+        print container_port.network
+        for p in container_port.network.links.all():
+            if (p.instance) and (p.instance.node == container_port.container.node) and (p.mac):
+                return p
+        return None
+
+    def get_ports(self, o):
+        i=0
+        ports = []
+        for port in o.ports.all():
+            if not port.mac:
+                raise Exception("Port on network %s is not yet ready" % port.network.name)
+
+            pd={}
+            pd["device"] = "eth%d" % i
+            pd["mac"] = port.mac
+            pd["ip"] = port.ip
+
+            instance_port = self.get_instance_port(port)
+            if not instance_port:
+                raise Exception("No instance on slice for port on network %s" % port.network.name)
+
+            pd["snoop_instance_mac"] = instance_port.mac
+            pd["snoop_instance_id"] = instance_port.instance.instance_id
+
+            ports.append(pd)
+        return ports
+
     def get_extra_attributes(self, o):
         fields={}
         fields["ansible_tag"] = "container-%s" % str(o.id)
         fields["baremetal_ssh"] = True
         fields["instance_name"] = "rootcontext"
-        fields["container_name"] = o.name
+        fields["container_name"] = "%s-%s" % (o.slice.name, str(o.id))
         fields["docker_image"] = o.docker_image
         fields["username"] = "xos"
+        fields["ports"] = self.get_ports(o)
         return fields
 
     def sync_fields(self, o, fields):
diff --git a/xos/openstack_observer/steps/sync_container.yaml b/xos/openstack_observer/steps/sync_container.yaml
index d97f0df..b1e151f 100644
--- a/xos/openstack_observer/steps/sync_container.yaml
+++ b/xos/openstack_observer/steps/sync_container.yaml
@@ -5,6 +5,18 @@
   user: {{ username }}
   sudo: yes
 
+  vars:
+    container_name: {{ container_name }}
+    docker_image: {{ docker_image }}
+    ports:
+    {% for port in ports %}
+       - device: {{ port.device }}
+         mac: {{ port.mac }}
+         ip: {{ port.ip }}
+         snoop_instance_mac: {{ port.snoop_instance_mac }}
+         snoop_instance_id: {{ port.snoop_instance_id }}
+    {% endfor %}
+
   tasks:
 
 #  - name: Fix /etc/hosts
@@ -13,6 +25,7 @@
 #      regexp="127.0.0.1 localhost"
 #      line="127.0.0.1 localhost {{ instance_hostname }}"
 
+{% if false %}
   - name: Add repo key
     apt_key:
       keyserver=hkp://pgp.mit.edu:80
@@ -38,11 +51,32 @@
       name=docker-py
       state=latest
 
-  - name: Start Container
-    docker:
-      docker_api_version: "1.18"
-      name: {{ container_name }}
-      # was: reloaded
-      state: running
-      image: {{ docker_image }}
+  - name: install Pipework
+    get_url: url=https://raw.githubusercontent.com/jpetazzo/pipework/master/pipework
+       dest=/usr/local/bin/pipework
+       mode=0755
+{% endif %}
+
+#  - name: Start Container
+#    docker:
+#      docker_api_version: "1.18"
+#      name: {{ container_name }}
+#      # was: reloaded
+#      state: running
+#      image: {{ docker_image }}
+
+  - name: container upstart
+    template: src=/opt/xos/openstack_observer/templates/container.conf.j2 dest=/etc/init/container-{{ container_name }}.conf
+
+  - name: container systemd
+    template: src=/opt/xos/openstack_observer/templates/container.service.j2 dest=/lib/systemd/system/container-{{ container_name }}.service
+
+  - name: container startup script
+    template: src=/opt/xos/openstack_observer/templates/start-container.sh.j2 dest=/usr/local/sbin/start-container-{{ container_name }}.sh mode=0755
+
+  - name: restart systemd
+    shell: systemctl daemon-reload
+
+  - name: Make sure container is running
+    service: name=container-{{ container_name }} state=started
 
diff --git a/xos/openstack_observer/templates/container.conf.j2 b/xos/openstack_observer/templates/container.conf.j2
new file mode 100644
index 0000000..d3ef42d
--- /dev/null
+++ b/xos/openstack_observer/templates/container.conf.j2
@@ -0,0 +1,11 @@
+# Upstart script for container
+description "container"
+author "smbaker@gmail.com"
+start on filesystem and started docker
+stop on runlevel [!2345]
+respawn
+
+script
+  /usr/local/sbin/start-container-{{ container_name }}.sh
+end script
+
diff --git a/xos/openstack_observer/templates/container.service.j2 b/xos/openstack_observer/templates/container.service.j2
new file mode 100644
index 0000000..9e2b83c
--- /dev/null
+++ b/xos/openstack_observer/templates/container.service.j2
@@ -0,0 +1,9 @@
+[Unit]
+Description={{ container_name }}
+After=docker.service
+
+[Service]
+ExecStart=/bin/bash -c "/usr/local/sbin/start-container-{{ container_name }}.sh"
+
+[Install]
+WantedBy=multi-user.target
diff --git a/xos/openstack_observer/templates/start-container.sh.j2 b/xos/openstack_observer/templates/start-container.sh.j2
new file mode 100644
index 0000000..5656992
--- /dev/null
+++ b/xos/openstack_observer/templates/start-container.sh.j2
@@ -0,0 +1,44 @@
+#!/bin/bash
+
+iptables -L > /dev/null
+ip6tables -L > /dev/null
+
+CONTAINER={{ container_name }}
+IMAGE={{ docker_image }}
+
+docker inspect $CONTAINER > /dev/null 2>&1
+if [ "$?" == 1 ]
+then
+    docker pull $IMAGE
+    docker run -d --name=$CONTAINER --privileged=true --net=none $IMAGE
+else
+    docker start $CONTAINER
+fi
+
+{% if ports %}
+{% for port in ports %}
+IP="{{ port.ip }}"
+MAC="{{ port.mac }}"
+DEVICE="{{ port.device }}"

+INSTANCE_MAC="{{ port.snoop_instance_mac }}"
+INSTANCE_ID="{{ port.snoop_instance_id }}"
+INSTANCE_TAP=`virsh domiflist $INSTANCE_ID | grep -i $INSTANCE_MAC | awk '{print $1}'`
+INSTANCE_TAP=${INSTANCE_TAP:3}
+VLAN_ID=`ovs-vsctl show | grep -i -A 1 port.*$INSTANCE_TAP | grep -i tag | awk '{print $2}'`
+TAP="con`echo $CONTAINER_$DEVICE|md5sum|awk '{print $1}'`"
+TAP=${TAP:0:12}
+echo im=$INSTANCE_MAC ii=$INSTANCE_ID it=$INSTANCE_TAP vlan=$VLAN_ID tap=$TAP con=$CONTAINER dev=$DEVICE mac=$MAC
+ovs-vsctl show | grep -i $TAP
+if [[ $? == 1 ]]; then
+    echo creating tap
+    ovs-vsctl add-port br-int $TAP tag=$VLAN_ID -- set interface $TAP type=internal
+else
+    echo tap exists
+fi
+
+docker exec $CONTAINER ifconfig $DEVICE >> /dev/null || pipework $TAP -i $DEVICE $CONTAINER $IP/24 $MAC
+{% endfor %}
+{% endif %}
+
+# Attach to container
+# docker start -a $CONTAINER
diff --git a/xos/tosca/custom_types/xos.m4 b/xos/tosca/custom_types/xos.m4
index 039b433..a661af7 100644
--- a/xos/tosca/custom_types/xos.m4
+++ b/xos/tosca/custom_types/xos.m4
@@ -491,6 +491,18 @@
                 type: string
                 required: false
                 description: OpenStack domain (or "Default")
+            rabbit_host:
+                type: string
+                required: false
+                description: Rabbit host
+            rabbit_user:
+                type: string
+                required: false
+                description: Rabbit user
+            rabbit_password:
+                type: string
+                required: false
+                description: Rabbit password
 
     tosca.nodes.Site:
         derived_from: tosca.nodes.Root
@@ -562,6 +574,23 @@
             node:
                 type: tosca.capabilities.xos.Node
 
+    tosca.nodes.DashboardView:
+        derived_from: tosca.nodes.Root
+        description: >
+            An XOS Dashboard View
+        capabilities:
+            dashboardview:
+                type: tosca.capabilities.xos.DashboardView
+        properties:
+            xos_base_props
+            enabled:
+                type: boolean
+                default: true
+            url:
+                type: string
+                required: false
+                description: URL to the dashboard
+
     tosca.relationships.MemberOfSlice:
         derived_from: tosca.relationships.Root
         valid_target_types: [ tosca.capabilities.xos.Slice ]
@@ -642,6 +671,10 @@
         derived_from: tosca.relationships.Root
         valid_target_types: [ tosca.capabilities.xos.Subscriber ]
 
+    tosca.relationships.UsesDashboard:
+        derived_from: tosca.relationships.Root
+        valid_target_types: [ tosca.capabilities.xos.DashboardView ]
+
     tosca.capabilities.xos.Service:
         derived_from: tosca.capabilities.Root
         description: An XOS Service
@@ -689,3 +722,7 @@
     tosca.capabilities.xos.Image:
         derived_from: tosca.capabilities.Root
         description: An XOS Image
+
+    tosca.capabilities.xos.DashboardView:
+        derived_from: tosca.capabilities.Root
+        description: An XOS DashboardView
diff --git a/xos/tosca/custom_types/xos.yaml b/xos/tosca/custom_types/xos.yaml
index 3cbe4b2..9170ecf 100644
--- a/xos/tosca/custom_types/xos.yaml
+++ b/xos/tosca/custom_types/xos.yaml
@@ -641,6 +641,18 @@
                 type: string
                 required: false
                 description: OpenStack domain (or "Default")
+            rabbit_host:
+                type: string
+                required: false
+                description: Rabbit host
+            rabbit_user:
+                type: string
+                required: false
+                description: Rabbit user
+            rabbit_password:
+                type: string
+                required: false
+                description: Rabbit password
 
     tosca.nodes.Site:
         derived_from: tosca.nodes.Root
@@ -745,6 +757,34 @@
             node:
                 type: tosca.capabilities.xos.Node
 
+    tosca.nodes.DashboardView:
+        derived_from: tosca.nodes.Root
+        description: >
+            An XOS Dashboard View
+        capabilities:
+            dashboardview:
+                type: tosca.capabilities.xos.DashboardView
+        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
+            enabled:
+                type: boolean
+                default: true
+            url:
+                type: string
+                required: false
+                description: URL to the dashboard
+
     tosca.relationships.MemberOfSlice:
         derived_from: tosca.relationships.Root
         valid_target_types: [ tosca.capabilities.xos.Slice ]
@@ -825,6 +865,10 @@
         derived_from: tosca.relationships.Root
         valid_target_types: [ tosca.capabilities.xos.Subscriber ]
 
+    tosca.relationships.UsesDashboard:
+        derived_from: tosca.relationships.Root
+        valid_target_types: [ tosca.capabilities.xos.DashboardView ]
+
     tosca.capabilities.xos.Service:
         derived_from: tosca.capabilities.Root
         description: An XOS Service
@@ -872,3 +916,7 @@
     tosca.capabilities.xos.Image:
         derived_from: tosca.capabilities.Root
         description: An XOS Image
+
+    tosca.capabilities.xos.DashboardView:
+        derived_from: tosca.capabilities.Root
+        description: An XOS DashboardView
diff --git a/xos/tosca/resources/controller.py b/xos/tosca/resources/controller.py
index 9a20ea5..2aa208c 100644
--- a/xos/tosca/resources/controller.py
+++ b/xos/tosca/resources/controller.py
@@ -15,7 +15,7 @@
 class XOSController(XOSResource):
     provides = "tosca.nodes.Controller"
     xos_model = Controller
-    copyin_props = ["backend_type", "version", "auth_url", "admin_user", "admin_password", "admin_tenant", "domain"]
+    copyin_props = ["backend_type", "version", "auth_url", "admin_user", "admin_password", "admin_tenant", "domain", "rabbit_host", "rabbit_user", "rabbit_password"]
 
     def get_xos_args(self):
         args = super(XOSController, self).get_xos_args()
diff --git a/xos/tosca/resources/dashboardview.py b/xos/tosca/resources/dashboardview.py
new file mode 100644
index 0000000..9f7687c
--- /dev/null
+++ b/xos/tosca/resources/dashboardview.py
@@ -0,0 +1,23 @@
+import os
+import pdb
+import sys
+import tempfile
+sys.path.append("/opt/tosca")
+from translator.toscalib.tosca_template import ToscaTemplate
+
+from core.models import DashboardView, Site, Deployment, SiteDeployment
+
+from xosresource import XOSResource
+
+class XOSDashboardView(XOSResource):
+    provides = "tosca.nodes.DashboardView"
+    xos_model = DashboardView
+    copyin_props = ["url","enabled"]
+
+    def get_xos_args(self):
+        return super(XOSDashboardView, self).get_xos_args()
+
+    def can_delete(self, obj):
+        return super(XOSDashboardView, self).can_delete(obj)
+
+
diff --git a/xos/tosca/resources/user.py b/xos/tosca/resources/user.py
index 53323c5..2b2a787 100644
--- a/xos/tosca/resources/user.py
+++ b/xos/tosca/resources/user.py
@@ -5,7 +5,7 @@
 sys.path.append("/opt/tosca")
 from translator.toscalib.tosca_template import ToscaTemplate
 
-from core.models import User, Site, SiteRole, SliceRole, SlicePrivilege, SitePrivilege
+from core.models import User, Site, SiteRole, SliceRole, SlicePrivilege, SitePrivilege, DashboardView, UserDashboardView
 
 from xosresource import XOSResource
 
@@ -46,6 +46,19 @@
                         sp.save()
                         self.info("Added site privilege on %s role %s for %s" % (str(dest), str(role), str(obj)))
 
+        for reqs in self.nodetemplate.requirements:
+            for (k,v) in reqs.items():
+                if (v["relationship"] == "tosca.relationships.UsesDashboard"):
+                    dashboard_name = v["node"]
+                    dashboard = self.get_xos_object(DashboardView, name=dashboard_name)
+
+                    udvs = UserDashboardView.objects.filter(user=obj, dashboardView=dashboard)
+                    if not udvs:
+                        self.info("Adding UserDashboardView from %s to %s" % (obj, dashboard))
+
+                        udv = UserDashboardView(user=obj, dashboardView=dashboard)
+                        udv.save()
+
     def create(self):
         nodetemplate = self.nodetemplate
 
diff --git a/xos/tosca/samples/dashboardview.yaml b/xos/tosca/samples/dashboardview.yaml
new file mode 100644
index 0000000..2a358f2
--- /dev/null
+++ b/xos/tosca/samples/dashboardview.yaml
@@ -0,0 +1,34 @@
+tosca_definitions_version: tosca_simple_yaml_1_0
+
+description: Dashboard View
+
+imports:
+   - custom_types/xos.yaml
+
+topology_template:
+  node_templates:
+    Ceilometer:
+      type: tosca.nodes.DashboardView
+      properties:
+          url: http:/xosmetering/
+
+    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/tosca/samples/new_site_deploy_slice.yaml b/xos/tosca/samples/new_site_deploy_slice.yaml
index 6ccadc1..5e36bcb 100644
--- a/xos/tosca/samples/new_site_deploy_slice.yaml
+++ b/xos/tosca/samples/new_site_deploy_slice.yaml
@@ -27,6 +27,9 @@
            admin_password: letmeout
            admin_tenant: 12345678
            domain: mydomain
+           rabbit_host: rabhost
+           rabbit_user: rabuser
+           rabbit_password: rabpw
 
     newsite:
       type: tosca.nodes.Site
diff --git a/xos/uwsgi/xos.ini b/xos/uwsgi/xos.ini
index 4c3f62c..63eb6b2 100644
--- a/xos/uwsgi/xos.ini
+++ b/xos/uwsgi/xos.ini
@@ -9,8 +9,8 @@
 workers = 3
 master = true
 processes = 8
-uid = uwsgi
-gid = webserver 
+uid = root
+gid = root
 harakiri = 20
 daemonize=/var/log/uwsgi.xos.log 
 static-map = /static=/var/www/xos/static