Merge commit '3587426b0f9786b7aa101cd67a4c46a3d1769c2e' into feature/serviceTopology
diff --git a/containers/Makefile b/containers/Makefile
new file mode 100644
index 0000000..0215b63
--- /dev/null
+++ b/containers/Makefile
@@ -0,0 +1,19 @@
+.PHONY: xos
+xos: nodes.yaml images.yaml
+	sudo docker-compose up -d
+	../xos/configurations/common/wait_for_xos_port.sh 9999
+	sudo docker-compose run xos python /opt/xos/tosca/run.py padmin@vicci.org /root/setup/setup.yaml
+	sudo docker-compose run xos python /opt/xos/tosca/run.py padmin@vicci.org /root/setup/nodes.yaml
+	sudo docker-compose run xos python /opt/xos/tosca/run.py padmin@vicci.org /root/setup/images.yaml
+
+nodes.yaml:
+	export SETUPDIR=.; bash ../xos/configurations/common/make-nodes-yaml.sh
+
+images.yaml:
+	export SETUPDIR=.; bash ../xos/configurations/common/make-images-yaml.sh
+
+.PHONY: local_containers
+local_containers:
+	cd containers/xos; make devel
+	cd containers/synchronizer; make
+
diff --git a/containers/README b/containers/README
deleted file mode 100644
index 9891efe..0000000
--- a/containers/README
+++ /dev/null
@@ -1,51 +0,0 @@
-
-1. Introduction
-
-  XOS is comprised of 3 core services:
-  
-  * A database backend (postgres)
-  * A webserver front end (django)
-  * A synchronizer daemon that interacts with the openstack backend.
-
-  We have created separate dockerfiles for each of these services, making it easier to
-  build the services independently and also deploy and run them in isolated environments. 
-
-2. Database Container
-  
-  To build and run the database container:
-  
-  $ cd postgres; make build && make run;
-
-3. XOS container
-  
-  To build and run the xos webserver container:
-
-  $ cd xos; make build && make run;
-
-  You should now be able to access the login page by visiting http://localhost:80 and
-  log in using the default paadmin account. It may be helpful to bootstrap xos with 
-  some sample data; deployment, controllers, sites, slices, etc. You can get started by
-  loading tosca configuration for the opencloud demo dataset:
-
-  $ cd xos; make runtosca;
-
-  Or you can create you own tosca configuraton file and customize the dataset however you
-  want. You can all load your own tosca configuration by setting the TOSCA_CONFIG_PATH 
-  environment variable before executing the make command:
-
-  $ cd xos; TOSCA_CONFIG_PATH=/path/to/tosca/config.yaml make runtosca
-
-4. Synchronizer container
-
-  The syncornonizer shares many of the same dependencies as the xos container. The synchronizer 
-  container takes advantage of this by building itself on top of the xos image. This means
-  you must build the xos image before building the synchronizer image. The XOS and 
-  synchronizer containers can run on separate hosts, but you must build the xos image
-  on the host that you plan to run the synchronizer container. Assuming you have already 
-  built the xos container, executing the following will build and run the synchronizer container:
-
-  $ cd synchronizer; make build && make run
-
-  
-
-
diff --git a/containers/README.md b/containers/README.md
index 46f970e..0fcdb13 100644
--- a/containers/README.md
+++ b/containers/README.md
@@ -14,53 +14,33 @@
 
 #### Database Container
 
-To build and run the database container:
+To build the database container:
 
 ```
-$ cd postgresql; make build && make run
+$ cd postgresql; make build
 ```
 
 #### XOS Container
 
-To build and run the xos webserver container:
+To build the XOS webserver container:
 
 ```
-$ cd xos; make build && make run
-```
-
-You should now be able to access the login page by visiting
-`http://localhost:8000` and log in using the default `padmin@vicci.org` account
-with password `letmein`. It may be helpful to bootstrap xos with some sample
-data; deployment, controllers, sites, slices, etc. You can get started by
-loading tosca configuration for the opencloud demo dataset:
-
-```
-$ cd xos; make runtosca
-```
-
-Or you can create you own tosca configuraton file and customize the dataset
-however you want. You can all load your own tosca configuration by setting the
-`TOSCA_CONFIG_PATH` environment variable before executing the make command:
-
-```
-$ cd xos; TOSCA_CONFIG_PATH=/path/to/tosca/config.yaml make runtosca
+$ cd xos; make build
 ```
 
 #### Synchronizer Container
 
-The Synchronizer shares many of the same dependencies as the xos container. The
+The Synchronizer shares many of the same dependencies as the XOS container. The
 synchronizer container takes advantage of this by building itself on top of the
-xos image. This means you must build the xos image before building the
-synchronizer image. The XOS and synchronizer containers can run on separate
-hosts, but you must build the xos image on the host that you plan to run the
-synchronizer container. Assuming you have already built the xos container,
-executing the following will build and run the synchronizer container:
+XOS image. This means you must build the XOS image before building the
+synchronizer image.  Assuming you have already built the XOS container,
+executing the following will build the Synchronizer container:
 
 ```
-$ cd synchronizer; make build && make run
+$ cd synchronizer; make build
 ```
 
-#### Solution Compose File ![](https://img.shields.io/badge/compose-beta-red.svg)
+#### Solution Compose File
 
 [Docker Compose](https://docs.docker.com/compose/) is a tool for defining and
 running multi-container Docker applications. With Compose, you use a Compose
@@ -69,9 +49,29 @@
 
 Included is a compose file in *YAML* format with content defined by the [Docker
 Compose Format](https://docs.docker.com/compose/compose-file/). With the compose
-file a complete XOS solution based on docker containers can be instantiated
+file a complete XOS solution based on Docker containers can be instantiated
 using a single command. To start the instance you can use the command:
 
 ```
 $ docker-compose up -d
 ```
+
+You should now be able to access the login page by visiting
+`http://localhost:8000` and log in using the default `padmin@vicci.org` account
+with password `letmein`.
+
+#### Configuring XOS for OpenStack
+
+If you have your own OpenStack cluster, and you would like to configure XOS to
+control it, copy the `admin-openrc.sh` credentials file for your cluster to
+this directory.  Make sure that OpenStack commands work from the local machine
+using the credentials, e.g., `source ./admin-openrc.sh; nova list`.  Then run:
+
+```
+$ make
+```
+
+XOS will be launched (the Makefile will run the `docker-compose up -d` command
+for you) and configured with the nodes and images available in your
+OpenStack cloud.  You can then log in to XOS as described above and start creating
+slices and instances.
diff --git a/containers/admin-openrc.sh b/containers/admin-openrc.sh
new file mode 100644
index 0000000..f27fdac
--- /dev/null
+++ b/containers/admin-openrc.sh
@@ -0,0 +1,6 @@
+# Replace with the OpenStack admin credentials for your cluster
+export OS_TENANT_NAME=admin
+export OS_USERNAME=admin
+export OS_PASSWORD=admin
+export OS_AUTH_URL=http://localhost:35357/v2.0
+
diff --git a/containers/docker-compose.yml b/containers/docker-compose.yml
index 464b560..24596a3 100644
--- a/containers/docker-compose.yml
+++ b/containers/docker-compose.yml
@@ -4,10 +4,15 @@
         - "5432"
 
 xos_synchronizer_openstack:
+    command: bash -c "sleep 120; python /opt/xos/synchronizers/openstack/xos-synchronizer.py"
     image: xosproject/xos-synchronizer-openstack
     labels:
         org.xosproject.kind: synchronizer
         org.xosproject.target: openstack
+    links:
+        - xos_db
+    volumes:
+        - .:/root/setup:ro
 
 # FUTURE
 #xos_swarm_synchronizer:
@@ -17,9 +22,11 @@
 #        org.xosproject.target: swarm
 
 xos:
-    image: xosproject/xos
     command: python /opt/xos/manage.py runserver 0.0.0.0:8000 --insecure --makemigrations
-    ports:
-        - "8000:8000"
+    image: xosproject/xos
     links:
         - xos_db
+    ports:
+        - "8000:8000"
+    volumes:
+        - .:/root/setup:ro
diff --git a/containers/setup.yaml b/containers/setup.yaml
new file mode 100644
index 0000000..c13f0eb
--- /dev/null
+++ b/containers/setup.yaml
@@ -0,0 +1,61 @@
+tosca_definitions_version: tosca_simple_yaml_1_0
+
+description: >
+    * Adds OpenCloud Sites, Deployments, and Controllers.
+
+imports:
+   - custom_types/xos.yaml
+
+topology_template:
+  node_templates:
+
+    MyDeployment:
+      type: tosca.nodes.Deployment
+      properties:
+          flavors: m1.large, m1.medium, m1.small
+
+    MyOpenStack:
+      type: tosca.nodes.Controller
+      requirements:
+          - deployment:
+              node: MyDeployment
+              relationship: tosca.relationships.ControllerDeployment
+      properties:
+          backend_type: OpenStack
+          version: Kilo
+          auth_url: { get_script_env: [ SELF, adminrc, OS_AUTH_URL, LOCAL_FILE] }
+          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] }
+          domain: Default
+      artifacts:
+          adminrc: /root/setup/admin-openrc.sh
+
+    mysite:
+      type: tosca.nodes.Site
+      properties:
+          display_name: MySite
+          site_url: http://xosproject.org/
+      requirements:
+          - deployment:
+               node: MyDeployment
+               relationship: tosca.relationships.SiteDeployment
+               requirements:
+                   - controller:
+                       node: MyOpenStack
+                       relationship: tosca.relationships.UsesController
+
+    # This user already exists in XOS with this password
+    # It's an example of how to create new users
+    padmin@vicci.org:
+      type: tosca.nodes.User
+      requirements:
+          - site:
+              node: mysite
+              relationship: tosca.relationships.MemberOfSite
+      properties:
+          is_admin: true
+          is_active: true
+          firstname: XOS
+          lastname: admin
+          password: letmein
diff --git a/xos/configurations/common/make-images-yaml.sh b/xos/configurations/common/make-images-yaml.sh
new file mode 100644
index 0000000..6321a9d
--- /dev/null
+++ b/xos/configurations/common/make-images-yaml.sh
@@ -0,0 +1,48 @@
+FN=$SETUPDIR/images.yaml
+
+rm -f $FN
+
+cat >> $FN <<EOF
+tosca_definitions_version: tosca_simple_yaml_1_0
+
+imports:
+   - custom_types/xos.yaml
+
+description: autogenerated nodes file
+
+topology_template:
+  node_templates:
+    mysite:
+        type: tosca.nodes.Site
+
+EOF
+
+IMAGES=$( bash -c "source $SETUPDIR/admin-openrc.sh ; glance image-list" |grep -v ID|grep -v +|awk '{print $4}' )
+I=0
+for IMAGE in $IMAGES; do
+    echo $IMAGE
+    cat >> $FN <<EOF
+    $IMAGE:
+      type: tosca.nodes.Image
+      properties:
+         disk_format: QCOW2
+         container_format: BARE
+
+EOF
+done
+
+cat >> $FN <<EOF
+    MyDeployment:
+      type: tosca.nodes.Deployment
+      properties:
+          flavors: m1.large, m1.medium, m1.small
+      requirements:
+EOF
+
+for IMAGE in $IMAGES; do
+    cat >> $FN <<EOF
+          - image:
+              node: $IMAGE
+              relationship: tosca.relationships.SupportsImage
+EOF
+done
diff --git a/xos/configurations/common/make-nodes-yaml.sh b/xos/configurations/common/make-nodes-yaml.sh
index 1c0003a..74b8d0b 100644
--- a/xos/configurations/common/make-nodes-yaml.sh
+++ b/xos/configurations/common/make-nodes-yaml.sh
@@ -18,7 +18,7 @@
         type: tosca.nodes.Site
 EOF
 
-NODES=$( bash -c "source $SETUPDIR/admin-openrc.sh ; nova hypervisor-list" |grep enabled|awk '{print $4}' )
+NODES=$( bash -c "source $SETUPDIR/admin-openrc.sh ; nova hypervisor-list" |grep -v ID|grep -v +|awk '{print $4}' )
 I=0
 for NODE in $NODES; do
     echo $NODE
diff --git a/xos/configurations/common/wait_for_xos_port.sh b/xos/configurations/common/wait_for_xos_port.sh
new file mode 100755
index 0000000..dab6e70
--- /dev/null
+++ b/xos/configurations/common/wait_for_xos_port.sh
@@ -0,0 +1,23 @@
+#! /bin/bash
+
+display_usage() { 
+    echo -e "\nUsage:\n$0 [xos-listen-port] \n" 
+} 
+
+if [  $# -lt 1 ] 
+then 
+    display_usage
+    exit 1
+fi 
+
+echo "Waiting for XOS to come up"
+until http 0.0.0.0:$1 &> /dev/null
+do
+    sleep 1
+    RUNNING_CONTAINER=`sudo docker ps|grep "xos"|awk '{print $$NF}'`
+    if [[ $RUNNING_CONTAINER == "" ]]; then
+        echo Container may have failed. check with \"make showlogs\'
+        exit 1
+    fi
+done
+echo "XOS is ready"
diff --git a/xos/configurations/opencloud/opencloud.yaml b/xos/configurations/opencloud/opencloud.yaml
index 0b4a3ed..c3a2c01 100644
--- a/xos/configurations/opencloud/opencloud.yaml
+++ b/xos/configurations/opencloud/opencloud.yaml
@@ -806,3 +806,893 @@
                   max_instances: 25
                   min_instances: 1
                   default_instances: 1
+# Nodes
+    node37.princeton.vicci.org:
+      type: tosca.nodes.Node
+      requirements:
+        - site:
+            node: princeton
+            relationship: tosca.relationships.MemberOfSite
+        - deployment:
+            node: campus
+            relationship: tosca.relationships.MemberOfDeployment
+
+
+    node39.princeton.vicci.org:
+      type: tosca.nodes.Node
+      requirements:
+        - site:
+            node: princeton
+            relationship: tosca.relationships.MemberOfSite
+        - deployment:
+            node: campus
+            relationship: tosca.relationships.MemberOfDeployment
+
+
+    node41.princeton.vicci.org:
+      type: tosca.nodes.Node
+      requirements:
+        - site:
+            node: princeton
+            relationship: tosca.relationships.MemberOfSite
+        - deployment:
+            node: campus
+            relationship: tosca.relationships.MemberOfDeployment
+
+
+    node43.princeton.vicci.org:
+      type: tosca.nodes.Node
+      requirements:
+        - site:
+            node: princeton
+            relationship: tosca.relationships.MemberOfSite
+        - deployment:
+            node: campus
+            relationship: tosca.relationships.MemberOfDeployment
+
+
+    node45.princeton.vicci.org:
+      type: tosca.nodes.Node
+      requirements:
+        - site:
+            node: princeton
+            relationship: tosca.relationships.MemberOfSite
+        - deployment:
+            node: campus
+            relationship: tosca.relationships.MemberOfDeployment
+
+
+    node49.princeton.vicci.org:
+      type: tosca.nodes.Node
+      requirements:
+        - site:
+            node: princeton
+            relationship: tosca.relationships.MemberOfSite
+        - deployment:
+            node: campus
+            relationship: tosca.relationships.MemberOfDeployment
+
+
+    node51.princeton.vicci.org:
+      type: tosca.nodes.Node
+      requirements:
+        - site:
+            node: princeton
+            relationship: tosca.relationships.MemberOfSite
+        - deployment:
+            node: campus
+            relationship: tosca.relationships.MemberOfDeployment
+
+
+    node52.princeton.vicci.org:
+      type: tosca.nodes.Node
+      requirements:
+        - site:
+            node: princeton
+            relationship: tosca.relationships.MemberOfSite
+        - deployment:
+            node: campus
+            relationship: tosca.relationships.MemberOfDeployment
+
+
+    node54.princeton.vicci.org:
+      type: tosca.nodes.Node
+      requirements:
+        - site:
+            node: princeton
+            relationship: tosca.relationships.MemberOfSite
+        - deployment:
+            node: campus
+            relationship: tosca.relationships.MemberOfDeployment
+
+
+    node55.princeton.vicci.org:
+      type: tosca.nodes.Node
+      requirements:
+        - site:
+            node: princeton
+            relationship: tosca.relationships.MemberOfSite
+        - deployment:
+            node: campus
+            relationship: tosca.relationships.MemberOfDeployment
+
+
+    node57.princeton.vicci.org:
+      type: tosca.nodes.Node
+      requirements:
+        - site:
+            node: princeton
+            relationship: tosca.relationships.MemberOfSite
+        - deployment:
+            node: campus
+            relationship: tosca.relationships.MemberOfDeployment
+
+
+    node59.princeton.vicci.org:
+      type: tosca.nodes.Node
+      requirements:
+        - site:
+            node: princeton
+            relationship: tosca.relationships.MemberOfSite
+        - deployment:
+            node: campus
+            relationship: tosca.relationships.MemberOfDeployment
+
+
+    node65.princeton.vicci.org:
+      type: tosca.nodes.Node
+      requirements:
+        - site:
+            node: princeton
+            relationship: tosca.relationships.MemberOfSite
+        - deployment:
+            node: campus
+            relationship: tosca.relationships.MemberOfDeployment
+
+
+    node66.princeton.vicci.org:
+      type: tosca.nodes.Node
+      requirements:
+        - site:
+            node: princeton
+            relationship: tosca.relationships.MemberOfSite
+        - deployment:
+            node: campus
+            relationship: tosca.relationships.MemberOfDeployment
+
+
+    node67.princeton.vicci.org:
+      type: tosca.nodes.Node
+      requirements:
+        - site:
+            node: princeton
+            relationship: tosca.relationships.MemberOfSite
+        - deployment:
+            node: campus
+            relationship: tosca.relationships.MemberOfDeployment
+
+
+    node68.princeton.vicci.org:
+      type: tosca.nodes.Node
+      requirements:
+        - site:
+            node: princeton
+            relationship: tosca.relationships.MemberOfSite
+        - deployment:
+            node: campus
+            relationship: tosca.relationships.MemberOfDeployment
+
+
+    node69.princeton.vicci.org:
+      type: tosca.nodes.Node
+      requirements:
+        - site:
+            node: princeton
+            relationship: tosca.relationships.MemberOfSite
+        - deployment:
+            node: campus
+            relationship: tosca.relationships.MemberOfDeployment
+
+
+    node2.stanford.vicci.org:
+      type: tosca.nodes.Node
+      requirements:
+        - site:
+            node: stanford
+            relationship: tosca.relationships.MemberOfSite
+        - deployment:
+            node: campus
+            relationship: tosca.relationships.MemberOfDeployment
+
+
+    node3.stanford.vicci.org:
+      type: tosca.nodes.Node
+      requirements:
+        - site:
+            node: stanford
+            relationship: tosca.relationships.MemberOfSite
+        - deployment:
+            node: campus
+            relationship: tosca.relationships.MemberOfDeployment
+
+
+    node5.stanford.vicci.org:
+      type: tosca.nodes.Node
+      requirements:
+        - site:
+            node: stanford
+            relationship: tosca.relationships.MemberOfSite
+        - deployment:
+            node: campus
+            relationship: tosca.relationships.MemberOfDeployment
+
+
+    node6.stanford.vicci.org:
+      type: tosca.nodes.Node
+      requirements:
+        - site:
+            node: stanford
+            relationship: tosca.relationships.MemberOfSite
+        - deployment:
+            node: campus
+            relationship: tosca.relationships.MemberOfDeployment
+
+
+    node7.stanford.vicci.org:
+      type: tosca.nodes.Node
+      requirements:
+        - site:
+            node: stanford
+            relationship: tosca.relationships.MemberOfSite
+        - deployment:
+            node: campus
+            relationship: tosca.relationships.MemberOfDeployment
+
+
+    node8.stanford.vicci.org:
+      type: tosca.nodes.Node
+      requirements:
+        - site:
+            node: stanford
+            relationship: tosca.relationships.MemberOfSite
+        - deployment:
+            node: campus
+            relationship: tosca.relationships.MemberOfDeployment
+
+
+    node9.stanford.vicci.org:
+      type: tosca.nodes.Node
+      requirements:
+        - site:
+            node: stanford
+            relationship: tosca.relationships.MemberOfSite
+        - deployment:
+            node: campus
+            relationship: tosca.relationships.MemberOfDeployment
+
+
+    node10.stanford.vicci.org:
+      type: tosca.nodes.Node
+      requirements:
+        - site:
+            node: stanford
+            relationship: tosca.relationships.MemberOfSite
+        - deployment:
+            node: campus
+            relationship: tosca.relationships.MemberOfDeployment
+
+
+    node11.stanford.vicci.org:
+      type: tosca.nodes.Node
+      requirements:
+        - site:
+            node: stanford
+            relationship: tosca.relationships.MemberOfSite
+        - deployment:
+            node: campus
+            relationship: tosca.relationships.MemberOfDeployment
+
+
+    node12.stanford.vicci.org:
+      type: tosca.nodes.Node
+      requirements:
+        - site:
+            node: stanford
+            relationship: tosca.relationships.MemberOfSite
+        - deployment:
+            node: campus
+            relationship: tosca.relationships.MemberOfDeployment
+
+
+    node13.stanford.vicci.org:
+      type: tosca.nodes.Node
+      requirements:
+        - site:
+            node: stanford
+            relationship: tosca.relationships.MemberOfSite
+        - deployment:
+            node: campus
+            relationship: tosca.relationships.MemberOfDeployment
+
+
+    node14.stanford.vicci.org:
+      type: tosca.nodes.Node
+      requirements:
+        - site:
+            node: stanford
+            relationship: tosca.relationships.MemberOfSite
+        - deployment:
+            node: campus
+            relationship: tosca.relationships.MemberOfDeployment
+
+
+    node15.stanford.vicci.org:
+      type: tosca.nodes.Node
+      requirements:
+        - site:
+            node: stanford
+            relationship: tosca.relationships.MemberOfSite
+        - deployment:
+            node: campus
+            relationship: tosca.relationships.MemberOfDeployment
+
+
+    node16.stanford.vicci.org:
+      type: tosca.nodes.Node
+      requirements:
+        - site:
+            node: stanford
+            relationship: tosca.relationships.MemberOfSite
+        - deployment:
+            node: campus
+            relationship: tosca.relationships.MemberOfDeployment
+
+
+    node17.stanford.vicci.org:
+      type: tosca.nodes.Node
+      requirements:
+        - site:
+            node: stanford
+            relationship: tosca.relationships.MemberOfSite
+        - deployment:
+            node: campus
+            relationship: tosca.relationships.MemberOfDeployment
+
+
+    node18.stanford.vicci.org:
+      type: tosca.nodes.Node
+      requirements:
+        - site:
+            node: stanford
+            relationship: tosca.relationships.MemberOfSite
+        - deployment:
+            node: campus
+            relationship: tosca.relationships.MemberOfDeployment
+
+
+    node19.stanford.vicci.org:
+      type: tosca.nodes.Node
+      requirements:
+        - site:
+            node: stanford
+            relationship: tosca.relationships.MemberOfSite
+        - deployment:
+            node: campus
+            relationship: tosca.relationships.MemberOfDeployment
+
+
+    node20.stanford.vicci.org:
+      type: tosca.nodes.Node
+      requirements:
+        - site:
+            node: stanford
+            relationship: tosca.relationships.MemberOfSite
+        - deployment:
+            node: campus
+            relationship: tosca.relationships.MemberOfDeployment
+
+
+    node21.stanford.vicci.org:
+      type: tosca.nodes.Node
+      requirements:
+        - site:
+            node: stanford
+            relationship: tosca.relationships.MemberOfSite
+        - deployment:
+            node: campus
+            relationship: tosca.relationships.MemberOfDeployment
+
+
+    node22.stanford.vicci.org:
+      type: tosca.nodes.Node
+      requirements:
+        - site:
+            node: stanford
+            relationship: tosca.relationships.MemberOfSite
+        - deployment:
+            node: campus
+            relationship: tosca.relationships.MemberOfDeployment
+
+
+    node23.stanford.vicci.org:
+      type: tosca.nodes.Node
+      requirements:
+        - site:
+            node: stanford
+            relationship: tosca.relationships.MemberOfSite
+        - deployment:
+            node: campus
+            relationship: tosca.relationships.MemberOfDeployment
+
+
+    node24.stanford.vicci.org:
+      type: tosca.nodes.Node
+      requirements:
+        - site:
+            node: stanford
+            relationship: tosca.relationships.MemberOfSite
+        - deployment:
+            node: campus
+            relationship: tosca.relationships.MemberOfDeployment
+
+
+    node25.stanford.vicci.org:
+      type: tosca.nodes.Node
+      requirements:
+        - site:
+            node: stanford
+            relationship: tosca.relationships.MemberOfSite
+        - deployment:
+            node: campus
+            relationship: tosca.relationships.MemberOfDeployment
+
+
+    node26.stanford.vicci.org:
+      type: tosca.nodes.Node
+      requirements:
+        - site:
+            node: stanford
+            relationship: tosca.relationships.MemberOfSite
+        - deployment:
+            node: campus
+            relationship: tosca.relationships.MemberOfDeployment
+
+
+    node27.stanford.vicci.org:
+      type: tosca.nodes.Node
+      requirements:
+        - site:
+            node: stanford
+            relationship: tosca.relationships.MemberOfSite
+        - deployment:
+            node: campus
+            relationship: tosca.relationships.MemberOfDeployment
+
+
+    node28.stanford.vicci.org:
+      type: tosca.nodes.Node
+      requirements:
+        - site:
+            node: stanford
+            relationship: tosca.relationships.MemberOfSite
+        - deployment:
+            node: campus
+            relationship: tosca.relationships.MemberOfDeployment
+
+
+    node29.stanford.vicci.org:
+      type: tosca.nodes.Node
+      requirements:
+        - site:
+            node: stanford
+            relationship: tosca.relationships.MemberOfSite
+        - deployment:
+            node: campus
+            relationship: tosca.relationships.MemberOfDeployment
+
+
+    node30.stanford.vicci.org:
+      type: tosca.nodes.Node
+      requirements:
+        - site:
+            node: stanford
+            relationship: tosca.relationships.MemberOfSite
+        - deployment:
+            node: campus
+            relationship: tosca.relationships.MemberOfDeployment
+
+
+    node31.stanford.vicci.org:
+      type: tosca.nodes.Node
+      requirements:
+        - site:
+            node: stanford
+            relationship: tosca.relationships.MemberOfSite
+        - deployment:
+            node: campus
+            relationship: tosca.relationships.MemberOfDeployment
+
+
+    node32.stanford.vicci.org:
+      type: tosca.nodes.Node
+      requirements:
+        - site:
+            node: stanford
+            relationship: tosca.relationships.MemberOfSite
+        - deployment:
+            node: campus
+            relationship: tosca.relationships.MemberOfDeployment
+
+
+    node33.stanford.vicci.org:
+      type: tosca.nodes.Node
+      requirements:
+        - site:
+            node: stanford
+            relationship: tosca.relationships.MemberOfSite
+        - deployment:
+            node: campus
+            relationship: tosca.relationships.MemberOfDeployment
+
+
+    node34.stanford.vicci.org:
+      type: tosca.nodes.Node
+      requirements:
+        - site:
+            node: stanford
+            relationship: tosca.relationships.MemberOfSite
+        - deployment:
+            node: campus
+            relationship: tosca.relationships.MemberOfDeployment
+
+
+    node35.stanford.vicci.org:
+      type: tosca.nodes.Node
+      requirements:
+        - site:
+            node: stanford
+            relationship: tosca.relationships.MemberOfSite
+        - deployment:
+            node: campus
+            relationship: tosca.relationships.MemberOfDeployment
+
+
+    node37.stanford.vicci.org:
+      type: tosca.nodes.Node
+      requirements:
+        - site:
+            node: stanford
+            relationship: tosca.relationships.MemberOfSite
+        - deployment:
+            node: campus
+            relationship: tosca.relationships.MemberOfDeployment
+
+
+    node38.stanford.vicci.org:
+      type: tosca.nodes.Node
+      requirements:
+        - site:
+            node: stanford
+            relationship: tosca.relationships.MemberOfSite
+        - deployment:
+            node: campus
+            relationship: tosca.relationships.MemberOfDeployment
+
+
+    node39.stanford.vicci.org:
+      type: tosca.nodes.Node
+      requirements:
+        - site:
+            node: stanford
+            relationship: tosca.relationships.MemberOfSite
+        - deployment:
+            node: campus
+            relationship: tosca.relationships.MemberOfDeployment
+
+
+    node40.stanford.vicci.org:
+      type: tosca.nodes.Node
+      requirements:
+        - site:
+            node: stanford
+            relationship: tosca.relationships.MemberOfSite
+        - deployment:
+            node: campus
+            relationship: tosca.relationships.MemberOfDeployment
+
+
+    node41.stanford.vicci.org:
+      type: tosca.nodes.Node
+      requirements:
+        - site:
+            node: stanford
+            relationship: tosca.relationships.MemberOfSite
+        - deployment:
+            node: campus
+            relationship: tosca.relationships.MemberOfDeployment
+
+
+    node42.stanford.vicci.org:
+      type: tosca.nodes.Node
+      requirements:
+        - site:
+            node: stanford
+            relationship: tosca.relationships.MemberOfSite
+        - deployment:
+            node: campus
+            relationship: tosca.relationships.MemberOfDeployment
+
+
+    node43.stanford.vicci.org:
+      type: tosca.nodes.Node
+      requirements:
+        - site:
+            node: stanford
+            relationship: tosca.relationships.MemberOfSite
+        - deployment:
+            node: campus
+            relationship: tosca.relationships.MemberOfDeployment
+
+
+    node44.stanford.vicci.org:
+      type: tosca.nodes.Node
+      requirements:
+        - site:
+            node: stanford
+            relationship: tosca.relationships.MemberOfSite
+        - deployment:
+            node: campus
+            relationship: tosca.relationships.MemberOfDeployment
+
+
+    node45.stanford.vicci.org:
+      type: tosca.nodes.Node
+      requirements:
+        - site:
+            node: stanford
+            relationship: tosca.relationships.MemberOfSite
+        - deployment:
+            node: campus
+            relationship: tosca.relationships.MemberOfDeployment
+
+
+    node46.stanford.vicci.org:
+      type: tosca.nodes.Node
+      requirements:
+        - site:
+            node: stanford
+            relationship: tosca.relationships.MemberOfSite
+        - deployment:
+            node: campus
+            relationship: tosca.relationships.MemberOfDeployment
+
+
+    node47.stanford.vicci.org:
+      type: tosca.nodes.Node
+      requirements:
+        - site:
+            node: stanford
+            relationship: tosca.relationships.MemberOfSite
+        - deployment:
+            node: campus
+            relationship: tosca.relationships.MemberOfDeployment
+
+
+    node48.stanford.vicci.org:
+      type: tosca.nodes.Node
+      requirements:
+        - site:
+            node: stanford
+            relationship: tosca.relationships.MemberOfSite
+        - deployment:
+            node: campus
+            relationship: tosca.relationships.MemberOfDeployment
+
+
+    node49.stanford.vicci.org:
+      type: tosca.nodes.Node
+      requirements:
+        - site:
+            node: stanford
+            relationship: tosca.relationships.MemberOfSite
+        - deployment:
+            node: campus
+            relationship: tosca.relationships.MemberOfDeployment
+
+
+    node50.stanford.vicci.org:
+      type: tosca.nodes.Node
+      requirements:
+        - site:
+            node: stanford
+            relationship: tosca.relationships.MemberOfSite
+        - deployment:
+            node: campus
+            relationship: tosca.relationships.MemberOfDeployment
+
+
+    node51.stanford.vicci.org:
+      type: tosca.nodes.Node
+      requirements:
+        - site:
+            node: stanford
+            relationship: tosca.relationships.MemberOfSite
+        - deployment:
+            node: campus
+            relationship: tosca.relationships.MemberOfDeployment
+
+
+    node52.stanford.vicci.org:
+      type: tosca.nodes.Node
+      requirements:
+        - site:
+            node: stanford
+            relationship: tosca.relationships.MemberOfSite
+        - deployment:
+            node: campus
+            relationship: tosca.relationships.MemberOfDeployment
+
+
+    node54.stanford.vicci.org:
+      type: tosca.nodes.Node
+      requirements:
+        - site:
+            node: stanford
+            relationship: tosca.relationships.MemberOfSite
+        - deployment:
+            node: campus
+            relationship: tosca.relationships.MemberOfDeployment
+
+
+    node55.stanford.vicci.org:
+      type: tosca.nodes.Node
+      requirements:
+        - site:
+            node: stanford
+            relationship: tosca.relationships.MemberOfSite
+        - deployment:
+            node: campus
+            relationship: tosca.relationships.MemberOfDeployment
+
+
+    node56.stanford.vicci.org:
+      type: tosca.nodes.Node
+      requirements:
+        - site:
+            node: stanford
+            relationship: tosca.relationships.MemberOfSite
+        - deployment:
+            node: campus
+            relationship: tosca.relationships.MemberOfDeployment
+
+
+    node57.stanford.vicci.org:
+      type: tosca.nodes.Node
+      requirements:
+        - site:
+            node: stanford
+            relationship: tosca.relationships.MemberOfSite
+        - deployment:
+            node: campus
+            relationship: tosca.relationships.MemberOfDeployment
+
+
+    node58.stanford.vicci.org:
+      type: tosca.nodes.Node
+      requirements:
+        - site:
+            node: stanford
+            relationship: tosca.relationships.MemberOfSite
+        - deployment:
+            node: campus
+            relationship: tosca.relationships.MemberOfDeployment
+
+
+    node59.stanford.vicci.org:
+      type: tosca.nodes.Node
+      requirements:
+        - site:
+            node: stanford
+            relationship: tosca.relationships.MemberOfSite
+        - deployment:
+            node: campus
+            relationship: tosca.relationships.MemberOfDeployment
+
+
+    node60.stanford.vicci.org:
+      type: tosca.nodes.Node
+      requirements:
+        - site:
+            node: stanford
+            relationship: tosca.relationships.MemberOfSite
+        - deployment:
+            node: campus
+            relationship: tosca.relationships.MemberOfDeployment
+
+
+    node61.stanford.vicci.org:
+      type: tosca.nodes.Node
+      requirements:
+        - site:
+            node: stanford
+            relationship: tosca.relationships.MemberOfSite
+        - deployment:
+            node: campus
+            relationship: tosca.relationships.MemberOfDeployment
+
+
+    node62.stanford.vicci.org:
+      type: tosca.nodes.Node
+      requirements:
+        - site:
+            node: stanford
+            relationship: tosca.relationships.MemberOfSite
+        - deployment:
+            node: campus
+            relationship: tosca.relationships.MemberOfDeployment
+
+
+    node63.stanford.vicci.org:
+      type: tosca.nodes.Node
+      requirements:
+        - site:
+            node: stanford
+            relationship: tosca.relationships.MemberOfSite
+        - deployment:
+            node: campus
+            relationship: tosca.relationships.MemberOfDeployment
+
+
+    node64.stanford.vicci.org:
+      type: tosca.nodes.Node
+      requirements:
+        - site:
+            node: stanford
+            relationship: tosca.relationships.MemberOfSite
+        - deployment:
+            node: campus
+            relationship: tosca.relationships.MemberOfDeployment
+
+
+    node67.stanford.vicci.org:
+      type: tosca.nodes.Node
+      requirements:
+        - site:
+            node: stanford
+            relationship: tosca.relationships.MemberOfSite
+        - deployment:
+            node: campus
+            relationship: tosca.relationships.MemberOfDeployment
+
+
+    node68.stanford.vicci.org:
+      type: tosca.nodes.Node
+      requirements:
+        - site:
+            node: stanford
+            relationship: tosca.relationships.MemberOfSite
+        - deployment:
+            node: campus
+            relationship: tosca.relationships.MemberOfDeployment
+
+
+    node69.stanford.vicci.org:
+      type: tosca.nodes.Node
+      requirements:
+        - site:
+            node: stanford
+            relationship: tosca.relationships.MemberOfSite
+        - deployment:
+            node: campus
+            relationship: tosca.relationships.MemberOfDeployment
+
+
+    node70.stanford.vicci.org:
+      type: tosca.nodes.Node
+      requirements:
+        - site:
+            node: stanford
+            relationship: tosca.relationships.MemberOfSite
+        - deployment:
+            node: campus
+            relationship: tosca.relationships.MemberOfDeployment
diff --git a/xos/core/admin.py b/xos/core/admin.py
index bc083c4..993a6f8 100644
--- a/xos/core/admin.py
+++ b/xos/core/admin.py
@@ -789,14 +789,34 @@
 
         return AdminFormMetaClass
 
+class ControllerAdminForm(forms.ModelForm):
+    backend_disabled = forms.BooleanField(required=False)
+    class Meta:
+        model = Controller
+
+    def __init__(self, *args, **kwargs):
+      request = kwargs.pop('request', None)
+      super(ControllerAdminForm, self).__init__(*args, **kwargs)
+
+      if self.instance and self.instance.pk:
+        self.fields['backend_disabled'].initial = self.instance.get_backend_register('disabled', False)
+      else:
+        # defaults when adding new controller
+        self.fields['backend_disabled'].initial = False
+
+    def save(self, commit=True):
+      self.instance.set_backend_register("disabled", self.cleaned_data["backend_disabled"])
+      return super(ControllerAdminForm, self).save(commit=commit)
+
 class ControllerAdmin(XOSBaseAdmin):
     model = Controller
-    fieldList = ['deployment', 'name', 'backend_type', 'version', 'auth_url', 'admin_user', 'admin_tenant','admin_password', 'domain', 'rabbit_host', 'rabbit_user', 'rabbit_password']
+    fieldList = ['deployment', 'name', 'backend_type', 'backend_disabled', 'version', 'auth_url', 'admin_user', 'admin_tenant','admin_password', 'domain', 'rabbit_host', 'rabbit_user', 'rabbit_password']
     fieldsets = [(None, {'fields': fieldList, 'classes':['suit-tab suit-tab-general']})]
     inlines = [ControllerSiteInline] # ,ControllerImagesInline]
     list_display = ['backend_status_icon', 'name', 'version', 'backend_type']
     list_display_links = ('backend_status_icon', 'name', )
     readonly_fields = ('backend_status_text',)
+    form = ControllerAdminForm
 
     user_readonly_fields = []
 
diff --git a/xos/core/models/plcorebase.py b/xos/core/models/plcorebase.py
index 5c0d7ab..0822bf5 100644
--- a/xos/core/models/plcorebase.py
+++ b/xos/core/models/plcorebase.py
@@ -119,6 +119,22 @@
             validators[field.name] = l
         return validators
 
+    def get_backend_register(self, k, default=None):
+        try:
+            return json.loads(self.backend_register).get(k, default)
+        except AttributeError:
+            return default
+
+    def set_backend_register(self, k, v):
+        br = {}
+        try:
+            br=json.loads(self.backend_register)
+        except AttributeError:
+            br={}
+
+        br[k] = v
+        self.backend_register = json.dumps(br)
+
     def get_backend_details(self):
         try:
             scratchpad = json.loads(self.backend_register)