Merge branch 'master' of github.com:jermowery/xos into AddVPNService
diff --git a/.gitignore b/.gitignore
index 451dd79..61b07cd 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,9 +3,13 @@
 *.swp
 profile
 *.moved-aside
+.idea
+xos.iml
 xos/configurations/frontend/Dockerfile
 xos/core/xoslib/karma-*
 xos/core/xoslib/docs
 xos/core/xoslib/coverage
 node_modules
 xos/xos_configuration/*
+.idea/*
+xos.iml
diff --git a/Makefile b/Makefile
deleted file mode 100644
index 2b55526..0000000
--- a/Makefile
+++ /dev/null
@@ -1,55 +0,0 @@
-NAME = xos
-SPECFILE = $(NAME).spec
-VERSION = $(shell rpm -q --specfile $(SPECFILE) --qf '%{VERSION}\n' | head -n 1)
-RELEASE = $(shell rpm -q --specfile $(SPECFILE) --qf '%{RELEASE}\n' | head -n 1)
-
-UPLOAD_SLICE=princeton_planetstack
-
-PWD = $(shell pwd)
-
-dist rpm: $(NAME)-$(VERSION)-$(RELEASE).rpm
-
-$(NAME)-$(VERSION).tar.gz:
-	mkdir -p $(NAME)-$(VERSION)
-	rsync -av --exclude=.svn --exclude=.git --exclude=*.tar.gz --exclude=*.rpm --exclude=__history --exclude=$(NAME)-$(VERSION)/ ./ $(NAME)-$(VERSION)
-	tar -czf $@ $(NAME)-$(VERSION)
-	rm -fr $(NAME)-$(VERSION)
-
-$(NAME)-$(VERSION)-$(RELEASE).rpm: $(NAME)-$(VERSION).tar.gz
-	mkdir -p build
-	rpmbuild -bb --define '_sourcedir $(PWD)' \
-                --define '_builddir $(PWD)/build' \
-                --define '_srcrpmdir $(PWD)' \
-                --define '_rpmdir $(PWD)' \
-                --define '_build_name_fmt %%{NAME}-%%{VERSION}-%%{RELEASE}.%%{ARCH}.rpm' \
-                $(SPECFILE)
-
-srpm: $(NAME)-$(VERSION)-$(RELEASE).src.rpm
-$(NAME)-$(VERSION)-$(RELEASE).src.rpm: $(NAME)-$(VERSION).tar.gz
-	rpmbuild -bs --define "_sourcedir $$(pwd)" \
-                --define "_srcrpmdir $$(pwd)" \
-                $(SPECFILE)
-
-clean:
-	rm -f $(NAME)-$(VERSION).tar.gz $(NAME)-$(VERSION)-$(RELEASE).src.rpm $(NAME)-$(VERSION)-$(RELEASE).noarch.rpm
-	rm -rf build
-
-upload: $(NAME)-$(VERSION)-$(RELEASE).rpm
-ifndef UPLOAD_HOST
-	$(error please specify UPLOAD_HOST=<hostname> on make command line)
-endif
-	scp $(NAME)-$(VERSION)-$(RELEASE).x86_64.rpm $(UPLOAD_SLICE)@$(UPLOAD_HOST):/root/
-
-install: upload
-	ssh $(UPLOAD_SLICE)@$(UPLOAD_HOST) yum -y install gcc graphviz-devel graphviz-python postgresql postgresql-server python-pip python-psycopg2 libxslt-devel python-httplib2 GeoIP
-	ssh $(UPLOAD_SLICE)@$(UPLOAD_HOST) rpm --install --upgrade --replacefiles --replacepkgs /root/$(NAME)-$(VERSION)-$(RELEASE).x86_64.rpm   
-	scp /opt/planetstack/hpc_wizard/bigquery_credentials.dat /opt/planetstack/hpc_wizard/client_secrets.json $(UPLOAD_SLICE)@$(UPLOAD_HOST):/opt/planetstack/hpc_wizard/ 
-
-install-keys:
-ifndef UPLOAD_HOST
-	$(error please specify UPLOAD_HOST=<hostname> on make command line)
-endif
-	scp /opt/planetstack/hpc_wizard/bigquery_credentials.dat /opt/planetstack/hpc_wizard/client_secrets.json $(UPLOAD_SLICE)@$(UPLOAD_HOST):/opt/planetstack/hpc_wizard/
-
-.PHONY: dist
-
diff --git a/README.md b/README.md
index 7a72658..ab36a2c 100644
--- a/README.md
+++ b/README.md
@@ -7,7 +7,10 @@
 Additional design notes, presentations, and other collateral are 
 also available at http://xosproject.org and http://cord.onosproject.org.
 
-The quickest way to get started is to look at the collection of
+One quick way to get started is to build and run the containers in
+*containers* (see the README in that directory for more information).
+
+Another quick way to get started is to look at the collection of
 canned configurations in *xos/configurations*. The *cord* 
 configuration in that directory corresponds to our current 
 CORD development environment, and the README you'll find there
diff --git a/ansible-hosts b/ansible-hosts
deleted file mode 100644
index 0dd74f1..0000000
--- a/ansible-hosts
+++ /dev/null
@@ -1,2 +0,0 @@
-[localhost]
-127.0.0.1
diff --git a/containers/README.md b/containers/README.md
index fb53887..46f970e 100644
--- a/containers/README.md
+++ b/containers/README.md
@@ -17,7 +17,7 @@
 To build and run the database container:
 
 ```
-$ cd postgres; make build && make run
+$ cd postgresql; make build && make run
 ```
 
 #### XOS Container
@@ -29,7 +29,7 @@
 ```
 
 You should now be able to access the login page by visiting
-`http://localhost:80` and log in using the default `paadmin@vicci.org` account
+`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:
diff --git a/containers/synchronizer/Makefile b/containers/synchronizer/Makefile
index 3b10312..352616a 100644
--- a/containers/synchronizer/Makefile
+++ b/containers/synchronizer/Makefile
@@ -3,13 +3,13 @@
 NO_DOCKER_CACHE?=false
 
 .PHONY: build
-build: ; docker build --no-cache=${NO_DOCKER_CACHE} --rm -t ${IMAGE_NAME} .
+build: ; sudo docker build --no-cache=${NO_DOCKER_CACHE} --rm -t ${IMAGE_NAME} .
 
 .PHONY: run
-run: ; docker run -d --name ${CONTAINER_NAME} -v /usr/local/share/ca-certificates:/usr/local/share/ca-certificates:ro ${IMAGE_NAME}
+run: ; sudo docker run -d --name ${CONTAINER_NAME} -v /usr/local/share/ca-certificates:/usr/local/share/ca-certificates:ro ${IMAGE_NAME}
 
 .PHONY: stop
-stop: ; docker stop ${CONTAINER_NAME}
+stop: ; sudo docker stop ${CONTAINER_NAME}
 
 .PHONY: rm
-rm: ; docker rm ${CONTAINER_NAME}
+rm: ; sudo docker rm ${CONTAINER_NAME}
diff --git a/containers/synchronizer/conf/synchronizer.conf b/containers/synchronizer/conf/synchronizer.conf
index cda6716..2131a25 100644
--- a/containers/synchronizer/conf/synchronizer.conf
+++ b/containers/synchronizer/conf/synchronizer.conf
@@ -4,6 +4,6 @@
 nodaemon=true
 
 [program:synchronizer]
-command=python /opt/xos/xos-observer.py
+command=python /opt/xos/synchronizers/openstack/xos-synchronizer.py
 stderr_logfile=/var/log/supervisor/synchronizer.err.log
 stdout_logfile=/var/log/supervisor/synchronizer.out.log
diff --git a/containers/xos/Dockerfile b/containers/xos/Dockerfile
index c70085f..7e9db23 100644
--- a/containers/xos/Dockerfile
+++ b/containers/xos/Dockerfile
@@ -1,4 +1,4 @@
-FROM       python:2.7.11
+FROM       ubuntu:14.04.2
 
 # XXX Workaround for docker bug:
 # https://github.com/docker/docker/issues/6345
@@ -75,8 +75,8 @@
 # Install XOS
 RUN git clone git://github.com/open-cloud/xos.git /tmp/xos && \
     mv /tmp/xos/xos /opt/ && \
-    chmod +x /opt/xos/scripts/opencloud && \
-    /opt/xos/scripts/opencloud genkeys
+    chmod +x /opt/xos/tools/xos-manage && \
+    /opt/xos/tools/xos-manage genkeys
 
 # install Tosca engine
 RUN chmod +x /opt/xos/tosca/run.py
diff --git a/containers/xos/Dockerfile.devel b/containers/xos/Dockerfile.devel
index abc6e46..29f1779 100644
--- a/containers/xos/Dockerfile.devel
+++ b/containers/xos/Dockerfile.devel
@@ -43,7 +43,7 @@
     django-crispy-forms \
     django-encrypted-fields \
     django-extensions \
-    django-filter \
+    django-filter==0.11.0 \
     django-geoposition \
     django-ipware \
     django_rest_swagger \
@@ -75,8 +75,8 @@
 
 # Install XOS
 ADD xos /opt/xos
-RUN chmod +x /opt/xos/scripts/opencloud
-RUN /opt/xos/scripts/opencloud genkeys
+RUN chmod +x /opt/xos/tools/xos-manage
+RUN /opt/xos/tools/xos-manage genkeys
 
 # install Tosca engine
 RUN chmod +x /opt/xos/tosca/run.py
diff --git a/containers/xos/Dockerfile.templ b/containers/xos/Dockerfile.templ
index 4bb201e..828c16b 100644
--- a/containers/xos/Dockerfile.templ
+++ b/containers/xos/Dockerfile.templ
@@ -70,8 +70,8 @@
 # Install XOS
 RUN git clone XOS_GIT_REPO -b XOS_GIT_BRANCH /tmp/xos && \
     mv /tmp/xos/xos /opt/ && \
-    chmod +x /opt/xos/scripts/opencloud && \
-    /opt/xos/scripts/opencloud genkeys
+    chmod +x /opt/xos/tools/xos-manage && \
+    /opt/xos/tools/xos-manage genkeys
 
 # install Tosca engine
 RUN bash /opt/xos/tosca/install_tosca.sh
diff --git a/containers/xos/Makefile b/containers/xos/Makefile
index 4e0d40a..0ba043d 100644
--- a/containers/xos/Makefile
+++ b/containers/xos/Makefile
@@ -6,22 +6,22 @@
 NO_DOCKER_CACHE?=false
 
 .PHONY: build
-build: ; make -C ../../xos/configurations/common -f Makefile.cloudlab; docker build --no-cache=${NO_DOCKER_CACHE} --rm -t ${IMAGE_NAME} .
+build: ; sudo docker build --no-cache=${NO_DOCKER_CACHE} --rm -t ${IMAGE_NAME} .
 
 .PHONY: custom
 custom: ; cat Dockerfile.templ | sed -e "s|XOS_GIT_REPO|${XOS_GIT_REPO}|g" -e "s|XOS_GIT_BRANCH|${XOS_GIT_BRANCH}|g" | docker build --no-cache=${NO_DOCKER_CACHE} --rm -t ${IMAGE_NAME} -
 
 .PHONY: devel
-devel: ; cd ../..; ls; docker build -f containers/xos/Dockerfile.devel --no-cache=${NO_DOCKER_CACHE} --rm -t ${IMAGE_NAME} .
+devel: ; cd ../..; ls; sudo docker build -f containers/xos/Dockerfile.devel --no-cache=${NO_DOCKER_CACHE} --rm -t ${IMAGE_NAME} .
 
 .PHONY: run
-run: ; docker run -d --name ${CONTAINER_NAME} -p 80:8000 -v /usr/local/share/ca-certificates:/usr/local/share/ca-certificates:ro ${IMAGE_NAME}
+run: ; sudo docker run -d --name ${CONTAINER_NAME} -p 80:8000 -v /usr/local/share/ca-certificates:/usr/local/share/ca-certificates:ro ${IMAGE_NAME}
 
 .PHONY: runtosca
-runtosca: ; docker exec -it ${CONTAINER_NAME} /usr/bin/python /opt/xos/tosca/run.py padmin@vicci.org ${TOSCA_CONFIG_PATH}
+runtosca: ; sudo docker exec -it ${CONTAINER_NAME} /usr/bin/python /opt/xos/tosca/run.py padmin@vicci.org ${TOSCA_CONFIG_PATH}
 
 .PHONY: stop
-stop: ; docker stop ${CONTAINER_NAME}
+stop: ; sudo docker stop ${CONTAINER_NAME}
 
 .PHONY: rm
-rm: ; docker rm ${CONTAINER_NAME}
+rm: ; sudo docker rm ${CONTAINER_NAME}
diff --git a/containers/xos/initdb b/containers/xos/initdb
index 3252747..1f5b770 100755
--- a/containers/xos/initdb
+++ b/containers/xos/initdb
@@ -10,7 +10,7 @@
 docker rm $CONTAINER_NAME
 
 # init db schema
-docker run -it --name=$CONTAINER_NAME $IMAGE_NAME /opt/xos/scripts/opencloud makemigrations
+docker run -it --name=$CONTAINER_NAME $IMAGE_NAME /opt/xos/tools/xos-manage makemigrations
 # run overrides the CMD specifed in the Dockerfile, so we re-set the CMD in the final commit"
 docker commit --change="CMD update-ca-certificates && python /opt/xos/manage.py runserver 0.0.0.0:8000 --insecure" $CONTAINER_NAME $IMAGE_NAME
 docker rm $CONTAINER_NAME
diff --git a/docker-cp.sh b/docker-cp.sh
deleted file mode 100755
index bec511d..0000000
--- a/docker-cp.sh
+++ /dev/null
@@ -1,9 +0,0 @@
-#! /bin/bash                                                                                                             
-# script for copying stuff into running Docker container
-# usage: docker-cp.sh <src> <dest>
-# example: docker-cp.sh foo /tmp/foo
-
-XOS=$( docker ps|grep "xos"|awk '{print $NF}' )
-FOLDER=`docker inspect -f   '{{.Id}}' $XOS`
-#cp $1 /var/lib/docker/aufs/mnt/$FOLDER/$2
-docker cp $1 $XOS:$2
diff --git a/external/keystone_user.py b/external/keystone_user.py
deleted file mode 100644
index 1245eec..0000000
--- a/external/keystone_user.py
+++ /dev/null
@@ -1,407 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-
-# Based on Jimmy Tang's implementation
-
-DOCUMENTATION = '''
----
-module: keystone_user
-version_added: "1.2"
-short_description: Manage OpenStack Identity (keystone) users, tenants and roles
-description:
-   - Manage users,tenants, roles from OpenStack.
-options:
-   login_user:
-     description:
-        - login username to authenticate to keystone
-     required: false
-     default: admin
-   login_password:
-     description:
-        - Password of login user
-     required: false
-     default: 'yes'
-   login_tenant_name:
-     description:
-        - The tenant login_user belongs to
-     required: false
-     default: None
-     version_added: "1.3"
-   token:
-     description:
-        - The token to be uses in case the password is not specified
-     required: false
-     default: None
-   endpoint:
-     description:
-        - The keystone url for authentication
-     required: false
-     default: 'http://127.0.0.1:35357/v2.0/'
-   user:
-     description:
-        - The name of the user that has to added/removed from OpenStack
-     required: false
-     default: None
-   password:
-     description:
-        - The password to be assigned to the user
-     required: false
-     default: None
-   tenant:
-     description:
-        - The tenant name that has be added/removed
-     required: false
-     default: None
-   tenant_description:
-     description:
-        - A description for the tenant
-     required: false
-     default: None
-   email:
-     description:
-        - An email address for the user
-     required: false
-     default: None
-   role:
-     description:
-        - The name of the role to be assigned or created
-     required: false
-     default: None
-   state:
-     description:
-        - Indicate desired state of the resource
-     choices: ['present', 'absent']
-     default: present
-requirements: [ python-keystoneclient ]
-author: Lorin Hochstein
-'''
-
-EXAMPLES = '''
-# Create a tenant
-- keystone_user: tenant=demo tenant_description="Default Tenant"
-
-# Create a user
-- keystone_user: user=john tenant=demo password=secrete
-
-# Apply the admin role to the john user in the demo tenant
-- keystone_user: role=admin user=john tenant=demo
-'''
-
-try:
-    from keystoneclient.v2_0 import client
-except ImportError:
-    keystoneclient_found = False
-else:
-    keystoneclient_found = True
-
-
-def authenticate(endpoint, token, login_user, login_password, login_tenant_name):
-    """Return a keystone client object"""
-
-    if token:
-        return client.Client(endpoint=endpoint, token=token)
-    else:
-        return client.Client(auth_url=endpoint, username=login_user,
-                             password=login_password, tenant_name=login_tenant_name)
-
-
-def tenant_exists(keystone, tenant):
-    """ Return True if tenant already exists"""
-    return tenant in [x.name for x in keystone.tenants.list()]
-
-
-def user_exists(keystone, user):
-    """" Return True if user already exists"""
-    return user in [x.name for x in keystone.users.list()]
-
-
-def get_tenant(keystone, name):
-    """ Retrieve a tenant by name"""
-    tenants = [x for x in keystone.tenants.list() if x.name == name]
-    count = len(tenants)
-    if count == 0:
-        raise KeyError("No keystone tenants with name %s" % name)
-    elif count > 1:
-        raise ValueError("%d tenants with name %s" % (count, name))
-    else:
-        return tenants[0]
-
-
-def get_user(keystone, name):
-    """ Retrieve a user by name"""
-    users = [x for x in keystone.users.list() if x.name == name]
-    count = len(users)
-    if count == 0:
-        raise KeyError("No keystone users with name %s" % name)
-    elif count > 1:
-        raise ValueError("%d users with name %s" % (count, name))
-    else:
-        return users[0]
-
-
-def get_role(keystone, name):
-    """ Retrieve a role by name"""
-    roles = [x for x in keystone.roles.list() if x.name == name]
-    count = len(roles)
-    if count == 0:
-        raise KeyError("No keystone roles with name %s" % name)
-    elif count > 1:
-        raise ValueError("%d roles with name %s" % (count, name))
-    else:
-        return roles[0]
-
-
-def get_tenant_id(keystone, name):
-    return get_tenant(keystone, name).id
-
-
-def get_user_id(keystone, name):
-    return get_user(keystone, name).id
-
-
-def ensure_tenant_exists(keystone, tenant_name, tenant_description,
-                         check_mode):
-    """ Ensure that a tenant exists.
-
-        Return (True, id) if a new tenant was created, (False, None) if it
-        already existed.
-    """
-
-    # Check if tenant already exists
-    try:
-        tenant = get_tenant(keystone, tenant_name)
-    except KeyError:
-        # Tenant doesn't exist yet
-        pass
-    else:
-        if tenant.description == tenant_description:
-            return (False, tenant.id)
-        else:
-            # We need to update the tenant description
-            if check_mode:
-                return (True, tenant.id)
-            else:
-                tenant.update(description=tenant_description)
-                return (True, tenant.id)
-
-    # We now know we will have to create a new tenant
-    if check_mode:
-        return (True, None)
-
-    ks_tenant = keystone.tenants.create(tenant_name=tenant_name,
-                                        description=tenant_description,
-                                        enabled=True)
-    return (True, ks_tenant.id)
-    
-
-def ensure_tenant_absent(keystone, tenant, check_mode):
-    """ Ensure that a tenant does not exist
-
-         Return True if the tenant was removed, False if it didn't exist
-         in the first place
-    """
-    if not tenant_exists(keystone, tenant):
-        return False
-
-    # We now know we will have to delete the tenant
-    if check_mode:
-        return True
-
-def ensure_user_exists_and_is_current(keystone, endpoint, user_name, password, email, tenant_name,
-                       check_mode):
-    """ Check if user exists and has the same email and password
-
-        Return (True, id) if a new user was created or one was updated, (False, id) if the user is 
-        up to date
-    """
-    
-    # Check if tenant already exists
-    try:
-        user = get_user(keystone, user_name)
-    except KeyError:
-        # Tenant doesn't exist yet
-        user = None
-        pass
-    else:
-        # User does exist, check if it's current
-        try:
-            authenticate(endpoint, None, user_name, password, tenant_name)
-        except: 
-            pass
-        else:
-            # It's current, we're done
-            return (False, user.id)
-
-    # We now know we will have to create a new user
-    if check_mode:
-        return (True, None)
-
-    tenant = get_tenant(keystone, tenant_name)
-
-    if (not user):
-        user = keystone.users.create(name=user_name, password=password,
-                                 email=email, tenant_id=tenant.id)
-    else:
-        user = keystone.users.update_password(user.id, password)
-        
-    return (True, user.id)
-
-
-def ensure_role_exists(keystone, user_name, tenant_name, role_name,
-                       check_mode):
-    """ Check if role exists
-
-        Return (True, id) if a new role was created or if the role was newly
-        assigned to the user for the tenant. (False, id) if the role already
-        exists and was already assigned to the user ofr the tenant.
-
-    """
-    # Check if the user has the role in the tenant
-    user = get_user(keystone, user_name)
-    tenant = get_tenant(keystone, tenant_name)
-    roles = [x for x in keystone.roles.roles_for_user(user, tenant)
-                     if x.name == role_name]
-    count = len(roles)
-
-    if count == 1:
-        # If the role is in there, we are done
-        role = roles[0]
-        return (False, role.id)
-    elif count > 1:
-        # Too many roles with the same name, throw an error
-        raise ValueError("%d roles with name %s" % (count, role_name))
-
-    # At this point, we know we will need to make changes
-    if check_mode:
-        return (True, None)
-
-    # Get the role if it exists
-    try:
-        role = get_role(keystone, role_name)
-    except KeyError:
-        # Role doesn't exist yet
-        role = keystone.roles.create(role_name)
-
-    # Associate the role with the user in the admin
-    keystone.roles.add_user_role(user, role, tenant)
-    return (True, role.id)
-
-
-def ensure_user_absent(keystone, user, check_mode):
-    raise NotImplementedError("Not yet implemented")
-
-
-def ensure_role_absent(keystone, uesr, tenant, role, check_mode):
-    raise NotImplementedError("Not yet implemented")
-
-
-def main():
-
-    argument_spec = openstack_argument_spec()
-    argument_spec.update(dict(
-            tenant_description=dict(required=False),
-            email=dict(required=False),
-            user=dict(required=False),
-            tenant=dict(required=False),
-            password=dict(required=False),
-            role=dict(required=False),
-            state=dict(default='present', choices=['present', 'absent']),
-            endpoint=dict(required=False,
-                          default="http://127.0.0.1:35357/v2.0"),
-            token=dict(required=False),
-            login_user=dict(required=False),
-            login_password=dict(required=False),
-            login_tenant_name=dict(required=False)
-    ))
-    # keystone operations themselves take an endpoint, not a keystone auth_url
-    del(argument_spec['auth_url'])
-    module = AnsibleModule(
-        argument_spec=argument_spec,
-        supports_check_mode=True,
-        mutually_exclusive=[['token', 'login_user'],
-                            ['token', 'login_password'],
-                            ['token', 'login_tenant_name']]
-    )
-
-    if not keystoneclient_found:
-        module.fail_json(msg="the python-keystoneclient module is required")
-
-    user = module.params['user']
-    password = module.params['password']
-    tenant = module.params['tenant']
-    tenant_description = module.params['tenant_description']
-    email = module.params['email']
-    role = module.params['role']
-    state = module.params['state']
-    endpoint = module.params['endpoint']
-    token = module.params['token']
-    login_user = module.params['login_user']
-    login_password = module.params['login_password']
-    login_tenant_name = module.params['login_tenant_name']
-
-    keystone = authenticate(endpoint, token, login_user, login_password, login_tenant_name)
-
-    check_mode = module.check_mode
-
-    try:
-        d = dispatch(keystone, user, password, tenant, tenant_description,
-                     email, role, state, endpoint, token, login_user,
-                     login_password, check_mode)
-    except Exception, e:
-        if check_mode:
-            # If we have a failure in check mode
-            module.exit_json(changed=True,
-                             msg="exception: %s" % e)
-        else:
-            module.fail_json(msg="exception: %s" % e)
-    else:
-        module.exit_json(**d)
-
-
-def dispatch(keystone, user=None, password=None, tenant=None,
-             tenant_description=None, email=None, role=None,
-             state="present", endpoint=None, token=None, login_user=None,
-             login_password=None, check_mode=False):
-    """ Dispatch to the appropriate method.
-
-        Returns a dict that will be passed to exit_json
-
-        tenant  user  role   state
-        ------  ----  ----  --------
-          X                  present     ensure_tenant_exists
-          X                  absent      ensure_tenant_absent
-          X      X           present     ensure_user_exists
-          X      X           absent      ensure_user_absent
-          X      X     X     present     ensure_role_exists
-          X      X     X     absent      ensure_role_absent
-
-
-        """
-    changed = False
-    id = None
-    if tenant and not user and not role and state == "present":
-        changed, id = ensure_tenant_exists(keystone, tenant,
-                                           tenant_description, check_mode)
-    elif tenant and not user and not role and state == "absent":
-        changed = ensure_tenant_absent(keystone, tenant, check_mode)
-    elif tenant and user and not role and state == "present":
-        changed, id = ensure_user_exists_and_is_current(keystone, endpoint, user, password,
-                                         email, tenant, check_mode)
-    elif tenant and user and not role and state == "absent":
-        changed = ensure_user_absent(keystone, user, check_mode)
-    elif tenant and user and role and state == "present":
-        changed, id = ensure_role_exists(keystone, user, tenant, role,
-                                         check_mode)
-    elif tenant and user and role and state == "absent":
-        changed = ensure_role_absent(keystone, user, tenant, role, check_mode)
-    else:
-        # Should never reach here
-        raise ValueError("Code should never reach here")
-
-    return dict(changed=changed, id=id)
-
-# import module snippets
-from ansible.module_utils.basic import *
-from ansible.module_utils.openstack import *
-if __name__ == '__main__':
-    main()
diff --git a/gui/.yo-rc.json b/gui/.yo-rc.json
new file mode 100644
index 0000000..33606db
--- /dev/null
+++ b/gui/.yo-rc.json
@@ -0,0 +1,6 @@
+{
+  "generator-xos": {
+    "name": "sampleView",
+    "folder": "ngXosViews"
+  }
+}
\ No newline at end of file
diff --git a/gui/README.md b/gui/README.md
new file mode 100644
index 0000000..ad147e6
--- /dev/null
+++ b/gui/README.md
@@ -0,0 +1,133 @@
+# ngXosLib
+
+This is a collection of helpers to develop views as Angular SPA.
+
+## Tools
+
+These tools are designed to help develop a GUI view. They assume XOS is running on your system and responding at: `localhost:9999`. The `xos/configurations/frontend` is normally sufficient for GUI development.
+
+### Apigen
+
+Usage: `npm run apigen`
+
+This tool generates an angular resource file for each endpoint available in Swagger.
+
+>You can generate api related documentation with: `npm run apidoc`. The output is locate in `api/docs`. You can also see a list of available methods through Swagger at `http://localhost:9999/docs/`
+
+### Vendors
+
+XOS comes with a set of common libraries, as listed in `bower.json`:
+- angular
+- angular-route
+- angular-resource
+- angular-cookie
+- ng-lodash
+
+These libraries are served through Django, so they are not included in your minified vendor file. To add a library and generate a new file (that will override the old one):
+- enter `ngXosLib` folder
+- run `bower install [myPackage] --save`
+- rebuild the file with `gulp vendor`
+
+>_NOTE before adding libraries please discuss it on the devel list to avoid this file becoming too big_
+
+### Helpers
+
+XOS comes with a helper library that is automatically loaded in the Django template.
+
+To use it, add `xos.helpers` to your required modules:
+
+```
+angular.module('xos.myView', [
+  'xos.helpers'
+])
+```
+
+It will automatically add a `token` to all your requests. Eventually you can take advantage of some other services:
+
+- **NoHyperlinks Interceptor**: will add a `?no_hyperlinks=1` to your request, to tell Django to return ids instead of links.
+- **XosApi** wrapper for `/xos` endpoints.
+- **XoslibApi** wrapper for `/xoslib` endpoints.
+- **HpcApi** wrapper for `/hpcapi` endpoints.
+
+>_NOTE: for the API related service, check the documentation in Section [Apigen](#apigen)._
+
+# ngXosViews
+
+In addition to auto-generated Django Admin Views and developer-defined Service Views, a set of custom views can be generate in XOS.
+
+These views are based on AngularJs and they communicate with XOS through the REST APIs, providing a powerful and flexible way to present and manage data.
+
+## How to Create a View
+
+### Getting Started
+
+We have created a [yeoman](http://yeoman.io/) generator to help scaffold views.
+
+>As it is in an early stage of development, you should manually link it to your system. To do this enter `/gui/ngXosLib/generator-xos` and run `npm link`.
+
+#### To Generate a New View
+
+From `/gui` run `yo xos`. This command will create a new folder with the provided name in `/gui/ngXosViews` that contains your application.
+
+>If you left View name empty it should be `/gui/ngXosViews/sampleView`
+
+#### Run a Development Server
+
+In your `view` folder run `npm start`.
+
+This will install the required dependencies and start a local server with [BrowserSync](http://www.browsersync.io/).
+
+#### Publish Your View
+
+Once your view is done, from your view root folder, run: `npm run build`.
+
+This will build your application and copy files in the appropriate directories for use by Django.
+
+At this point you can enter: `http://localhost:9999/admin/core/dashboardview/add/` and add your custom view.
+
+>_NOTE: url field should be `template:xosSampleView`_
+
+##### Add This View to a Configuration Setup
+
+You can easily set this as a default view in a configuration by editing the `{config}.yml` file for that configuration. Add these lines:
+
+```
+{TabName}:                                    
+  type: tosca.nodes.DashboardView              
+  properties:                                  
+      url: template:{viewName}     
+```
+
+Then edit the _User_ section (normally it starts with `padmin@vicci.org`) as follows:
+
+```
+padmin@vicci.org:                                          
+  type: tosca.nodes.User                                   
+  properties:                                              
+      firstname: XOS                                       
+      lastname: admin                                      
+      is_admin: true                                       
+  requirements:                                            
+      - tenant_dashboard:                                  
+          node: Tenant                                     
+          relationship: tosca.relationships.UsesDashboard  
+      - {custom_dashboard}:                              
+          node: {TabName}                                 
+          relationship: tosca.relationships.UsesDashboard  
+```
+
+#### Install Dependencies in Your App
+
+To install a local dependency use bower with `--save`. Common modules are saved in `devDependencies` as they already loaded in the Django template.
+
+The `npm start` command watches your dependencies and will automatically inject it in your `index.html`.
+
+#### Linting
+
+A styleguide is enforced through [EsLint](http://eslint.org/) and is checked during the build process. We **highly** recommend installing the linter in your editor to have realtime hints.
+
+#### Test
+
+The generator sets up a test environment with a default test.
+To run it, execute: `npm test`
+
diff --git a/xos/core/xoslib/ngXosLib/.bowerrc b/gui/ngXosLib/.bowerrc
similarity index 100%
rename from xos/core/xoslib/ngXosLib/.bowerrc
rename to gui/ngXosLib/.bowerrc
diff --git a/xos/core/xoslib/ngXosLib/.gitignore b/gui/ngXosLib/.gitignore
similarity index 100%
rename from xos/core/xoslib/ngXosLib/.gitignore
rename to gui/ngXosLib/.gitignore
diff --git a/gui/ngXosLib/README.md b/gui/ngXosLib/README.md
new file mode 100644
index 0000000..aabae3e
--- /dev/null
+++ b/gui/ngXosLib/README.md
@@ -0,0 +1,101 @@
+# ngXosLib
+
+A collection of programs to develop Views as Angular SPA.
+
+## Tools
+
+These tools are designed to help develop UIs for XOS. They assume XOS is running on your system at `localhost:9999`. The `xos/configurations/frontend` is normally a sufficient configuration for development.
+
+### Apigen
+
+Usage: `npm run apigen`
+
+This tool generates an angular resource file for each endpoint available in Swagger.
+
+>You can generate api related documentation with: `npm run apidoc`. The output is locate in `api/docs`. You can also see a list of available methods through Swagger at `http://localhost:9999/docs/`
+
+### Vendors
+
+XOS comes with a set of common libraries, as listed in `bower.json`:
+- angular
+- angular-route
+- angular-resource
+- angular-cookie
+- ng-lodash
+
+These libraries are served through Django, so they will not be included in your minified vendor file. To add a library and generate a new file (that will override the old one):
+- enter `ngXosLib` folder
+- run `bower install [myPackage] --save`
+- rebuild the file with `gulp vendor`
+
+>_NOTE: before adding libraries please discuss it on the devel list to avoid this file becoming huge_
+
+### Helpers
+
+XOS comes with a helper library that is automatically loaded in the Django template.
+
+To use it, add `xos.helpers` to your required modules:
+
+```
+angular.module('xos.myView', [
+  'xos.helpers'
+])
+```
+
+It will automatically add a `token` to all your requests. Eventually you can take advantage of some other services:
+
+- **NoHyperlinks Interceptor**: will add a `?no_hyperlinks=1` to your request, to tell Django to return ids instead of links.
+- **XosApi** wrapper for `/xos` endpoints.
+- **XoslibApi** wrapper for `/xoslib` endpoints.
+- **HpcApi** wrapper for `/hpcapi` endpoints.
+
+>_NOTE: for the API related service, check documentation in [Apigen](#apigen) section._
+
+### Yo XOS
+
+We have created a [yeoman](http://yeoman.io/) generator to help to scaffold views.
+
+>As it is in an early stage of development you should manually link it to your system. To do this, enter `xos/core/xoslib/ngXosLib/generator-xos` and run `npm link`.
+
+#### To Generate a New View
+
+From `xos/core/xoslib` run `yo xos`. This command creates a new folder with the provided name in: `xos/core/xoslib/ngXosViews` that contain your application.
+
+>If you left the View name empty, it should be `xos/core/xoslib/ngXosViews/sampleView`
+
+#### Run a Development Server
+
+In your `view` folder run `npm start`.
+
+_This will install the required dependencies and start a local server with [BrowserSync](http://www.browsersync.io/)_
+
+#### Publish your View
+
+Once your view is done, from your view root folder, run: `npm run build`.
+
+This will build your application and copy files in the appropriate locations to be used by Django.
+
+At this point you can enter: `http://localhost:9999/admin/core/dashboardview/add/` and add your custom view.
+
+>_NOTE url field should be `template:xosSampleView`_
+
+#### Install Dependencies in Your app
+
+To install a local dependency, use bower with `--save`. Common modules are saved in `devDependencies` as they already loaded in the Django template.
+
+The `npm start` command watches your dependencies and automatically injects it in your `index.html`.
+
+#### Linting
+
+A styleguide is enforced through [EsLint](http://eslint.org/) and is checked during the build process. We **highly** suggest installing the linter in your editor to have realtime hints.
+
+#### Test
+
+The generator sets up a test environment with a default test.
+To run it execute: `npm test`
+
+## TODO
+
+- Use Angular $resource instead of $http
+- Use ngDoc instead of jsDoc
+- Define styleguide (both visual and js) and if needed define some UI components
diff --git a/xos/core/xoslib/ngXosLib/api/.gitignore b/gui/ngXosLib/api/.gitignore
similarity index 100%
rename from xos/core/xoslib/ngXosLib/api/.gitignore
rename to gui/ngXosLib/api/.gitignore
diff --git a/xos/core/xoslib/ngXosLib/api/ng-hpcapi.js b/gui/ngXosLib/api/ng-hpcapi.js
similarity index 100%
rename from xos/core/xoslib/ngXosLib/api/ng-hpcapi.js
rename to gui/ngXosLib/api/ng-hpcapi.js
diff --git a/xos/core/xoslib/ngXosLib/api/ng-xos.js b/gui/ngXosLib/api/ng-xos.js
similarity index 100%
rename from xos/core/xoslib/ngXosLib/api/ng-xos.js
rename to gui/ngXosLib/api/ng-xos.js
diff --git a/xos/core/xoslib/ngXosLib/api/ng-xoslib.js b/gui/ngXosLib/api/ng-xoslib.js
similarity index 100%
rename from xos/core/xoslib/ngXosLib/api/ng-xoslib.js
rename to gui/ngXosLib/api/ng-xoslib.js
diff --git a/xos/core/xoslib/ngXosLib/apiTemplates/custom-angular-class.mustache b/gui/ngXosLib/apiTemplates/custom-angular-class.mustache
similarity index 100%
rename from xos/core/xoslib/ngXosLib/apiTemplates/custom-angular-class.mustache
rename to gui/ngXosLib/apiTemplates/custom-angular-class.mustache
diff --git a/xos/core/xoslib/ngXosLib/bower.json b/gui/ngXosLib/bower.json
similarity index 100%
rename from xos/core/xoslib/ngXosLib/bower.json
rename to gui/ngXosLib/bower.json
diff --git a/xos/core/xoslib/ngXosLib/generator-xos/app/index.js b/gui/ngXosLib/generator-xos/app/index.js
similarity index 100%
rename from xos/core/xoslib/ngXosLib/generator-xos/app/index.js
rename to gui/ngXosLib/generator-xos/app/index.js
diff --git a/xos/core/xoslib/ngXosLib/generator-xos/app/templates/.bowerrc b/gui/ngXosLib/generator-xos/app/templates/.bowerrc
similarity index 100%
rename from xos/core/xoslib/ngXosLib/generator-xos/app/templates/.bowerrc
rename to gui/ngXosLib/generator-xos/app/templates/.bowerrc
diff --git a/xos/core/xoslib/ngXosLib/generator-xos/app/templates/.eslintrc b/gui/ngXosLib/generator-xos/app/templates/.eslintrc
similarity index 100%
rename from xos/core/xoslib/ngXosLib/generator-xos/app/templates/.eslintrc
rename to gui/ngXosLib/generator-xos/app/templates/.eslintrc
diff --git a/xos/core/xoslib/ngXosLib/generator-xos/app/templates/.gitignore b/gui/ngXosLib/generator-xos/app/templates/.gitignore
similarity index 100%
rename from xos/core/xoslib/ngXosLib/generator-xos/app/templates/.gitignore
rename to gui/ngXosLib/generator-xos/app/templates/.gitignore
diff --git a/xos/core/xoslib/ngXosLib/generator-xos/app/templates/bower.json b/gui/ngXosLib/generator-xos/app/templates/bower.json
similarity index 100%
rename from xos/core/xoslib/ngXosLib/generator-xos/app/templates/bower.json
rename to gui/ngXosLib/generator-xos/app/templates/bower.json
diff --git a/xos/core/xoslib/ngXosLib/generator-xos/app/templates/env/default.js b/gui/ngXosLib/generator-xos/app/templates/env/default.js
similarity index 100%
rename from xos/core/xoslib/ngXosLib/generator-xos/app/templates/env/default.js
rename to gui/ngXosLib/generator-xos/app/templates/env/default.js
diff --git a/xos/core/xoslib/ngXosLib/generator-xos/app/templates/gulp/build.js b/gui/ngXosLib/generator-xos/app/templates/gulp/build.js
similarity index 100%
rename from xos/core/xoslib/ngXosLib/generator-xos/app/templates/gulp/build.js
rename to gui/ngXosLib/generator-xos/app/templates/gulp/build.js
diff --git a/xos/core/xoslib/ngXosLib/generator-xos/app/templates/gulp/server.js b/gui/ngXosLib/generator-xos/app/templates/gulp/server.js
similarity index 100%
rename from xos/core/xoslib/ngXosLib/generator-xos/app/templates/gulp/server.js
rename to gui/ngXosLib/generator-xos/app/templates/gulp/server.js
diff --git a/xos/core/xoslib/ngXosViews/ceilometerDashboard/gulpfile.js b/gui/ngXosLib/generator-xos/app/templates/gulpfile.js
similarity index 70%
copy from xos/core/xoslib/ngXosViews/ceilometerDashboard/gulpfile.js
copy to gui/ngXosLib/generator-xos/app/templates/gulpfile.js
index de911e9..b2cdab8 100644
--- a/xos/core/xoslib/ngXosViews/ceilometerDashboard/gulpfile.js
+++ b/gui/ngXosLib/generator-xos/app/templates/gulpfile.js
@@ -5,14 +5,13 @@
 
 var options = {
   src: 'src/',
-  css: 'src/css/',
   scripts: 'src/js/',
   tmp: 'src/.tmp',
   dist: 'dist/',
   api: '../../ngXosLib/api/',
   helpers: '../../ngXosLib/xosHelpers/src/',
-  static: '../../static/', // this is the django static folder
-  dashboards: '../../dashboards/' // this is the django html folder
+  static: '../../../xos/core/xoslib/static/', // this is the django static folder
+  dashboards: '../../../xos/core/xoslib/dashboards/' // this is the django html folder
 };
 
 wrench.readdirSyncRecursive('./gulp')
diff --git a/xos/core/xoslib/ngXosLib/generator-xos/app/templates/karma.conf.js b/gui/ngXosLib/generator-xos/app/templates/karma.conf.js
similarity index 100%
rename from xos/core/xoslib/ngXosLib/generator-xos/app/templates/karma.conf.js
rename to gui/ngXosLib/generator-xos/app/templates/karma.conf.js
diff --git a/xos/core/xoslib/ngXosLib/generator-xos/app/templates/package.json b/gui/ngXosLib/generator-xos/app/templates/package.json
similarity index 100%
rename from xos/core/xoslib/ngXosLib/generator-xos/app/templates/package.json
rename to gui/ngXosLib/generator-xos/app/templates/package.json
diff --git a/xos/core/xoslib/ngXosLib/generator-xos/app/templates/spec/sample.test.js b/gui/ngXosLib/generator-xos/app/templates/spec/sample.test.js
similarity index 100%
rename from xos/core/xoslib/ngXosLib/generator-xos/app/templates/spec/sample.test.js
rename to gui/ngXosLib/generator-xos/app/templates/spec/sample.test.js
diff --git a/xos/core/xoslib/ngXosLib/generator-xos/app/templates/src/css/dev.css b/gui/ngXosLib/generator-xos/app/templates/src/css/dev.css
similarity index 100%
rename from xos/core/xoslib/ngXosLib/generator-xos/app/templates/src/css/dev.css
rename to gui/ngXosLib/generator-xos/app/templates/src/css/dev.css
diff --git a/xos/core/xoslib/ngXosLib/generator-xos/app/templates/src/index.html b/gui/ngXosLib/generator-xos/app/templates/src/index.html
similarity index 100%
rename from xos/core/xoslib/ngXosLib/generator-xos/app/templates/src/index.html
rename to gui/ngXosLib/generator-xos/app/templates/src/index.html
diff --git a/xos/core/xoslib/ngXosLib/generator-xos/app/templates/src/js/main.js b/gui/ngXosLib/generator-xos/app/templates/src/js/main.js
similarity index 100%
rename from xos/core/xoslib/ngXosLib/generator-xos/app/templates/src/js/main.js
rename to gui/ngXosLib/generator-xos/app/templates/src/js/main.js
diff --git a/xos/core/xoslib/ngXosLib/generator-xos/app/templates/src/templates/users-list.tpl.html b/gui/ngXosLib/generator-xos/app/templates/src/templates/users-list.tpl.html
similarity index 100%
rename from xos/core/xoslib/ngXosLib/generator-xos/app/templates/src/templates/users-list.tpl.html
rename to gui/ngXosLib/generator-xos/app/templates/src/templates/users-list.tpl.html
diff --git a/xos/core/xoslib/ngXosLib/generator-xos/package.json b/gui/ngXosLib/generator-xos/package.json
similarity index 100%
rename from xos/core/xoslib/ngXosLib/generator-xos/package.json
rename to gui/ngXosLib/generator-xos/package.json
diff --git a/xos/core/xoslib/ngXosLib/gulp/ngXosHelpers.js b/gui/ngXosLib/gulp/ngXosHelpers.js
similarity index 100%
rename from xos/core/xoslib/ngXosLib/gulp/ngXosHelpers.js
rename to gui/ngXosLib/gulp/ngXosHelpers.js
diff --git a/xos/core/xoslib/ngXosLib/gulp/ngXosVendor.js b/gui/ngXosLib/gulp/ngXosVendor.js
similarity index 100%
rename from xos/core/xoslib/ngXosLib/gulp/ngXosVendor.js
rename to gui/ngXosLib/gulp/ngXosVendor.js
diff --git a/xos/core/xoslib/ngXosLib/gulpfile.js b/gui/ngXosLib/gulpfile.js
similarity index 67%
rename from xos/core/xoslib/ngXosLib/gulpfile.js
rename to gui/ngXosLib/gulpfile.js
index da08f7e..d893755 100644
--- a/xos/core/xoslib/ngXosLib/gulpfile.js
+++ b/gui/ngXosLib/gulpfile.js
@@ -4,7 +4,7 @@
 var wrench = require('wrench');
 
 var options = {
-  ngXosVendor: '../static/js/vendor/', //save here the minfied vendor file, this is automatically loaded in the django page
+  ngXosVendor: '../../xos/core/xoslib/static/js/vendor/', //save here the minfied vendor file, this is automatically loaded in the django page
   xosHelperSource: './xosHelpers/src/'
 };
 
diff --git a/xos/core/xoslib/ngXosLib/karma.conf.js b/gui/ngXosLib/karma.conf.js
similarity index 100%
rename from xos/core/xoslib/ngXosLib/karma.conf.js
rename to gui/ngXosLib/karma.conf.js
diff --git a/xos/core/xoslib/ngXosLib/package.json b/gui/ngXosLib/package.json
similarity index 100%
rename from xos/core/xoslib/ngXosLib/package.json
rename to gui/ngXosLib/package.json
diff --git a/xos/core/xoslib/ngXosLib/xos-resource-generator.js b/gui/ngXosLib/xos-resource-generator.js
similarity index 100%
rename from xos/core/xoslib/ngXosLib/xos-resource-generator.js
rename to gui/ngXosLib/xos-resource-generator.js
diff --git a/xos/core/xoslib/ngXosLib/xos-swagger-def.js b/gui/ngXosLib/xos-swagger-def.js
similarity index 100%
rename from xos/core/xoslib/ngXosLib/xos-swagger-def.js
rename to gui/ngXosLib/xos-swagger-def.js
diff --git a/xos/core/xoslib/ngXosLib/xosHelpers/spec/csrftoken.test.js b/gui/ngXosLib/xosHelpers/spec/csrftoken.test.js
similarity index 100%
rename from xos/core/xoslib/ngXosLib/xosHelpers/spec/csrftoken.test.js
rename to gui/ngXosLib/xosHelpers/spec/csrftoken.test.js
diff --git a/xos/core/xoslib/ngXosLib/xosHelpers/src/services/api.services.js b/gui/ngXosLib/xosHelpers/src/services/api.services.js
similarity index 100%
rename from xos/core/xoslib/ngXosLib/xosHelpers/src/services/api.services.js
rename to gui/ngXosLib/xosHelpers/src/services/api.services.js
diff --git a/xos/core/xoslib/ngXosLib/xosHelpers/src/services/csrfToken.interceptor.js b/gui/ngXosLib/xosHelpers/src/services/csrfToken.interceptor.js
similarity index 100%
rename from xos/core/xoslib/ngXosLib/xosHelpers/src/services/csrfToken.interceptor.js
rename to gui/ngXosLib/xosHelpers/src/services/csrfToken.interceptor.js
diff --git a/xos/core/xoslib/ngXosLib/xosHelpers/src/services/noHyperlinks.interceptor.js b/gui/ngXosLib/xosHelpers/src/services/noHyperlinks.interceptor.js
similarity index 100%
rename from xos/core/xoslib/ngXosLib/xosHelpers/src/services/noHyperlinks.interceptor.js
rename to gui/ngXosLib/xosHelpers/src/services/noHyperlinks.interceptor.js
diff --git a/xos/core/xoslib/ngXosLib/xosHelpers/src/xosHelpers.module.js b/gui/ngXosLib/xosHelpers/src/xosHelpers.module.js
similarity index 100%
rename from xos/core/xoslib/ngXosLib/xosHelpers/src/xosHelpers.module.js
rename to gui/ngXosLib/xosHelpers/src/xosHelpers.module.js
diff --git a/xos/core/xoslib/ngXosViews/.gitignore b/gui/ngXosViews/.gitignore
similarity index 100%
rename from xos/core/xoslib/ngXosViews/.gitignore
rename to gui/ngXosViews/.gitignore
diff --git a/xos/core/xoslib/ngXosViews/ceilometerDashboard/.bowerrc b/gui/ngXosViews/ceilometerDashboard/.bowerrc
similarity index 100%
rename from xos/core/xoslib/ngXosViews/ceilometerDashboard/.bowerrc
rename to gui/ngXosViews/ceilometerDashboard/.bowerrc
diff --git a/xos/core/xoslib/ngXosViews/ceilometerDashboard/.eslintrc b/gui/ngXosViews/ceilometerDashboard/.eslintrc
similarity index 100%
rename from xos/core/xoslib/ngXosViews/ceilometerDashboard/.eslintrc
rename to gui/ngXosViews/ceilometerDashboard/.eslintrc
diff --git a/xos/core/xoslib/ngXosViews/ceilometerDashboard/.gitignore b/gui/ngXosViews/ceilometerDashboard/.gitignore
similarity index 100%
rename from xos/core/xoslib/ngXosViews/ceilometerDashboard/.gitignore
rename to gui/ngXosViews/ceilometerDashboard/.gitignore
diff --git a/xos/core/xoslib/ngXosViews/ceilometerDashboard/bower.json b/gui/ngXosViews/ceilometerDashboard/bower.json
similarity index 100%
rename from xos/core/xoslib/ngXosViews/ceilometerDashboard/bower.json
rename to gui/ngXosViews/ceilometerDashboard/bower.json
diff --git a/xos/core/xoslib/ngXosViews/ceilometerDashboard/env/default.js b/gui/ngXosViews/ceilometerDashboard/env/default.js
similarity index 100%
rename from xos/core/xoslib/ngXosViews/ceilometerDashboard/env/default.js
rename to gui/ngXosViews/ceilometerDashboard/env/default.js
diff --git a/xos/core/xoslib/ngXosViews/ceilometerDashboard/env/srikanth.js b/gui/ngXosViews/ceilometerDashboard/env/srikanth.js
similarity index 100%
rename from xos/core/xoslib/ngXosViews/ceilometerDashboard/env/srikanth.js
rename to gui/ngXosViews/ceilometerDashboard/env/srikanth.js
diff --git a/xos/core/xoslib/ngXosViews/ceilometerDashboard/gulp/build.js b/gui/ngXosViews/ceilometerDashboard/gulp/build.js
similarity index 100%
rename from xos/core/xoslib/ngXosViews/ceilometerDashboard/gulp/build.js
rename to gui/ngXosViews/ceilometerDashboard/gulp/build.js
diff --git a/xos/core/xoslib/ngXosViews/ceilometerDashboard/gulp/server.js b/gui/ngXosViews/ceilometerDashboard/gulp/server.js
similarity index 100%
rename from xos/core/xoslib/ngXosViews/ceilometerDashboard/gulp/server.js
rename to gui/ngXosViews/ceilometerDashboard/gulp/server.js
diff --git a/xos/core/xoslib/ngXosViews/ceilometerDashboard/gulpfile.js b/gui/ngXosViews/ceilometerDashboard/gulpfile.js
similarity index 71%
rename from xos/core/xoslib/ngXosViews/ceilometerDashboard/gulpfile.js
rename to gui/ngXosViews/ceilometerDashboard/gulpfile.js
index de911e9..a3523ee 100644
--- a/xos/core/xoslib/ngXosViews/ceilometerDashboard/gulpfile.js
+++ b/gui/ngXosViews/ceilometerDashboard/gulpfile.js
@@ -11,8 +11,8 @@
   dist: 'dist/',
   api: '../../ngXosLib/api/',
   helpers: '../../ngXosLib/xosHelpers/src/',
-  static: '../../static/', // this is the django static folder
-  dashboards: '../../dashboards/' // this is the django html folder
+  static: '../../../xos/core/xoslib/static/', // this is the django static folder
+  dashboards: '../../../xos/core/xoslib/dashboards/' // this is the django html folder
 };
 
 wrench.readdirSyncRecursive('./gulp')
diff --git a/xos/core/xoslib/ngXosViews/ceilometerDashboard/karma.conf.js b/gui/ngXosViews/ceilometerDashboard/karma.conf.js
similarity index 100%
rename from xos/core/xoslib/ngXosViews/ceilometerDashboard/karma.conf.js
rename to gui/ngXosViews/ceilometerDashboard/karma.conf.js
diff --git a/xos/core/xoslib/ngXosViews/ceilometerDashboard/package.json b/gui/ngXosViews/ceilometerDashboard/package.json
similarity index 100%
rename from xos/core/xoslib/ngXosViews/ceilometerDashboard/package.json
rename to gui/ngXosViews/ceilometerDashboard/package.json
diff --git a/xos/core/xoslib/ngXosViews/ceilometerDashboard/spec/.eslintrc b/gui/ngXosViews/ceilometerDashboard/spec/.eslintrc
similarity index 100%
rename from xos/core/xoslib/ngXosViews/ceilometerDashboard/spec/.eslintrc
rename to gui/ngXosViews/ceilometerDashboard/spec/.eslintrc
diff --git a/xos/core/xoslib/ngXosViews/ceilometerDashboard/spec/backend.mock.js b/gui/ngXosViews/ceilometerDashboard/spec/backend.mock.js
similarity index 100%
rename from xos/core/xoslib/ngXosViews/ceilometerDashboard/spec/backend.mock.js
rename to gui/ngXosViews/ceilometerDashboard/spec/backend.mock.js
diff --git a/xos/core/xoslib/ngXosViews/ceilometerDashboard/spec/ceilometer.test.js b/gui/ngXosViews/ceilometerDashboard/spec/ceilometer.test.js
similarity index 100%
rename from xos/core/xoslib/ngXosViews/ceilometerDashboard/spec/ceilometer.test.js
rename to gui/ngXosViews/ceilometerDashboard/spec/ceilometer.test.js
diff --git a/xos/core/xoslib/ngXosViews/ceilometerDashboard/src/css/ceilometerDashboard.css b/gui/ngXosViews/ceilometerDashboard/src/css/ceilometerDashboard.css
similarity index 100%
rename from xos/core/xoslib/ngXosViews/ceilometerDashboard/src/css/ceilometerDashboard.css
rename to gui/ngXosViews/ceilometerDashboard/src/css/ceilometerDashboard.css
diff --git a/xos/core/xoslib/ngXosViews/ceilometerDashboard/src/css/dev.css b/gui/ngXosViews/ceilometerDashboard/src/css/dev.css
similarity index 100%
rename from xos/core/xoslib/ngXosViews/ceilometerDashboard/src/css/dev.css
rename to gui/ngXosViews/ceilometerDashboard/src/css/dev.css
diff --git a/xos/core/xoslib/ngXosViews/ceilometerDashboard/src/index.html b/gui/ngXosViews/ceilometerDashboard/src/index.html
similarity index 100%
rename from xos/core/xoslib/ngXosViews/ceilometerDashboard/src/index.html
rename to gui/ngXosViews/ceilometerDashboard/src/index.html
diff --git a/xos/core/xoslib/ngXosViews/ceilometerDashboard/src/js/main.js b/gui/ngXosViews/ceilometerDashboard/src/js/main.js
similarity index 100%
rename from xos/core/xoslib/ngXosViews/ceilometerDashboard/src/js/main.js
rename to gui/ngXosViews/ceilometerDashboard/src/js/main.js
diff --git a/xos/core/xoslib/ngXosViews/ceilometerDashboard/src/meters_mock.json b/gui/ngXosViews/ceilometerDashboard/src/meters_mock.json
similarity index 100%
rename from xos/core/xoslib/ngXosViews/ceilometerDashboard/src/meters_mock.json
rename to gui/ngXosViews/ceilometerDashboard/src/meters_mock.json
diff --git a/xos/core/xoslib/ngXosViews/ceilometerDashboard/src/stats_mock.json b/gui/ngXosViews/ceilometerDashboard/src/stats_mock.json
similarity index 100%
rename from xos/core/xoslib/ngXosViews/ceilometerDashboard/src/stats_mock.json
rename to gui/ngXosViews/ceilometerDashboard/src/stats_mock.json
diff --git a/xos/core/xoslib/ngXosViews/ceilometerDashboard/src/templates/accordion-group.html b/gui/ngXosViews/ceilometerDashboard/src/templates/accordion-group.html
similarity index 100%
rename from xos/core/xoslib/ngXosViews/ceilometerDashboard/src/templates/accordion-group.html
rename to gui/ngXosViews/ceilometerDashboard/src/templates/accordion-group.html
diff --git a/xos/core/xoslib/ngXosViews/ceilometerDashboard/src/templates/accordion.html b/gui/ngXosViews/ceilometerDashboard/src/templates/accordion.html
similarity index 100%
rename from xos/core/xoslib/ngXosViews/ceilometerDashboard/src/templates/accordion.html
rename to gui/ngXosViews/ceilometerDashboard/src/templates/accordion.html
diff --git a/xos/core/xoslib/ngXosViews/ceilometerDashboard/src/templates/ceilometer-dashboard.tpl.html b/gui/ngXosViews/ceilometerDashboard/src/templates/ceilometer-dashboard.tpl.html
similarity index 100%
rename from xos/core/xoslib/ngXosViews/ceilometerDashboard/src/templates/ceilometer-dashboard.tpl.html
rename to gui/ngXosViews/ceilometerDashboard/src/templates/ceilometer-dashboard.tpl.html
diff --git a/xos/core/xoslib/ngXosViews/ceilometerDashboard/src/templates/ceilometer-samples.tpl.html b/gui/ngXosViews/ceilometerDashboard/src/templates/ceilometer-samples.tpl.html
similarity index 100%
rename from xos/core/xoslib/ngXosViews/ceilometerDashboard/src/templates/ceilometer-samples.tpl.html
rename to gui/ngXosViews/ceilometerDashboard/src/templates/ceilometer-samples.tpl.html
diff --git a/xos/core/xoslib/ngXosViews/ceilometerDashboard/src/templates/ceilometer-stats.tpl.html b/gui/ngXosViews/ceilometerDashboard/src/templates/ceilometer-stats.tpl.html
similarity index 100%
rename from xos/core/xoslib/ngXosViews/ceilometerDashboard/src/templates/ceilometer-stats.tpl.html
rename to gui/ngXosViews/ceilometerDashboard/src/templates/ceilometer-stats.tpl.html
diff --git a/xos/core/xoslib/ngXosViews/ceilometerDashboard/teone@clnode015.clemson.cloudlab.us b/gui/ngXosViews/ceilometerDashboard/teone@clnode015.clemson.cloudlab.us
similarity index 100%
rename from xos/core/xoslib/ngXosViews/ceilometerDashboard/teone@clnode015.clemson.cloudlab.us
rename to gui/ngXosViews/ceilometerDashboard/teone@clnode015.clemson.cloudlab.us
diff --git a/xos/core/xoslib/ngXosViews/contentProvider/.bowerrc b/gui/ngXosViews/contentProvider/.bowerrc
similarity index 100%
rename from xos/core/xoslib/ngXosViews/contentProvider/.bowerrc
rename to gui/ngXosViews/contentProvider/.bowerrc
diff --git a/xos/core/xoslib/ngXosViews/contentProvider/.eslintrc b/gui/ngXosViews/contentProvider/.eslintrc
similarity index 100%
rename from xos/core/xoslib/ngXosViews/contentProvider/.eslintrc
rename to gui/ngXosViews/contentProvider/.eslintrc
diff --git a/xos/core/xoslib/ngXosViews/contentProvider/.gitignore b/gui/ngXosViews/contentProvider/.gitignore
similarity index 100%
rename from xos/core/xoslib/ngXosViews/contentProvider/.gitignore
rename to gui/ngXosViews/contentProvider/.gitignore
diff --git a/xos/core/xoslib/ngXosViews/contentProvider/bower.json b/gui/ngXosViews/contentProvider/bower.json
similarity index 100%
rename from xos/core/xoslib/ngXosViews/contentProvider/bower.json
rename to gui/ngXosViews/contentProvider/bower.json
diff --git a/xos/core/xoslib/ngXosViews/contentProvider/gulp/build.js b/gui/ngXosViews/contentProvider/gulp/build.js
similarity index 100%
rename from xos/core/xoslib/ngXosViews/contentProvider/gulp/build.js
rename to gui/ngXosViews/contentProvider/gulp/build.js
diff --git a/xos/core/xoslib/ngXosViews/contentProvider/gulp/server.js b/gui/ngXosViews/contentProvider/gulp/server.js
similarity index 100%
rename from xos/core/xoslib/ngXosViews/contentProvider/gulp/server.js
rename to gui/ngXosViews/contentProvider/gulp/server.js
diff --git a/xos/core/xoslib/ngXosViews/ceilometerDashboard/gulpfile.js b/gui/ngXosViews/contentProvider/gulpfile.js
similarity index 70%
copy from xos/core/xoslib/ngXosViews/ceilometerDashboard/gulpfile.js
copy to gui/ngXosViews/contentProvider/gulpfile.js
index de911e9..b2cdab8 100644
--- a/xos/core/xoslib/ngXosViews/ceilometerDashboard/gulpfile.js
+++ b/gui/ngXosViews/contentProvider/gulpfile.js
@@ -5,14 +5,13 @@
 
 var options = {
   src: 'src/',
-  css: 'src/css/',
   scripts: 'src/js/',
   tmp: 'src/.tmp',
   dist: 'dist/',
   api: '../../ngXosLib/api/',
   helpers: '../../ngXosLib/xosHelpers/src/',
-  static: '../../static/', // this is the django static folder
-  dashboards: '../../dashboards/' // this is the django html folder
+  static: '../../../xos/core/xoslib/static/', // this is the django static folder
+  dashboards: '../../../xos/core/xoslib/dashboards/' // this is the django html folder
 };
 
 wrench.readdirSyncRecursive('./gulp')
diff --git a/xos/core/xoslib/ngXosViews/contentProvider/karma.conf.js b/gui/ngXosViews/contentProvider/karma.conf.js
similarity index 100%
rename from xos/core/xoslib/ngXosViews/contentProvider/karma.conf.js
rename to gui/ngXosViews/contentProvider/karma.conf.js
diff --git a/xos/core/xoslib/ngXosViews/contentProvider/package.json b/gui/ngXosViews/contentProvider/package.json
similarity index 100%
rename from xos/core/xoslib/ngXosViews/contentProvider/package.json
rename to gui/ngXosViews/contentProvider/package.json
diff --git a/xos/core/xoslib/ngXosViews/contentProvider/spec/contentprovider.test.js b/gui/ngXosViews/contentProvider/spec/contentprovider.test.js
similarity index 100%
rename from xos/core/xoslib/ngXosViews/contentProvider/spec/contentprovider.test.js
rename to gui/ngXosViews/contentProvider/spec/contentprovider.test.js
diff --git a/xos/core/xoslib/ngXosViews/contentProvider/spec/mocks/contentProvider.mock.js b/gui/ngXosViews/contentProvider/spec/mocks/contentProvider.mock.js
similarity index 100%
rename from xos/core/xoslib/ngXosViews/contentProvider/spec/mocks/contentProvider.mock.js
rename to gui/ngXosViews/contentProvider/spec/mocks/contentProvider.mock.js
diff --git a/xos/core/xoslib/ngXosViews/contentProvider/spec/sample.test.js b/gui/ngXosViews/contentProvider/spec/sample.test.js
similarity index 100%
rename from xos/core/xoslib/ngXosViews/contentProvider/spec/sample.test.js
rename to gui/ngXosViews/contentProvider/spec/sample.test.js
diff --git a/xos/core/xoslib/ngXosViews/contentProvider/src/css/dev.css b/gui/ngXosViews/contentProvider/src/css/dev.css
similarity index 100%
rename from xos/core/xoslib/ngXosViews/contentProvider/src/css/dev.css
rename to gui/ngXosViews/contentProvider/src/css/dev.css
diff --git a/xos/core/xoslib/ngXosViews/contentProvider/src/index.html b/gui/ngXosViews/contentProvider/src/index.html
similarity index 100%
rename from xos/core/xoslib/ngXosViews/contentProvider/src/index.html
rename to gui/ngXosViews/contentProvider/src/index.html
diff --git a/xos/core/xoslib/ngXosViews/contentProvider/src/js/main.js b/gui/ngXosViews/contentProvider/src/js/main.js
similarity index 100%
rename from xos/core/xoslib/ngXosViews/contentProvider/src/js/main.js
rename to gui/ngXosViews/contentProvider/src/js/main.js
diff --git a/xos/core/xoslib/ngXosViews/contentProvider/src/templates/cp_actions.html b/gui/ngXosViews/contentProvider/src/templates/cp_actions.html
similarity index 100%
rename from xos/core/xoslib/ngXosViews/contentProvider/src/templates/cp_actions.html
rename to gui/ngXosViews/contentProvider/src/templates/cp_actions.html
diff --git a/xos/core/xoslib/ngXosViews/contentProvider/src/templates/cp_cdn_prefix.html b/gui/ngXosViews/contentProvider/src/templates/cp_cdn_prefix.html
similarity index 100%
rename from xos/core/xoslib/ngXosViews/contentProvider/src/templates/cp_cdn_prefix.html
rename to gui/ngXosViews/contentProvider/src/templates/cp_cdn_prefix.html
diff --git a/xos/core/xoslib/ngXosViews/contentProvider/src/templates/cp_detail.html b/gui/ngXosViews/contentProvider/src/templates/cp_detail.html
similarity index 100%
rename from xos/core/xoslib/ngXosViews/contentProvider/src/templates/cp_detail.html
rename to gui/ngXosViews/contentProvider/src/templates/cp_detail.html
diff --git a/xos/core/xoslib/ngXosViews/contentProvider/src/templates/cp_list.html b/gui/ngXosViews/contentProvider/src/templates/cp_list.html
similarity index 100%
rename from xos/core/xoslib/ngXosViews/contentProvider/src/templates/cp_list.html
rename to gui/ngXosViews/contentProvider/src/templates/cp_list.html
diff --git a/xos/core/xoslib/ngXosViews/contentProvider/src/templates/cp_origin_server.html b/gui/ngXosViews/contentProvider/src/templates/cp_origin_server.html
similarity index 100%
rename from xos/core/xoslib/ngXosViews/contentProvider/src/templates/cp_origin_server.html
rename to gui/ngXosViews/contentProvider/src/templates/cp_origin_server.html
diff --git a/xos/core/xoslib/ngXosViews/contentProvider/src/templates/cp_side_nav.html b/gui/ngXosViews/contentProvider/src/templates/cp_side_nav.html
similarity index 100%
rename from xos/core/xoslib/ngXosViews/contentProvider/src/templates/cp_side_nav.html
rename to gui/ngXosViews/contentProvider/src/templates/cp_side_nav.html
diff --git a/xos/core/xoslib/ngXosViews/contentProvider/src/templates/cp_user.html b/gui/ngXosViews/contentProvider/src/templates/cp_user.html
similarity index 100%
rename from xos/core/xoslib/ngXosViews/contentProvider/src/templates/cp_user.html
rename to gui/ngXosViews/contentProvider/src/templates/cp_user.html
diff --git a/xos/core/xoslib/ngXosViews/contentProvider/src/templates/users-list.tpl.html b/gui/ngXosViews/contentProvider/src/templates/users-list.tpl.html
similarity index 100%
rename from xos/core/xoslib/ngXosViews/contentProvider/src/templates/users-list.tpl.html
rename to gui/ngXosViews/contentProvider/src/templates/users-list.tpl.html
diff --git a/install_opencloud b/install_opencloud
deleted file mode 100755
index ec0e0ab..0000000
--- a/install_opencloud
+++ /dev/null
@@ -1,52 +0,0 @@
-#!/bin/sh
-yum -y install postgresql postgresql-server
-yum -y install python-psycopg2
-yum -y install graphviz
-yum -y install graphviz-devel
-yum -y install graphviz-python
-yum -y install libxslt-devel
-yum -y install python-pip
-yum -y install wget
-yum -y install tar
-yum -y install gcc
-yum -y install libxml2-dev
-yum -y install libxslt1-dev
-yum -y install python-devel
-
-
-pip-python install django==1.5
-pip-python install djangorestframework
-pip-python install markdown  # Markdown support for the browseable API.
-pip-python install pyyaml    # YAML content-type support.
-pip-python install django-filter  # Filtering support
-pip-python install lxml  # XML manipulation library
-pip-python install netaddr # IP Addr library
-pip-python install pytz
-pip-python install django-timezones
-pip-python install requests
-pip-python install django-crispy-forms
-pip-python install django-geoposition
-pip-python install django-extensions
-pip-python install django-suit
-pip-python install django-evolution
-pip-python install docutils
-pip-python install cython
-pip-python install bitfield
-pip-python install pygments
-
-easy_install django_evolution
-
-wget http://phantomjs.googlecode.com/files/phantomjs-1.7.0-linux-x86_64.tar.bz2
-
-mv ./phantomjs-1.7.0-linux-x86_64.tar.bz2 /usr/local/share
-
-cd /usr/local/share
-
-tar xvf phantomjs-1.7.0-linux-x86_64.tar.bz2
-
-ln -s /usr/local/share/phantomjs-1.7.0-linux-x86_64 /usr/local/share/phantomjs
-
-ln -s /usr/local/share/phantomjs/bin/phantomjs /usr/local/bin/phantomjs
-
-phantomjs --version
-
diff --git a/observer-initscript b/observer-initscript
deleted file mode 100755
index d1466b2..0000000
--- a/observer-initscript
+++ /dev/null
@@ -1,63 +0,0 @@
-#!/bin/bash
-#
-# observer       Starts and stops Observer daemon
-#
-
-# Source function library.
-. /etc/init.d/functions
-
-[ -f /etc/sysconfig/xosobserver ] && . /etc/sysconfig/xosobserver
-
-
-xosobserver=${NODEMANAGER-"python /opt/xos/xos-observer.py -d"}
-prog="OpenCloud Observer"
-pidfile=${PIDFILE-/var/run/xosobserver.pid}
-
-RETVAL=0
-
-function start() {
-    action $"Starting $prog: " daemon --pidfile=$pidfile --check=xosobserver $xosobserver "$@"
-}
-
-function stop() {
-    action $"Stopping $prog: " killproc -p $pidfile xosobserver
-}
-
-case "$1" in
-    start)
-	start $options
-	;;
-    stop)
-	stop
-	;;
-    status)
-	status -p $pidfile xosobserver
-	RETVAL=$?
-	;;
-    restart|reload)
-	shift
-	stop
-	start $options "$@"
-	;;
-    condrestart)
-	shift
-	[ -f ${pidfile} ] && { stop; start $options "$@"; }
-	;;
-    restartverbose)
-	shift
-	stop
-	$xosobserver $verboseoptions "$@"
-	;;
-    restartdebug)
-	shift
-	stop
-	echo "Restarting with $debugoptions $@ .."
-	$xosobserver $debugoptions "$@"
-	;;
-    *)
-	echo $"Usage: $0 {start|stop|status|restart|condrestart|restartdebug [-d]}"
-	exit 1
-	;;
-esac
-
-exit $RETVAL
diff --git a/observer.conf b/observer.conf
deleted file mode 100644
index 92545eb..0000000
--- a/observer.conf
+++ /dev/null
@@ -1,2 +0,0 @@
-[program:observer]
-command=python /opt/xos/xos-observer.py
diff --git a/setup.py b/setup.py
deleted file mode 100644
index 1162279..0000000
--- a/setup.py
+++ /dev/null
@@ -1,25 +0,0 @@
-import os
-import shutil 
-from distutils.core import setup
-
-def copytree(src, dst, symlinks=False, ignore=None):
-    if not os.path.exists(dst):
-        os.makedirs(dst)
-    for item in os.listdir(src):
-        s = os.path.join(src, item)
-        d = os.path.join(dst, item)
-        if os.path.isdir(s):
-            copytree(s, d, symlinks, ignore)
-        else:
-            if not os.path.exists(d) or os.stat(src).st_mtime - os.stat(dst).st_mtime > 1:
-                shutil.copy2(s, d)
-
-setup(name='planetstack',
-      version='0.1',
-      description='PlanetStack',
-      scripts=['xos/xos-observer.py'],
-      data_files=[
-        ('/lib/systemd/system/', ['xos/redhat/xos-observer.service']),
-        ])
-
-copytree('xos/', '/opt/xos')
diff --git a/synchronizers b/synchronizers
deleted file mode 120000
index d587898..0000000
--- a/synchronizers
+++ /dev/null
@@ -1 +0,0 @@
-observers
\ No newline at end of file
diff --git a/upgrade-container.sh b/upgrade-container.sh
deleted file mode 100755
index 09c639d..0000000
--- a/upgrade-container.sh
+++ /dev/null
@@ -1,26 +0,0 @@
-#!/bin/bash
-
-TMPDIR="/tmp/initdata"
-XOSDIR="/home/ubuntu/xos"
-
-mkdir -p $TMPDIR
-rm -f $TMPDIR/*.json
-
-XOS=$( docker ps|grep "xos:latest"|awk '{print $NF}' )
-docker exec $XOS /opt/xos/scripts/opencloud dumpdata
-docker cp $XOS:/opt/xos_backups/dumpdata-latest.json $TMPDIR
-docker cp $XOS:/opt/xos/xos_config $TMPDIR
-cp $TMPDIR/*.json $XOSDIR/xos/core/fixtures/initial_data.json
-cp $TMPDIR/xos_config $XOSDIR/xos/
-
-git pull
-
-if [[ $? != 0 ]]; then
-    echo "git pull" failed
-    exit
-fi
-
-docker build -t xos .
-
-docker stop $XOS
-docker run -p 8000:8000 xos 
diff --git a/wiki/figures/modeling-services-fig1.png b/wiki/figures/modeling-services-fig1.png
deleted file mode 100644
index 6df4b43..0000000
--- a/wiki/figures/modeling-services-fig1.png
+++ /dev/null
Binary files differ
diff --git a/wiki/figures/modeling-services-fig2.png b/wiki/figures/modeling-services-fig2.png
deleted file mode 100644
index a854b19..0000000
--- a/wiki/figures/modeling-services-fig2.png
+++ /dev/null
Binary files differ
diff --git a/xos-apps/README.md b/xos-apps/README.md
new file mode 100644
index 0000000..66d71eb
--- /dev/null
+++ b/xos-apps/README.md
@@ -0,0 +1,10 @@
+## Applications on XOS
+
+This directory may prove to be unnecessary, but for now we
+are using it for applications that run on top of the XOS API.
+Initially, this includes only an auto-scaling app that uses
+monitoring data to decide when to scale a service up/down.
+
+This is treated as an application rather than yet another
+service because it offers only a GUI front-end; it is not
+modelled as a service that other services can build upon.
diff --git a/xos.deps b/xos.deps
deleted file mode 100644
index 6eae1fc..0000000
--- a/xos.deps
+++ /dev/null
@@ -1,47 +0,0 @@
-{
-    "Node": [
-        "Site", 
-        "Deployment"
-    ], 
-    "Slice": [
-        "Site"
-    ], 
-    "ReservedResource": [
-        "Sliver"
-    ], 
-    "SliceMembership": [
-        "User", 
-        "Slice", 
-        "Role"
-    ], 
-    "NetworkSlice": [
-        "Network", 
-        "Slice"
-    ], 
-    "Tag": [
-        "Project"
-    ], 
-    "User": [
-        "Site"
-    ], 
-    "SliceTag": [
-        "Slice"
-    ], 
-    "Reservation": [
-        "Slice"
-    ], 
-    "NetworkSliver": [
-        "Network", 
-        "Sliver"
-    ], 
-    "SitePrivilege": [
-        "User", 
-        "Site", 
-        "Role"
-    ], 
-    "Sliver": [
-        "Image", 
-        "Slice", 
-        "Node"
-    ]
-}
diff --git a/xos.spec b/xos.spec
deleted file mode 100644
index c585e7e..0000000
--- a/xos.spec
+++ /dev/null
@@ -1,158 +0,0 @@
-Summary: OpenCloud core services
-Name: xos
-Version: 1.2.0
-Release: 5
-License: GPL+
-Group: Development/Tools
-Source0: %{_tmppath}/%{name}-%{version}.tar.gz
-BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}
-requires: postgresql
-requires: postgresql-server
-requires: python-psycopg2
-requires: graphviz
-requires: graphviz-devel
-requires: graphviz-python
-requires: libxslt-devel
-requires: python-pip
-requires: tar
-requires: gcc
-requires: python-httplib2
-requires: GeoIP
-requires: wget
-
-%description
-%{summary}
-
-%prep
-%setup -q
-
-%build
-# Empty section.
-
-%pre
-pip-python install django==1.7
-pip-python install djangorestframework==2.4.4
-pip-python install markdown  # Markdown support for the browseable API.
-pip-python install pyyaml    # YAML content-type support.
-pip-python install django-filter  # Filtering support
-pip-python install lxml  # XML manipulation library
-pip-python install netaddr # IP Addr library
-pip-python install pytz
-pip-python install django-timezones
-pip-python install requests
-pip-python install django-crispy-forms
-pip-python install django-geoposition
-pip-python install django-extensions
-pip-python install django-suit
-pip-python install django-evolution
-pip-python install django-bitfield
-pip-python install django-ipware
-pip-python install django-encrypted-fields
-pip-python install python-keyczar
-pip-python install python-keystoneclient
-pip-python install python-novaclient
-pip-python install python-neutronclient 
-pip-python install python-glanceclient
-pip-python install python-ceilometerclient
-pip-python install django_rest_swagger
-
-
-easy_install django_evolution
-easy_install python_gflags
-easy_install google_api_python_client
-
-if [ ! -f /usr/lib/python2.7/site-packages/suit/static/suit/js/jquery-1.9.1.min.js ]; then
-    wget -P /usr/lib/python2.7/site-packages/suit/static/suit/js http://code.jquery.com/jquery-1.9.1.min.js
-fi
-
-if [ ! -f /usr/share/GeoIP/GeoLiteCity.dat ]; then
-   rm -f /usr/share/GeoIP/GeoLiteCity.*
-   wget -P /usr/share/GeoIP http://geolite.maxmind.com/download/geoip/database/GeoLiteCity.dat.gz
-   gzip -d /usr/share/GeoIP/GeoLiteCity*.gz
-fi
-
-if [ "$1" == 2 ] ; then
-    if [[ -e /opt/xos/scripts/opencloud ]]; then
-        echo "UPGRADE - saving current state"
-        /opt/xos/scripts/opencloud dumpdata
-    fi
-fi
-
-%install
-rm -rf %{buildroot}
-mkdir -p  %{buildroot}
-install -d %{buildroot}/opt/xos
-install -d %{buildroot}/etc/init.d
-
-# in builddir
-
-rm -rf %{buildroot}/opt/xos
-# don't copy symbolic links (they are handled in %post)
-rsync -rptgoD ./xos %{buildroot}/opt/.  
-cp observer-initscript %{buildroot}/etc/init.d/xosobserver
-
-find %{buildroot}/opt/xos -type f -print | sed "s@^$RPM_BUILD_ROOT@@g" > %{_tmppath}/tmp-filelist
-echo /etc/init.d/xosobserver >> %{_tmppath}/tmp-filelist
-
-# remove config files from the file list (see %config below)
-cat > %{_tmppath}/config-files << "EOF"
-/opt/xos/xos_config
-/opt/xos/deployment_auth.py
-EOF
-
-sort %{_tmppath}/tmp-filelist > %{_tmppath}/tmp-filelist.sorted
-sort %{_tmppath}/config-files > %{_tmppath}/config-files.sorted
-comm -13 %{_tmppath}/config-files.sorted %{_tmppath}/tmp-filelist.sorted > %{_tmppath}/tmp-filelist
-
-cp %{_tmppath}/tmp-filelist /tmp/tmp-filelist
-
-
-%clean
-rm -rf %{buildroot}
-
-%files -f %{_tmppath}/tmp-filelist
-%defattr(-,root,root,-)
-%config /opt/xos/xos_config
-%config /opt/xos/deployment_auth.py
-%config /opt/xos/model-deps
-
-%post
-ln -s openstack_observer /opt/xos/observer
-#ln -s config-opencloud.py /opt/xos/syndicate_observer/syndicatelib_config/config.py
-
-if [ ! -e /opt/xos/public_keys ]; then
-    cd /opt/xos
-    scripts/opencloud genkeys
-fi
-
-if [ "$1" == 1 ] ; then
-    echo "NEW INSTALL - initializing database"
-    /opt/xos/scripts/opencloud initdb
-else
-    # scripts/opencloud will choose evolve or migrate depending on django version
-    echo "UPGRADE - doing evolution/migration"
-    /opt/xos/scripts/opencloud evolvedb
-fi
-
-# Clone ansible with latest openstack modules
-git clone --recursive git://github.com/ansible/ansible.git /opt/ansible
-mkdir -p /etc/ansible
-echo > /etc/ansible/hosts << "EOF"
-[localhost]
-127.0.0.1
-EOF
-
-
-# start the server
-/opt/xos/scripts/opencloud runserver
-
-%preun
-if [ "$1" = 0 ] ; then
-    echo "UNINSTALL - destroying xos"
-    rm -rf /opt/xos
-fi
-
-%changelog
-* Sat Feb 22 2014  Siobhan Tully  1.0.0
-- First Build
-
diff --git a/xos/README.md b/xos/README.md
new file mode 100644
index 0000000..daec000
--- /dev/null
+++ b/xos/README.md
@@ -0,0 +1,21 @@
+## XOS Source Tree
+
+This is the main directory for XOS. Sub-directories include:
+
+* configurations -- collection of canned configurations
+* core -- core model definitions
+* generators -- tools to generate auxiliary structures from data model
+* model_policies -- invariants on the data model
+* nginx, uwsgi -- related to web server that runs XOS
+* openstack -- client-side interaction with OpenStack (to be depreciated)
+* services -- model definitions for a set of services
+* synchronizers -- collection of synchronizers
+* templates -- Django GUI templates
+* test -- system-wide tests to be collected here
+* tosca -- tosca modeling layer on top of RESTful API
+* tools -- assorted tools and scripts
+* xos -- common source code for all Django applications
+* xos_configuration -- top-level XOS configuration parameters
+
+Of these, configuration, services, and synchronizers are most
+relevant to developers.
diff --git a/xos/configurations/bash/copyin-vtn.sh b/xos/configurations/bash/copyin-vtn.sh
new file mode 100644
index 0000000..ef18704
--- /dev/null
+++ b/xos/configurations/bash/copyin-vtn.sh
@@ -0,0 +1,12 @@
+#! /bin/bash
+
+export SETUPDIR=/root/setup
+
+# copy in file necessary to setup VTN
+
+cd ../cord
+CONTAINER=$( docker ps|grep "xos"|awk '{print $NF}' )
+make vtn_network_cfg_json
+docker cp $SETUPDIR/vtn-network-cfg.json $CONTAINER:/root/setup/
+docker cp ../common/id_rsa.pub $CONTAINER:/opt/xos/observers/onos/onos_key.pub
+docker cp ../common/id_rsa $CONTAINER:/opt/xos/observers/onos/onos_key
diff --git a/xos/configurations/common/Dockerfile.common b/xos/configurations/common/Dockerfile.common
index 8bfd813..11f51fc 100644
--- a/xos/configurations/common/Dockerfile.common
+++ b/xos/configurations/common/Dockerfile.common
@@ -104,8 +104,8 @@
 # Initscript is broken in Ubuntu
 #ADD observer-initscript /etc/init.d/xosobserver
 
-RUN chmod +x /opt/xos/scripts/opencloud
-RUN /opt/xos/scripts/opencloud genkeys
+RUN chmod +x /opt/xos/tools/xos-manage
+RUN /opt/xos/tools/xos-manage genkeys
 
 # Workaround for AUFS issue
 # https://github.com/docker/docker/issues/783#issuecomment-56013588
@@ -119,7 +119,7 @@
 # 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
+RUN /opt/xos/tools/xos-manage remigrate
 
 # git clone uses cached copy, doesn't pick up latest
 RUN git -C /opt/ansible pull
@@ -141,4 +141,4 @@
 
 # Define default command.
 #CMD ["/bin/bash"]
-#CMD /opt/xos/scripts/docker_start_xos
+#CMD /opt/xos/tools/docker_start_xos
diff --git a/xos/configurations/common/Makefile.devstack b/xos/configurations/common/Makefile.devstack
index 2764b28..0dff27c 100644
--- a/xos/configurations/common/Makefile.devstack
+++ b/xos/configurations/common/Makefile.devstack
@@ -2,7 +2,7 @@
 DEVSTACK_ROOT:=~/devstack
 SETUPDIR:=../setup
 
-all: prereqs admin-openrc flat_name nodes_yaml public_key private_key ceilometer_url node_key net_fix
+all: prereqs admin-openrc flat_name nodes_yaml public_key private_key ceilometer_url other_keys net_fix
 
 prereqs:
 	make -f Makefile.prereqs
@@ -15,10 +15,10 @@
 
 flat_name:
 	echo private|tr -d '\n' > $(SETUPDIR)/flat_net_name
-	bash -c "source admin-openrc.sh; openstack network set --share private"
+	bash -c "source $(SETUPDIR)/admin-openrc.sh; neutron net-update private --shared"
 
 nodes_yaml:
-	bash ./make-nodes-yaml.sh > $(SETUPDIR)/nodes.yaml
+	export SETUPDIR=$(SETUPDIR); bash ./make-nodes-yaml.sh
 
 ceilometer_url:
 	echo http://`hostname -i`/xosmetering/ > $(SETUPDIR)/ceilometer_url
@@ -32,10 +32,11 @@
 ~/.ssh/id_rsa.pub:
 	cat /dev/zero | ssh-keygen -q -N ""
 
-node_key:
-	sudo cat ~/.ssh/id_rsa > $(SETUPDIR)/node_key
-	sudo cat ~/.ssh/id_rsa.pub > $(SETUPDIR)/node_key.pub
+other_keys: public_key private_key
+	cp $(SETUPDIR)/id_rsa $(SETUPDIR)/node_key
+	cp $(SETUPDIR)/id_rsa.pub $(SETUPDIR)/node_key.pub
+	cp $(SETUPDIR)/id_rsa.pub $(SETUPDIR)/padmin_public_key
 
 net_fix:
 	sudo devstack/net-fix.sh
-	bash -c "source admin-openrc.sh; neutron subnet-update private-subnet --dns-nameservers list=true 8.8.8.8 8.8.4.4"
+	bash -c "source $(SETUPDIR)/admin-openrc.sh; neutron subnet-update private-subnet --dns-nameservers list=true 8.8.8.8 8.8.4.4"
diff --git a/xos/configurations/cord/Makefile b/xos/configurations/cord/Makefile
index c95d9dd..41bb37f 100644
--- a/xos/configurations/cord/Makefile
+++ b/xos/configurations/cord/Makefile
@@ -14,6 +14,10 @@
 	sudo MYIP=$(MYIP) docker-compose run xos python /opt/xos/tosca/run.py padmin@vicci.org /opt/xos/configurations/cord/cord.yaml
 	sudo MYIP=$(MYIP) docker-compose run xos python /opt/xos/tosca/run.py padmin@vicci.org /opt/xos/configurations/cord/ceilometer.yaml
 
+containers:
+	cd ../../../containers/xos; make devel
+	cd ../../../containers/synchronizer; make
+
 common_cloudlab:
 	make -C ../common -f Makefile.cloudlab
 
diff --git a/xos/configurations/cord/Makefile.inside b/xos/configurations/cord/Makefile.inside
index 1b4fb97..d7bdbaf 100644
--- a/xos/configurations/cord/Makefile.inside
+++ b/xos/configurations/cord/Makefile.inside
@@ -1,7 +1,7 @@
 all: setup_xos run_develserver
 
 setup_xos:
-	bash /opt/xos/scripts/docker_setup_xos
+	bash /opt/xos/tools/docker_setup_xos
 	python /opt/xos/tosca/run.py padmin@vicci.org /opt/xos/configurations/common/fixtures.yaml
 	python /opt/xos/tosca/run.py padmin@vicci.org /opt/xos/configurations/common/base.yaml
 	python /opt/xos/tosca/run.py padmin@vicci.org /opt/xos/configurations/common/nodes.yaml
diff --git a/xos/configurations/cord/README-VTN.md b/xos/configurations/cord/README-VTN.md
index 38fc2b4..b51bae7 100644
--- a/xos/configurations/cord/README-VTN.md
+++ b/xos/configurations/cord/README-VTN.md
@@ -2,12 +2,18 @@
 
 see also: https://github.com/hyunsun/documentations/wiki/Neutron-ONOS-Integration-for-CORD-VTN#onos-setup
 
-inside the xos container:
+VTN doesn't seem to like cloudlab's networks (flat-net-1, ext-net, etc). I've placed a script in xos/scripts/ called destroy-all-networks.sh that will automate tearing down all of cloudlab's neutron networks.
+
+    cd xos/scripts
+    ./destroy-all-networks.sh
+
+inside the xos container, update the configuration. Make sure to restart Openstack Synchronizer afterward. Might be a good idea to restart the XOS UI as well:
 
     python /opt/xos/tosca/run.py padmin@vicci.org /opt/xos/tosca/samples/vtn.yaml
     emacs /opt/xos/xos_configuration/xos_common_config
         [networking]
         use_vtn=True
+    supervisorctl restart observer
 
 ctl node:
 
@@ -53,8 +59,6 @@
     #  4) delete any existing br-int bridge
     #  5) [nm only] turn off neutron-dhcp-agent
 
-VTN doesn't seem to like cloudlab's networks (flat-net-1, ext-net, etc). You might have to delete them all. I've placed a script in xos/scripts/ called destroy-all-networks.sh that will automate tearing down all of cloudlab's neutron networks.
-
 For development, I suggest using the bash configuration (remember to start the ONOS observer manually) so that 
 there aren't a bunch of preexisting Neutron networks and nova instances to get in the way. 
 
@@ -64,3 +68,40 @@
 also listening on 6640.
 * Adding use_vtn=True to the [networking] section in the XOS config file has two effects: 1) it sets the gateway in sync_controller_networks, and 2) it disables automatic creation of nat-net for new slices. This is because VTN will fail if there is no gateway on a network, and because we don't have nat-net under the VTN configuration.
 * When using of-vfctl to look at flow rules, if you get a protocol error, try "ovs-ofctl show -O OpenFlow13 br-int "
+* Note that the VTN Synchronizer isn't started automatically. It's only use for inter-Service connectivity, so no need to mess with it until intra-Slice connectivity is working first. 
+* Note that the VTN Synchronizer won't connect non-access networks. Any network templates you want VTN to connect must have Access set to "Direct" or "Indirect". 
+
+There is no management network yet, so no way to SSH into the slices. I've been setting up a VNC tunnel, like this:
+
+    # on compute node, run the following and note the IP address and port number
+    virsh vncdisplay <instance-id>
+    
+    # from home
+    ssh -o "GatewayPorts yes"  -L <port+5900>:<IP>:<port+5900> <username>@<compute_node_hostname>
+    
+    # example
+    ssh -o "GatewayPorts yes"  -L 5901:192.168.0.7:5901 smbaker@cp-1.smbaker-xos3.xos-pg0.clemson.cloudlab.us
+
+Then open a VNC session to the local port on your local machine. You'll have a console on the Instance. The username is "Ubuntu" and the password can be obtained from your cloudlab experiment description
+
+Things that can be tested:
+
+* Create an Instance, it should have a Private network, and there should be a tap attached from the instance to br-int
+* Two Instances in the same Slice can talk to one another. They can be on the same machine or different machines.
+* Two Slices can talk to one another if the slices are associated with Services and those Services have a Tenancy relationship between them. Note that 1) The VTN Synchronizer must be running, 2) There must be a Private network with Access=[Direct|Indirect], and 3) The connectivity is unidirectional, from subscriber service to provider service.
+
+Testing service composition
+
+1. Change the private network template's 'Access' field from None to Direct
+2. Create a Service, Service-A
+3. Enter Slice Admin for Slice-1 and assign it to Service-A
+4. Create a Service, Service-B
+5. Enter Slice Admin for Slice-2 and assign it to Service-B
+6. Enter Service Admin for Service-B, Go to Tenancy Tab
+7. In the 'Provided Tenants' section of Service-B, create a Tenant with Subsciber-Service=Serivce-A. 
+8. Start the VTN Observer. It will send a REST request to VTN app.
+9. Launch tcpdump in one of Slice-2's instances
+10. From Slice-1, start pinging the instance in Slice-2 where you launched tcpdump
+11. You should see the pings arrive and responses sent out. Note that the ping responses will not reach Slice-1, since VTN traffic is unidirectional.
+12. Delete the Tenancy relation you created in Step #7. The ping traffic should no longer appear in the tcpdump.
+
diff --git a/xos/configurations/cord/docker-compose.yml b/xos/configurations/cord/docker-compose.yml
index e09dc1a..3518f80 100644
--- a/xos/configurations/cord/docker-compose.yml
+++ b/xos/configurations/cord/docker-compose.yml
@@ -4,7 +4,7 @@
         - "5432"
 
 xos_synchronizer_openstack:
-    command: bash -c "sleep 120 ; python /opt/xos/xos-observer.py"
+    command: bash -c "sleep 120; python /opt/xos/synchronizers/openstack/xos-synchronizer.py"
     image: xosproject/xos-synchronizer-openstack
     labels:
         org.xosproject.kind: synchronizer
@@ -20,7 +20,7 @@
 
 xos_synchronizer_onos:
     image: xosproject/xos-synchronizer-openstack
-    command: bash -c "sleep 120 ; python /opt/xos/observers/onos/onos-observer.py -C /opt/xos/observers/onos/onos_observer_config"
+    command: bash -c "sleep 120; python /opt/xos/synchronizers/onos/onos-synchronizer.py -C /opt/xos/synchronizers/onos/onos_synchronizer_config"
     labels:
         org.xosproject.kind: synchronizer
         org.xosproject.target: onos
@@ -33,8 +33,7 @@
 
 xos_synchronizer_vcpe:
     image: xosproject/xos-synchronizer-openstack
-    #command: /usr/bin/supervisord -c /opt/xos/observers/vcpe/supervisor/vcpe-observer.conf
-    command: bash -c "sleep 120 ; python /opt/xos/observers/vcpe/vcpe-observer.py -C /opt/xos/observers/vcpe/vcpe_observer_config"
+    command: bash -c "sleep 120; python /opt/xos/synchronizers/vcpe/vcpe-synchronizer.py -C /opt/xos/synchronizers/vcpe/vcpe_synchronizer_config"
     labels:
         org.xosproject.kind: synchronizer
         org.xosproject.target: vcpe
@@ -45,10 +44,10 @@
     volumes:
         - ../setup/id_rsa:/opt/xos/observers/vcpe/vcpe_private_key:ro  # private key
         - ../setup:/root/setup:ro
-        
+
 xos_synchronizer_vbng:
     image: xosproject/xos-synchronizer-openstack
-    command: bash -c "sleep 120 ; python /opt/xos/observers/vbng/vbng-observer.py -C /opt/xos/observers/vbng/vbng_observer_config"
+    command: bash -c "sleep 120; python /opt/xos/synchronizers/vbng/vbng-synchronizer.py -C /opt/xos/synchronizers/vbng/vbng_synchronizer_config"
     labels:
         org.xosproject.kind: synchronizer
         org.xosproject.target: vbng
@@ -59,8 +58,7 @@
 
 xos_synchronizer_monitoring_channel:
     image: xosproject/xos-synchronizer-openstack
-    #command: /usr/bin/supervisord -c /opt/xos/observers/monitoring_channel/supervisor/monitoring_channel_observer.conf
-    command: bash -c "sleep 120 ; python /opt/xos/observers/monitoring_channel/monitoring_channel_observer.py -C /opt/xos/observers/monitoring_channel/monitoring_channel_observer_config"
+    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
diff --git a/xos/configurations/cord/make-vtn-networkconfig-json.sh b/xos/configurations/cord/make-vtn-networkconfig-json.sh
index c4506cc..5256292 100755
--- a/xos/configurations/cord/make-vtn-networkconfig-json.sh
+++ b/xos/configurations/cord/make-vtn-networkconfig-json.sh
@@ -1,5 +1,7 @@
 FN=$SETUPDIR/vtn-network-cfg.json
 
+echo "Writing to $FN"
+
 rm -f $FN
 
 cat >> $FN <<EOF
@@ -12,6 +14,10 @@
 
 NODES=$( sudo bash -c "source $SETUPDIR/admin-openrc.sh ; nova hypervisor-list" |grep enabled|awk '{print $4}' )
 
+# also configure ONOS to manage the nm node
+NM=`grep "^nm" /root/setup/fqdn.map | awk '{ print $2 }'`
+NODES="$NODES $NM"
+
 NODECOUNT=0
 for NODE in $NODES; do
     ((NODECOUNT++))
diff --git a/xos/configurations/devel/Makefile b/xos/configurations/devel/Makefile
index 5112311..1e650f3 100644
--- a/xos/configurations/devel/Makefile
+++ b/xos/configurations/devel/Makefile
@@ -2,7 +2,7 @@
 
 cloudlab: common_cloudlab xos
 
-devstack: upgrade_pkgs common_devstack devstack_net_fix xos
+devstack: upgrade_pkgs common_devstack xos
 
 xos:
 	sudo MYIP=$(MYIP) docker-compose up -d
@@ -10,6 +10,10 @@
 	sudo MYIP=$(MYIP) docker-compose run xos python /opt/xos/tosca/run.py padmin@vicci.org /opt/xos/configurations/common/base.yaml
 	sudo MYIP=$(MYIP) docker-compose run xos python /opt/xos/tosca/run.py padmin@vicci.org /root/setup/nodes.yaml
 
+containers:
+	cd ../../../containers/xos; make devel
+	cd ../../../containers/synchronizer; make
+
 common_cloudlab:
 	make -C ../common -f Makefile.cloudlab
 
@@ -34,9 +38,11 @@
 enter-synchronizer:
 	sudo docker exec -it devel_xos_synchronizer_openstack_1 bash
 
-devstack_net_fix:
-	sudo ../common/devstack/net-fix.sh
-	sudo bash -c "source ../setup/admin-openrc.sh; neutron subnet-update private-subnet --dns-nameservers list=true 8.8.8.8 8.8.4.4"
-
 upgrade_pkgs:
 	sudo pip install httpie --upgrade
+
+rebuild_xos:
+	make -C ../../../containers/xos devel
+
+rebuild_synchronizer:
+	make -C ../../../containers/synchronizer
diff --git a/xos/configurations/devel/README.md b/xos/configurations/devel/README.md
index 2361396..84bf6fc 100644
--- a/xos/configurations/devel/README.md
+++ b/xos/configurations/devel/README.md
@@ -65,6 +65,8 @@
 
 Delete the containers and relaunch them: `make rm; make [cloudlab|devstack]`
 
+Build the containers from scratch using the local XOS source tree: `make containers`
+
 View logs: `make showlogs`
 
 See what containers are running: `make ps`
diff --git a/xos/configurations/devel/docker-compose.yml b/xos/configurations/devel/docker-compose.yml
index c602980..b592bce 100644
--- a/xos/configurations/devel/docker-compose.yml
+++ b/xos/configurations/devel/docker-compose.yml
@@ -5,7 +5,7 @@
 
 xos_synchronizer_openstack:
     image: xosproject/xos-synchronizer-openstack
-    command: bash -c "sleep 120; python /opt/xos/xos-observer.py"
+    command: bash -c "sleep 120; python /opt/xos/synchronizers/openstack/xos-synchronizer.py"
     labels:
         org.xosproject.kind: synchronizer
         org.xosproject.target: openstack
diff --git a/xos/configurations/frontend/Makefile b/xos/configurations/frontend/Makefile
index c061bc1..130153a 100644
--- a/xos/configurations/frontend/Makefile
+++ b/xos/configurations/frontend/Makefile
@@ -1,11 +1,14 @@
 MYIP:=$(shell hostname -i)
 
 frontend:
-	sudo make -f ../common/Makefile.prereq
+	sudo make -f ../common/Makefile.prereqs
 	sudo docker-compose up -d
 	bash ../common/wait_for_xos.sh
 	sudo docker-compose run xos python /opt/xos/tosca/run.py padmin@vicci.org /opt/xos/configurations/frontend/sample.yaml
 
+containers:
+	cd ../../../containers/xos; make devel
+
 stop:
 	sudo docker-compose stop
 
diff --git a/xos/configurations/frontend/README.md b/xos/configurations/frontend/README.md
index 1cf244d..a0ee72e 100644
--- a/xos/configurations/frontend/README.md
+++ b/xos/configurations/frontend/README.md
@@ -25,6 +25,8 @@
 
 Delete the containers and relaunch them: `make rm; make`
 
+Build the containers from scratch using the local XOS source tree: `make containers`
+
 View logs: `make showlogs`
 
 See what containers are running: `make ps`
diff --git a/xos/configurations/test/Makefile b/xos/configurations/test/Makefile
index a79e322..adf349a 100644
--- a/xos/configurations/test/Makefile
+++ b/xos/configurations/test/Makefile
@@ -12,6 +12,10 @@
 	sudo MYIP=$(MYIP) docker-compose run xos bash -c "cd /opt/xos/tosca/tests; python ./alltests.py"
 	sudo MYIP=$(MYIP) docker-compose run xos bash -c "cd /opt/xos/tosca/tests; python ./allObserverTests.py"
 
+containers:
+	cd ../../../containers/xos; make devel
+	cd ../../../containers/synchronizer; make
+
 common_cloudlab:
 	make -C ../common -f Makefile.cloudlab
 
diff --git a/xos/configurations/vtn/Makefile b/xos/configurations/vtn/Makefile
new file mode 100644
index 0000000..335f83d
--- /dev/null
+++ b/xos/configurations/vtn/Makefile
@@ -0,0 +1,53 @@
+SETUPDIR:=../setup
+MYIP:=$(shell hostname -i)
+
+cloudlab: common_cloudlab ansible_hosts xos
+
+devstack: upgrade_pkgs common_devstack ansible_hosts xos
+
+xos: vtn_network_cfg_json
+	sudo MYIP=$(MYIP) docker-compose up -d
+	bash ../common/wait_for_xos.sh
+	sudo MYIP=$(MYIP) docker-compose run xos python /opt/xos/tosca/run.py padmin@vicci.org /opt/xos/configurations/common/base.yaml
+	sudo MYIP=$(MYIP) docker-compose run xos python /opt/xos/tosca/run.py padmin@vicci.org /root/setup/nodes.yaml
+	sudo MYIP=$(MYIP) docker-compose run xos python /opt/xos/tosca/run.py padmin@vicci.org /opt/xos/tosca/samples/vtn.yaml
+
+containers:
+	cd ../../../containers/xos; make devel
+	cd ../../../containers/synchronizer; make
+
+common_cloudlab:
+	make -C ../common -f Makefile.cloudlab
+
+common_devstack:
+	make -C ../common -f Makefile.devstack
+
+vtn_network_cfg_json:
+	export SETUPDIR=$(SETUPDIR); bash ../cord/make-vtn-networkconfig-json.sh
+
+ansible_hosts:
+	sudo bash -c "export SETUPDIR=$(SETUPDIR); scripts/gen-inventory.sh"
+
+stop:
+	sudo MYIP=$(MYIP) docker-compose stop
+
+showlogs:
+	sudo MYIP=$(MYIP) docker-compose logs
+
+rm: stop
+	sudo MYIP=$(MYIP) docker-compose rm
+
+ps:
+	sudo MYIP=$(MYIP) docker-compose ps
+
+enter-xos:
+	sudo docker exec -it vtn_xos_1 bash
+
+enter-synchronizer:
+	sudo docker exec -it vtn_xos_synchronizer_openstack_1 bash
+
+upgrade_pkgs:
+	sudo pip install httpie --upgrade
+
+destroy-networks:
+	sudo ../../tools/destroy-all-networks.sh
diff --git a/xos/configurations/vtn/README.md b/xos/configurations/vtn/README.md
new file mode 100644
index 0000000..f4c8248
--- /dev/null
+++ b/xos/configurations/vtn/README.md
@@ -0,0 +1,80 @@
+# XOS+VTN development environment
+
+This goal is to use this configuration to do basic end-to-end development of XOS and VTN.  
+It launches
+XOS in three Docker containers (development GUI, Synchronizer, database) and configures XOS
+to talk to an OpenStack backend.  *docker-compose* is used to manage the containers.
+
+See [the VTN README](../cord/README-VTN.md) for more information.
+
+## How to run it
+
+The configuration can be either run on [CloudLab](http://cloudlab.us) (controlling
+an OpenStack backend set up by a CloudLab profile) or used with a basic
+[DevStack](http://docs.openstack.org/developer/devstack/) configuration.
+
+### CloudLab
+
+To get started on CloudLab:
+* Create an experiment using the *OpenStack* profile.  Choose *Kilo* and
+disable security groups.
+* Wait until you get an email from CloudLab with title "OpenStack Instance Finished Setting Up".
+* Login to the *ctl* node of your experiment and run:
+```
+ctl:~$ git clone https://github.com/open-cloud/xos.git
+ctl:~$ cd xos/xos/configurations/vtn/
+ctl:~/xos/xos/configurations/vtn$ make cloudlab
+```
+
+The configuration provides an Ansible script that automates the configuration
+steps outlined in [the VTN README](../cord/README-VTN.md).  Run:
+```
+ctl:~/xos/xos/configurations/vtn$ make destroy-networks
+ctl:~/xos/xos/configurations/vtn$ sudo ansible-playbook setup.yml
+```
+
+
+### DevStack
+
+*NOTE: THIS CONFIGURATION IS NOT YET WORKING WITH DEVSTACK.*
+
+The following instructions can be used to install DevStack and XOS together
+on a single node.  This setup has been run successfully in a VirtualBox VM
+with 2 CPUs and 4096 GB RAM.
+
+First, if you happen to be installing DevStack on a CloudLab node, you can
+configure about 1TB of unallocated disk space for DevStack as follows:
+```
+~$ sudo mkdir -p /opt/stack
+~$ sudo /usr/testbed/bin/mkextrafs /opt/stack
+```
+
+To install DevStack and XOS:
+
+```
+~$ git clone https://github.com/open-cloud/xos.git
+~$ git clone https://git.openstack.org/openstack-dev/devstack
+~$ cd devstack
+~/devstack$ cp ../xos/xos/configurations/common/devstack/local.conf .
+~/devstack$ ./stack.sh
+~/devstack$ cd ../xos/xos/configurations/devel/
+~/xos/xos/configurations/devel$ make devstack
+```
+
+## Docker Helpers
+
+Stop the containers: `make stop`
+
+Restart the containers: `make stop; make [cloudlab|devstack]`
+
+Delete the containers and relaunch them: `make rm; make [cloudlab|devstack]`
+
+Build the containers from scratch using the local XOS source tree: `make containers`
+
+View logs: `make showlogs`
+
+See what containers are running: `make ps`
+
+Open a shell on the XOS container: `make enter-xos`
+
+Open a shell on the Synchronizer container: `make enter-synchronizer`
diff --git a/xos/configurations/vtn/docker-compose.yml b/xos/configurations/vtn/docker-compose.yml
new file mode 100644
index 0000000..c54927b
--- /dev/null
+++ b/xos/configurations/vtn/docker-compose.yml
@@ -0,0 +1,54 @@
+xos_db:
+    image: xosproject/xos-postgres
+    expose:
+        - "5432"
+
+xos_synchronizer_openstack:
+    image: xosproject/xos-synchronizer-openstack
+    command: bash -c "python /opt/xos/synchronizers/openstack/xos-synchronizer.py"
+    labels:
+        org.xosproject.kind: synchronizer
+        org.xosproject.target: openstack
+    links:
+        - xos_db
+    extra_hosts:
+        - ctl:${MYIP}
+    volumes:
+        - ../setup:/root/setup:ro
+        - ../common/xos_common_config:/opt/xos/xos_configuration/xos_common_config:ro
+        - ./files/xos_vtn_config:/opt/xos/xos_configuration/xos_vtn_config:ro
+
+
+xos_synchronizer_onos:
+    image: xosproject/xos-synchronizer-openstack
+    command: bash -c "python /opt/xos/observers/onos/onos-observer.py -C /opt/xos/observers/onos/onos_observer_config"
+    labels:
+        org.xosproject.kind: synchronizer
+        org.xosproject.target: onos
+    links:
+        - xos_db
+    extra_hosts:
+        - ctl:${MYIP}
+    volumes:
+        - ../setup:/root/setup:ro
+        - ../setup/id_rsa:/opt/xos/observers/onos/onos_key:ro  # private key
+
+# FUTURE
+#xos_swarm_synchronizer:
+#    image: xosproject/xos-swarm-synchronizer
+#    labels:
+#        org.xosproject.kind: synchronizer
+#        org.xosproject.target: swarm
+
+xos:
+    image: xosproject/xos
+    command: python /opt/xos/manage.py runserver 0.0.0.0:8000 --insecure --makemigrations
+    ports:
+        - "9999:8000"
+    links:
+        - xos_db
+    volumes:
+      - ../setup:/root/setup:ro
+      - ../common/xos_common_config:/opt/xos/xos_configuration/xos_common_config:ro
+      - ./files/xos_vtn_config:/opt/xos/xos_configuration/xos_vtn_config:ro
+      - ../setup/id_rsa.pub:/opt/xos/observers/onos/onos_key.pub:ro
diff --git a/xos/configurations/vtn/files/neutron-supervisor.conf b/xos/configurations/vtn/files/neutron-supervisor.conf
new file mode 100644
index 0000000..591df7d
--- /dev/null
+++ b/xos/configurations/vtn/files/neutron-supervisor.conf
@@ -0,0 +1,2 @@
+[program:neutron-server]
+command=/usr/bin/python /usr/bin/neutron-server --config-file=/etc/neutron/plugins/ml2/ml2_conf.ini --config-file=/etc/neutron/neutron.conf --config-file /usr/local/etc/neutron/plugins/ml2/conf_onos.ini --log-file=/var/log/neutron/neutron-server.log
diff --git a/xos/configurations/vtn/files/xos_vtn_config b/xos/configurations/vtn/files/xos_vtn_config
new file mode 100644
index 0000000..5dfd459
--- /dev/null
+++ b/xos/configurations/vtn/files/xos_vtn_config
@@ -0,0 +1,2 @@
+[networking]
+use_vtn=True
diff --git a/xos/configurations/vtn/scripts/gen-inventory.sh b/xos/configurations/vtn/scripts/gen-inventory.sh
new file mode 100755
index 0000000..f793a9a
--- /dev/null
+++ b/xos/configurations/vtn/scripts/gen-inventory.sh
@@ -0,0 +1,29 @@
+FN=/etc/ansible/hosts
+
+echo "Writing to $FN"
+
+rm -f $FN
+
+cat >> $FN <<EOF
+localhost
+
+[nodes]
+EOF
+
+NODES=$( sudo bash -c "source $SETUPDIR/admin-openrc.sh ; nova hypervisor-list" |grep enabled|awk '{print $4}' )
+
+# also configure ONOS to manage the nm node
+NM=`grep "^nm" /root/setup/fqdn.map | awk '{ print $2 }'`
+NODES="$NODES $NM"
+
+for NODE in $NODES; do
+    cat >> $FN <<EOF
+$NODE
+EOF
+done
+
+cat >> $FN <<EOF
+[nodes:vars]
+ansible_ssh_user=root
+ansible_ssh_key=/root/setup/id_rsa
+EOF
diff --git a/xos/configurations/vtn/setup.yml b/xos/configurations/vtn/setup.yml
new file mode 100644
index 0000000..ed7cd59
--- /dev/null
+++ b/xos/configurations/vtn/setup.yml
@@ -0,0 +1,51 @@
+---
+- hosts: localhost
+  connection: local
+  sudo: yes
+  vars:
+    vtn_host: cp-1.devel.xos-pg0.apt.emulab.net
+  tasks:
+  - apt: name={{ item }} state=installed
+    with_items:
+    - python-pip
+    - supervisor
+
+  - pip: name={{ item }} state=latest
+    with_items:
+    - setuptools
+    - pip
+    - testrepository
+  - git: repo=https://github.com/openstack/networking-onos.git
+      dest=/srv/networking-onos
+  - shell: cd /srv/networking-onos; python setup.py install
+
+  # Edit /etc/neutron/plugins/ml2/ml2_conf.ini
+  - ini_file: dest=/usr/local/etc/neutron/plugins/ml2/conf_onos.ini
+      section=onos option=url_path value=http://{{ vtn_host }}:8181/onos/openstackswitching
+  - ini_file: dest=/usr/local/etc/neutron/plugins/ml2/conf_onos.ini
+      section=onos option=username value=karaf
+  - ini_file: dest=/usr/local/etc/neutron/plugins/ml2/conf_onos.ini
+      section=onos option=password value=karaf
+
+  # Edit /etc/neutron/neutron.conf
+#  - ini_file: dest=/etc/neutron/neutron.conf
+#      section=DEFAULT option=core_plugin value=neutron.plugins.ml2.plugin.Ml2Plugin
+
+  # Edit /etc/neutron/plugins/ml2/ml2_conf.ini
+  - ini_file: dest=/etc/neutron/plugins/ml2/ml2_conf.ini
+      section=ml2 option=tenant_network_types value=vxlan
+  - ini_file: dest=/etc/neutron/plugins/ml2/ml2_conf.ini
+      section=ml2 option=type_drivers value=vxlan
+  - ini_file: dest=/etc/neutron/plugins/ml2/ml2_conf.ini
+      section=ml2 option=mechanism_drivers value=onos_ml2
+  - ini_file: dest=/etc/neutron/plugins/ml2/ml2_conf.ini
+      section=ml2_type_vxlan option=vni_ranges value=1001:2000
+
+  - service: name=neutron-server state=stopped enabled=no
+  # Run neutron-server with extra config file
+  - copy: src=files/neutron-supervisor.conf dest=/etc/supervisor/conf.d/
+  - shell: supervisorctl reload
+
+#  - shell: ../../scripts/destroy-all-networks.sh
+  - shell: cd ../cord/dataplane; bash ./generate-bm.sh > hosts-bm
+  - shell: cd ../cord/dataplane; ansible-playbook -i hosts-bm dataplane-vtn.yaml
diff --git a/xos/core/__init__.py b/xos/core/__init__.py
index e69de29..e01f9cd 100644
--- a/xos/core/__init__.py
+++ b/xos/core/__init__.py
@@ -0,0 +1 @@
+# from tests import *
diff --git a/xos/core/admin.py b/xos/core/admin.py
index ad49cec..21b7565 100644
--- a/xos/core/admin.py
+++ b/xos/core/admin.py
@@ -194,15 +194,15 @@
         # for Service admins to render their Administration page
         if getattr(self, "extracontext_registered_admins", False):
             admins=[]
-            for model, model_admin in admin.site._registry.items():

-                if model == self.model:

-                    continue

-                if model._meta.app_label == self.model._meta.app_label:

-                    info = {"app": model._meta.app_label,

-                            "model": model._meta.model_name,

-                            "name": capfirst(model._meta.verbose_name_plural),

-                            "url": self.url_for_model_changelist(request,model) }

-                    admins.append(info)

+            for model, model_admin in admin.site._registry.items():
+                if model == self.model:
+                    continue
+                if model._meta.app_label == self.model._meta.app_label:
+                    info = {"app": model._meta.app_label,
+                            "model": model._meta.model_name,
+                            "name": capfirst(model._meta.verbose_name_plural),
+                            "url": self.url_for_model_changelist(request,model) }
+                    admins.append(info)
             extra_context["registered_admins"] = admins
 
     def change_view(self,request,object_id, extra_context=None):
diff --git a/xos/core/api/auth.py b/xos/core/api/auth.py
deleted file mode 100644
index 8796f14..0000000
--- a/xos/core/api/auth.py
+++ /dev/null
@@ -1,8 +0,0 @@
-from openstack.client import OpenStackClient
-
-def auth_check(username, password, tenant):
-    client = OpenStackClient(username=username,
-                             password=password,
-                             tenant=tenant)
-    client.authenticate()
-    return client
diff --git a/xos/core/api/deployment_networks.py b/xos/core/api/deployment_networks.py
deleted file mode 100644
index ee1f68e..0000000
--- a/xos/core/api/deployment_networks.py
+++ /dev/null
@@ -1,40 +0,0 @@
-from types import StringTypes
-from core.models import Deployment
-from django.contrib.auth import authenticate
-
-def _get_deployment_networks(filter):
-    if isinstance(filter, StringTypes) and filter.isdigit():
-        filter = int(filter)
-    if isinstance(filter, int):
-        deployment_networks = Deployment.objects.filter(id=filter)
-    elif isinstance(filter, StringTypes):
-        deployment_networks = Deployment.objects.filter(name=filter)
-    elif isinstance(filter, dict):
-        deployment_networks = Deployment.objects.filter(**filter)
-    else:
-        deployment_networks = []
-    return deployment_networks 
-
-def add_deployment_network(auth, name):
-    user = authenticate(username=auth.get('username'),
-                        password=auth.get('password'))
-    deployment = Deployment(name=name)
-    deployment.save()
-    return deployment
-
-def delete_deployment_network(auth, filter={}):
-    user = authenticate(username=auth.get('username'),
-                        password=auth.get('password'))
-    deployments = _get_deployment_networks(filter)
-    for deployment in deployments:
-        deployment.delete()
-    return 1
-
-def get_deployment_networks(auth, filter={}):
-    user = authenticate(username=auth.get('username'),
-                        password=auth.get('password'))
-    deployments = _get_deployment_networks(filter)
-    return deployments             
-        
-
-    
diff --git a/xos/core/api/images.py b/xos/core/api/images.py
deleted file mode 100644
index 933216f..0000000
--- a/xos/core/api/images.py
+++ /dev/null
@@ -1,33 +0,0 @@
-from types import StringTypes
-from django.contrib.auth import authenticate
-from core.models import Image
- 
-def _get_images(filter):
-    if isinstance(filter, StringTypes) and filter.isdigit():
-        filter = int(filter)
-    if isinstance(filter, int):
-        images = Image.objects.filter(id=filter)
-    elif isinstance(filter, StringTypes):
-        images = Image.objects.filter(name=filter)
-    elif isinstance(filter, dict):
-        images = Image.objects.filter(**filter)
-    else:
-        images = []
-    return images
-
-def add_image(auth, fields={}):
-    """not implemented"""
-    return 
-
-def delete_image(auth, filter={}):
-    """not implemented"""
-    return 1
-
-def get_images(auth, filter={}):
-    user = authenticate(username=auth.get('username'),
-                        password=auth.get('password'))
-    images = _get_images(filter)
-    return images             
-        
-
-    
diff --git a/xos/core/api/instances.py b/xos/core/api/instances.py
deleted file mode 100644
index 92e928c..0000000
--- a/xos/core/api/instances.py
+++ /dev/null
@@ -1,65 +0,0 @@
-from types import StringTypes
-from django.contrib.auth import authenticate
-from openstack.manager import OpenStackManager
-from core.models import Instance, Slice
-from core.api.images import _get_images
-from core.api.slices import _get_slices
-from core.api.deployment_networks import _get_deployment_networks
-from core.api.nodes import _get_nodes
-
-def _get_instances(filter):
-    if isinstance(filter, StringTypes) and filter.isdigit():
-        filter = int(filter)
-    if isinstance(filter, int):
-        instances = Instance.objects.filter(id=filter)
-    elif isinstance(filter, StringTypes):
-        instances = Instance.objects.filter(name=filter)
-    elif isinstance(filter, dict):
-        instances = Instance.objects.filter(**filter)
-    else:
-        instances = []
-    return instances
- 
-def add_instance(auth, fields):
-    user = authenticate(username=auth.get('username'),
-                        password=auth.get('password'))
-    
-    images = _get_images(fields.get('image'))
-    slices = _get_slices(fields.get('slice'))
-    deployment_networks = _get_deployment_networks(fields.get('deploymentNetwork'))
-    nodes = _get_nodes(fields.get('node'))
-    if images: fields['image'] = images[0]     
-    if slices: fields['slice'] = slices[0]     
-    if deployment_networks: fields['deploymentNetwork'] = deployment_networks[0]     
-    if nodes: fields['node'] = nodes[0]     
-
-    instance = Instance(**fields)
-    auth['tenant'] = instance.slice.name
-    instance.os_manager = OpenStackManager(auth=auth, caller = user)    
-    instance.save()
-    return instance
-
-def update_instance(auth, instance, **fields):
-    return  
-
-def delete_instance(auth, filter={}):
-    user = authenticate(username=auth.get('username'),
-                        password=auth.get('password'))
-    instances = _get_instances(filter)
-    for instance in instances:
-        auth['tenant'] = instance.slice.name 
-        slice.os_manager = OpenStackManager(auth=auth, caller = user)
-        instance.delete()
-    return 1
-
-def get_instances(auth, filter={}):
-    user = authenticate(username=auth.get('username'),
-                        password=auth.get('password'))
-    if 'slice' in filter:
-        slices = _get_slices(filter.get('slice'))
-        if slices: filter['slice'] = slices[0]
-    instances = _get_instances(filter)
-    return instances             
-        
-
-    
diff --git a/xos/core/api/nodes.py b/xos/core/api/nodes.py
deleted file mode 100644
index 4f7ceeb..0000000
--- a/xos/core/api/nodes.py
+++ /dev/null
@@ -1,36 +0,0 @@
-from types import StringTypes
-from django.contrib.auth import authenticate
-from core.models import Node
- 
-def _get_nodes(filter):
-    if isinstance(filter, StringTypes) and filter.isdigit():
-        filter = int(filter)
-    if isinstance(filter, int):
-        nodes = Node.objects.filter(id=filter)
-    elif isinstance(filter, StringTypes):
-        nodes = Node.objects.filter(name=filter)
-    elif isinstance(filter, dict):
-        nodes = Node.objects.filter(**filter)
-    else:
-        nodes = []
-    return nodes
-
-def add_node(auth, fields={}):
-    """not implemented"""
-    return 
-
-def delete_node(auth, filter={}):
-    """not implemented"""
-    return 1
-
-def update_node(auth, id, fields={}):
-    return 
-
-def get_nodes(auth, filter={}):
-    user = authenticate(username=auth.get('username'),
-                        password=auth.get('password'))
-    nodes = _get_nodes(filter)
-    return nodes             
-        
-
-    
diff --git a/xos/core/api/roles.py b/xos/core/api/roles.py
deleted file mode 100644
index 4ea05c9..0000000
--- a/xos/core/api/roles.py
+++ /dev/null
@@ -1,44 +0,0 @@
-from types import StringTypes
-from django.contrib.auth import authenticate
-from openstack.manager import OpenStackManager
-from core.models import Role
- 
-
-def _get_roles(filter):
-    if isinstance(filter, StringTypes) and filter.isdigit():
-        filter = int(filter)
-    if isinstance(filter, int):
-        roles = Role.objects.filter(id=filter)
-    elif isinstance(filter, StringTypes):
-        roles = Role.objects.filter(role_type=filter)
-    elif isinstance(filter, dict):
-        roles = Role.objects.filter(**filter)
-    else:
-        roles = []
-    return roles
-
-def add_role(auth, name):
-    user = authenticate(username=auth.get('username'),
-                        password=auth.get('password'))
-    auth['tenant'] = user.site.login_base
-
-    role = Role(role_type=name)
-    role.os_manager = OpenStackManager(auth=auth, caller = user) 
-    role.save()
-    return role
-
-def delete_role(auth, filter={}):
-    user = authenticate(username=auth.get('username'),
-                        password=auth.get('password'))
-    roles = _get_roles(filter) 
-    for role in roles:
-        auth['tenant'] = user.site.login_base
-        role.os_manager = OpenStackManager(auth=auth, caller = user)
-        role.delete()
-    return 1
-
-def get_roles(auth, filter={}):
-    user = authenticate(username=auth.get('username'),
-                        password=auth.get('password'))
-    return _get_roles(filter)             
-        
diff --git a/xos/core/api/site_privileges.py b/xos/core/api/site_privileges.py
deleted file mode 100644
index 6d79701..0000000
--- a/xos/core/api/site_privileges.py
+++ /dev/null
@@ -1,73 +0,0 @@
-from types import StringTypes
-import re
-from django.contrib.auth import authenticate
-from openstack.manager import OpenStackManager
-from core.models import SitePrivilege
-from core.api.users import _get_users
-from core.api.sites import _get_sites
-from core.api.roles import _get_roles
-
-
-def _get_site_privileges(filter):
-    if isinstance(filter, StringTypes) and filter.isdigit():
-        filter = int(filter)
-    if isinstance(filter, int):
-        site_privileges = SitePrivilege.objects.filter(id=filter)
-    elif isinstance(filter, StringTypes):
-        site_privileges = SitePrivilege.objects.filter(name=filter)
-    elif isinstance(filter, dict):
-        site_privileges = SitePrivilege.objects.filter(**filter)
-    else:
-        site_privileges = []
-    return site_privileges
- 
-def add_site_privilege(auth, fields):
-    user = authenticate(username=auth.get('username'),
-                        password=auth.get('password'))
-
-    users = _get_user(fields.get('user')) 
-    sites = _get_slice(fields.get('site')) 
-    roles = _get_role(fields.get('role'))
-    
-    if users: fields['user'] = users[0]     
-    if slices: fields['site'] = sites[0] 
-    if roles: fields['role'] = roles[0]
- 
-    auth['tenant'] = sites[0].login_base
-    site_privilege = SitePrivilege(**fields)
-    site_privilege.os_manager = OpenStackManager(auth=auth, caller = user) 
-    site_privilege.save()
-    return site_privilege
-
-def update_site_privilege(auth, id, **fields):
-    return  
-
-def delete_site_privilege(auth, filter={}):
-    user = authenticate(username=auth.get('username'),
-                        password=auth.get('password'))
-    auth['tenant'] = user.site.login_base
-    manager = OpenStackManager(auth=auth, caller = user)
-
-    site_privileges = _get_site_privileges(filter)
-    for site_privilege in site_privileges:
-        auth['tenant'] = user.site.login_base
-        site_privilege.os_manager = OpenStackManager(auth=auth, caller = user)
-        site_privilege.delete()
-    return 1
-
-def get_site_privileges(auth, filter={}):
-    user = authenticate(username=auth.get('username'),
-                        password=auth.get('password'))
-    users = _get_users(filter.get('user'))
-    sites = _get_slices(filter.get('site'))
-    roles = _get_roles(filter.get('role'))
-
-    if users: filter['user'] = users[0]
-    if sites: filter['site'] = sites[0]
-    if roles: filter['role'] = roles[0]
-    
-    site_privileges = _get_site_privileges(filter)
-    return site_privileges             
-        
-
-    
diff --git a/xos/core/api/sites.py b/xos/core/api/sites.py
deleted file mode 100644
index 123f139..0000000
--- a/xos/core/api/sites.py
+++ /dev/null
@@ -1,60 +0,0 @@
-from types import StringTypes
-from django.contrib.auth import authenticate
-from openstack.manager import OpenStackManager    
-from core.models import Site
-
-def _get_sites(filter):
-    if isinstance(filter, StringTypes) and filter.isdigit():
-        filter = int(filter)
-    if isinstance(filter, int):
-        sites = Site.objects.filter(id=filter)
-    elif isinstance(filter, StringTypes):
-        sites = Site.objects.filter(login_base=filter)
-    elif isinstance(filter, dict):
-        sites = Site.objects.filter(**filter)
-    else:
-        sites = []
-    return sites 
-
-def add_site(auth, fields):
-    user = authenticate(username=auth.get('username'),
-                        password=auth.get('password'))
-    auth['tenant'] = user.site.login_base
-
-    site = Site(**fields)
-    site.os_manager = OpenStackManager(auth=auth, caller = user)
-    site.save()
-    return site
-
-def update_site(auth, id, **fields):
-    user = authenticate(username=auth.get('username'),
-                        password=auth.get('password'))
-    auth['tenant'] = user.site.login_base
-
-    sites = _get_sites(id)
-    if not sites:
-        return
-
-    site = Site[0]
-    site.os_manager = OpenStackManager(auth=auth, caller = user)
-    site.update(**fields)
-    return site 
-
-def delete_site(auth, filter={}):
-    user = authenticate(username=auth.get('username'),
-                        password=auth.get('password'))
-    auth['tenant'] = user.site.login_base
-    sites = _get_sites(id)
-    for site in sites:
-        site.os_manager = OpenStackManager(auth=auth, caller = user)
-        site.delete()
-    return 1
-
-def get_sites(auth, filter={}):
-    user = authenticate(username=auth.get('username'),
-                        password=auth.get('password'))
-    sites = _get_sites(filter)
-    return sites             
-        
-
-    
diff --git a/xos/core/api/slice_memberships.py b/xos/core/api/slice_memberships.py
deleted file mode 100644
index 3e25ae7..0000000
--- a/xos/core/api/slice_memberships.py
+++ /dev/null
@@ -1,70 +0,0 @@
-from types import StringTypes
-from django.contrib.auth import authenticate
-from openstack.manager import OpenStackManager
-from core.models import SliceMembership
-from core.api.users import _get_users
-from core.api.slices import _get_slices
-from core.api.roles import _get_roles
-
-def _get_slice_memberships(filter):
-    if isinstance(filter, StringTypes) and filter.isdigit():
-        filter = int(filter)
-    if isinstance(filter, int):
-        slice_memberships = SitePrivilege.objects.filter(id=filter)
-    elif isinstance(filter, StringTypes):
-        slice_memberships = SitePrivilege.objects.filter(name=filter)
-    elif isinstance(filter, dict):
-        slice_memberships = SitePrivilege.objects.filter(**filter)
-    else:
-        slice_memberships = []
-    return slice_memberships
-
- 
-def add_slice_membership(auth, fields):
-    user = authenticate(username=auth.get('username'),
-                        password=auth.get('password'))
-
-    users = _get_users(fields.get('user')) 
-    slices = _get_slices(fields.get('slice')) 
-    roles = _get_roles(fields.get('role'))
-    
-    if users: fields['user'] = users[0]     
-    if slices: fields['slice'] = slices[0] 
-    if roles: fields['role'] = roles[0]
- 
-    slice_membership = SliceMembership(**fields)
-    auth['tenant'] = sites[0].login_base
-    slice_membership.os_manager = OpenStackManager(auth=auth, caller = user) 
-    slice_membership.save()
-    return slice_membership
-
-def update_slice_membership(auth, id, **fields):
-    return  
-
-def delete_slice_membership(auth, filter={}):
-    user = authenticate(username=auth.get('username'),
-                        password=auth.get('password'))
-    auth['tenant'] = user.site.login_base
-
-    slice_memberships = _get_slice_memberships(filter)
-    for slice_membership in slice_memberships:
-        slice_membership.os_manager = OpenStackManager(auth=auth, caller = user)
-        slice_membership.delete()
-    return 1
-
-def get_slice_memberships(auth, filter={}):
-    user = authenticate(username=auth.get('username'),
-                        password=auth.get('password'))
-    users = _get_users(fields.get('user'))
-    slices = _get_slices(fields.get('slice'))
-    roles = _get_roles(fields.get('role'))
-
-    if users: fields['user'] = users[0]
-    if slices: fields['slice'] = slices[0]
-    if roles: fields['role'] = roles[0]
-
-    slice_memberships = _get_slice_memberships(filter)
-    return slice_memberships             
-        
-
-    
diff --git a/xos/core/api/slices.py b/xos/core/api/slices.py
deleted file mode 100644
index c9e94a2..0000000
--- a/xos/core/api/slices.py
+++ /dev/null
@@ -1,74 +0,0 @@
-import re
-from types import StringTypes
-from django.contrib.auth import authenticate
-from openstack.manager import OpenStackManager
-from core.models import Slice
-from core.api.sites import _get_sites
-
-def _get_slices(filter):
-    if isinstance(filter, StringTypes) and filter.isdigit():
-        filter = int(filter)
-    if isinstance(filter, int):
-        slices = Slice.objects.filter(id=filter)
-    elif isinstance(filter, StringTypes):
-        slices = Slice.objects.filter(name=filter)
-    elif isinstance(filter, dict):
-        slices = Slice.objects.filter(**filter)
-    else:
-        slices = []
-    return slices
-    
- 
-def add_slice(auth, fields):
-    user = authenticate(username=auth.get('username'),
-                        password=auth.get('password'))
-    auth['tenant'] = user.site.login_base
-
-    login_base = fields['name'][:fields['name'].find('_')]
-    sites = _get_sites(login_base) 
-    if sites: fields['site'] = sites[0]     
-    slice = Slice(**fields)
-    slice.os_manager = OpenStackManager(auth=auth, caller = user) 
-    slice.save()
-    return slice
-
-def update_slice(auth, id, **fields):
-    user = authenticate(username=auth.get('username'),
-                        password=auth.get('password'))
-    auth['tenant'] = user.site.login_base
-
-    slices = _get_slices(id)
-    if not slices:
-        return
-    slice = slices[0]
-    sites = _get_sites(fields.get('site'))
-    if sites: fields['site'] = sites[0]
-
-    slice.os_manager = OpenStackManager(auth=auth, caller = user)
-    for (k,v) in fields.items():
-        setattr(slice, k, v)
-    slice.save()
-
-    return slice 
-
-def delete_slice(auth, filter={}):
-    user = authenticate(username=auth.get('username'),
-                        password=auth.get('password'))
-    auth['tenant'] = user.site.login_base
-    slices = _get_slices(filter)
-    for slice in slices:
-        slice.os_manager = OpenStackManager(auth=auth, caller = user) 
-        slice.delete()
-    return 1
-
-def get_slices(auth, filter={}):
-    user = authenticate(username=auth.get('username'),
-                        password=auth.get('password'))
-    if 'site' in filter:
-        sites = _get_sites(filter.get('site'))
-        if sites: filter['site'] = sites[0]
-    slices = _get_slices(filter)
-    return slices             
-        
-
-    
diff --git a/xos/core/api/subnets.py b/xos/core/api/subnets.py
deleted file mode 100644
index d618eda..0000000
--- a/xos/core/api/subnets.py
+++ /dev/null
@@ -1,74 +0,0 @@
-import commands
-from types import StringTypes
-from openstack.client import OpenStackClient
-from openstack.driver import OpenStackDriver
-from core.api.auth import auth_check
-from core.models import Subnet
-from core.api.slices import _get_slices
-
-
-def _get_subnets(filter):
-    if isinstance(filter, StringTypes) and filter.isdigit():
-        filter = int(filter)
-    if isinstance(filter, int):
-        subnets = Subnet.objects.filter(id=filter)
-    elif isinstance(filter, StringTypes):
-        # the name is the subnet's slice's name
-        slices = _get_slices(filter)
-        slice = None
-        if slices: slice=slices[0]
-        subnets = Subnet.objects.filter(slice=slice)
-    elif isinstance(filter, dict):
-        subnets = Subnet.objects.filter(**filter)
-    else:
-        subnets = []
-    return subnets
-
-def add_subnet(auth, fields):
-    driver = OpenStackDriver(client = auth_check(auth))
-    slices = _get_slices(fields.get('slice')) 
-    if slices: fields['slice'] = slices[0]     
-    subnet = Subnet(**fields)
-    # create quantum subnet
-    quantum_subnet = driver.create_subnet(name= subnet.slice.name,
-                                          network_id=subnet.slice.network_id,
-                                          cidr_ip = subnet.cidr,
-                                          ip_version=subnet.ip_version,
-                                          start = subnet.start,
-                                          end = subnet.end)
-    subnet.subnet_id=quantum_subnet['id']
-    ## set dns servers
-    #driver.update_subnet(subnet.id, {'dns_nameservers': ['8.8.8.8', '8.8.4.4']})
-
-    # add subnet as interface to slice's router
-    try: driver.add_router_interface(subnet.slice.router_id, subnet.subnet_id)
-    except: pass         
-    #add_route = 'route add -net %s dev br-ex gw 10.100.0.5' % self.cidr
-    commands.getstatusoutput(add_route)    
-    subnet.save()
-    return subnet
-
-def update_subnet(auth, subnet, **fields):
-    return  
-
-def delete_subnet(auth, filter={}):
-    driver = OpenStackDriver(client = auth_check(auth))   
-    subnets = Subnet.objects.filter(**filter)
-    for subnet in subnets:
-        driver.delete_router_interface(subnet.slice.router_id, subnet.subnet_id)
-        driver.delete_subnet(subnet.subnet_id) 
-        subnet.delete()
-        #del_route = 'route del -net %s' % subnet.cidr
-    commands.getstatusoutput(del_route)
-    return 1
-
-def get_subnets(auth, filter={}):
-    client = auth_check(auth)
-    if 'slice' in filter:
-        slice = _get_slice(filter.get('slice'))
-        if slice: filter['slice'] = slice
-    subnets = Subnet.objects.filter(**filter)
-    return subnets             
-        
-
-    
diff --git a/xos/core/api/users.py b/xos/core/api/users.py
deleted file mode 100644
index 08e851c..0000000
--- a/xos/core/api/users.py
+++ /dev/null
@@ -1,75 +0,0 @@
-from types import StringTypes
-from django.contrib.auth import authenticate
-from openstack.manager import OpenStackManager    
-from core.models import User, Site
-from core.api.sites import _get_sites
-
-def _get_users(filter):
-    if isinstance(filter, StringTypes) and filter.isdigit():
-        filter = int(filter)
-    if isinstance(filter, int):
-        users = User.objects.filter(id=filter)
-    elif isinstance(filter, StringTypes):
-        users = User.objects.filter(email=filter)
-    elif isinstance(filter, dict):
-        users = User.objects.filter(**filter)
-    else:
-        users = []
-    return users 
-
-def add_user(auth, fields):
-    user = authenticate(username=auth.get('username'),
-                        password=auth.get('password'))
-    auth['tenant'] = user.site.login_base
-
-    sites = _get_sites(fields.get('site')) 
-    if sites: fields['site'] = sites[0]     
-    user = User(**fields)
-    user.os_manager = OpenStackManager(auth=auth, caller = user)
-    user.save()
-    return user
-
-def update_user(auth, id, **fields):
-    user = authenticate(username=auth.get('username'),
-                        password=auth.get('password'))
-    auth['tenant'] = user.site.login_base
-
-    users = User.objects.filter(id=id)
-    if not users:
-        return
-
-    user = users[0]
-    nova_fields = {}
-    if 'email' in fields:
-        nova_fields['name'] = fields['email'][:self.email.find('@')]
-        nova_fields['email'] = fields['email']
-    if 'password' in fields:
-        nova_fields['password'] = fields['password']
-    if 'enabled' in fields:
-        nova_fields['enabled'] = fields['enabled']
-    sites = _get_sites(fields.get('site'))
-    if sites: fields['site'] = sites[0]
-    user.os_manager = OpenStackManager(auth=auth, caller = user)
-    for (k,v) in fields.items():
-        setattr(user, k, v)    
-    user.save()
-    return user 
-
-def delete_user(auth, filter={}):
-    user = authenticate(username=auth.get('username'),
-                        password=auth.get('password'))
-    auth['tenant'] = user.site.login_base
-    users = _get_users(filter)
-    for user in users:
-        user.os_manager = OpenStackManager(auth=auth, caller = user) 
-        user.delete()
-    return 1
-
-def get_users(auth, filter={}):
-    user = authenticate(username=auth.get('username'),
-                        password=auth.get('password'))
-    users = _get_users(filter)
-    return users             
-        
-
-    
diff --git a/xos/core/api_root.py b/xos/core/api_root.py
deleted file mode 100644
index c3d69f1..0000000
--- a/xos/core/api_root.py
+++ /dev/null
@@ -1,21 +0,0 @@
-from rest_framework.decorators import api_view
-from rest_framework.response import Response
-from rest_framework.reverse import reverse
-
-@api_view(['GET'])
-def api_root(request, format=None):
-    return Response({
-        'deployments': reverse('deployment-list', request=request, format=format),
-        'images': reverse('image-list', request=request, format=format),
-        'nodes': reverse('node-list', request=request, format=format),
-        'projects': reverse('project-list', request=request, format=format),
-        'reservations': reverse('reservation-list', request=request, format=format),
-        'roles': reverse('role-list', request=request, format=format),
-        'serviceclasses': reverse('serviceclass-list', request=request, format=format),
-        'serviceresources': reverse('serviceresource-list', request=request, format=format),
-        'sites': reverse('site-list', request=request, format=format),
-        'slices': reverse('slice-list', request=request, format=format),
-        'instances': reverse('instance-list', request=request, format=format),
-        'tags': reverse('tag-list', request=request, format=format),
-        'users': reverse('user-list', request=request, format=format),
-    })
diff --git a/xos/core/fixtures/initial_data.json b/xos/core/fixtures/core_initial_data.json
similarity index 100%
rename from xos/core/fixtures/initial_data.json
rename to xos/core/fixtures/core_initial_data.json
diff --git a/xos/core/models/__init__.py b/xos/core/models/__init__.py
index c380e9c..a022cae 100644
--- a/xos/core/models/__init__.py
+++ b/xos/core/models/__init__.py
@@ -2,7 +2,7 @@
 from .project import Project
 from .singletonmodel import SingletonModel
 from .service import Service, Tenant, TenantWithContainer, CoarseTenant, ServicePrivilege, TenantRoot, TenantRootPrivilege, TenantRootRole, Subscriber, Provider
-from .service import ServiceAttribute, TenantAttribute
+from .service import ServiceAttribute, TenantAttribute, ServiceRole
 from .tag import Tag
 from .role import Role
 from .site import Site, Deployment, DeploymentRole, DeploymentPrivilege, Controller, ControllerRole, ControllerSite, SiteDeployment
diff --git a/xos/core/models/instance.py b/xos/core/models/instance.py
index cd7dd26..62a86c4 100644
--- a/xos/core/models/instance.py
+++ b/xos/core/models/instance.py
@@ -15,7 +15,6 @@
 from core.models import Flavor
 from django.contrib.contenttypes import generic
 from xos.config import Config
-from monitor import driver as monitor
 from django.core.exceptions import PermissionDenied, ValidationError
 
 config = Config()
diff --git a/xos/core/models/plcorebase.py b/xos/core/models/plcorebase.py
index 9f7aa4c..5c0d7ab 100644
--- a/xos/core/models/plcorebase.py
+++ b/xos/core/models/plcorebase.py
@@ -9,13 +9,13 @@
 from django.forms.models import model_to_dict
 from django.utils import timezone
 from django.core.exceptions import PermissionDenied
-import model_policy
+import synchronizers.model_policy
 from model_autodeletion import ephemeral_models
 from cgi import escape as html_escape
 
 try:
     # This is a no-op if observer_disabled is set to 1 in the config file
-    from observer import *
+    from synchronizers.base import *
 except:
     print >> sys.stderr, "import of observer failed! printing traceback and disabling observer:"
     import traceback
diff --git a/xos/core/models/service.py b/xos/core/models/service.py
index 7cf2a6b..b5ba737 100644
--- a/xos/core/models/service.py
+++ b/xos/core/models/service.py
@@ -174,9 +174,9 @@
             for ns in slice.networkslices.all():
                 if not ns.network:
                     continue
-                if ns.network.template.access in ["direct", "indirect"]:
-                    # skip access networks; we want to use the private network
-                    continue
+#                if ns.network.template.access in ["direct", "indirect"]:
+#                    # skip access networks; we want to use the private network
+#                    continue
                 if ns.network.name in ["wan_network", "lan_network"]:
                     # we don't want to attach to the vCPE's lan or wan network
                     # we only want to attach to its private network
diff --git a/xos/core/models/slice.py b/xos/core/models/slice.py
index 84622cf..42e3a25 100644
--- a/xos/core/models/slice.py
+++ b/xos/core/models/slice.py
@@ -15,6 +15,7 @@
 from core.models import Flavor, Image
 from core.models.plcorebase import StrippedCharField
 from django.core.exceptions import PermissionDenied, ValidationError
+from xos.exceptions import *
 
 # Create your models here.
 
@@ -52,13 +53,13 @@
         site = Site.objects.get(id=self.site.id)
         # allow preexisting slices to keep their original name for now
         if not self.id and not self.name.startswith(site.login_base):
-            raise ValidationError('slice name must begin with %s' % site.login_base)
+            raise XOSValidationError('slice name must begin with %s' % site.login_base)
 
         if self.name == site.login_base+"_":
-            raise ValidationError('slice name is too short')
+            raise XOSValidationError('slice name is too short')
 
         if " " in self.name:
-            raise ValidationError('slice name must not contain spaces')
+            raise XOSValidationError('slice name must not contain spaces')
 
         if self.serviceClass is None:
             # We allowed None=True for serviceClass because Django evolution
@@ -82,7 +83,7 @@
                 raise PermissionDenied("Insufficient privileges to change slice creator")
         
         if not self.creator:
-            raise ValidationError('slice has no creator')
+            raise XOSValidationError('slice has no creator')
 
         if self.network=="Private Only":
             # "Private Only" was the default from the old Tenant View
diff --git a/xos/core/models/user.py b/xos/core/models/user.py
index cb90145..0b8e3af 100644
--- a/xos/core/models/user.py
+++ b/xos/core/models/user.py
@@ -15,12 +15,12 @@
 from timezones.fields import TimeZoneField
 from operator import itemgetter, attrgetter
 from core.middleware import get_request
-import model_policy
+import synchronizers.model_policy
 
 # ------ from plcorebase.py ------
 try:
     # This is a no-op if observer_disabled is set to 1 in the config file
-    from observer import *
+    from synchronizers.base import *
 except:
     print >> sys.stderr, "import of observer failed! printing traceback and disabling observer:"
     import traceback
diff --git a/xos/core/static/xos.css b/xos/core/static/xos.css
index 685361e..f7b7d24 100644
--- a/xos/core/static/xos.css
+++ b/xos/core/static/xos.css
@@ -310,6 +310,14 @@
 }
 /************************* END NAV *************************/
 
+/************************* FORM TWEAKS *************************/
+@media (min-width: 992px){
+    .form-column.col-lg-4 {
+        width: 66.66666667%;
+    }
+}
+/************************* FORM TWEAKS *************************/
+
 /*   CSS for jquery Tabs */
 #hometabs {
 border-bottom: 1px solid #105E9E;
diff --git a/xos/core/tests.py b/xos/core/tests.py
index e3d7faa..06bf678 100644
--- a/xos/core/tests.py
+++ b/xos/core/tests.py
@@ -1,128 +1,337 @@
+# TEST
+# To execute these tests use `python manage.py test core`
+
 #!/usr/bin/env python
 from django.test import TestCase
-from core.models import *
-from rest_framework.test import *
-from genapi import *
+from django.contrib.auth.models import User
+from rest_framework import status
+from rest_framework.test import APIClient
+from rest_framework.test import APITestCase
 import json
-from datetime import datetime
+from django.forms.models import model_to_dict
 
-FIXTURES_FILE = 'core/fixtures/initial_data.json'
-MODELS = ['Deployment','Image','Node','Reservation','Slice','Instance','User']
+from core.models import *
 
-def is_dynamic_type(x):
-	t = type(x)
-	return t in [datetime]
+print "-------------------------- Let's test!!!!!!!! --------------------------"
 
-class APITestCase(TestCase):
-	def setUp(self):
-		self.init_data=json.loads(open(FIXTURES_FILE).read())
-		self.data_dict={}
-		self.hidden_keys={}
+from django.apps import apps
+from django.test.client import Client
+from django.test import testcases
+from django.http import SimpleCookie, HttpRequest, QueryDict
+from importlib import import_module
+from django.conf import settings
+class FixedClient(Client):
+    def login(self, **credentials):
+        """
+        Sets the Factory to appear as if it has successfully logged into a site.
 
-		for d in self.init_data:
-			model_tag = d['model']
-			model_name = model_tag.split('.')[1]
+        Returns True if login is possible; False if the provided credentials
+        are incorrect, or the user is inactive, or if the sessions framework is
+        not available.
+        """
+        from django.contrib.auth import authenticate, login
+        user = authenticate(**credentials)
+        if (user and user.is_active and
+                apps.is_installed('django.contrib.sessions')):
+            engine = import_module(settings.SESSION_ENGINE)
 
-			try:
-				self.data_dict[model_name].append(d)
-			except:
-				self.data_dict[model_name]=[d]
+            # Create a fake request to store login details.
+            request = HttpRequest()
 
-		# Any admin user would do
-		self.calling_user = User('sapan@onlab.us')
-		self.client = APIClient()
-		self.client.force_authenticate(user=self.calling_user)
+            # XOS's admin.py requires these to be filled in
+            request.POST = {"username": credentials["username"],
+                            "password": credentials["password"]}
+
+            if self.session:
+                request.session = self.session
+            else:
+                request.session = engine.SessionStore()
+            login(request, user)
+
+            # Save the session values.
+            request.session.save()
+
+            # Set the cookie to represent the session.
+            session_cookie = settings.SESSION_COOKIE_NAME
+            self.cookies[session_cookie] = request.session.session_key
+            cookie_data = {
+                'max-age': None,
+                'path': '/',
+                'domain': settings.SESSION_COOKIE_DOMAIN,
+                'secure': settings.SESSION_COOKIE_SECURE or None,
+                'expires': None,
+                }
+            self.cookies[session_cookie].update(cookie_data)
+
+            return True
+        else:
+            return False
+
+class FixedAPITestCase(testcases.TestCase):
+    client_class = FixedClient
+
+# Environment Tests - Should pass everytime, if not something in the config is broken.
+class SimpleTest(TestCase):
+    fixtures = []
+
+    def test_basic_addition(self):
+        """
+        Tests that 1 + 1 always equals 2.
+        """
+        self.assertEqual(1 + 1, 2)
 
 
-	def check_items(self, response, data_list):
-		rdict = {}
-		for r in response:
-			rdict['%d'%r['id']]=r
+# Site Test
+class SiteTest(TestCase):
+    fixtures = []
 
-		for d in data_list:
-			match = True
-			try:
-				item = rdict['%d'%d['pk']]
-			except Exception,e:
-				print 'API missing item %d / %r'%(d['pk'],rdict.keys())
-				raise e
+    def setUp(self):
+        Site.objects.create(
+            name="Test Site",
+            login_base="test_"
+        )
 
-			fields=d['fields']
-			fields['id']=d['pk']
-
-			for k in item.keys():
-				try:
-					resp_val = fields[k]
-				except KeyError:
-					if (not self.hidden_keys.has_key(k)):
-						print 'Hidden key %s'%k
-						self.hidden_keys[k]=True
-
-					continue
-
-				if (item[k]!=resp_val and not is_dynamic_type(item[k])):
-					if (type(resp_val)==type(item[k])):
-						print 'Key %s did not match: 1. %r 2. %r'%(k,item[k],resp_val)
-						print fields
-						match = False
+    def test_read_site(self):
+        """
+        Should read a site in the DB.
+        """
+        site = Site.objects.get(name="Test Site")
+        # print(site._meta.get_all_field_names())
+        self.assertEqual(site.login_base, "test_")
 
 
+class UnautheticatedRequest(FixedAPITestCase):
+    fixtures = []
 
-	def create(self, model, mplural, record):
-		request = self.client.put('/xos/%s/'%mplural,record['fields'])
+    def test_require_authentication(self):
+        """
+        Ensure that request must be authenticated
+        """
+        response = self.client.get('/xos/sites/', format='json')
+        self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
 
-		#if (len2==len1):
-		#	raise Exception('Could not delete %s/%d'%(model,pk))
 
-		return
+class SiteTestAPI(FixedAPITestCase):
+    fixtures = []
 
-	def update(self, model, mplural, pk):
-		src_record = self.data_dict[model.lower()][0]
-		record_to_update = src_record['fields']
-		now = datetime.now()
-		record_to_update['enacted']=now
-		response = self.client.put('/xos/%s/%d/'%(mplural,pk),record_to_update)
-		self.assertEqual(response.data['enacted'],now)
+    def setUp(self):
+        self.site = Site.objects.create(
+            name="Test Site",
+            login_base="test_"
+        )
+        self.user = User(
+            username='testuser',
+            email='test@mail.org',
+            password='testing',
+            site=self.site,
+            is_admin=True
+        )
+        self.user.save()
+        self.client.login(username='test@mail.org', password='testing')
 
-		return
+    def test_read_site_API(self):
+        """
+        Read a Site trough API
+        """
+        response = self.client.get('/xos/sites/', format='json')
+        parsed = json.loads(response.content)
+        self.assertEqual(response.status_code, status.HTTP_200_OK)
+        self.assertEqual(len(parsed), 1)
+        self.assertEqual(parsed[0]['login_base'], 'test_')
 
-	def delete(self, model, mplural, pk):
-		mclass = globals()[model]
-		len1 = len(mclass.objects.all())
-		response = self.client.delete('/xos/%s/%d/'%(mplural,pk))
-		len2 = len(mclass.objects.all())
-		self.assertNotEqual(len1,len2)
+    def test_create_site_API(self):
+        """
+        Create a Site trough API
+        """
+        data = {
+            'name': "Another Test Site",
+            'login_base': "another_test_",
+            'location': [10, 20],
+            'abbreviated_name': 'test'
+        }
+        response = self.client.post('/xos/sites/', data, format='json')
+        self.assertEqual(response.status_code, status.HTTP_201_CREATED)
+        self.assertEqual(Site.objects.count(), 2)
+        self.assertEqual(Site.objects.filter(name="Another Test Site").count(), 1)
 
-		return
 
-	def retrieve(self, m, mplural, mlower):
-		response = self.client.get('/xos/%s/'%mplural)
-		#force_authenticate(request,user=self.calling_user)
-		self.check_items(response.data,self.data_dict[mlower])
+class SliceTestAPI(FixedAPITestCase):
+    fixtures = []
 
-		return
+    def setUp(self):
+        self.site = Site.objects.create(
+            name="Test Site",
+            login_base="test_"
+        )
+        self.pi = SiteRole.objects.create(role='pi')
+        self.user = User(
+            username='testuser',
+            email='test@mail.org',
+            password='testing',
+            site=self.site
+        )
+        self.user.save()
+        self.siteprivileges = SitePrivilege.objects.create(
+            user=self.user,
+            site=self.site,
+            role=self.pi
+        )
+        self.serviceClass = ServiceClass.objects.create(
+            name='Test Service Class'
+        )
+        self.client.login(username='test@mail.org', password='testing')
 
-	def test_initial_retrieve(self):
-		for m in MODELS:
-			print 'Checking retrieve on %s...'%m
-			self.retrieve(m, m.lower()+'s',m.lower())
+    def test_create_site_slice(self):
+        """
+        Add a slice to a given site
+        """
+        data = {
+            'name': "test_slice",
+            'site': self.site.id,
+            'serviceClass': self.serviceClass.id
+        }
+        response = self.client.post('/xos/slices/?no_hyperlinks=1', data, format='json')
+        self.assertEqual(response.status_code, status.HTTP_201_CREATED)
 
-	
-	def test_update(self):
-		for m in MODELS:
-			print 'Checking update on %s...'%m
-			first = self.data_dict[m.lower()][0]['pk']
-			self.update(m, m.lower()+'s',int(first))
-	
-	def test_delete(self):
-		for m in MODELS:
-			print 'Checking delete on %s...'%m
-			first = self.data_dict[m.lower()][0]['pk']
-			self.delete(m, m.lower()+'s',int(first))
+    def test_validation_slice_name(self):
+        """
+        The slice name should start with site.login_base
+        curl -H "Accept: application/json; indent=4" -u padmin@vicci.org:letmein 'http://xos:9999/xos/slices/?no_hyperlinks=1' -H "Content-Type: application/json" -X POST --data '{"name": "test", "site":"1", "serviceClass":1}'
+        """
+        data = {
+            'name': "wrong_slice",
+            'site': self.site.id,
+            'serviceClass': self.serviceClass.id
+        }
+        response = self.client.post('/xos/slices/?no_hyperlinks=1', data, format='json')
+        parsed = json.loads(response.content)
+        self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
+        self.assertEqual(parsed['detail']['specific_error'], "slice name must begin with test_")
 
-	def test_create(self):
-		for m in MODELS:
-			print 'Checking create on %s...'%m
-			first = self.data_dict[m.lower()][0]
-			self.create(m, m.lower()+'s',first)
+    def test_only_admin_can_change_creator(self):
+        """
+        Only an admin can change the creator of a slice
+        """
+        slice = Slice.objects.create(
+            name="test_slice",
+            site=self.site,
+            serviceClass=self.serviceClass,
+            creator=self.user
+        )
 
+        user2 = User(
+            username='another_testuser',
+            email='another_test@mail.org',
+            password='testing',
+            site=self.site
+        )
+        user2.save()
+
+        data = model_to_dict(slice)
+        data['creator'] = user2.id
+        json_data = json.dumps(data)
+
+        response = self.client.put('/xos/slices/%s/?no_hyperlinks=1' % slice.id, json_data, format='json', content_type="application/json")
+        self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
+        parsed = json.loads(response.content)
+        self.assertEqual(parsed['detail']['specific_error'], "Insufficient privileges to change slice creator")
+
+class ServiceTestAPI(FixedAPITestCase):
+    fixtures = []
+
+    def setUp(self):
+        self.site = Site.objects.create(
+            name="Test Site",
+            login_base="test_"
+        )
+        self.admin = User(
+            username='testadmin',
+            email='admin@mail.org',
+            password='testing',
+            site=self.site,
+            is_admin=True
+        )
+        self.admin.save()
+
+        self.user = User(
+            username='testuser',
+            email='user@mail.org',
+            password='testing',
+            site=self.site
+        )
+        self.user.save()
+
+        self.service1 = Service.objects.create(
+            name="fakeService1",
+            versionNumber="1.0.0",
+            published=True,
+            enabled=True
+        )
+
+        self.service2 = Service.objects.create(
+            name="fakeService1",
+            versionNumber="1.0.0",
+            published=True,
+            enabled=True
+        )
+
+        self.service_role = ServiceRole.objects.create(role='admin')
+
+        self.service_privileges = ServicePrivilege.objects.create(
+            user=self.user,
+            service=self.service2,
+            role=self.service_role
+        )
+
+    # TODO
+    # [x] admin view all service
+    # [ ] user view only service2
+    # [x] admin view a specific service service
+    # [ ] user view can't view a specific service
+    # [ ] user update service2
+    # [ ] usercan NOT update service2
+    # [x] admin update service1
+    def test_admin_read_all_service(self):
+        """
+        Admin should read all the services
+        """
+        self.client.login(username='admin@mail.org', password='testing')
+        response = self.client.get('/xos/services/', format='json')
+        self.assertEqual(response.status_code, status.HTTP_200_OK)
+        self.assertEqual(len(json.loads(response.content)), 2)
+
+    # need to understand how slices are related
+    def xtest_user_read_all_service(self):
+        """
+        User should read only service for which have privileges
+        """
+        self.client.login(username='user@mail.org', password='testing')
+        response = self.client.get('/xos/services/', format='json')
+        self.assertEqual(response.status_code, status.HTTP_200_OK)
+        self.assertEqual(len(json.loads(response.content)), 1)
+
+    def test_admin_read_one_service(self):
+        """
+        Read a given service
+        """
+        self.client.login(username='admin@mail.org', password='testing')
+        response = self.client.get('/xos/services/%s/' % self.service1.id, format='json')
+        parsed = json.loads(response.content)
+        self.assertEqual(response.status_code, status.HTTP_200_OK)
+        self.assertEqual(parsed['name'], self.service1.name)
+
+    def test_admin_update_service(self):
+        """
+        Update a given service
+        """
+        data = model_to_dict(self.service1)
+        data['name'] = "newName"
+        json_data = json.dumps(data)
+
+        self.client.login(username='admin@mail.org', password='testing')
+        response = self.client.put('/xos/services/%s/' % self.service1.id, json_data, format='json', content_type="application/json")
+        parsed = json.loads(response.content)
+        self.assertEqual(response.status_code, status.HTTP_200_OK)
+        model = Service.objects.get(id=self.service1.id)
+        self.assertEqual(model.name, data['name'])
+        
\ No newline at end of file
diff --git a/xos/core/views/deployments.py b/xos/core/views/deployments.py
deleted file mode 100644
index 285a53a..0000000
--- a/xos/core/views/deployments.py
+++ /dev/null
@@ -1,12 +0,0 @@
-from core.serializers import DeploymentSerializer
-from rest_framework import generics
-from core.models import Deployment
-
-class DeploymentList(generics.ListCreateAPIView):
-    queryset = Deployment.objects.all()
-    serializer_class = DeploymentSerializer
-
-class DeploymentDetail(generics.RetrieveUpdateDestroyAPIView):
-    queryset = Deployment.objects.all()
-    serializer_class = DeploymentSerializer
-
diff --git a/xos/core/views/hpc_config.py b/xos/core/views/hpc_config.py
index 3c1baa2..a181a1c 100644
--- a/xos/core/views/hpc_config.py
+++ b/xos/core/views/hpc_config.py
@@ -1,5 +1,4 @@
 from django.http import HttpResponse, HttpResponseServerError
-from monitor import driver
 from core.models import *
 from services.hpc.models import *
 from services.requestrouter.models import *
@@ -110,22 +109,22 @@
 ENABLE_PLC=False
 ENABLE_PS=True
 BASE_HRN="princeton"
-RELEVANT_SERVICE_NAMES=['vcoblitz', 'coredirect', 'codnsdemux', "syndicate_comon_server"]

-COBLITZ_SLICE_NAME=BASE_HRN+"_vcoblitz"

+RELEVANT_SERVICE_NAMES=['vcoblitz', 'coredirect', 'codnsdemux', "syndicate_comon_server"]
+COBLITZ_SLICE_NAME=BASE_HRN+"_vcoblitz"
 COBLITZ_SLICE_ID=70
 COBLITZ_PS_SLICE_NAME="{hpc_slicename}"
 DNSREDIR_SLICE_NAME=BASE_HRN+"_coredirect"
-DNSREDIR_SLICE_ID=71

-DNSREDIR_PS_SLICE_NAME="{redir_slicename}"

-DNSDEMUX_SLICE_NAME=BASE_HRN+"_codnsdemux"

-DNSDEMUX_SLICE_ID=69

-DNSDEMUX_PS_SLICE_NAME="{demux_slicename}"

-CMI_URL="http://{cmi_hostname}/"

-CMI_HTTP_PORT="8004"

-CMI_HTTPS_PORT="8003"

-PUPPET_MASTER_HOSTNAME="{cmi_hostname}"

-PUPPET_MASTER_PORT="8140"

-PS_HOSTNAME="{xos_hostname}"

+DNSREDIR_SLICE_ID=71
+DNSREDIR_PS_SLICE_NAME="{redir_slicename}"
+DNSDEMUX_SLICE_NAME=BASE_HRN+"_codnsdemux"
+DNSDEMUX_SLICE_ID=69
+DNSDEMUX_PS_SLICE_NAME="{demux_slicename}"
+CMI_URL="http://{cmi_hostname}/"
+CMI_HTTP_PORT="8004"
+CMI_HTTPS_PORT="8003"
+PUPPET_MASTER_HOSTNAME="{cmi_hostname}"
+PUPPET_MASTER_PORT="8140"
+PS_HOSTNAME="{xos_hostname}"
 PS_PORT="{xos_port}"
 COBLITZ_PORT_80={hpc_port80}
 """.format(**d))
diff --git a/xos/core/views/images.py b/xos/core/views/images.py
deleted file mode 100644
index 5ea5d76..0000000
--- a/xos/core/views/images.py
+++ /dev/null
@@ -1,12 +0,0 @@
-from core.serializers import ImageSerializer
-from rest_framework import generics
-from core.models import Image
-
-class ImageList(generics.ListCreateAPIView):
-    queryset = Image.objects.all()
-    serializer_class = ImageSerializer
-
-class ImageDetail(generics.RetrieveUpdateDestroyAPIView):
-    queryset = Image.objects.all()
-    serializer_class = ImageSerializer
-
diff --git a/xos/core/views/instances.py b/xos/core/views/instances.py
deleted file mode 100644
index e424538..0000000
--- a/xos/core/views/instances.py
+++ /dev/null
@@ -1,13 +0,0 @@
-from core.serializers import InstanceSerializer
-from rest_framework import generics
-from core.models import Instance
-
-class InstanceList(generics.ListCreateAPIView):
-    queryset = Instance.objects.all()
-    serializer_class = InstanceSerializer
-
-class InstanceDetail(generics.RetrieveUpdateDestroyAPIView):
-    queryset = Instance.objects.all()
-    serializer_class = InstanceSerializer
-
-
diff --git a/xos/core/views/nodes.py b/xos/core/views/nodes.py
deleted file mode 100644
index 8706114..0000000
--- a/xos/core/views/nodes.py
+++ /dev/null
@@ -1,13 +0,0 @@
-from core.serializers import NodeSerializer
-from rest_framework import generics
-from core.models import Node
-
-class NodeList(generics.ListCreateAPIView):
-    queryset = Node.objects.all()
-    serializer_class = NodeSerializer
-
-class NodeDetail(generics.RetrieveUpdateDestroyAPIView):
-    queryset = Node.objects.all()
-    serializer_class = NodeSerializer
-
-
diff --git a/xos/core/views/observer.py b/xos/core/views/observer.py
index 2912db9..3aabc4a 100644
--- a/xos/core/views/observer.py
+++ b/xos/core/views/observer.py
@@ -1,5 +1,4 @@
 from django.http import HttpResponse
-from monitor import driver
 from core.models import *
 import json
 import os
diff --git a/xos/core/views/projects.py b/xos/core/views/projects.py
deleted file mode 100644
index c5311d5..0000000
--- a/xos/core/views/projects.py
+++ /dev/null
@@ -1,13 +0,0 @@
-from core.serializers import ProjectSerializer
-from rest_framework import generics
-from core.models import Project
-
-class ProjectList(generics.ListCreateAPIView):
-    queryset = Project.objects.all()
-    serializer_class = ProjectSerializer
-
-class ProjectDetail(generics.RetrieveUpdateDestroyAPIView):
-    queryset = Project.objects.all()
-    serializer_class = ProjectSerializer
-
-
diff --git a/xos/core/views/reservations.py b/xos/core/views/reservations.py
deleted file mode 100644
index 03f79eb..0000000
--- a/xos/core/views/reservations.py
+++ /dev/null
@@ -1,13 +0,0 @@
-from core.serializers import ReservationSerializer
-from rest_framework import generics
-from core.models import Reservation
-
-class ReservationList(generics.ListCreateAPIView):
-    queryset = Reservation.objects.all()
-    serializer_class = ReservationSerializer
-
-class ReservationDetail(generics.RetrieveUpdateDestroyAPIView):
-    queryset = Reservation.objects.all()
-    serializer_class = ReservationSerializer
-
-
diff --git a/xos/core/views/roles.py b/xos/core/views/roles.py
deleted file mode 100644
index 13c9917..0000000
--- a/xos/core/views/roles.py
+++ /dev/null
@@ -1,13 +0,0 @@
-from core.serializers import RoleSerializer
-from rest_framework import generics
-from core.models import Role
-
-class RoleList(generics.ListCreateAPIView):
-    queryset = Role.objects.all()
-    serializer_class = RoleSerializer
-
-class RoleDetail(generics.RetrieveUpdateDestroyAPIView):
-    queryset = Role.objects.all()
-    serializer_class = RoleSerializer
-
-
diff --git a/xos/core/views/serviceGraph.py b/xos/core/views/serviceGraph.py
index e11988b..5ce0581 100644
--- a/xos/core/views/serviceGraph.py
+++ b/xos/core/views/serviceGraph.py
@@ -1,7 +1,6 @@
 from django.http import HttpResponse
 from django.views.generic import TemplateView, View
 from django import template
-from monitor import driver
 from core.models import *
 import json
 import os
diff --git a/xos/core/views/serviceclasses.py b/xos/core/views/serviceclasses.py
deleted file mode 100644
index b8b1b70..0000000
--- a/xos/core/views/serviceclasses.py
+++ /dev/null
@@ -1,13 +0,0 @@
-from core.serializers import ServiceClassSerializer
-from rest_framework import generics
-from core.models import ServiceClass
-
-class ServiceClassList(generics.ListCreateAPIView):
-    queryset = ServiceClass.objects.all()
-    serializer_class = ServiceClassSerializer
-
-class ServiceClassDetail(generics.RetrieveUpdateDestroyAPIView):
-    queryset = ServiceClass.objects.all()
-    serializer_class = ServiceClassSerializer
-
-
diff --git a/xos/core/views/serviceresources.py b/xos/core/views/serviceresources.py
deleted file mode 100644
index e394c18..0000000
--- a/xos/core/views/serviceresources.py
+++ /dev/null
@@ -1,13 +0,0 @@
-from core.serializers import ServiceResourceSerializer
-from rest_framework import generics
-from core.models import ServiceResource
-
-class ServiceResourceList(generics.ListCreateAPIView):
-    queryset = ServiceResource.objects.all()
-    serializer_class = ServiceResourceSerializer
-
-class ServiceResourceDetail(generics.RetrieveUpdateDestroyAPIView):
-    queryset = ServiceResource.objects.all()
-    serializer_class = ServiceResourceSerializer
-
-
diff --git a/xos/core/views/site_privileges.py b/xos/core/views/site_privileges.py
deleted file mode 100644
index 90053e5..0000000
--- a/xos/core/views/site_privileges.py
+++ /dev/null
@@ -1,13 +0,0 @@
-from core.serializers import SitePrivilegeSerializer
-from rest_framework import generics
-from core.models import SitePrivilege
-
-class SitePrivilegeList(generics.ListCreateAPIView):
-    queryset = SitePrivilege.objects.all()
-    serializer_class = SitePrivilegeSerializer
-
-class SitePrivilegeDetail(generics.RetrieveUpdateDestroyAPIView):
-    queryset = SitePrivilege.objects.all()
-    serializer_class = SitePrivilegeSerializer
-
-
diff --git a/xos/core/views/sites.py b/xos/core/views/sites.py
deleted file mode 100644
index 4ec9cb2..0000000
--- a/xos/core/views/sites.py
+++ /dev/null
@@ -1,11 +0,0 @@
-from core.serializers import SiteSerializer
-from rest_framework import generics
-from core.models import Site
-
-class SiteList(generics.ListCreateAPIView):
-    queryset = Site.objects.all()
-    serializer_class = SiteSerializer
-
-class SiteDetail(generics.RetrieveUpdateDestroyAPIView):
-    queryset = Site.objects.all()
-    serializer_class = SiteSerializer
diff --git a/xos/core/views/slice_privileges.py b/xos/core/views/slice_privileges.py
deleted file mode 100644
index 4dd1f93..0000000
--- a/xos/core/views/slice_privileges.py
+++ /dev/null
@@ -1,13 +0,0 @@
-from core.serializers import SlicePrivilegeSerializer
-from rest_framework import generics
-from core.models import SlicePrivilege
-
-class SlicePrivilegeList(generics.ListCreateAPIView):
-    queryset = SlicePrivilege.objects.all()
-    serializer_class = SlicePrivilegeSerializer
-
-class SlicePrivilegeDetail(generics.RetrieveUpdateDestroyAPIView):
-    queryset = SlicePrivilege.objects.all()
-    serializer_class = SlicePrivilegeSerializer
-
-
diff --git a/xos/core/views/slices.py b/xos/core/views/slices.py
deleted file mode 100644
index e3ab139..0000000
--- a/xos/core/views/slices.py
+++ /dev/null
@@ -1,13 +0,0 @@
-from core.serializers import SliceSerializer
-from rest_framework import generics
-from core.models import Slice
-
-class SliceList(generics.ListCreateAPIView):
-    queryset = Slice.objects.all()
-    serializer_class = SliceSerializer
-
-class SliceDetail(generics.RetrieveUpdateDestroyAPIView):
-    queryset = Slice.objects.all()
-    serializer_class = SliceSerializer
-
-
diff --git a/xos/core/views/stats.py b/xos/core/views/stats.py
deleted file mode 100644
index f0cdd74..0000000
--- a/xos/core/views/stats.py
+++ /dev/null
@@ -1,24 +0,0 @@
-from django.http import HttpResponse
-from monitor import driver
-from core.models import *
-import json
-
-def Stats(request):
-    model = request.GET['model_name']
-    pk = int(request.GET['pk'])
-    meter = request.GET['meter']
-    controller_name = request.GET['controller_name']
-    
-    controller = Controller.objects.filter(name=controller_name)
-
-    if len(controller)==0:
-        return HttpResponse(json.dumps({"stat_list": [], "error": "not found"}))
-
-    controller=controller[0]
-    keystone = {'username':controller.admin_user, 'password':controller.admin_password, 'tenant_name':controller.admin_tenant, 'auth_url':controller.auth_url, 'cacert':'/etc/ssl/certs/ca-certificates.crt'}
-
-    for k,v in keystone.items():
-        keystone['os_'+k] = v
-
-    meters = driver.get_meter(meter, model, pk, keystone)
-    return HttpResponse(json.dumps(meters))
diff --git a/xos/core/views/subnets.py b/xos/core/views/subnets.py
deleted file mode 100644
index 881f615..0000000
--- a/xos/core/views/subnets.py
+++ /dev/null
@@ -1,66 +0,0 @@
-from django.http import Http404
-from rest_framework.views import APIView
-from rest_framework.response import Response
-from rest_framework import status
-
-from core.api.subnets import add_subnet, delete_subnet, get_subnets, update_subnet
-from core.serializers import SubnetSerializer
-from util.request import parse_request
-
-
-class SubnetListCreate(APIView):
-    """ 
-    List all subnets or create a new subnet.
-    """
-
-    def post(self, request, format = None):
-        data = parse_request(request.DATA)  
-        if 'auth' not in data:
-            return Response(status=status.HTTP_400_BAD_REQUEST)        
-        elif 'subnet' in data:
-            subnet = add_subnet(data['auth'], data['subnet'])
-            serializer = SubnetSerializer(subnet)
-            return Response(serializer.data, status=status.HTTP_201_CREATED)
-        else:
-            subnets = get_subnets(data['auth'])
-            serializer = SubnetSerializer(subnets, many=True)
-            return Response(serializer.data)
-        
-            
-class SubnetRetrieveUpdateDestroy(APIView):
-    """
-    Retrieve, update or delete a subnet 
-    """
-
-    def post(self, request, pk, format=None):
-        """Retrieve a subnet"""
-        data = parse_request(request.DATA)
-        if 'auth' not in data:
-            return Response(status=status.HTTP_400_BAD_REQUEST)
-        subnets = get_subnets(data['auth'], {'id': pk})
-        if not subnets:
-            return Response(status=status.HTTP_404_NOT_FOUND)
-        serializer = SubnetSerializer(subnets[0])
-        return Response(serializer.data)                  
-
-    def put(self, request, pk, format=None):
-        """update a subnet""" 
-        data = parse_request(request.DATA)
-        if 'auth' not in data:
-            return Response(status=status.HTTP_400_BAD_REQUEST)
-        elif 'subnet' not in data:
-            return Response(status=status.HTTP_400_BAD_REQUEST)
-
-        subnet = update_subnet(pk, data['subnet'])
-        serializer = SubnetSerializer(subnet)
-        return Response(serializer.data) 
-
-    def delete(self, request, pk, format=None):
-        data = parse_request(request.DATA) 
-        if 'auth' not in data:
-            return Response(status=status.HTTP_400_BAD_REQUEST)
-        delete_subnet(data['auth'], {'id': pk})
-        return Response(status=status.HTTP_204_NO_CONTENT) 
-            
-            
-        
diff --git a/xos/core/views/tags.py b/xos/core/views/tags.py
deleted file mode 100644
index ba8a035..0000000
--- a/xos/core/views/tags.py
+++ /dev/null
@@ -1,13 +0,0 @@
-from core.serializers import TagSerializer
-from rest_framework import generics
-from core.models import Tag
-
-class TagList(generics.ListCreateAPIView):
-    queryset = Tag.objects.all()
-    serializer_class = TagSerializer
-
-class TagDetail(generics.RetrieveUpdateDestroyAPIView):
-    queryset = Tag.objects.all()
-    serializer_class = TagSerializer
-
-
diff --git a/xos/core/views/users.py b/xos/core/views/users.py
deleted file mode 100644
index 06ac0f3..0000000
--- a/xos/core/views/users.py
+++ /dev/null
@@ -1,11 +0,0 @@
-from core.serializers import UserSerializer
-from rest_framework import generics
-from core.models import User
-
-class UserList(generics.ListCreateAPIView):
-    queryset = User.objects.all()
-    serializer_class = UserSerializer
-
-class UserDetail(generics.RetrieveUpdateDestroyAPIView):
-    queryset = User.objects.all()
-    serializer_class = UserSerializer
diff --git a/xos/core/xoslib/methods/ceilometerview.py b/xos/core/xoslib/methods/ceilometerview.py
index f9f9d89..825cce4 100644
--- a/xos/core/xoslib/methods/ceilometerview.py
+++ b/xos/core/xoslib/methods/ceilometerview.py
@@ -16,7 +16,7 @@
 from django.utils.translation import ugettext_lazy as _
 from django.utils import timezone
 from django.core.exceptions import PermissionDenied
-from util.logger import observer_logger as logger
+from xos.logger import observer_logger as logger
 
 # This REST API endpoint provides information that the ceilometer view needs to display
 
diff --git a/xos/core/xoslib/methods/cordsubscriber.py b/xos/core/xoslib/methods/cordsubscriber.py
index b22d70e..49e32a5 100644
--- a/xos/core/xoslib/methods/cordsubscriber.py
+++ b/xos/core/xoslib/methods/cordsubscriber.py
@@ -207,8 +207,8 @@
 
     def list(self, request):
         object_list = self.filter_queryset(self.get_queryset())
-

-        serializer = self.get_serializer(object_list, many=True)

+
+        serializer = self.get_serializer(object_list, many=True)
 
         return Response({"subscribers": serializer.data})
 
@@ -306,10 +306,10 @@
             raise XOSMissingField("subscriber has no bbs_account")
 
         result=subprocess.check_output(["python", "/opt/xos/observers/vcpe/broadbandshield.py", "dump", subscriber.volt.vcpe.bbs_account, "123"])
-        if request.GET.get("theformat",None)=="text":

-            from django.http import HttpResponse

-            return HttpResponse(result, content_type="text/plain")

-        else:

+        if request.GET.get("theformat",None)=="text":
+            from django.http import HttpResponse
+            return HttpResponse(result, content_type="text/plain")
+        else:
             return Response( {"bbs_dump": result } )
 
     def setup_demo_subscriber(self, subscriber):
@@ -392,15 +392,15 @@
     # contact vBNG service and dump current list of mappings
     def get_vbng_dump(self, request, pk=None):
         result=subprocess.check_output(["curl", "http://10.0.3.136:8181/onos/virtualbng/privateip/map"])
-        if request.GET.get("theformat",None)=="text":

-            from django.http import HttpResponse

-            result = json.loads(result)["map"]

-

-            lines = []

-            for row in result:

-                for k in row.keys():

-                     lines.append( "%s %s" % (k, row[k]) )

-

-            return HttpResponse("\n".join(lines), content_type="text/plain")

-        else:

+        if request.GET.get("theformat",None)=="text":
+            from django.http import HttpResponse
+            result = json.loads(result)["map"]
+
+            lines = []
+            for row in result:
+                for k in row.keys():
+                     lines.append( "%s %s" % (k, row[k]) )
+
+            return HttpResponse("\n".join(lines), content_type="text/plain")
+        else:
             return Response( {"vbng_dump": json.loads(result)["map"] } )
diff --git a/xos/core/xoslib/ngXosLib/README.md b/xos/core/xoslib/ngXosLib/README.md
deleted file mode 100644
index 0166efd..0000000
--- a/xos/core/xoslib/ngXosLib/README.md
+++ /dev/null
@@ -1,101 +0,0 @@
-# ngXosLib
-
-This is a collection of helpers to develop views as Angular SPA.
-
-## Tools
-
-This tools are designed to help you developing UI for XOS. As they born for this purpose if often necessary that a XOS instance is running on your sistem and responding at: `localhost:9999`. The `xos/configurations/frontend` is normally enough.
-
-### Apigen
-
-Usage: `npm run apigen`
-
-This tool will automatically generate an angular resource file for each endpoint available in Swagger.
-
->You can generate api related documentation with: `npm run apidoc`. The output is locate in `api/docs`. You can have a list of available method also trough Swagger at `http://localhost:9999/docs/`
-
-### Vendors
-
-Xos comes with a preset of common libraries, as listed in `bower.json`:
-- angular
-- angular-route
-- angular-resource
-- angular-cookie
-- ng-lodash
-
-This libraries are server through Django, so they will not be included in your minified vendor file. To add a library and generate a new file (that will override the old one), you should:
-- enter `ngXosLib` folder
-- run `bower install [myPackage] --save`
-- rebuild the file with `gulp vendor`
-
->_NOTE before adding libraries please discuss it to avoid this file to became huge_
-
-### Helpers
-
-XOS comes with an helper library that is automatically loaded in the Django template.
-
-To use it, add `xos.helpers` to your required modules:
-
-```
-angular.module('xos.myView', [
-  'xos.helpers'
-])
-```
-
-It will automatically ad a `token` to all your request, eventually you can take advantage of some other services:
-
-- **NoHyperlinks Interceptor**: will add a `?no_hyperlinks=1` to your request, to tell Django to return ids instead of links.
-- **XosApi** wrapper for `/xos` endpoints.
-- **XoslibApi** wrapper for `/xoslib` endpoints.
-- **HpcApi** wrapper for `/hpcapi` endpoints.
-
->_NOTE: for the API related service, check documentation in [Apigen](#apigen) section._
-
-### Yo Xos
-
-We have created a [yeoman](http://yeoman.io/) generator to help you scaffolding views.
-
->As it is in an early stage of development you should manually link it to your system, to do this enter `xos/core/xoslib/ngXosLib/generator-xos` and run `npm link`.
-
-#### To generate a new view
-
-From `xos/core/xoslib` run `yo xos`. This command will create a new folder with the provided name in: `xos/core/xoslib/ngXosViews` that contain your application.
-
->If you left empty the view name it should be `xos/core/xoslib/ngXosViews/sampleView`
-
-#### Run a development server
-
-In your `view` folder and run `npm start`.
-
-_This will install required dependencies and start a local server with [BrowserSync](http://www.browsersync.io/)_
-
-#### Publish your view
-
-Once your view is done, from your view root folder, run: `npm run build`.
-
-This will build your application and copy files in the appropriate locations to be used by django.
-
-At this point you can enter: `http://localhost:9999/admin/core/dashboardview/add/` and add your custom view.
-
->_NOTE url field should be `template:xosSampleView`_
-
-#### Install dependencies in your app
-
-To install a local dependency use bower with `--save`. Common modules are saved in `devDependencies` as they already loaded in the Django template.
-
-The `npm start` command is watching your dependencies and will automatically inject it in your `index.html`.
-
-#### Linting
-
-A styleguide is enforced trough [EsLint](http://eslint.org/) and is checked during the build process. We **highly** suggest to install the linter in your editor to have realtime hint.
-
-#### Test
-
-The generator set up a test environment with a default test.
-To run it execute: `npm test`
-
-## TODO
-
-- Use Angular $resource instead of $http
-- Use ngDoc instead of jsDoc
-- Define styleguide (both visual and js) and if needed define some UI components
\ No newline at end of file
diff --git a/xos/core/xoslib/ngXosLib/generator-xos/app/templates/gulpfile.js b/xos/core/xoslib/ngXosLib/generator-xos/app/templates/gulpfile.js
deleted file mode 100644
index f114774..0000000
--- a/xos/core/xoslib/ngXosLib/generator-xos/app/templates/gulpfile.js
+++ /dev/null
@@ -1,24 +0,0 @@
-'use strict';
-
-var gulp = require('gulp');
-var wrench = require('wrench');
-
-var options = {
-  src: 'src/',
-  scripts: 'src/js/',
-  tmp: 'src/.tmp',
-  dist: 'dist/',
-  api: '../../ngXosLib/api/',
-  helpers: '../../ngXosLib/xosHelpers/src/',
-  static: '../../static/', // this is the django static folder
-  dashboards: '../../dashboards/' // this is the django html folder
-};
-
-wrench.readdirSyncRecursive('./gulp')
-.map(function(file) {
-  require('./gulp/' + file)(options);
-});
-
-gulp.task('default', function () {
-  gulp.start('build');
-});
diff --git a/xos/core/xoslib/ngXosViews/contentProvider/gulpfile.js b/xos/core/xoslib/ngXosViews/contentProvider/gulpfile.js
deleted file mode 100644
index f114774..0000000
--- a/xos/core/xoslib/ngXosViews/contentProvider/gulpfile.js
+++ /dev/null
@@ -1,24 +0,0 @@
-'use strict';
-
-var gulp = require('gulp');
-var wrench = require('wrench');
-
-var options = {
-  src: 'src/',
-  scripts: 'src/js/',
-  tmp: 'src/.tmp',
-  dist: 'dist/',
-  api: '../../ngXosLib/api/',
-  helpers: '../../ngXosLib/xosHelpers/src/',
-  static: '../../static/', // this is the django static folder
-  dashboards: '../../dashboards/' // this is the django html folder
-};
-
-wrench.readdirSyncRecursive('./gulp')
-.map(function(file) {
-  require('./gulp/' + file)(options);
-});
-
-gulp.task('default', function () {
-  gulp.start('build');
-});
diff --git a/xos/core/api/__init__.py b/xos/generate/__init__.py
similarity index 100%
rename from xos/core/api/__init__.py
rename to xos/generate/__init__.py
diff --git a/xos/dependency_walker.py b/xos/generate/dependency_walker.py
similarity index 97%
rename from xos/dependency_walker.py
rename to xos/generate/dependency_walker.py
index d99b783..210ec0f 100644
--- a/xos/dependency_walker.py
+++ b/xos/generate/dependency_walker.py
@@ -12,7 +12,7 @@
 import pdb
 from core.models import *
 
-from util.logger import Logger, logging
+from xos.logger import Logger, logging
 logger = Logger(level=logging.INFO)
 
 missing_links={}
diff --git a/xos/importer/__init__.py b/xos/importer/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/xos/importer/__init__.py
+++ /dev/null
diff --git a/xos/importer/plclassic/__init__.py b/xos/importer/plclassic/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/xos/importer/plclassic/__init__.py
+++ /dev/null
diff --git a/xos/importer/plclassic/importer.py b/xos/importer/plclassic/importer.py
deleted file mode 100644
index de8628b..0000000
--- a/xos/importer/plclassic/importer.py
+++ /dev/null
@@ -1,70 +0,0 @@
-import os
-#os.environ.setdefault("DJANGO_SETTINGS_MODULE", "xos.settings")
-import sys
-from optparse import OptionParser
-from getpass import getpass
-import xmlrpclib
-from plclassic.site_importer import SiteImporter
-from plclassic.user_importer import UserImporter
-from plclassic.slice_importer import SliceImporter
-from plclassic.instance_importer import InstanceImporter
-
-
-class Call:
-    def __init__(self, callable, auth):
-        self.callable = callable
-        self.auth = auth
-
-    def __call__(self, *args, **kwds):
-        a = [self.auth] + list(args)
-        return self.callable(*a)
-
-class API():
-    def __init__(self, username, password, url):
-        self.auth = {'AuthMethod': 'password',
-                     'Username': username,
-                     'AuthString': password}
-        self.server = xmlrpclib.ServerProxy(url, allow_none=True)
-
-    def __getattr__(self, name):         
-        return Call(getattr(self.server, name), self.auth) 
-
-class Importer: 
-
-    def __init__(self, username, password, url):
-        api = API(username, password, url)
-        self.sites = SiteImporter(api)
-        self.slices = SliceImporter(api)
-        self.users = UserImporter(api)
-        self.instances = InstanceImporter(api)
-
-    def run(self):
-        self.sites.run()
-        self.users.run()
-        self.slices.run(remote_sites=self.sites.remote_sites, 
-                        local_sites=self.sites.local_sites)
-        self.instances.run()           
-
-
-
-if __name__ == '__main__':
-    parser = OptionParser()
-        
-    parser.add_option("-u", "--username", dest="username",
-                        help="PLC username with which to authenticate")
-    parser.add_option("", "--url", dest="url",
-                        help="PLC url to contact")
-
-    (config, args) = parser.parse_args()
-    if len(sys.argv) == 1:
-        parser.print_help()
-        sys.exit(1)
-
-    password = None
-    try:
-        password = getpass()
-    except (EOFError, KeyboardInterrupt):
-        print
-        sys.exit(0)
-
-    Importer(config.username, password, config.url).run()
diff --git a/xos/importer/plclassic/instance_importer.py b/xos/importer/plclassic/instance_importer.py
deleted file mode 100644
index 0858572..0000000
--- a/xos/importer/plclassic/instance_importer.py
+++ /dev/null
@@ -1,9 +0,0 @@
-from PLC.Nodes import Nodes
-
-class InstanceImporter:
-
-    def __init__(self, api):
-        self.api = api
-
-    def run(self):
-        return
diff --git a/xos/importer/plclassic/role_importer.py b/xos/importer/plclassic/role_importer.py
deleted file mode 100644
index 107587a..0000000
--- a/xos/importer/plclassic/role_importer.py
+++ /dev/null
@@ -1,9 +0,0 @@
-class RoleImporter:
-
-    def __init__(self, api):
-        self.api = api
-
-    def run(self):
-
-         return 
-
diff --git a/xos/importer/plclassic/site_importer.py b/xos/importer/plclassic/site_importer.py
deleted file mode 100644
index 2ee8157..0000000
--- a/xos/importer/plclassic/site_importer.py
+++ /dev/null
@@ -1,33 +0,0 @@
-from core.models import Site
-
-class SiteImporter:
-
-    def __init__(self, api):
-        self.api = api
-        self.remote_sites = {}
-        self.local_sites = {}
-
-    def run(self):
-        db_sites = Site.objects.all()
-        for db_site in db_sites:
-            self.local_sites[db_site.login_base] = db_site
-        print "%s local sites" % len(db_sites)
-
-        sites = self.api.GetSites({'peer_id': None})
-        print "%s remote sites" % len(sites)
-        count = 0
-        for site in sites:
-            self.remote_sites[site['site_id']] = site 
-            if site['login_base'] not in self.local_sites:
-                new_site = Site(name=site['name'],
-                                login_base=site['login_base'],
-                                site_url=site['url'],
-                                enabled=site['enabled'],
-                                longitude=site['longitude'],
-                                latitude=site['latitude'],
-                                is_public=site['is_public'],
-                                abbreviated_name=site['abbreviated_name'])
-                new_site.save()
-                count += 1
-                self.local_sites[new_site.login_base] = new_site
-        print "imported %s sites" % count
diff --git a/xos/importer/plclassic/slice_importer.py b/xos/importer/plclassic/slice_importer.py
deleted file mode 100644
index b2dd84f..0000000
--- a/xos/importer/plclassic/slice_importer.py
+++ /dev/null
@@ -1,46 +0,0 @@
-from core.models import Slice
-
-class SliceImporter:
-
-    def __init__(self, api):
-        self.api = api
-        self.remote_slices = {}
-        self.local_slices = {}
-
-    def run(self, remote_sites={}, local_sites={}):
-        if not remote_sites:
-            sites = self.api.GetSites({'peer_id': None})
-            for site in sites:
-                remote_sites[site['site_id']] = site
-        
-
-        if not local_sites:
-            from core.models import Site
-            sites = Site.objects.all()
-            for site in sites:
-                local_sites[site.login_base] = site            
-
-        db_slices = Slice.objects.all()
-        for db_slice in db_slices:
-            self.local_slices[db_slice.name] = db_slice
-        print "%s local slices" % len(db_slices)
-
-        slices = self.api.GetSlices({'peer_id': None})
-        print "%s remote slices" % len(slices)
-        count = 0 
-        for slice in slices:
-            self.remote_slices[slice['slice_id']] = slice
-            if slice['name'] not in self.local_slices:
-                site = local_sites[remote_sites[slice['site_id']]['login_base']]
-                new_slice = Slice(name=slice['name'],
-                                   omf_friendly = False,
-                                   description = slice['description'],
-                                   slice_url = slice['url'],
-                                   site = site)
-                new_slice.save()
-                count += 1
-                self.local_slices[new_slice.name] = new_slice
-        print "Imported %s slices" % count
-
-          
-
diff --git a/xos/importer/plclassic/user_importer.py b/xos/importer/plclassic/user_importer.py
deleted file mode 100644
index 21d74b6..0000000
--- a/xos/importer/plclassic/user_importer.py
+++ /dev/null
@@ -1,19 +0,0 @@
-
-class UserImporter:
-
-    def __init__(self, api):
-        self.api = api
-        self.users = {}
-
-    def run(self):
-        users = self.api.GetPersons()
-
-    def save_site_privs(self, user):
-        # update site roles
-        pass
-
-    def save_slice_privs(self, user):
-        # update slice roles
-        pass
-          
-
diff --git a/xos/manage.py b/xos/manage.py
index 5d09794..219d0e7 100644
--- a/xos/manage.py
+++ b/xos/manage.py
@@ -3,21 +3,22 @@
 import sys
 
 if __name__ == "__main__":
+    os.chdir('..')  # <<<---This is what you want to add
     os.environ.setdefault("DJANGO_SETTINGS_MODULE", "xos.settings")
 
     from django.core.management import execute_from_command_line
 
     if "--makemigrations" in sys.argv:
-        os.system("/opt/xos/scripts/opencloud makemigrations")
+        os.system("/opt/xos/tools/xos-manage makemigrations")
         sys.argv.remove("--makemigrations")
 
     if "--nomodelpolicy" in sys.argv:
-        import model_policy
+        import synchronizers.model_policy as model_policy
         model_policy.EnableModelPolicy(False)
         sys.argv.remove("--nomodelpolicy")
 
     if "--noobserver" in sys.argv:
-        import observer
+        import synchronizers.base as observer
         observer.EnableObserver(False)
         sys.argv.remove("--noobserver")
 
diff --git a/xos/monitor/__init__.py b/xos/monitor/__init__.py
deleted file mode 100644
index 6debf82..0000000
--- a/xos/monitor/__init__.py
+++ /dev/null
@@ -1,11 +0,0 @@
-from xos.settings import STATISTICS_DRIVER
-
-if (STATISTICS_DRIVER=="ceilometer"):
-    from observer import ceilometer
-    driver = ceilometer.CeilometerDriver()
-elif (not STATISTICS_DRIVER) or (STATISTICS_DRIVER.lower() == "none"):
-    # disabled
-    driver = None
-else:
-    driver = None
-    print "WARNING: Unknown statistics driver %s" % STATISTICS_DRIVER
diff --git a/xos/monitor/monitordriver.py b/xos/monitor/monitordriver.py
deleted file mode 100644
index 50e208c..0000000
--- a/xos/monitor/monitordriver.py
+++ /dev/null
@@ -1,20 +0,0 @@
-# Implement this interface
-# to serve as a driver for analytics
-
-class DashboardStatistics(dict):
-    def __init__(self):
-        self['stat_list'] = []
-        self['average'] = 0
-        self['sum'] = 0
-        self['unit'] = 'units'
-        self['stat_list']=[]
-        # stat_list is a list of dicts
-        # [ {'timestamp': datetime, 'value': value} ]
-
-
-class MonitorDriver:
-    def __init__(self):
-        pass
-
-    def get_meter(self, meter_name, obj, pk, credentials=None):
-        pass
diff --git a/xos/neutron_extension/1:2013.2.2-0ubuntu1~cloud0/nat.py b/xos/neutron_extension/1:2013.2.2-0ubuntu1~cloud0/nat.py
deleted file mode 100644
index 04e39f1..0000000
--- a/xos/neutron_extension/1:2013.2.2-0ubuntu1~cloud0/nat.py
+++ /dev/null
@@ -1,50 +0,0 @@
-from neutron.api.v2 import attributes
-
-FORWARD_PORTS = 'nat:forward_ports'
-
-EXTENDED_ATTRIBUTES_2_0 = {
-    'ports': {
-        FORWARD_PORTS: {'allow_post': True, 'allow_put': True,
-                       'default': attributes.ATTR_NOT_SPECIFIED,
-                       'is_visible': True},
-    }
-}
-
-
-class Nat(object):
-    """Extension class supporting OpenCloud NAT networking
-
-    This class is used by Quantum's extension framework to make
-    metadata about the OpenCloud Port extension available to
-    clients. No new resources are defined by this extension. Instead,
-    the existing Port resource's request and response messages are
-    extended with attributes in the OpenCloud namespace.
-    """
-
-    @classmethod
-    def get_name(cls):
-        return "OpenCloud NAT Networking Extension"
-
-    @classmethod
-    def get_alias(cls):
-        return "nat"
-
-    @classmethod
-    def get_description(cls):
-        return "Add TCP/UDP port forwarding through NAT to Quantum Port objects"
-
-    @classmethod
-    def get_namespace(cls):
-        # return "http://docs.openstack.org/ext/provider/api/v1.0"
-        # Nothing there right now
-        return "http://www.vicci.org/ext/opencloud/nat/api/v0.1"
-
-    @classmethod
-    def get_updated(cls):
-        return "2013-09-12T10:00:00-00:00"
-
-    def get_extended_resources(self, version):
-        if version == "2.0":
-            return EXTENDED_ATTRIBUTES_2_0
-        else:
-            return {}
diff --git a/xos/neutron_extension/1:2013.2.2-0ubuntu1~cloud0/ovs_db_v2.py b/xos/neutron_extension/1:2013.2.2-0ubuntu1~cloud0/ovs_db_v2.py
deleted file mode 100644
index 39cf315..0000000
--- a/xos/neutron_extension/1:2013.2.2-0ubuntu1~cloud0/ovs_db_v2.py
+++ /dev/null
@@ -1,425 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2011 Nicira Networks, Inc.
-# All Rights Reserved.
-#
-#    Licensed under the Apache License, Version 2.0 (the "License"); you may
-#    not use this file except in compliance with the License. You may obtain
-#    a copy of the License at
-#
-#         http://www.apache.org/licenses/LICENSE-2.0
-#
-#    Unless required by applicable law or agreed to in writing, software
-#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-#    License for the specific language governing permissions and limitations
-#    under the License.
-# @author: Aaron Rosen, Nicira Networks, Inc.
-# @author: Bob Kukura, Red Hat, Inc.
-
-from sqlalchemy import func
-from sqlalchemy.orm import exc
-
-from neutron.common import exceptions as q_exc
-import neutron.db.api as db
-from neutron.db import models_v2
-from neutron.db import securitygroups_db as sg_db
-from neutron.extensions import securitygroup as ext_sg
-from neutron import manager
-from neutron.openstack.common.db import exception as db_exc
-from neutron.openstack.common import log as logging
-from neutron.plugins.openvswitch.common import constants
-from neutron.plugins.openvswitch import ovs_models_v2
-
-LOG = logging.getLogger(__name__)
-
-
-def initialize():
-    db.configure_db()
-
-
-def get_network_binding(session, network_id):
-    session = session or db.get_session()
-    try:
-        binding = (session.query(ovs_models_v2.NetworkBinding).
-                   filter_by(network_id=network_id).
-                   one())
-        return binding
-    except exc.NoResultFound:
-        return
-
-
-def add_network_binding(session, network_id, network_type,
-                        physical_network, segmentation_id):
-    with session.begin(subtransactions=True):
-        binding = ovs_models_v2.NetworkBinding(network_id, network_type,
-                                               physical_network,
-                                               segmentation_id)
-        session.add(binding)
-
-def get_port_forwarding(session, port_id):
-    session = session or db.get_session()
-    try:
-        forward = (session.query(ovs_models_v2.PortForwarding).
-                   filter_by(port_id=port_id).one())
-        return forward['forward_ports']
-    except exc.NoResultFound:
-        return
-
-def clear_port_forwarding(session, port_id):
-    with session.begin(subtransactions=True):
-        try:
-            # Get rid of old port bindings
-            forward = (session.query(ovs_models_v2.PortForwarding).
-                       filter_by(port_id=port_id).one())
-            if forward:
-                session.delete(forward)
-        except exc.NoResultFound:
-            pass
-
-def add_port_forwarding(session, port_id, forward_ports):
-    with session.begin(subtransactions=True):
-        forward = ovs_models_v2.PortForwarding(port_id, forward_ports)
-        session.add(forward)
-
-def sync_vlan_allocations(network_vlan_ranges):
-    """Synchronize vlan_allocations table with configured VLAN ranges."""
-
-    session = db.get_session()
-    with session.begin():
-        # get existing allocations for all physical networks
-        allocations = dict()
-        allocs = (session.query(ovs_models_v2.VlanAllocation).
-                  all())
-        for alloc in allocs:
-            if alloc.physical_network not in allocations:
-                allocations[alloc.physical_network] = set()
-            allocations[alloc.physical_network].add(alloc)
-
-        # process vlan ranges for each configured physical network
-        for physical_network, vlan_ranges in network_vlan_ranges.iteritems():
-            # determine current configured allocatable vlans for this
-            # physical network
-            vlan_ids = set()
-            for vlan_range in vlan_ranges:
-                vlan_ids |= set(xrange(vlan_range[0], vlan_range[1] + 1))
-
-            # remove from table unallocated vlans not currently allocatable
-            if physical_network in allocations:
-                for alloc in allocations[physical_network]:
-                    try:
-                        # see if vlan is allocatable
-                        vlan_ids.remove(alloc.vlan_id)
-                    except KeyError:
-                        # it's not allocatable, so check if its allocated
-                        if not alloc.allocated:
-                            # it's not, so remove it from table
-                            LOG.debug(_("Removing vlan %(vlan_id)s on "
-                                        "physical network "
-                                        "%(physical_network)s from pool"),
-                                      {'vlan_id': alloc.vlan_id,
-                                       'physical_network': physical_network})
-                            session.delete(alloc)
-                del allocations[physical_network]
-
-            # add missing allocatable vlans to table
-            for vlan_id in sorted(vlan_ids):
-                alloc = ovs_models_v2.VlanAllocation(physical_network, vlan_id)
-                session.add(alloc)
-
-        # remove from table unallocated vlans for any unconfigured physical
-        # networks
-        for allocs in allocations.itervalues():
-            for alloc in allocs:
-                if not alloc.allocated:
-                    LOG.debug(_("Removing vlan %(vlan_id)s on physical "
-                                "network %(physical_network)s from pool"),
-                              {'vlan_id': alloc.vlan_id,
-                               'physical_network': alloc.physical_network})
-                    session.delete(alloc)
-
-
-def get_vlan_allocation(physical_network, vlan_id):
-    session = db.get_session()
-    try:
-        alloc = (session.query(ovs_models_v2.VlanAllocation).
-                 filter_by(physical_network=physical_network,
-                           vlan_id=vlan_id).
-                 one())
-        return alloc
-    except exc.NoResultFound:
-        return
-
-
-def reserve_vlan(session):
-    with session.begin(subtransactions=True):
-        alloc = (session.query(ovs_models_v2.VlanAllocation).
-                 filter_by(allocated=False).
-                 with_lockmode('update').
-                 first())
-        if alloc:
-            LOG.debug(_("Reserving vlan %(vlan_id)s on physical network "
-                        "%(physical_network)s from pool"),
-                      {'vlan_id': alloc.vlan_id,
-                       'physical_network': alloc.physical_network})
-            alloc.allocated = True
-            return (alloc.physical_network, alloc.vlan_id)
-    raise q_exc.NoNetworkAvailable()
-
-
-def reserve_specific_vlan(session, physical_network, vlan_id):
-    with session.begin(subtransactions=True):
-        try:
-            alloc = (session.query(ovs_models_v2.VlanAllocation).
-                     filter_by(physical_network=physical_network,
-                               vlan_id=vlan_id).
-                     with_lockmode('update').
-                     one())
-            if alloc.allocated:
-                if vlan_id == constants.FLAT_VLAN_ID:
-                    raise q_exc.FlatNetworkInUse(
-                        physical_network=physical_network)
-                else:
-                    raise q_exc.VlanIdInUse(vlan_id=vlan_id,
-                                            physical_network=physical_network)
-            LOG.debug(_("Reserving specific vlan %(vlan_id)s on physical "
-                        "network %(physical_network)s from pool"),
-                      {'vlan_id': vlan_id,
-                       'physical_network': physical_network})
-            alloc.allocated = True
-        except exc.NoResultFound:
-            LOG.debug(_("Reserving specific vlan %(vlan_id)s on physical "
-                        "network %(physical_network)s outside pool"),
-                      {'vlan_id': vlan_id,
-                       'physical_network': physical_network})
-            alloc = ovs_models_v2.VlanAllocation(physical_network, vlan_id)
-            alloc.allocated = True
-            session.add(alloc)
-
-
-def release_vlan(session, physical_network, vlan_id, network_vlan_ranges):
-    with session.begin(subtransactions=True):
-        try:
-            alloc = (session.query(ovs_models_v2.VlanAllocation).
-                     filter_by(physical_network=physical_network,
-                               vlan_id=vlan_id).
-                     with_lockmode('update').
-                     one())
-            alloc.allocated = False
-            inside = False
-            for vlan_range in network_vlan_ranges.get(physical_network, []):
-                if vlan_id >= vlan_range[0] and vlan_id <= vlan_range[1]:
-                    inside = True
-                    break
-            if not inside:
-                session.delete(alloc)
-                LOG.debug(_("Releasing vlan %(vlan_id)s on physical network "
-                            "%(physical_network)s outside pool"),
-                          {'vlan_id': vlan_id,
-                           'physical_network': physical_network})
-            else:
-                LOG.debug(_("Releasing vlan %(vlan_id)s on physical network "
-                            "%(physical_network)s to pool"),
-                          {'vlan_id': vlan_id,
-                           'physical_network': physical_network})
-        except exc.NoResultFound:
-            LOG.warning(_("vlan_id %(vlan_id)s on physical network "
-                          "%(physical_network)s not found"),
-                        {'vlan_id': vlan_id,
-                         'physical_network': physical_network})
-
-
-def sync_tunnel_allocations(tunnel_id_ranges):
-    """Synchronize tunnel_allocations table with configured tunnel ranges."""
-
-    # determine current configured allocatable tunnels
-    tunnel_ids = set()
-    for tunnel_id_range in tunnel_id_ranges:
-        tun_min, tun_max = tunnel_id_range
-        if tun_max + 1 - tun_min > 1000000:
-            LOG.error(_("Skipping unreasonable tunnel ID range "
-                        "%(tun_min)s:%(tun_max)s"),
-                      {'tun_min': tun_min, 'tun_max': tun_max})
-        else:
-            tunnel_ids |= set(xrange(tun_min, tun_max + 1))
-
-    session = db.get_session()
-    with session.begin():
-        # remove from table unallocated tunnels not currently allocatable
-        allocs = (session.query(ovs_models_v2.TunnelAllocation).
-                  all())
-        for alloc in allocs:
-            try:
-                # see if tunnel is allocatable
-                tunnel_ids.remove(alloc.tunnel_id)
-            except KeyError:
-                # it's not allocatable, so check if its allocated
-                if not alloc.allocated:
-                    # it's not, so remove it from table
-                    LOG.debug(_("Removing tunnel %s from pool"),
-                              alloc.tunnel_id)
-                    session.delete(alloc)
-
-        # add missing allocatable tunnels to table
-        for tunnel_id in sorted(tunnel_ids):
-            alloc = ovs_models_v2.TunnelAllocation(tunnel_id)
-            session.add(alloc)
-
-
-def get_tunnel_allocation(tunnel_id):
-    session = db.get_session()
-    try:
-        alloc = (session.query(ovs_models_v2.TunnelAllocation).
-                 filter_by(tunnel_id=tunnel_id).
-                 with_lockmode('update').
-                 one())
-        return alloc
-    except exc.NoResultFound:
-        return
-
-
-def reserve_tunnel(session):
-    with session.begin(subtransactions=True):
-        alloc = (session.query(ovs_models_v2.TunnelAllocation).
-                 filter_by(allocated=False).
-                 with_lockmode('update').
-                 first())
-        if alloc:
-            LOG.debug(_("Reserving tunnel %s from pool"), alloc.tunnel_id)
-            alloc.allocated = True
-            return alloc.tunnel_id
-    raise q_exc.NoNetworkAvailable()
-
-
-def reserve_specific_tunnel(session, tunnel_id):
-    with session.begin(subtransactions=True):
-        try:
-            alloc = (session.query(ovs_models_v2.TunnelAllocation).
-                     filter_by(tunnel_id=tunnel_id).
-                     with_lockmode('update').
-                     one())
-            if alloc.allocated:
-                raise q_exc.TunnelIdInUse(tunnel_id=tunnel_id)
-            LOG.debug(_("Reserving specific tunnel %s from pool"), tunnel_id)
-            alloc.allocated = True
-        except exc.NoResultFound:
-            LOG.debug(_("Reserving specific tunnel %s outside pool"),
-                      tunnel_id)
-            alloc = ovs_models_v2.TunnelAllocation(tunnel_id)
-            alloc.allocated = True
-            session.add(alloc)
-
-
-def release_tunnel(session, tunnel_id, tunnel_id_ranges):
-    with session.begin(subtransactions=True):
-        try:
-            alloc = (session.query(ovs_models_v2.TunnelAllocation).
-                     filter_by(tunnel_id=tunnel_id).
-                     with_lockmode('update').
-                     one())
-            alloc.allocated = False
-            inside = False
-            for tunnel_id_range in tunnel_id_ranges:
-                if (tunnel_id >= tunnel_id_range[0]
-                    and tunnel_id <= tunnel_id_range[1]):
-                    inside = True
-                    break
-            if not inside:
-                session.delete(alloc)
-                LOG.debug(_("Releasing tunnel %s outside pool"), tunnel_id)
-            else:
-                LOG.debug(_("Releasing tunnel %s to pool"), tunnel_id)
-        except exc.NoResultFound:
-            LOG.warning(_("tunnel_id %s not found"), tunnel_id)
-
-
-def get_port(port_id):
-    session = db.get_session()
-    try:
-        port = session.query(models_v2.Port).filter_by(id=port_id).one()
-    except exc.NoResultFound:
-        port = None
-    return port
-
-
-def get_port_from_device(port_id):
-    """Get port from database."""
-    LOG.debug(_("get_port_with_securitygroups() called:port_id=%s"), port_id)
-    session = db.get_session()
-    sg_binding_port = sg_db.SecurityGroupPortBinding.port_id
-
-    query = session.query(models_v2.Port,
-                          sg_db.SecurityGroupPortBinding.security_group_id)
-    query = query.outerjoin(sg_db.SecurityGroupPortBinding,
-                            models_v2.Port.id == sg_binding_port)
-    query = query.filter(models_v2.Port.id == port_id)
-    port_and_sgs = query.all()
-    if not port_and_sgs:
-        return None
-    port = port_and_sgs[0][0]
-    plugin = manager.NeutronManager.get_plugin()
-    port_dict = plugin._make_port_dict(port)
-    port_dict[ext_sg.SECURITYGROUPS] = [
-        sg_id for port_, sg_id in port_and_sgs if sg_id]
-    port_dict['security_group_rules'] = []
-    port_dict['security_group_source_groups'] = []
-    port_dict['fixed_ips'] = [ip['ip_address']
-                              for ip in port['fixed_ips']]
-    return port_dict
-
-
-def set_port_status(port_id, status):
-    session = db.get_session()
-    try:
-        port = session.query(models_v2.Port).filter_by(id=port_id).one()
-        port['status'] = status
-        session.merge(port)
-        session.flush()
-    except exc.NoResultFound:
-        raise q_exc.PortNotFound(port_id=port_id)
-
-
-def get_tunnel_endpoints():
-    session = db.get_session()
-
-    tunnels = session.query(ovs_models_v2.TunnelEndpoint)
-    return [{'id': tunnel.id,
-             'ip_address': tunnel.ip_address} for tunnel in tunnels]
-
-
-def _generate_tunnel_id(session):
-    max_tunnel_id = session.query(
-        func.max(ovs_models_v2.TunnelEndpoint.id)).scalar() or 0
-    return max_tunnel_id + 1
-
-
-def add_tunnel_endpoint(ip, max_retries=10):
-    """Return the endpoint of the given IP address or generate a new one."""
-
-    # NOTE(rpodolyaka): generation of a new tunnel endpoint must be put into a
-    #                   repeatedly executed transactional block to ensure it
-    #                   doesn't conflict with any other concurrently executed
-    #                   DB transactions in spite of the specified transactions
-    #                   isolation level value
-    for i in xrange(max_retries):
-        LOG.debug(_('Adding a tunnel endpoint for %s'), ip)
-        try:
-            session = db.get_session()
-            with session.begin(subtransactions=True):
-                tunnel = (session.query(ovs_models_v2.TunnelEndpoint).
-                          filter_by(ip_address=ip).with_lockmode('update').
-                          first())
-
-                if tunnel is None:
-                    tunnel_id = _generate_tunnel_id(session)
-                    tunnel = ovs_models_v2.TunnelEndpoint(ip, tunnel_id)
-                    session.add(tunnel)
-
-                return tunnel
-        except db_exc.DBDuplicateEntry:
-            # a concurrent transaction has been commited, try again
-            LOG.debug(_('Adding a tunnel endpoint failed due to a concurrent'
-                        'transaction had been commited (%s attempts left)'),
-                      max_retries - (i + 1))
-
-    raise q_exc.NeutronException(
-        message=_('Unable to generate a new tunnel id'))
diff --git a/xos/neutron_extension/1:2013.2.2-0ubuntu1~cloud0/ovs_models_v2.py b/xos/neutron_extension/1:2013.2.2-0ubuntu1~cloud0/ovs_models_v2.py
deleted file mode 100644
index 7e022f5..0000000
--- a/xos/neutron_extension/1:2013.2.2-0ubuntu1~cloud0/ovs_models_v2.py
+++ /dev/null
@@ -1,118 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2011 Nicira Networks, Inc.
-# All Rights Reserved.
-#
-#    Licensed under the Apache License, Version 2.0 (the "License"); you may
-#    not use this file except in compliance with the License. You may obtain
-#    a copy of the License at
-#
-#         http://www.apache.org/licenses/LICENSE-2.0
-#
-#    Unless required by applicable law or agreed to in writing, software
-#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-#    License for the specific language governing permissions and limitations
-#    under the License.
-# @author: Aaron Rosen, Nicira Networks, Inc.
-# @author: Bob Kukura, Red Hat, Inc.
-
-
-from sqlalchemy import Boolean, Column, ForeignKey, Integer, String, PickleType
-from sqlalchemy.schema import UniqueConstraint
-
-from neutron.db.models_v2 import model_base
-
-
-class VlanAllocation(model_base.BASEV2):
-    """Represents allocation state of vlan_id on physical network."""
-    __tablename__ = 'ovs_vlan_allocations'
-
-    physical_network = Column(String(64), nullable=False, primary_key=True)
-    vlan_id = Column(Integer, nullable=False, primary_key=True,
-                     autoincrement=False)
-    allocated = Column(Boolean, nullable=False)
-
-    def __init__(self, physical_network, vlan_id):
-        self.physical_network = physical_network
-        self.vlan_id = vlan_id
-        self.allocated = False
-
-    def __repr__(self):
-        return "<VlanAllocation(%s,%d,%s)>" % (self.physical_network,
-                                               self.vlan_id, self.allocated)
-
-
-class TunnelAllocation(model_base.BASEV2):
-    """Represents allocation state of tunnel_id."""
-    __tablename__ = 'ovs_tunnel_allocations'
-
-    tunnel_id = Column(Integer, nullable=False, primary_key=True,
-                       autoincrement=False)
-    allocated = Column(Boolean, nullable=False)
-
-    def __init__(self, tunnel_id):
-        self.tunnel_id = tunnel_id
-        self.allocated = False
-
-    def __repr__(self):
-        return "<TunnelAllocation(%d,%s)>" % (self.tunnel_id, self.allocated)
-
-
-class NetworkBinding(model_base.BASEV2):
-    """Represents binding of virtual network to physical realization."""
-    __tablename__ = 'ovs_network_bindings'
-
-    network_id = Column(String(36),
-                        ForeignKey('networks.id', ondelete="CASCADE"),
-                        primary_key=True)
-    # 'gre', 'vlan', 'flat', 'local'
-    network_type = Column(String(32), nullable=False)
-    physical_network = Column(String(64))
-    segmentation_id = Column(Integer)  # tunnel_id or vlan_id
-
-    def __init__(self, network_id, network_type, physical_network,
-                 segmentation_id):
-        self.network_id = network_id
-        self.network_type = network_type
-        self.physical_network = physical_network
-        self.segmentation_id = segmentation_id
-
-    def __repr__(self):
-        return "<NetworkBinding(%s,%s,%s,%d)>" % (self.network_id,
-                                                  self.network_type,
-                                                  self.physical_network,
-                                                  self.segmentation_id)
-
-class PortForwarding(model_base.BASEV2):
-    """Ports to be forwarded through NAT """
-    __tablename__ = 'ovs_port_forwarding'
-
-    port_id = Column(String(36),
-                     ForeignKey('ports.id', ondelete="CASCADE"),
-                     primary_key=True)
-    forward_ports = Column(PickleType)
-
-    def __init__(self, port_id, forward_ports):
-        self.port_id = port_id
-        self.forward_ports = forward_ports
-
-    def __repr__(self):
-        return "<PortForwarding(%s,%s)>" % (self.port_id, self.forward_ports)
-
-class TunnelEndpoint(model_base.BASEV2):
-    """Represents tunnel endpoint in RPC mode."""
-    __tablename__ = 'ovs_tunnel_endpoints'
-    __table_args__ = (
-        UniqueConstraint('id', name='uniq_ovs_tunnel_endpoints0id'),
-    )
-
-    ip_address = Column(String(64), primary_key=True)
-    id = Column(Integer, nullable=False)
-
-    def __init__(self, ip_address, id):
-        self.ip_address = ip_address
-        self.id = id
-
-    def __repr__(self):
-        return "<TunnelEndpoint(%s,%s)>" % (self.ip_address, self.id)
-
diff --git a/xos/neutron_extension/1:2013.2.2-0ubuntu1~cloud0/ovs_neutron_plugin.py b/xos/neutron_extension/1:2013.2.2-0ubuntu1~cloud0/ovs_neutron_plugin.py
deleted file mode 100644
index abf0f80..0000000
--- a/xos/neutron_extension/1:2013.2.2-0ubuntu1~cloud0/ovs_neutron_plugin.py
+++ /dev/null
@@ -1,708 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2011 Nicira Networks, Inc.
-# All Rights Reserved.
-#
-#    Licensed under the Apache License, Version 2.0 (the "License"); you may
-#    not use this file except in compliance with the License. You may obtain
-#    a copy of the License at
-#
-#         http://www.apache.org/licenses/LICENSE-2.0
-#
-#    Unless required by applicable law or agreed to in writing, software
-#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-#    License for the specific language governing permissions and limitations
-#    under the License.
-# @author: Somik Behera, Nicira Networks, Inc.
-# @author: Brad Hall, Nicira Networks, Inc.
-# @author: Dan Wendlandt, Nicira Networks, Inc.
-# @author: Dave Lapsley, Nicira Networks, Inc.
-# @author: Aaron Rosen, Nicira Networks, Inc.
-# @author: Bob Kukura, Red Hat, Inc.
-# @author: Seetharama Ayyadevara, Freescale Semiconductor, Inc.
-
-import sys
-
-from oslo.config import cfg
-
-from neutron.agent import securitygroups_rpc as sg_rpc
-from neutron.api.rpc.agentnotifiers import dhcp_rpc_agent_api
-from neutron.api.rpc.agentnotifiers import l3_rpc_agent_api
-from neutron.api.v2 import attributes
-from neutron.common import constants as q_const
-from neutron.common import exceptions as q_exc
-from neutron.common import rpc as q_rpc
-from neutron.common import topics
-from neutron.common import utils
-from neutron.db import agents_db
-from neutron.db import agentschedulers_db
-from neutron.db import allowedaddresspairs_db as addr_pair_db
-from neutron.db import db_base_plugin_v2
-from neutron.db import dhcp_rpc_base
-from neutron.db import external_net_db
-from neutron.db import extradhcpopt_db
-from neutron.db import extraroute_db
-from neutron.db import l3_agentschedulers_db
-from neutron.db import l3_gwmode_db
-from neutron.db import l3_rpc_base
-from neutron.db import portbindings_db
-from neutron.db import quota_db  # noqa
-from neutron.db import securitygroups_rpc_base as sg_db_rpc
-from neutron.extensions import allowedaddresspairs as addr_pair
-from neutron.extensions import extra_dhcp_opt as edo_ext
-from neutron.extensions import portbindings
-from neutron.extensions import providernet as provider
-from neutron.extensions import nat
-from neutron import manager
-from neutron.openstack.common import importutils
-from neutron.openstack.common import log as logging
-from neutron.openstack.common import rpc
-from neutron.openstack.common.rpc import proxy
-from neutron.plugins.common import constants as svc_constants
-from neutron.plugins.common import utils as plugin_utils
-from neutron.plugins.openvswitch.common import config  # noqa
-from neutron.plugins.openvswitch.common import constants
-from neutron.plugins.openvswitch import ovs_db_v2
-
-
-LOG = logging.getLogger(__name__)
-
-
-class OVSRpcCallbacks(dhcp_rpc_base.DhcpRpcCallbackMixin,
-                      l3_rpc_base.L3RpcCallbackMixin,
-                      sg_db_rpc.SecurityGroupServerRpcCallbackMixin):
-
-    # history
-    #   1.0 Initial version
-    #   1.1 Support Security Group RPC
-
-    RPC_API_VERSION = '1.1'
-
-    def __init__(self, notifier, tunnel_type):
-        self.notifier = notifier
-        self.tunnel_type = tunnel_type
-
-    def create_rpc_dispatcher(self):
-        '''Get the rpc dispatcher for this manager.
-
-        If a manager would like to set an rpc API version, or support more than
-        one class as the target of rpc messages, override this method.
-        '''
-        return q_rpc.PluginRpcDispatcher([self,
-                                          agents_db.AgentExtRpcCallback()])
-
-    @classmethod
-    def get_port_from_device(cls, device):
-        port = ovs_db_v2.get_port_from_device(device)
-        if port:
-            port['device'] = device
-        return port
-
-    def get_device_details(self, rpc_context, **kwargs):
-        """Agent requests device details."""
-        agent_id = kwargs.get('agent_id')
-        device = kwargs.get('device')
-        LOG.debug(_("Device %(device)s details requested from %(agent_id)s"),
-                  {'device': device, 'agent_id': agent_id})
-        port = ovs_db_v2.get_port(device)
-        if port:
-            binding = ovs_db_v2.get_network_binding(None, port['network_id'])
-            entry = {'device': device,
-                     'network_id': port['network_id'],
-                     'port_id': port['id'],
-                     'admin_state_up': port['admin_state_up'],
-                     'network_type': binding.network_type,
-                     'segmentation_id': binding.segmentation_id,
-                     'physical_network': binding.physical_network}
-            new_status = (q_const.PORT_STATUS_ACTIVE if port['admin_state_up']
-                          else q_const.PORT_STATUS_DOWN)
-            if port['status'] != new_status:
-                ovs_db_v2.set_port_status(port['id'], new_status)
-        else:
-            entry = {'device': device}
-            LOG.debug(_("%s can not be found in database"), device)
-        return entry
-
-    def update_device_down(self, rpc_context, **kwargs):
-        """Device no longer exists on agent."""
-        agent_id = kwargs.get('agent_id')
-        device = kwargs.get('device')
-        host = kwargs.get('host')
-        port = ovs_db_v2.get_port(device)
-        LOG.debug(_("Device %(device)s no longer exists on %(agent_id)s"),
-                  {'device': device, 'agent_id': agent_id})
-        if port:
-            entry = {'device': device,
-                     'exists': True}
-            plugin = manager.NeutronManager.get_plugin()
-            if (host and
-                not plugin.get_port_host(rpc_context, port['id']) == host):
-                LOG.debug(_("Device %(device)s not bound to the"
-                            " agent host %(host)s"),
-                          {'device': device, 'host': host})
-            elif port['status'] != q_const.PORT_STATUS_DOWN:
-                # Set port status to DOWN
-                ovs_db_v2.set_port_status(port['id'],
-                                          q_const.PORT_STATUS_DOWN)
-        else:
-            entry = {'device': device,
-                     'exists': False}
-            LOG.debug(_("%s can not be found in database"), device)
-        return entry
-
-    def update_device_up(self, rpc_context, **kwargs):
-        """Device is up on agent."""
-        agent_id = kwargs.get('agent_id')
-        device = kwargs.get('device')
-        host = kwargs.get('host')
-        port = ovs_db_v2.get_port(device)
-        LOG.debug(_("Device %(device)s up on %(agent_id)s"),
-                  {'device': device, 'agent_id': agent_id})
-        plugin = manager.NeutronManager.get_plugin()
-        if port:
-            if (host and
-                not plugin.get_port_host(rpc_context, port['id']) == host):
-                LOG.debug(_("Device %(device)s not bound to the"
-                            " agent host %(host)s"),
-                          {'device': device, 'host': host})
-                return
-            elif port['status'] != q_const.PORT_STATUS_ACTIVE:
-                ovs_db_v2.set_port_status(port['id'],
-                                          q_const.PORT_STATUS_ACTIVE)
-        else:
-            LOG.debug(_("%s can not be found in database"), device)
-
-    def tunnel_sync(self, rpc_context, **kwargs):
-        """Update new tunnel.
-
-        Updates the datbase with the tunnel IP. All listening agents will also
-        be notified about the new tunnel IP.
-        """
-        tunnel_ip = kwargs.get('tunnel_ip')
-        # Update the database with the IP
-        tunnel = ovs_db_v2.add_tunnel_endpoint(tunnel_ip)
-        tunnels = ovs_db_v2.get_tunnel_endpoints()
-        entry = dict()
-        entry['tunnels'] = tunnels
-        # Notify all other listening agents
-        self.notifier.tunnel_update(rpc_context, tunnel.ip_address,
-                                    tunnel.id, self.tunnel_type)
-        # Return the list of tunnels IP's to the agent
-        return entry
-
-
-class AgentNotifierApi(proxy.RpcProxy,
-                       sg_rpc.SecurityGroupAgentRpcApiMixin):
-    '''Agent side of the openvswitch rpc API.
-
-    API version history:
-        1.0 - Initial version.
-
-    '''
-
-    BASE_RPC_API_VERSION = '1.0'
-
-    def __init__(self, topic):
-        super(AgentNotifierApi, self).__init__(
-            topic=topic, default_version=self.BASE_RPC_API_VERSION)
-        self.topic_network_delete = topics.get_topic_name(topic,
-                                                          topics.NETWORK,
-                                                          topics.DELETE)
-        self.topic_port_update = topics.get_topic_name(topic,
-                                                       topics.PORT,
-                                                       topics.UPDATE)
-        self.topic_tunnel_update = topics.get_topic_name(topic,
-                                                         constants.TUNNEL,
-                                                         topics.UPDATE)
-
-    def network_delete(self, context, network_id):
-        self.fanout_cast(context,
-                         self.make_msg('network_delete',
-                                       network_id=network_id),
-                         topic=self.topic_network_delete)
-
-    def port_update(self, context, port, network_type, segmentation_id,
-                    physical_network):
-        self.fanout_cast(context,
-                         self.make_msg('port_update',
-                                       port=port,
-                                       network_type=network_type,
-                                       segmentation_id=segmentation_id,
-                                       physical_network=physical_network),
-                         topic=self.topic_port_update)
-
-    def tunnel_update(self, context, tunnel_ip, tunnel_id, tunnel_type):
-        self.fanout_cast(context,
-                         self.make_msg('tunnel_update',
-                                       tunnel_ip=tunnel_ip,
-                                       tunnel_id=tunnel_id,
-                                       tunnel_type=tunnel_type),
-                         topic=self.topic_tunnel_update)
-
-
-class OVSNeutronPluginV2(db_base_plugin_v2.NeutronDbPluginV2,
-                         external_net_db.External_net_db_mixin,
-                         extraroute_db.ExtraRoute_db_mixin,
-                         l3_gwmode_db.L3_NAT_db_mixin,
-                         sg_db_rpc.SecurityGroupServerRpcMixin,
-                         l3_agentschedulers_db.L3AgentSchedulerDbMixin,
-                         agentschedulers_db.DhcpAgentSchedulerDbMixin,
-                         portbindings_db.PortBindingMixin,
-                         extradhcpopt_db.ExtraDhcpOptMixin,
-                         addr_pair_db.AllowedAddressPairsMixin):
-
-    """Implement the Neutron abstractions using Open vSwitch.
-
-    Depending on whether tunneling is enabled, either a GRE, VXLAN tunnel or
-    a new VLAN is created for each network. An agent is relied upon to
-    perform the actual OVS configuration on each host.
-
-    The provider extension is also supported. As discussed in
-    https://bugs.launchpad.net/neutron/+bug/1023156, this class could
-    be simplified, and filtering on extended attributes could be
-    handled, by adding support for extended attributes to the
-    NeutronDbPluginV2 base class. When that occurs, this class should
-    be updated to take advantage of it.
-
-    The port binding extension enables an external application relay
-    information to and from the plugin.
-    """
-
-    # This attribute specifies whether the plugin supports or not
-    # bulk/pagination/sorting operations. Name mangling is used in
-    # order to ensure it is qualified by class
-    __native_bulk_support = True
-    __native_pagination_support = True
-    __native_sorting_support = True
-
-    _supported_extension_aliases = ["provider", "external-net", "router",
-                                    "ext-gw-mode", "binding", "quotas",
-                                    "security-group", "agent", "extraroute",
-                                    "l3_agent_scheduler",
-                                    "dhcp_agent_scheduler",
-                                    "extra_dhcp_opt",
-                                    "allowed-address-pairs",
-                                    "nat"]
-
-    @property
-    def supported_extension_aliases(self):
-        if not hasattr(self, '_aliases'):
-            aliases = self._supported_extension_aliases[:]
-            sg_rpc.disable_security_group_extension_if_noop_driver(aliases)
-            self._aliases = aliases
-        return self._aliases
-
-    def __init__(self, configfile=None):
-        self.base_binding_dict = {
-            portbindings.VIF_TYPE: portbindings.VIF_TYPE_OVS,
-            portbindings.CAPABILITIES: {
-                portbindings.CAP_PORT_FILTER:
-                'security-group' in self.supported_extension_aliases}}
-        ovs_db_v2.initialize()
-        self._parse_network_vlan_ranges()
-        ovs_db_v2.sync_vlan_allocations(self.network_vlan_ranges)
-        self.tenant_network_type = cfg.CONF.OVS.tenant_network_type
-        if self.tenant_network_type not in [constants.TYPE_LOCAL,
-                                            constants.TYPE_VLAN,
-                                            constants.TYPE_GRE,
-                                            constants.TYPE_VXLAN,
-                                            constants.TYPE_NONE]:
-            LOG.error(_("Invalid tenant_network_type: %s. "
-                      "Server terminated!"),
-                      self.tenant_network_type)
-            sys.exit(1)
-        self.enable_tunneling = cfg.CONF.OVS.enable_tunneling
-        self.tunnel_type = None
-        if self.enable_tunneling:
-            self.tunnel_type = cfg.CONF.OVS.tunnel_type or constants.TYPE_GRE
-        elif cfg.CONF.OVS.tunnel_type:
-            self.tunnel_type = cfg.CONF.OVS.tunnel_type
-            self.enable_tunneling = True
-        self.tunnel_id_ranges = []
-        if self.enable_tunneling:
-            self._parse_tunnel_id_ranges()
-            ovs_db_v2.sync_tunnel_allocations(self.tunnel_id_ranges)
-        elif self.tenant_network_type in constants.TUNNEL_NETWORK_TYPES:
-            LOG.error(_("Tunneling disabled but tenant_network_type is '%s'. "
-                      "Server terminated!"), self.tenant_network_type)
-            sys.exit(1)
-        self.setup_rpc()
-        self.network_scheduler = importutils.import_object(
-            cfg.CONF.network_scheduler_driver
-        )
-        self.router_scheduler = importutils.import_object(
-            cfg.CONF.router_scheduler_driver
-        )
-
-    def setup_rpc(self):
-        # RPC support
-        self.service_topics = {svc_constants.CORE: topics.PLUGIN,
-                               svc_constants.L3_ROUTER_NAT: topics.L3PLUGIN}
-        self.conn = rpc.create_connection(new=True)
-        self.notifier = AgentNotifierApi(topics.AGENT)
-        self.agent_notifiers[q_const.AGENT_TYPE_DHCP] = (
-            dhcp_rpc_agent_api.DhcpAgentNotifyAPI()
-        )
-        self.agent_notifiers[q_const.AGENT_TYPE_L3] = (
-            l3_rpc_agent_api.L3AgentNotify
-        )
-        self.callbacks = OVSRpcCallbacks(self.notifier, self.tunnel_type)
-        self.dispatcher = self.callbacks.create_rpc_dispatcher()
-        for svc_topic in self.service_topics.values():
-            self.conn.create_consumer(svc_topic, self.dispatcher, fanout=False)
-        # Consume from all consumers in a thread
-        self.conn.consume_in_thread()
-
-    def _parse_network_vlan_ranges(self):
-        try:
-            self.network_vlan_ranges = plugin_utils.parse_network_vlan_ranges(
-                cfg.CONF.OVS.network_vlan_ranges)
-        except Exception as ex:
-            LOG.error(_("%s. Server terminated!"), ex)
-            sys.exit(1)
-        LOG.info(_("Network VLAN ranges: %s"), self.network_vlan_ranges)
-
-    def _parse_tunnel_id_ranges(self):
-        for entry in cfg.CONF.OVS.tunnel_id_ranges:
-            entry = entry.strip()
-            try:
-                tun_min, tun_max = entry.split(':')
-                self.tunnel_id_ranges.append((int(tun_min), int(tun_max)))
-            except ValueError as ex:
-                LOG.error(_("Invalid tunnel ID range: "
-                            "'%(range)s' - %(e)s. Server terminated!"),
-                          {'range': entry, 'e': ex})
-                sys.exit(1)
-        LOG.info(_("Tunnel ID ranges: %s"), self.tunnel_id_ranges)
-
-    def _extend_network_dict_provider(self, context, network):
-        binding = ovs_db_v2.get_network_binding(context.session,
-                                                network['id'])
-        network[provider.NETWORK_TYPE] = binding.network_type
-        if binding.network_type in constants.TUNNEL_NETWORK_TYPES:
-            network[provider.PHYSICAL_NETWORK] = None
-            network[provider.SEGMENTATION_ID] = binding.segmentation_id
-        elif binding.network_type == constants.TYPE_FLAT:
-            network[provider.PHYSICAL_NETWORK] = binding.physical_network
-            network[provider.SEGMENTATION_ID] = None
-        elif binding.network_type == constants.TYPE_VLAN:
-            network[provider.PHYSICAL_NETWORK] = binding.physical_network
-            network[provider.SEGMENTATION_ID] = binding.segmentation_id
-        elif binding.network_type == constants.TYPE_LOCAL:
-            network[provider.PHYSICAL_NETWORK] = None
-            network[provider.SEGMENTATION_ID] = None
-
-    def _process_provider_create(self, context, attrs):
-        network_type = attrs.get(provider.NETWORK_TYPE)
-        physical_network = attrs.get(provider.PHYSICAL_NETWORK)
-        segmentation_id = attrs.get(provider.SEGMENTATION_ID)
-
-        network_type_set = attributes.is_attr_set(network_type)
-        physical_network_set = attributes.is_attr_set(physical_network)
-        segmentation_id_set = attributes.is_attr_set(segmentation_id)
-
-        if not (network_type_set or physical_network_set or
-                segmentation_id_set):
-            return (None, None, None)
-
-        if not network_type_set:
-            msg = _("provider:network_type required")
-            raise q_exc.InvalidInput(error_message=msg)
-        elif network_type == constants.TYPE_FLAT:
-            if segmentation_id_set:
-                msg = _("provider:segmentation_id specified for flat network")
-                raise q_exc.InvalidInput(error_message=msg)
-            else:
-                segmentation_id = constants.FLAT_VLAN_ID
-        elif network_type == constants.TYPE_VLAN:
-            if not segmentation_id_set:
-                msg = _("provider:segmentation_id required")
-                raise q_exc.InvalidInput(error_message=msg)
-            if not utils.is_valid_vlan_tag(segmentation_id):
-                msg = (_("provider:segmentation_id out of range "
-                         "(%(min_id)s through %(max_id)s)") %
-                       {'min_id': q_const.MIN_VLAN_TAG,
-                        'max_id': q_const.MAX_VLAN_TAG})
-                raise q_exc.InvalidInput(error_message=msg)
-        elif network_type in constants.TUNNEL_NETWORK_TYPES:
-            if not self.enable_tunneling:
-                msg = _("%s networks are not enabled") % network_type
-                raise q_exc.InvalidInput(error_message=msg)
-            if physical_network_set:
-                msg = _("provider:physical_network specified for %s "
-                        "network") % network_type
-                raise q_exc.InvalidInput(error_message=msg)
-            else:
-                physical_network = None
-            if not segmentation_id_set:
-                msg = _("provider:segmentation_id required")
-                raise q_exc.InvalidInput(error_message=msg)
-        elif network_type == constants.TYPE_LOCAL:
-            if physical_network_set:
-                msg = _("provider:physical_network specified for local "
-                        "network")
-                raise q_exc.InvalidInput(error_message=msg)
-            else:
-                physical_network = None
-            if segmentation_id_set:
-                msg = _("provider:segmentation_id specified for local "
-                        "network")
-                raise q_exc.InvalidInput(error_message=msg)
-            else:
-                segmentation_id = None
-        else:
-            msg = _("provider:network_type %s not supported") % network_type
-            raise q_exc.InvalidInput(error_message=msg)
-
-        if network_type in [constants.TYPE_VLAN, constants.TYPE_FLAT]:
-            if physical_network_set:
-                if physical_network not in self.network_vlan_ranges:
-                    msg = _("Unknown provider:physical_network "
-                            "%s") % physical_network
-                    raise q_exc.InvalidInput(error_message=msg)
-            elif 'default' in self.network_vlan_ranges:
-                physical_network = 'default'
-            else:
-                msg = _("provider:physical_network required")
-                raise q_exc.InvalidInput(error_message=msg)
-
-        return (network_type, physical_network, segmentation_id)
-
-    def create_network(self, context, network):
-        (network_type, physical_network,
-         segmentation_id) = self._process_provider_create(context,
-                                                          network['network'])
-
-        session = context.session
-        #set up default security groups
-        tenant_id = self._get_tenant_id_for_create(
-            context, network['network'])
-        self._ensure_default_security_group(context, tenant_id)
-
-        with session.begin(subtransactions=True):
-            if not network_type:
-                # tenant network
-                network_type = self.tenant_network_type
-                if network_type == constants.TYPE_NONE:
-                    raise q_exc.TenantNetworksDisabled()
-                elif network_type == constants.TYPE_VLAN:
-                    (physical_network,
-                     segmentation_id) = ovs_db_v2.reserve_vlan(session)
-                elif network_type in constants.TUNNEL_NETWORK_TYPES:
-                    segmentation_id = ovs_db_v2.reserve_tunnel(session)
-                # no reservation needed for TYPE_LOCAL
-            else:
-                # provider network
-                if network_type in [constants.TYPE_VLAN, constants.TYPE_FLAT]:
-                    ovs_db_v2.reserve_specific_vlan(session, physical_network,
-                                                    segmentation_id)
-                elif network_type in constants.TUNNEL_NETWORK_TYPES:
-                    ovs_db_v2.reserve_specific_tunnel(session, segmentation_id)
-                # no reservation needed for TYPE_LOCAL
-            net = super(OVSNeutronPluginV2, self).create_network(context,
-                                                                 network)
-            ovs_db_v2.add_network_binding(session, net['id'], network_type,
-                                          physical_network, segmentation_id)
-
-            self._process_l3_create(context, net, network['network'])
-            self._extend_network_dict_provider(context, net)
-            # note - exception will rollback entire transaction
-        LOG.debug(_("Created network: %s"), net['id'])
-        return net
-
-    def update_network(self, context, id, network):
-        provider._raise_if_updates_provider_attributes(network['network'])
-
-        session = context.session
-        with session.begin(subtransactions=True):
-            net = super(OVSNeutronPluginV2, self).update_network(context, id,
-                                                                 network)
-            self._process_l3_update(context, net, network['network'])
-            self._extend_network_dict_provider(context, net)
-        return net
-
-    def delete_network(self, context, id):
-        session = context.session
-        with session.begin(subtransactions=True):
-            binding = ovs_db_v2.get_network_binding(session, id)
-            super(OVSNeutronPluginV2, self).delete_network(context, id)
-            if binding.network_type in constants.TUNNEL_NETWORK_TYPES:
-                ovs_db_v2.release_tunnel(session, binding.segmentation_id,
-                                         self.tunnel_id_ranges)
-            elif binding.network_type in [constants.TYPE_VLAN,
-                                          constants.TYPE_FLAT]:
-                ovs_db_v2.release_vlan(session, binding.physical_network,
-                                       binding.segmentation_id,
-                                       self.network_vlan_ranges)
-            # the network_binding record is deleted via cascade from
-            # the network record, so explicit removal is not necessary
-        self.notifier.network_delete(context, id)
-
-    def get_network(self, context, id, fields=None):
-        session = context.session
-        with session.begin(subtransactions=True):
-            net = super(OVSNeutronPluginV2, self).get_network(context,
-                                                              id, None)
-            self._extend_network_dict_provider(context, net)
-        return self._fields(net, fields)
-
-    def get_networks(self, context, filters=None, fields=None,
-                     sorts=None,
-                     limit=None, marker=None, page_reverse=False):
-        session = context.session
-        with session.begin(subtransactions=True):
-            nets = super(OVSNeutronPluginV2,
-                         self).get_networks(context, filters, None, sorts,
-                                            limit, marker, page_reverse)
-            for net in nets:
-                self._extend_network_dict_provider(context, net)
-
-        return [self._fields(net, fields) for net in nets]
-
-    def create_port(self, context, port):
-        # Set port status as 'DOWN'. This will be updated by agent
-        port['port']['status'] = q_const.PORT_STATUS_DOWN
-        port_data = port['port']
-        session = context.session
-        with session.begin(subtransactions=True):
-            self._ensure_default_security_group_on_port(context, port)
-            sgids = self._get_security_groups_on_port(context, port)
-            dhcp_opts = port['port'].get(edo_ext.EXTRADHCPOPTS, [])
-            port = super(OVSNeutronPluginV2, self).create_port(context, port)
-            self._process_portbindings_create_and_update(context,
-                                                         port_data, port)
-            self._process_port_create_security_group(context, port, sgids)
-            self._process_port_create_extra_dhcp_opts(context, port,
-                                                      dhcp_opts)
-            port[addr_pair.ADDRESS_PAIRS] = (
-                self._process_create_allowed_address_pairs(
-                    context, port,
-                    port_data.get(addr_pair.ADDRESS_PAIRS)))
-        self.notify_security_groups_member_updated(context, port)
-        return port
-
-    def _extend_port_dict_nat(self, context, port):
-        forward = ovs_db_v2.get_port_forwarding(context.session, port['id'])
-        if forward:
-            port[nat.FORWARD_PORTS] = forward
-        else:
-            port[nat.FORWARD_PORTS] = None
-
-    def _process_nat_update(self, context, attrs, id):
-        forward_ports = attrs.get(nat.FORWARD_PORTS)
-        forward_ports_set = attributes.is_attr_set(forward_ports)
-
-        if not forward_ports_set:
-            return None
-
-        # LOG.info("forward ports %s" % forward_ports)
-        valid_protocols = ["tcp", "udp"]
-        for entry in forward_ports:
-            if not isinstance(entry, dict):
-                msg = _("nat:forward_ports: must specify a list of dicts (ex: 'l4_protocol=tcp,l4_port=80')")
-                raise q_exc.InvalidInput(error_message=msg)
-            if not ("l4_protocol" in entry and "l4_port" in entry):
-                msg = _("nat:forward_ports: dict is missing l4_protocol and l4_port (ex: 'l4_protocol=tcp,l4_port=80')")
-                raise q_exc.InvalidInput(error_message=msg)
-            if entry['l4_protocol'] not in valid_protocols:
-                msg = _("nat:forward_ports: invalid protocol (only tcp and udp allowed)")
-                raise q_exc.InvalidInput(error_message=msg)
-
-            l4_port = entry['l4_port']
-            if ":" in l4_port:
-                try:
-                    (first, last) = l4_port.split(":")
-                    first = int(first)
-                    last = int(last)
-                except:
-                    msg = _("nat:forward_ports: l4_port range must be integer:integer")
-                    raise q_exc.InvalidInput(error_message=msg)
-            else:
-                try:
-                    l4_port = int(l4_port)
-                except:
-                    msg = _("nat:forward_ports: l4_port must be an integer")
-                    raise q_exc.InvalidInput(error_message=msg)
-
-        return forward_ports
-
-    def get_port(self, context, id, fields=None):
-        session = context.session
-        with session.begin(subtransactions=True):
-            port = super(OVSNeutronPluginV2, self).get_port(context, id, None)
-            self._extend_port_dict_nat(context, port)
-        return self._fields(port, fields)
-
-    def get_ports(self, context, filters=None, fields=None):
-        session = context.session
-        with session.begin(subtransactions=True):
-            ports = super(OVSNeutronPluginV2, self).get_ports(context, filters,
-                                                          None)
-            for port in ports:
-                self._extend_port_dict_nat(context, port)
-
-        return [self._fields(port, fields) for port in ports]
-
-    def update_port(self, context, id, port):
-        forward_ports = self._process_nat_update(context, port['port'], id)
-
-        session = context.session
-        need_port_update_notify = False
-        changed_fixed_ips = 'fixed_ips' in port['port']
-        with session.begin(subtransactions=True):
-            original_port = super(OVSNeutronPluginV2, self).get_port(
-                context, id)
-            updated_port = super(OVSNeutronPluginV2, self).update_port(
-                context, id, port)
-            if addr_pair.ADDRESS_PAIRS in port['port']:
-                self._delete_allowed_address_pairs(context, id)
-                self._process_create_allowed_address_pairs(
-                    context, updated_port,
-                    port['port'][addr_pair.ADDRESS_PAIRS])
-                need_port_update_notify = True
-            elif changed_fixed_ips:
-                self._check_fixed_ips_and_address_pairs_no_overlap(
-                    context, updated_port)
-
-            if forward_ports:
-                ovs_db_v2.clear_port_forwarding(session, updated_port['id'])
-                ovs_db_v2.add_port_forwarding(session, updated_port['id'], forward_ports)
-            self._extend_port_dict_nat(context, updated_port)
-
-            need_port_update_notify |= self.update_security_group_on_port(
-                context, id, port, original_port, updated_port)
-            self._process_portbindings_create_and_update(context,
-                                                         port['port'],
-                                                         updated_port)
-            need_port_update_notify |= self._update_extra_dhcp_opts_on_port(
-                context, id, port, updated_port)
-
-        need_port_update_notify |= self.is_security_group_member_updated(
-            context, original_port, updated_port)
-        if original_port['admin_state_up'] != updated_port['admin_state_up']:
-            need_port_update_notify = True
-
-        if need_port_update_notify:
-            binding = ovs_db_v2.get_network_binding(None,
-                                                    updated_port['network_id'])
-            self.notifier.port_update(context, updated_port,
-                                      binding.network_type,
-                                      binding.segmentation_id,
-                                      binding.physical_network)
-        return updated_port
-
-    def delete_port(self, context, id, l3_port_check=True):
-
-        # if needed, check to see if this is a port owned by
-        # and l3-router.  If so, we should prevent deletion.
-        if l3_port_check:
-            self.prevent_l3_port_deletion(context, id)
-
-        session = context.session
-        with session.begin(subtransactions=True):
-            self.disassociate_floatingips(context, id)
-            port = self.get_port(context, id)
-            self._delete_port_security_group_bindings(context, id)
-            super(OVSNeutronPluginV2, self).delete_port(context, id)
-
-        self.notify_security_groups_member_updated(context, port)
diff --git a/xos/observers/base/__init__.py b/xos/observers/base/__init__.py
deleted file mode 100644
index 8b13789..0000000
--- a/xos/observers/base/__init__.py
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/xos/observers/hpc/hpc-observer.py b/xos/observers/hpc/hpc-observer.py
deleted file mode 100755
index d6a71ff..0000000
--- a/xos/observers/hpc/hpc-observer.py
+++ /dev/null
@@ -1,11 +0,0 @@
-#!/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__)),"../..")
-sys.path.append(observer_path)
-mod = importlib.import_module("xos-observer")
-mod.main()
diff --git a/xos/observers/monitoring_channel/monitoring_channel_observer.py b/xos/observers/monitoring_channel/monitoring_channel_observer.py
deleted file mode 100755
index d6a71ff..0000000
--- a/xos/observers/monitoring_channel/monitoring_channel_observer.py
+++ /dev/null
@@ -1,11 +0,0 @@
-#!/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__)),"../..")
-sys.path.append(observer_path)
-mod = importlib.import_module("xos-observer")
-mod.main()
diff --git a/xos/observers/onos/onos-observer.py b/xos/observers/onos/onos-observer.py
deleted file mode 100755
index d6a71ff..0000000
--- a/xos/observers/onos/onos-observer.py
+++ /dev/null
@@ -1,11 +0,0 @@
-#!/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__)),"../..")
-sys.path.append(observer_path)
-mod = importlib.import_module("xos-observer")
-mod.main()
diff --git a/xos/observers/vbng/vbng-observer.py b/xos/observers/vbng/vbng-observer.py
deleted file mode 100755
index d6a71ff..0000000
--- a/xos/observers/vbng/vbng-observer.py
+++ /dev/null
@@ -1,11 +0,0 @@
-#!/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__)),"../..")
-sys.path.append(observer_path)
-mod = importlib.import_module("xos-observer")
-mod.main()
diff --git a/xos/observers/vcpe/vcpe-observer.py b/xos/observers/vcpe/vcpe-observer.py
deleted file mode 100755
index d6a71ff..0000000
--- a/xos/observers/vcpe/vcpe-observer.py
+++ /dev/null
@@ -1,11 +0,0 @@
-#!/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__)),"../..")
-sys.path.append(observer_path)
-mod = importlib.import_module("xos-observer")
-mod.main()
diff --git a/xos/observers/vtn/steps/sync_tenant.py b/xos/observers/vtn/steps/sync_tenant.py
deleted file mode 100644
index 7610177..0000000
--- a/xos/observers/vtn/steps/sync_tenant.py
+++ /dev/null
@@ -1,57 +0,0 @@
-import os
-import requests
-import socket
-import sys
-import base64
-from django.db.models import F, Q
-from xos.config import Config
-from observer.syncstep import SyncStep
-from core.models import Service
-from core.models.service import COARSE_KIND
-from services.cord.models import Tenant
-from util.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)
-
-# XXX should save and load this
-glo_saved_vtn_maps = []
-
-class SyncTenant(SyncStep):
-    provides=[Tenant]
-    observes=Tenant
-    requested_interval=0
-
-    def __init__(self, **args):
-        SyncStep.__init__(self, **args)
-
-    def call(self, **args):
-        global glo_saved_vtn_maps
-
-        logger.info("sync'ing vtn services")
-
-        vtn_maps = []
-        for service in Service.objects.all():
-           for id in service.get_vtn_src_ids():
-               dependencies = service.get_vtn_dependencies_ids()
-               if dependencies:
-                   for dependency in dependencies:
-                       vtn_maps.append( (id, dependency) )
-
-        for vtn_map in vtn_maps:
-            if not (vtn_map in glo_saved_vtn_maps):
-               print "XXX", vtn_map, glo_saved_vtn_maps
-               # call vtn rest api to add map
-               print "POST /onos/cordvtn/service-dependency/%s/%s" % (vtn_map[0], vtn_map[1])
-
-        for vtn_map in glo_saved_vtn_maps:
-            if not vtn_map in vtn_maps:
-                # call vtn rest api to delete map
-                print "DELETE /onos/cordvtn/service-dependency/%s" % (vtn_map[0],)
-
-        glo_saved_vtn_maps = vtn_maps
-        # TODO: save this
-
diff --git a/xos/observers/vtn/vtn-observer.py b/xos/observers/vtn/vtn-observer.py
deleted file mode 100755
index d6a71ff..0000000
--- a/xos/observers/vtn/vtn-observer.py
+++ /dev/null
@@ -1,11 +0,0 @@
-#!/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__)),"../..")
-sys.path.append(observer_path)
-mod = importlib.import_module("xos-observer")
-mod.main()
diff --git a/xos/openstack_observer/ceilometer.py b/xos/openstack_observer/ceilometer.py
deleted file mode 100644
index 792515e..0000000
--- a/xos/openstack_observer/ceilometer.py
+++ /dev/null
@@ -1,120 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-
-from ceilometerclient import client
-from os import environ as env
-import keystoneclient.v2_0.client as ksclient
-import re
-import datetime
-import time
-from monitor.monitordriver import *
-import pdb
-
-def object_to_filter(model_name, pk):
-    from core.models import *
-    filter_dict = {
-            'ControllerSlice':[ControllerSlice, 'tenant_id', 'project_id'],
-            'Instance':[Instance, 'instance_id', 'resource_id'],
-            'ControllerSite':[ControllerSite, 'tenant_id', 'project_id']
-    }
-
-    mod,field,tag = filter_dict[model_name]
-    obj = mod.objects.get(pk=pk)
-    return '%s=%s'%(tag,getattr(obj,field))
-
-
-def cli_to_array(cli_query):
-    '''This converts from the cli list of queries to what is required
-    by the python api.
-    so from:
-    "this<=34;that=foo"
-    to
-    "[{field=this,op=le,value=34},{field=that,op=eq,value=foo}]"
-    '''
-    if cli_query is None:
-        return None
-
-    op_lookup = {'!=': 'ne',
-                 '>=': 'ge',
-                 '<=': 'le',
-                 '>': 'gt',
-                 '<': 'lt',
-                 '=': 'eq'}
-
-    def split_by_op(string):
-        # two character split (<=,!=)
-        frags = re.findall(r'([[a-zA-Z0-9_.]+)([><!]=)([^ -,\t\n\r\f\v]+)',
-                           string)
-        if len(frags) == 0:
-            #single char split (<,=)
-            frags = re.findall(r'([a-zA-Z0-9_.]+)([><=])([^ -,\t\n\r\f\v]+)',
-                               string)
-        return frags
-
-    opts = []
-    queries = cli_query.split(';')
-    for q in queries:
-        frag = split_by_op(q)
-        if len(frag) > 1:
-            raise ValueError('incorrect seperator %s in query "%s"' %
-                             ('(should be ";")', q))
-        if len(frag) == 0:
-            raise ValueError('invalid query %s' % q)
-        query = frag[0]
-        opt = {}
-        opt['field'] = query[0]
-        opt['op'] = op_lookup[query[1]]
-        opt['value'] = query[2]
-        opts.append(opt)
-    return opts
-
-def meters_to_stats(meters):
-    stats = DashboardStatistics()
-    for m in meters:
-        timestamp = m.duration_start
-        stats['stat_list'].append({'timestamp':timestamp, 'value':m.sum})
-        stats['sum']+=m.sum
-        stats['average']+=m.sum
-        stats['unit'] = 'ns'
-
-    if (len(meters)):
-        stats['average']/=len(meters)
-    else:
-        stats['average']=0
-    return stats
-
-
-class CeilometerDriver(MonitorDriver):
-    def get_meter(self, meter, obj, pk, keystone=None):
-        if (not keystone):
-                keystone={}
-                keystone['os_username']=env['OS_USERNAME']
-                keystone['os_password']=env['OS_PASSWORD']
-                keystone['os_auth_url']=env['OS_AUTH_URL']
-                keystone['os_tenant_name']=env['OS_TENANT_NAME']
-                keystone['os_cacert']=env['OS_CACERT']
-                keystone['os_region_name']=env['OS_REGION_NAME']
-
-                keystone['username']=env['OS_USERNAME']
-                keystone['password']=env['OS_PASSWORD']
-                keystone['auth_url']=env['OS_AUTH_URL']
-                keystone['tenant_name']=env['OS_TENANT_NAME']
-                keystone['cacert']=env['OS_CACERT']
-                keystone['region_name']=env['OS_REGION_NAME']
-
-        keystone['auth_plugin']=client.AuthPlugin(**keystone)
-
-        ceilometer = client.get_client(2,**keystone)
-        
-        cur_ts = datetime.datetime.fromtimestamp(time.time()-86400)
-        str_ts = cur_ts.strftime('%Y-%m-%dT%H:%M:%S')
-
-        object_filter = object_to_filter(obj, pk)
-        filter=';'.join([object_filter,'timestamp>%s'%str_ts])
-        #query = cli_to_array("project_id=124de34266b24f57957345cdb43cc9ff;timestamp>2014-12-11T00:00:00")
-        query = cli_to_array(filter)
-
-        meters = ceilometer.statistics.list(meter,q=query,period=3600)
-
-        stats = meters_to_stats(meters)
-        return stats
diff --git a/xos/openstack_observer/deleter.py b/xos/openstack_observer/deleter.py
deleted file mode 100644
index 93fa572..0000000
--- a/xos/openstack_observer/deleter.py
+++ /dev/null
@@ -1,16 +0,0 @@
-import os
-import base64
-from xos.config import Config
-
-class Deleter:
-	model=None # Must be overridden
-
-        def __init__(self, *args, **kwargs):
-                pass
-
-	def call(self, pk, model_dict):
-		# Fetch object from XOS db and delete it
-		pass
-
-	def __call__(self, *args, **kwargs):
-		return self.call(*args, **kwargs)
diff --git a/xos/openstack_observer/error_mapper.py b/xos/openstack_observer/error_mapper.py
deleted file mode 100644
index 3039a56..0000000
--- a/xos/openstack_observer/error_mapper.py
+++ /dev/null
@@ -1,25 +0,0 @@
-from xos.config import Config
-from util.logger import Logger, logging, logger
-
-class ErrorMapper:
-	def __init__(self, error_map_file):
-		self.error_map = {}
-		try:
-			error_map_lines = open(error_map_file).read().splitlines()
-			for l in error_map_lines:
-				if (not l.startswith('#')):
-					splits = l.split('->')
-					k,v = map(lambda i:i.rstrip(),splits)
-					self.error_map[k]=v
-		except:
-			logging.info('Could not read error map')
-
-
-	def map(self, error):
-		return self.error_map[error]
-
-
-
-
-
-
diff --git a/xos/scripts/docker_start_xos b/xos/scripts/docker_start_xos
deleted file mode 100755
index eee9b8f..0000000
--- a/xos/scripts/docker_start_xos
+++ /dev/null
@@ -1,7 +0,0 @@
-#! /bin/bash
-
-bash /opt/xos/scripts/docker_setup_xos
-
-cd /opt/xos
-PUBLIC_HOSTNAME=`./xos-config.py get server_hostname $HOSTNAME`
-python manage.py runserver $PUBLIC_HOSTNAME:8000 --insecure
diff --git a/xos/services/ceilometer/admin.py b/xos/services/ceilometer/admin.py
index fe52996..ed8e47a 100644
--- a/xos/services/ceilometer/admin.py
+++ b/xos/services/ceilometer/admin.py
@@ -48,26 +48,26 @@
 class MonitoringChannelForm(forms.ModelForm):
     creator = forms.ModelChoiceField(queryset=User.objects.all())
 
-    def __init__(self,*args,**kwargs):

-        super (MonitoringChannelForm,self ).__init__(*args,**kwargs)

-        self.fields['kind'].widget.attrs['readonly'] = True

-        self.fields['provider_service'].queryset = CeilometerService.get_service_objects().all()

-        if self.instance:

-            # fields for the attributes

-            self.fields['creator'].initial = self.instance.creator

-        if (not self.instance) or (not self.instance.pk):

-            # default fields for an 'add' form

-            self.fields['kind'].initial = CEILOMETER_KIND

-            self.fields['creator'].initial = get_request().user

-            if CeilometerService.get_service_objects().exists():

-               self.fields["provider_service"].initial = CeilometerService.get_service_objects().all()[0]

-

-

-    def save(self, commit=True):

-        self.instance.creator = self.cleaned_data.get("creator")

-        return super(MonitoringChannelForm, self).save(commit=commit)

-

-    class Meta:

+    def __init__(self,*args,**kwargs):
+        super (MonitoringChannelForm,self ).__init__(*args,**kwargs)
+        self.fields['kind'].widget.attrs['readonly'] = True
+        self.fields['provider_service'].queryset = CeilometerService.get_service_objects().all()
+        if self.instance:
+            # fields for the attributes
+            self.fields['creator'].initial = self.instance.creator
+        if (not self.instance) or (not self.instance.pk):
+            # default fields for an 'add' form
+            self.fields['kind'].initial = CEILOMETER_KIND
+            self.fields['creator'].initial = get_request().user
+            if CeilometerService.get_service_objects().exists():
+               self.fields["provider_service"].initial = CeilometerService.get_service_objects().all()[0]
+
+
+    def save(self, commit=True):
+        self.instance.creator = self.cleaned_data.get("creator")
+        return super(MonitoringChannelForm, self).save(commit=commit)
+
+    class Meta:
         model = MonitoringChannel
 
 class MonitoringChannelAdmin(ReadOnlyAwareAdmin):
diff --git a/xos/services/cord/admin.py b/xos/services/cord/admin.py
index ced79af..5f1a285 100644
--- a/xos/services/cord/admin.py
+++ b/xos/services/cord/admin.py
@@ -55,29 +55,29 @@
     c_tag = forms.CharField()
     creator = forms.ModelChoiceField(queryset=User.objects.all())
 
-    def __init__(self,*args,**kwargs):

-        super (VOLTTenantForm,self ).__init__(*args,**kwargs)

-        self.fields['kind'].widget.attrs['readonly'] = True

-        self.fields['provider_service'].queryset = VOLTService.get_service_objects().all()

-        if self.instance:

-            # fields for the attributes

-            self.fields['c_tag'].initial = self.instance.c_tag

-            self.fields['s_tag'].initial = self.instance.s_tag

-            self.fields['creator'].initial = self.instance.creator

-        if (not self.instance) or (not self.instance.pk):

-            # default fields for an 'add' form

-            self.fields['kind'].initial = VOLT_KIND

-            self.fields['creator'].initial = get_request().user

-            if VOLTService.get_service_objects().exists():

-               self.fields["provider_service"].initial = VOLTService.get_service_objects().all()[0]

-

-    def save(self, commit=True):

-        self.instance.s_tag = self.cleaned_data.get("s_tag")

-        self.instance.c_tag = self.cleaned_data.get("c_tag")

-        self.instance.creator = self.cleaned_data.get("creator")

-        return super(VOLTTenantForm, self).save(commit=commit)

-

-    class Meta:

+    def __init__(self,*args,**kwargs):
+        super (VOLTTenantForm,self ).__init__(*args,**kwargs)
+        self.fields['kind'].widget.attrs['readonly'] = True
+        self.fields['provider_service'].queryset = VOLTService.get_service_objects().all()
+        if self.instance:
+            # fields for the attributes
+            self.fields['c_tag'].initial = self.instance.c_tag
+            self.fields['s_tag'].initial = self.instance.s_tag
+            self.fields['creator'].initial = self.instance.creator
+        if (not self.instance) or (not self.instance.pk):
+            # default fields for an 'add' form
+            self.fields['kind'].initial = VOLT_KIND
+            self.fields['creator'].initial = get_request().user
+            if VOLTService.get_service_objects().exists():
+               self.fields["provider_service"].initial = VOLTService.get_service_objects().all()[0]
+
+    def save(self, commit=True):
+        self.instance.s_tag = self.cleaned_data.get("s_tag")
+        self.instance.c_tag = self.cleaned_data.get("c_tag")
+        self.instance.creator = self.cleaned_data.get("creator")
+        return super(VOLTTenantForm, self).save(commit=commit)
+
+    class Meta:
         model = VOLTTenant
 
 class VOLTTenantAdmin(ReadOnlyAwareAdmin):
@@ -105,24 +105,24 @@
     backend_network_label = forms.CharField(required=False)
     bbs_slice = forms.ModelChoiceField(queryset=Slice.objects.all(), required=False)
 
-    def __init__(self,*args,**kwargs):

-        super (VCPEServiceForm,self ).__init__(*args,**kwargs)

-        if self.instance:

-            self.fields['bbs_api_hostname'].initial = self.instance.bbs_api_hostname

-            self.fields['bbs_api_port'].initial = self.instance.bbs_api_port

-            self.fields['bbs_server'].initial = self.instance.bbs_server

-            self.fields['backend_network_label'].initial = self.instance.backend_network_label

-            self.fields['bbs_slice'].initial = self.instance.bbs_slice

-

-    def save(self, commit=True):

-        self.instance.bbs_api_hostname = self.cleaned_data.get("bbs_api_hostname")

-        self.instance.bbs_api_port = self.cleaned_data.get("bbs_api_port")

-        self.instance.bbs_server = self.cleaned_data.get("bbs_server")

-        self.instance.backend_network_label = self.cleaned_data.get("backend_network_label")

-        self.instance.bbs_slice = self.cleaned_data.get("bbs_slice")

-        return super(VCPEServiceForm, self).save(commit=commit)

-

-    class Meta:

+    def __init__(self,*args,**kwargs):
+        super (VCPEServiceForm,self ).__init__(*args,**kwargs)
+        if self.instance:
+            self.fields['bbs_api_hostname'].initial = self.instance.bbs_api_hostname
+            self.fields['bbs_api_port'].initial = self.instance.bbs_api_port
+            self.fields['bbs_server'].initial = self.instance.bbs_server
+            self.fields['backend_network_label'].initial = self.instance.backend_network_label
+            self.fields['bbs_slice'].initial = self.instance.bbs_slice
+
+    def save(self, commit=True):
+        self.instance.bbs_api_hostname = self.cleaned_data.get("bbs_api_hostname")
+        self.instance.bbs_api_port = self.cleaned_data.get("bbs_api_port")
+        self.instance.bbs_server = self.cleaned_data.get("bbs_server")
+        self.instance.backend_network_label = self.cleaned_data.get("backend_network_label")
+        self.instance.bbs_slice = self.cleaned_data.get("bbs_slice")
+        return super(VCPEServiceForm, self).save(commit=commit)
+
+    class Meta:
         model = VCPEService
 
 class VCPEServiceAdmin(ReadOnlyAwareAdmin):
@@ -164,30 +164,30 @@
     instance = forms.ModelChoiceField(queryset=Instance.objects.all(),required=False)
     last_ansible_hash = forms.CharField(required=False)
 
-    def __init__(self,*args,**kwargs):

-        super (VCPETenantForm,self ).__init__(*args,**kwargs)

-        self.fields['kind'].widget.attrs['readonly'] = True

-        self.fields['provider_service'].queryset = VCPEService.get_service_objects().all()

-        if self.instance:

-            # fields for the attributes

-            self.fields['bbs_account'].initial = self.instance.bbs_account

-            self.fields['creator'].initial = self.instance.creator

-            self.fields['instance'].initial = self.instance.instance

-            self.fields['last_ansible_hash'].initial = self.instance.last_ansible_hash

-        if (not self.instance) or (not self.instance.pk):

-            # default fields for an 'add' form

-            self.fields['kind'].initial = VCPE_KIND

-            self.fields['creator'].initial = get_request().user

-            if VCPEService.get_service_objects().exists():

-               self.fields["provider_service"].initial = VCPEService.get_service_objects().all()[0]

-

-    def save(self, commit=True):

-        self.instance.creator = self.cleaned_data.get("creator")

-        self.instance.instance = self.cleaned_data.get("instance")

-        self.instance.last_ansible_hash = self.cleaned_data.get("last_ansible_hash")

-        return super(VCPETenantForm, self).save(commit=commit)

-

-    class Meta:

+    def __init__(self,*args,**kwargs):
+        super (VCPETenantForm,self ).__init__(*args,**kwargs)
+        self.fields['kind'].widget.attrs['readonly'] = True
+        self.fields['provider_service'].queryset = VCPEService.get_service_objects().all()
+        if self.instance:
+            # fields for the attributes
+            self.fields['bbs_account'].initial = self.instance.bbs_account
+            self.fields['creator'].initial = self.instance.creator
+            self.fields['instance'].initial = self.instance.instance
+            self.fields['last_ansible_hash'].initial = self.instance.last_ansible_hash
+        if (not self.instance) or (not self.instance.pk):
+            # default fields for an 'add' form
+            self.fields['kind'].initial = VCPE_KIND
+            self.fields['creator'].initial = get_request().user
+            if VCPEService.get_service_objects().exists():
+               self.fields["provider_service"].initial = VCPEService.get_service_objects().all()[0]
+
+    def save(self, commit=True):
+        self.instance.creator = self.cleaned_data.get("creator")
+        self.instance.instance = self.cleaned_data.get("instance")
+        self.instance.last_ansible_hash = self.cleaned_data.get("last_ansible_hash")
+        return super(VCPETenantForm, self).save(commit=commit)
+
+    class Meta:
         model = VCPETenant
 
 class VCPETenantAdmin(ReadOnlyAwareAdmin):
@@ -211,16 +211,16 @@
 class VBNGServiceForm(forms.ModelForm):
     vbng_url = forms.CharField(required=False)
 
-    def __init__(self,*args,**kwargs):

-        super (VBNGServiceForm,self ).__init__(*args,**kwargs)

-        if self.instance:

-            self.fields['vbng_url'].initial = self.instance.vbng_url

-

-    def save(self, commit=True):

-        self.instance.vbng_url = self.cleaned_data.get("vbng_url")

-        return super(VBNGServiceForm, self).save(commit=commit)

-

-    class Meta:

+    def __init__(self,*args,**kwargs):
+        super (VBNGServiceForm,self ).__init__(*args,**kwargs)
+        if self.instance:
+            self.fields['vbng_url'].initial = self.instance.vbng_url
+
+    def save(self, commit=True):
+        self.instance.vbng_url = self.cleaned_data.get("vbng_url")
+        return super(VBNGServiceForm, self).save(commit=commit)
+
+    class Meta:
         model = VBNGService
 
 class VBNGServiceAdmin(ReadOnlyAwareAdmin):
@@ -260,30 +260,30 @@
     mapped_ip = forms.CharField(required=False)
     mapped_mac =  forms.CharField(required=False)
 
-    def __init__(self,*args,**kwargs):

-        super (VBNGTenantForm,self ).__init__(*args,**kwargs)

-        self.fields['kind'].widget.attrs['readonly'] = True

-        self.fields['provider_service'].queryset = VBNGService.get_service_objects().all()

-        if self.instance:

-            # fields for the attributes

-            self.fields['routeable_subnet'].initial = self.instance.routeable_subnet

-            self.fields['mapped_hostname'].initial = self.instance.mapped_hostname

-            self.fields['mapped_ip'].initial = self.instance.mapped_ip

-            self.fields['mapped_mac'].initial = self.instance.mapped_mac

-        if (not self.instance) or (not self.instance.pk):

-            # default fields for an 'add' form

-            self.fields['kind'].initial = VBNG_KIND

-            if VBNGService.get_service_objects().exists():

-               self.fields["provider_service"].initial = VBNGService.get_service_objects().all()[0]

-

-    def save(self, commit=True):

-        self.instance.routeable_subnet = self.cleaned_data.get("routeable_subnet")

-        self.instance.mapped_hostname = self.cleaned_data.get("mapped_hostname")

-        self.instance.mapped_ip = self.cleaned_data.get("mapped_ip")

-        self.instance.mapped_mac = self.cleaned_data.get("mapped_mac")

-        return super(VBNGTenantForm, self).save(commit=commit)

-

-    class Meta:

+    def __init__(self,*args,**kwargs):
+        super (VBNGTenantForm,self ).__init__(*args,**kwargs)
+        self.fields['kind'].widget.attrs['readonly'] = True
+        self.fields['provider_service'].queryset = VBNGService.get_service_objects().all()
+        if self.instance:
+            # fields for the attributes
+            self.fields['routeable_subnet'].initial = self.instance.routeable_subnet
+            self.fields['mapped_hostname'].initial = self.instance.mapped_hostname
+            self.fields['mapped_ip'].initial = self.instance.mapped_ip
+            self.fields['mapped_mac'].initial = self.instance.mapped_mac
+        if (not self.instance) or (not self.instance.pk):
+            # default fields for an 'add' form
+            self.fields['kind'].initial = VBNG_KIND
+            if VBNGService.get_service_objects().exists():
+               self.fields["provider_service"].initial = VBNGService.get_service_objects().all()[0]
+
+    def save(self, commit=True):
+        self.instance.routeable_subnet = self.cleaned_data.get("routeable_subnet")
+        self.instance.mapped_hostname = self.cleaned_data.get("mapped_hostname")
+        self.instance.mapped_ip = self.cleaned_data.get("mapped_ip")
+        self.instance.mapped_mac = self.cleaned_data.get("mapped_mac")
+        return super(VBNGTenantForm, self).save(commit=commit)
+
+    class Meta:
         model = VBNGTenant
 
 class VBNGTenantAdmin(ReadOnlyAwareAdmin):
@@ -326,20 +326,20 @@
 class CordSubscriberRootForm(forms.ModelForm):
     url_filter_level = forms.CharField(required = False)
 
-    def __init__(self,*args,**kwargs):

-        super (CordSubscriberRootForm,self ).__init__(*args,**kwargs)

-        self.fields['kind'].widget.attrs['readonly'] = True

-        if self.instance:

-            self.fields['url_filter_level'].initial = self.instance.url_filter_level

-        if (not self.instance) or (not self.instance.pk):

-            # default fields for an 'add' form

-            self.fields['kind'].initial = CORD_SUBSCRIBER_KIND

-

-    def save(self, commit=True):

-        self.instance.url_filter_level = self.cleaned_data.get("url_filter_level")

-        return super(CordSubscriberRootForm, self).save(commit=commit)

-

-    class Meta:

+    def __init__(self,*args,**kwargs):
+        super (CordSubscriberRootForm,self ).__init__(*args,**kwargs)
+        self.fields['kind'].widget.attrs['readonly'] = True
+        if self.instance:
+            self.fields['url_filter_level'].initial = self.instance.url_filter_level
+        if (not self.instance) or (not self.instance.pk):
+            # default fields for an 'add' form
+            self.fields['kind'].initial = CORD_SUBSCRIBER_KIND
+
+    def save(self, commit=True):
+        self.instance.url_filter_level = self.cleaned_data.get("url_filter_level")
+        return super(CordSubscriberRootForm, self).save(commit=commit)
+
+    class Meta:
         model = CordSubscriberRoot
 
 class CordSubscriberRootAdmin(ReadOnlyAwareAdmin):
diff --git a/xos/services/cord/templates/vbngadmin.html b/xos/services/cord/templates/vbngadmin.html
index 721f76c..cceaee0 100644
--- a/xos/services/cord/templates/vbngadmin.html
+++ b/xos/services/cord/templates/vbngadmin.html
@@ -1,6 +1,6 @@
-<div class = "left-nav">
-<ul>
-<li><a href="/admin/cord/vbngtenant/">vBNG Tenants</a></li>
-</ul>
+<div class = "row text-center">
+    <div class="col-xs-12">
+        <a class="btn btn-primary" href="/admin/cord/vbngtenant/">vBNG Tenants</a>
+    </div>
 </div>
 
diff --git a/xos/services/cord/templates/vcpeadmin.html b/xos/services/cord/templates/vcpeadmin.html
index 7a5d43f..a21dabe 100644
--- a/xos/services/cord/templates/vcpeadmin.html
+++ b/xos/services/cord/templates/vcpeadmin.html
@@ -1,7 +1,9 @@
-<div class = "left-nav">
-<ul>
-<li><a href="/admin/cord/vcpetenant/">vCPE Tenants</a></li>
-<li><a href="/admin/dashboard/cord/">Subscriber View</a></li>
-</ul>
+<div class = "row text-center">
+    <div class="col-xs-6">
+        <a class="btn btn-primary" href="/admin/cord/vcpetenant/">vCPE Tenants</a>
+    </div>
+    <div class="col-xs-6">
+        <a class="btn btn-primary" href="/admin/dashboard/cord/">Subscriber View</a>
+    </div>
 </div>
 
diff --git a/xos/services/cord/templates/voltadmin.html b/xos/services/cord/templates/voltadmin.html
index 5bf28ff..e6887c5 100644
--- a/xos/services/cord/templates/voltadmin.html
+++ b/xos/services/cord/templates/voltadmin.html
@@ -1,6 +1,6 @@
-<div class = "left-nav">
-<ul>
-<li><a href="/admin/cord/volttenant/">vOLT Tenants</a></li>
-</ul>
+<div class = "row text-center">
+    <div class="col-xs-12">
+        <a href="/admin/cord/volttenant/">vOLT Tenants</a>
+    </div>
 </div>
 
diff --git a/xos/services/helloworld/view.py b/xos/services/helloworld/view.py
index ab170a2..6ad9ae1 100644
--- a/xos/services/helloworld/view.py
+++ b/xos/services/helloworld/view.py
@@ -1,7 +1,6 @@
 from django.http import HttpResponse
 from django.views.generic import TemplateView, View
 from django import template
-from monitor import driver
 from core.models import *
 from services.helloworld.models import *
 import json
diff --git a/xos/services/hpc/admin.py b/xos/services/hpc/admin.py
index 233668b..d9f28c6 100644
--- a/xos/services/hpc/admin.py
+++ b/xos/services/hpc/admin.py
@@ -25,7 +25,8 @@
 
     def __init__(self, *args, **kwargs):
         super(HpcServiceForm, self).__init__(*args, **kwargs)
-        self.fields['scale'].initial = kwargs["instance"].scale
+        if ("instance" in kwargs) and (hasattr(kwargs["instance"], "scale")):
+            self.fields['scale'].initial = kwargs["instance"].scale
 
     def save(self, *args, **kwargs):
         if self.cleaned_data['scale']:
diff --git a/xos/services/hpc/filteredadmin.py b/xos/services/hpc/filteredadmin.py
index 6cad25c..b677b54 100644
--- a/xos/services/hpc/filteredadmin.py
+++ b/xos/services/hpc/filteredadmin.py
@@ -31,14 +31,14 @@
         pk = getattr(result, self.pk_attname)
         if self.embedded:
             return reverse('admin:%s_%s_embeddedfilteredchange' % (self.opts.app_label,
-                                                           self.opts.model_name),

-                           args=(quote(self.service.id), quote(pk),),

+                                                           self.opts.model_name),
+                           args=(quote(self.service.id), quote(pk),),
                            current_app=self.model_admin.admin_site.name)
 
         else:
             return reverse('admin:%s_%s_filteredchange' % (self.opts.app_label,
-                                                           self.opts.model_name),

-                           args=(quote(self.service.id), quote(pk),),

+                                                           self.opts.model_name),
+                           args=(quote(self.service.id), quote(pk),),
                            current_app=self.model_admin.admin_site.name)
 
 class FilteredAdmin(ReadOnlyAwareAdmin):
@@ -71,10 +71,10 @@
 
    def get_urls(self):
        from django.conf.urls import patterns, url
-

-       def wrap(view):

-            def wrapper(*args, **kwargs):

-                return self.admin_site.admin_view(view)(*args, **kwargs)

+
+       def wrap(view):
+            def wrapper(*args, **kwargs):
+                return self.admin_site.admin_view(view)(*args, **kwargs)
             return update_wrapper(wrapper, view)
 
        urls = super(FilteredAdmin, self).get_urls()
diff --git a/xos/services/onos/admin.py b/xos/services/onos/admin.py
index d13a991..3f9f96c 100644
--- a/xos/services/onos/admin.py
+++ b/xos/services/onos/admin.py
@@ -21,19 +21,19 @@
 class ONOSServiceForm(forms.ModelForm):
     use_external_host = forms.CharField(required=False)
 
-    def __init__(self,*args,**kwargs):

-        super (ONOSServiceForm,self ).__init__(*args,**kwargs)

-        if self.instance:

-            # fields for the attributes

-            self.fields['use_external_host'].initial = self.instance.use_external_host

-

-    def save(self, commit=True):

-        self.instance.use_external_host = self.cleaned_data.get("use_external_host")

-        return super(ONOSServiceForm, self).save(commit=commit)

-

-    class Meta:

-        model = ONOSService

-

+    def __init__(self,*args,**kwargs):
+        super (ONOSServiceForm,self ).__init__(*args,**kwargs)
+        if self.instance:
+            # fields for the attributes
+            self.fields['use_external_host'].initial = self.instance.use_external_host
+
+    def save(self, commit=True):
+        self.instance.use_external_host = self.cleaned_data.get("use_external_host")
+        return super(ONOSServiceForm, self).save(commit=commit)
+
+    class Meta:
+        model = ONOSService
+
 class ONOSServiceAdmin(ReadOnlyAwareAdmin):
     model = ONOSService
     verbose_name = "ONOS Service"
@@ -67,29 +67,29 @@
     name = forms.CharField()
     dependencies = forms.CharField(required=False)
 
-    def __init__(self,*args,**kwargs):

-        super (ONOSAppForm,self ).__init__(*args,**kwargs)

-        self.fields['kind'].widget.attrs['readonly'] = True

-        self.fields['provider_service'].queryset = ONOSService.get_service_objects().all()

-        if self.instance:

-            # fields for the attributes

-            self.fields['creator'].initial = self.instance.creator

-            self.fields['name'].initial = self.instance.name

-            self.fields['dependencies'].initial = self.instance.dependencies

-        if (not self.instance) or (not self.instance.pk):

-            # default fields for an 'add' form

-            self.fields['kind'].initial = ONOS_KIND

-            self.fields['creator'].initial = get_request().user

-            if ONOSService.get_service_objects().exists():

-               self.fields["provider_service"].initial = ONOSService.get_service_objects().all()[0]

-

-    def save(self, commit=True):

-        self.instance.creator = self.cleaned_data.get("creator")

-        self.instance.name = self.cleaned_data.get("name")

-        self.instance.dependencies = self.cleaned_data.get("dependencies")

-        return super(ONOSAppForm, self).save(commit=commit)

-

-    class Meta:

+    def __init__(self,*args,**kwargs):
+        super (ONOSAppForm,self ).__init__(*args,**kwargs)
+        self.fields['kind'].widget.attrs['readonly'] = True
+        self.fields['provider_service'].queryset = ONOSService.get_service_objects().all()
+        if self.instance:
+            # fields for the attributes
+            self.fields['creator'].initial = self.instance.creator
+            self.fields['name'].initial = self.instance.name
+            self.fields['dependencies'].initial = self.instance.dependencies
+        if (not self.instance) or (not self.instance.pk):
+            # default fields for an 'add' form
+            self.fields['kind'].initial = ONOS_KIND
+            self.fields['creator'].initial = get_request().user
+            if ONOSService.get_service_objects().exists():
+               self.fields["provider_service"].initial = ONOSService.get_service_objects().all()[0]
+
+    def save(self, commit=True):
+        self.instance.creator = self.cleaned_data.get("creator")
+        self.instance.name = self.cleaned_data.get("name")
+        self.instance.dependencies = self.cleaned_data.get("dependencies")
+        return super(ONOSAppForm, self).save(commit=commit)
+
+    class Meta:
         model = ONOSApp
 
 class ONOSAppAdmin(ReadOnlyAwareAdmin):
diff --git a/xos/observers/__init__.py b/xos/synchronizers/__init__.py
similarity index 100%
rename from xos/observers/__init__.py
rename to xos/synchronizers/__init__.py
diff --git a/xos/observers/base/SyncInstanceUsingAnsible.py b/xos/synchronizers/base/SyncInstanceUsingAnsible.py
similarity index 97%
rename from xos/observers/base/SyncInstanceUsingAnsible.py
rename to xos/synchronizers/base/SyncInstanceUsingAnsible.py
index 81f6632..335932f 100644
--- a/xos/observers/base/SyncInstanceUsingAnsible.py
+++ b/xos/synchronizers/base/SyncInstanceUsingAnsible.py
@@ -6,10 +6,10 @@
 import time
 from django.db.models import F, Q
 from xos.config import Config
-from observer.syncstep import SyncStep
-from observer.ansible import run_template_ssh
+from synchronizers.base.syncstep import SyncStep
+from synchronizers.base.ansible import run_template_ssh
 from core.models import Service, Slice, ControllerSlice, ControllerUser
-from util.logger import Logger, logging
+from xos.logger import Logger, logging
 
 logger = Logger(level=logging.INFO)
 
diff --git a/xos/observers/base/SyncSliverUsingAnsible.py b/xos/synchronizers/base/SyncSliverUsingAnsible.py
similarity index 94%
rename from xos/observers/base/SyncSliverUsingAnsible.py
rename to xos/synchronizers/base/SyncSliverUsingAnsible.py
index 9455780..c64e5ea 100644
--- a/xos/observers/base/SyncSliverUsingAnsible.py
+++ b/xos/synchronizers/base/SyncSliverUsingAnsible.py
@@ -6,10 +6,10 @@
 import time
 from django.db.models import F, Q
 from xos.config import Config
-from observer.syncstep import SyncStep
-from observer.ansible import run_template_ssh
+from synchronizers.base.syncstep import SyncStep
+from synchronizers.base.ansible import run_template_ssh
 from core.models import Service, Slice
-from util.logger import Logger, logging
+from xos.logger import Logger, logging
 
 logger = Logger(level=logging.INFO)
 
diff --git a/xos/openstack_observer/__init__.py b/xos/synchronizers/base/__init__.py
similarity index 100%
rename from xos/openstack_observer/__init__.py
rename to xos/synchronizers/base/__init__.py
diff --git a/xos/openstack_observer/ansible.py b/xos/synchronizers/base/ansible.py
similarity index 96%
rename from xos/openstack_observer/ansible.py
rename to xos/synchronizers/base/ansible.py
index 94b09bd..7c30685 100644
--- a/xos/openstack_observer/ansible.py
+++ b/xos/synchronizers/base/ansible.py
@@ -10,13 +10,13 @@
 import traceback
 import subprocess
 from xos.config import Config, XOS_DIR
-from util.logger import observer_logger
+from xos.logger import observer_logger
 
 try:
     step_dir = Config().observer_steps_dir
     sys_dir = Config().observer_sys_dir
 except:
-    step_dir = XOS_DIR + '/observer/steps'
+    step_dir = XOS_DIR + '/synchronizers/openstack/steps'
     sys_dir = '/opt/opencloud'
 
 os_template_loader = jinja2.FileSystemLoader( searchpath=step_dir)
@@ -100,7 +100,7 @@
 
     if (not Config().observer_pretend):
         if not run_ansible_script:
-            run_ansible_script = os.path.join(XOS_DIR, "observer/run_ansible")
+            run_ansible_script = os.path.join(XOS_DIR, "synchronizers/base/run_ansible")
 
         process = subprocess.Popen("%s %s" % (run_ansible_script, shellquote(fqp)), shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=env)
         msg = process.stdout.read()
diff --git a/xos/openstack_observer/backend.py b/xos/synchronizers/base/backend.py
similarity index 86%
rename from xos/openstack_observer/backend.py
rename to xos/synchronizers/base/backend.py
index 5657491..5f11d46 100644
--- a/xos/openstack_observer/backend.py
+++ b/xos/synchronizers/base/backend.py
@@ -2,10 +2,10 @@
 import sys
 import threading
 import time
-from observer.event_loop import XOSObserver
-from observer.event_manager import EventListener
-from util.logger import Logger, logging
-from model_policy import run_policy
+from synchronizers.base.event_loop import XOSObserver
+from synchronizers.base.event_manager import EventListener
+from xos.logger import Logger, logging
+from synchronizers.model_policy import run_policy
 from xos.config import Config
 
 logger = Logger(level=logging.INFO)
diff --git a/xos/synchronizers/base/backend.py.bak b/xos/synchronizers/base/backend.py.bak
new file mode 100644
index 0000000..6e46b85
--- /dev/null
+++ b/xos/synchronizers/base/backend.py.bak
@@ -0,0 +1,34 @@
+import threading
+import time
+from observer.event_loop import XOSObserver
+from observer.event_manager import EventListener
+from util.logger import Logger, logging
+from model_policy import run_policy
+from xos.config import Config
+
+logger = Logger(level=logging.INFO)
+
+class Backend:
+    
+    def run(self):
+            # start the openstack observer
+            observer = XOSObserver()
+            observer_thread = threading.Thread(target=observer.run)
+            observer_thread.start()
+            
+            # start model policies thread
+            observer_name = getattr(Config(), "observer_name", "")
+     	    if (not observer_name):	
+             	model_policy_thread = threading.Thread(target=run_policy)
+             	model_policy_thread.start()
+     	    else:
+         		print "Skipping model policies thread for service observer."
+
+            model_policy_thread = threading.Thread(target=run_policy)
+            model_policy_thread.start()
+
+            # start event listene
+            event_manager = EventListener(wake_up=observer.wake_up)
+            event_manager_thread = threading.Thread(target=event_manager.run)
+            event_manager_thread.start()
+
diff --git a/xos/synchronizers/base/controller.diff b/xos/synchronizers/base/controller.diff
new file mode 100644
index 0000000..865b83e
--- /dev/null
+++ b/xos/synchronizers/base/controller.diff
@@ -0,0 +1,37 @@
+diff -up xos/model_policies/model_policy_Controller.py.orig xos/model_policies/model_policy_Controller.py
+--- xos/model_policies/model_policy_Controller.py.orig	2015-01-19 20:09:13.000000000 +0000
++++ xos/model_policies/model_policy_Controller.py	2015-04-07 21:48:51.462215000 +0000
+@@ -1,6 +1,6 @@
+ 
+ def handle(controller):
+-    from core.models import Controller, Site, ControllerSite, Slice, ControllerSlice, User, ControllerUser
++    from core.models import Controller, Site, ControllerSite, Slice, ControllerSlice, User, ControllerUser, ControllerImages, ControllerNetwork
+     from collections import defaultdict
+ 
+     # relations for all sites
+@@ -36,3 +36,25 @@ def handle(controller):
+             controller not in ctrls_by_user[user]:
+             controller_user = ControllerUser(controller=controller, user=user)
+             controller_user.save()
++    # relations for all networks
++    ctrls_by_network = defaultdict(list)
++    ctrl_networks = ControllerNetwork.objects.all()
++    for ctrl_network in ctrl_networks:
++        ctrls_by_network[ctrl_network.network].append(ctrl_network.controller)
++    networks = Network.objects.all()
++    for network in networks:
++        if network not in ctrls_by_network or \
++            controller not in ctrls_by_network[network]:
++            controller_network = ControllerNetwork(controller=controller, network=network)
++            controller_network.save()
++    # relations for all images
++    ctrls_by_image = defaultdict(list)
++    ctrl_images = ControllerImages.objects.all()
++    for ctrl_image in ctrl_images:
++        ctrls_by_image[ctrl_image.image].append(ctrl_image.controller)
++    images = Image.objects.all()
++    for image in images:
++        if image not in ctrls_by_image or \
++            controller not in ctrls_by_image[image]:
++            controller_image = ControllerImages(controller=controller, image=image)
++            controller_image.save()
diff --git a/xos/ec2_observer/deleter.py b/xos/synchronizers/base/deleter.py
similarity index 100%
rename from xos/ec2_observer/deleter.py
rename to xos/synchronizers/base/deleter.py
diff --git a/xos/ec2_observer/error_mapper.py b/xos/synchronizers/base/error_mapper.py
similarity index 90%
rename from xos/ec2_observer/error_mapper.py
rename to xos/synchronizers/base/error_mapper.py
index 3039a56..9eb878d 100644
--- a/xos/ec2_observer/error_mapper.py
+++ b/xos/synchronizers/base/error_mapper.py
@@ -1,5 +1,5 @@
 from xos.config import Config
-from util.logger import Logger, logging, logger
+from xos.logger import Logger, logging, logger
 
 class ErrorMapper:
 	def __init__(self, error_map_file):
diff --git a/xos/openstack_observer/event_loop.py b/xos/synchronizers/base/event_loop.py
similarity index 97%
rename from xos/openstack_observer/event_loop.py
rename to xos/synchronizers/base/event_loop.py
index 0ac626b..6cfc9f6 100644
--- a/xos/openstack_observer/event_loop.py
+++ b/xos/synchronizers/base/event_loop.py
@@ -19,15 +19,15 @@
 from django.db import reset_queries
 #from openstack.manager import OpenStackManager
 from openstack.driver import OpenStackDriver
-from util.logger import Logger, logging, logger
+from xos.logger import Logger, logging, logger
 #from timeout import timeout
 from xos.config import Config, XOS_DIR
-from observer.steps import *
+from synchronizers.base.steps import *
 from syncstep import SyncStep
 from toposort import toposort
-from observer.error_mapper import *
-from openstack_observer.openstacksyncstep import OpenStackSyncStep
-from observer.steps.sync_object import SyncObject
+from synchronizers.base.error_mapper import *
+from synchronizers.openstack.openstacksyncstep import OpenStackSyncStep
+from synchronizers.base.steps.sync_object import SyncObject
 
 # Load app models
 
@@ -121,7 +121,7 @@
 			if hasattr(Config(), "observer_steps_dir"):
 				step_dir = Config().observer_steps_dir
 			else:
-				step_dir = XOS_DIR + "/observer/steps"
+				step_dir = XOS_DIR + "/synchronizers/openstack/steps"
 
 		for fn in os.listdir(step_dir):
 			pathname = os.path.join(step_dir,fn)
diff --git a/xos/openstack_observer/event_manager.py b/xos/synchronizers/base/event_manager.py
similarity index 100%
rename from xos/openstack_observer/event_manager.py
rename to xos/synchronizers/base/event_manager.py
diff --git a/xos/synchronizers/base/observer b/xos/synchronizers/base/observer
new file mode 120000
index 0000000..ae75af5
--- /dev/null
+++ b/xos/synchronizers/base/observer
@@ -0,0 +1 @@
+openstack_observer
\ No newline at end of file
diff --git a/xos/openstack_observer/openstacksyncstep.py b/xos/synchronizers/base/openstacksyncstep.py
similarity index 100%
rename from xos/openstack_observer/openstacksyncstep.py
rename to xos/synchronizers/base/openstacksyncstep.py
diff --git a/xos/openstack_observer/run_ansible b/xos/synchronizers/base/run_ansible
similarity index 100%
rename from xos/openstack_observer/run_ansible
rename to xos/synchronizers/base/run_ansible
diff --git a/xos/openstack_observer/run_ansible_verbose b/xos/synchronizers/base/run_ansible_verbose
similarity index 100%
rename from xos/openstack_observer/run_ansible_verbose
rename to xos/synchronizers/base/run_ansible_verbose
diff --git a/xos/openstack_observer/steps/__init__.py b/xos/synchronizers/base/steps/__init__.py
similarity index 100%
rename from xos/openstack_observer/steps/__init__.py
rename to xos/synchronizers/base/steps/__init__.py
diff --git a/xos/openstack_observer/steps/delete_slivers.yaml b/xos/synchronizers/base/steps/delete_slivers.yaml
similarity index 100%
rename from xos/openstack_observer/steps/delete_slivers.yaml
rename to xos/synchronizers/base/steps/delete_slivers.yaml
diff --git a/xos/openstack_observer/steps/purge_disabled_users.py b/xos/synchronizers/base/steps/purge_disabled_users.py
similarity index 85%
rename from xos/openstack_observer/steps/purge_disabled_users.py
rename to xos/synchronizers/base/steps/purge_disabled_users.py
index b5168e3..0973b8c 100644
--- a/xos/openstack_observer/steps/purge_disabled_users.py
+++ b/xos/synchronizers/base/steps/purge_disabled_users.py
@@ -3,9 +3,9 @@
 import datetime
 from django.db.models import F, Q
 from xos.config import Config
-from observer.openstacksyncstep import OpenStackSyncStep
+from synchronizers.base.openstacksyncstep import OpenStackSyncStep
 from core.models.user import User
-from util.logger import observer_logger as logger
+from xos.logger import observer_logger as logger
 
 class SyncRoles(OpenStackSyncStep):
     provides=[User]
diff --git a/xos/openstack_observer/steps/sliver.yaml b/xos/synchronizers/base/steps/sliver.yaml
similarity index 100%
rename from xos/openstack_observer/steps/sliver.yaml
rename to xos/synchronizers/base/steps/sliver.yaml
diff --git a/xos/openstack_observer/steps/sync_container.py b/xos/synchronizers/base/steps/sync_container.py
similarity index 95%
rename from xos/openstack_observer/steps/sync_container.py
rename to xos/synchronizers/base/steps/sync_container.py
index adb81c9..d647aef 100644
--- a/xos/openstack_observer/steps/sync_container.py
+++ b/xos/synchronizers/base/steps/sync_container.py
@@ -6,12 +6,12 @@
 import time
 from django.db.models import F, Q
 from xos.config import Config
-from observers.base.SyncInstanceUsingAnsible import SyncInstanceUsingAnsible
-from observer.syncstep import SyncStep, DeferredException
-from observer.ansible import run_template_ssh
+from synchronizers.base.SyncInstanceUsingAnsible import SyncInstanceUsingAnsible
+from synchronizers.base.syncstep import SyncStep, DeferredException
+from synchronizers.base.ansible import run_template_ssh
 from core.models import Service, Slice, Instance
 from services.onos.models import ONOSService, ONOSApp
-from util.logger import Logger, logging
+from xos.logger import Logger, logging
 
 # hpclibrary will be in steps/..
 parentdir = os.path.join(os.path.dirname(__file__),"..")
diff --git a/xos/openstack_observer/steps/sync_container.yaml b/xos/synchronizers/base/steps/sync_container.yaml
similarity index 100%
rename from xos/openstack_observer/steps/sync_container.yaml
rename to xos/synchronizers/base/steps/sync_container.yaml
diff --git a/xos/openstack_observer/steps/sync_controller_images.py b/xos/synchronizers/base/steps/sync_controller_images.py
similarity index 88%
rename from xos/openstack_observer/steps/sync_controller_images.py
rename to xos/synchronizers/base/steps/sync_controller_images.py
index 551d9ac..c1e5136 100644
--- a/xos/openstack_observer/steps/sync_controller_images.py
+++ b/xos/synchronizers/base/steps/sync_controller_images.py
@@ -3,12 +3,12 @@
 from collections import defaultdict
 from django.db.models import F, Q
 from xos.config import Config
-from observer.openstacksyncstep import OpenStackSyncStep
-from observer.syncstep import *
+from synchronizers.base.openstacksyncstep import OpenStackSyncStep
+from synchronizers.base.syncstep import *
 from core.models import Controller
 from core.models import Image, ControllerImages
-from util.logger import observer_logger as logger 
-from observer.ansible import *
+from xos.logger import observer_logger as logger 
+from synchronizers.base.ansible import *
 import json
 
 class SyncControllerImages(OpenStackSyncStep):
diff --git a/xos/openstack_observer/steps/sync_controller_images.yaml b/xos/synchronizers/base/steps/sync_controller_images.yaml
similarity index 100%
rename from xos/openstack_observer/steps/sync_controller_images.yaml
rename to xos/synchronizers/base/steps/sync_controller_images.yaml
diff --git a/xos/openstack_observer/steps/sync_controller_networks.py b/xos/synchronizers/base/steps/sync_controller_networks.py
similarity index 96%
rename from xos/openstack_observer/steps/sync_controller_networks.py
rename to xos/synchronizers/base/steps/sync_controller_networks.py
index ad1604b..990cb87 100644
--- a/xos/openstack_observer/steps/sync_controller_networks.py
+++ b/xos/synchronizers/base/steps/sync_controller_networks.py
@@ -4,13 +4,13 @@
 from netaddr import IPAddress, IPNetwork
 from django.db.models import F, Q
 from xos.config import Config
-from observer.openstacksyncstep import OpenStackSyncStep
-from observer.syncstep import *
+from synchronizers.base.openstacksyncstep import OpenStackSyncStep
+from synchronizers.base.syncstep import *
 from core.models.network import *
 from core.models.slice import *
 from core.models.instance import Instance
-from util.logger import observer_logger as logger
-from observer.ansible import *
+from xos.logger import observer_logger as logger
+from synchronizers.base.ansible import *
 from openstack.driver import OpenStackDriver
 from xos.config import Config
 import json
diff --git a/xos/openstack_observer/steps/sync_controller_networks.yaml b/xos/synchronizers/base/steps/sync_controller_networks.yaml
similarity index 100%
rename from xos/openstack_observer/steps/sync_controller_networks.yaml
rename to xos/synchronizers/base/steps/sync_controller_networks.yaml
diff --git a/xos/openstack_observer/steps/sync_controller_site_privileges.py b/xos/synchronizers/base/steps/sync_controller_site_privileges.py
similarity index 95%
rename from xos/openstack_observer/steps/sync_controller_site_privileges.py
rename to xos/synchronizers/base/steps/sync_controller_site_privileges.py
index d257536..59919fe 100644
--- a/xos/openstack_observer/steps/sync_controller_site_privileges.py
+++ b/xos/synchronizers/base/steps/sync_controller_site_privileges.py
@@ -3,13 +3,13 @@
 from collections import defaultdict
 from django.db.models import F, Q
 from xos.config import Config
-from observer.openstacksyncstep import OpenStackSyncStep
-from observer.syncstep import *
+from synchronizers.base.openstacksyncstep import OpenStackSyncStep
+from synchronizers.base.syncstep import *
 from core.models.site import Controller, SitePrivilege 
 from core.models.user import User
 from core.models.controlleruser import ControllerUser, ControllerSitePrivilege
-from util.logger import observer_logger as logger
-from observer.ansible import *
+from xos.logger import observer_logger as logger
+from synchronizers.base.ansible import *
 import json
 
 class SyncControllerSitePrivileges(OpenStackSyncStep):
diff --git a/xos/openstack_observer/steps/sync_controller_sites.py b/xos/synchronizers/base/steps/sync_controller_sites.py
similarity index 92%
rename from xos/openstack_observer/steps/sync_controller_sites.py
rename to xos/synchronizers/base/steps/sync_controller_sites.py
index 614d435..1b3c2ba 100644
--- a/xos/openstack_observer/steps/sync_controller_sites.py
+++ b/xos/synchronizers/base/steps/sync_controller_sites.py
@@ -2,11 +2,11 @@
 import base64
 from django.db.models import F, Q
 from xos.config import Config
-from openstack_observer.openstacksyncstep import OpenStackSyncStep
+from synchronizers.openstack.openstacksyncstep import OpenStackSyncStep
 from core.models.site import *
-from observer.syncstep import *
-from observer.ansible import *
-from util.logger import observer_logger as logger
+from synchronizers.base.syncstep import *
+from synchronizers.base.ansible import *
+from xos.logger import observer_logger as logger
 import json
 
 class SyncControllerSites(OpenStackSyncStep):
diff --git a/xos/openstack_observer/steps/sync_controller_sites.yaml b/xos/synchronizers/base/steps/sync_controller_sites.yaml
similarity index 100%
rename from xos/openstack_observer/steps/sync_controller_sites.yaml
rename to xos/synchronizers/base/steps/sync_controller_sites.yaml
diff --git a/xos/openstack_observer/steps/sync_controller_slice_privileges.py b/xos/synchronizers/base/steps/sync_controller_slice_privileges.py
similarity index 94%
rename from xos/openstack_observer/steps/sync_controller_slice_privileges.py
rename to xos/synchronizers/base/steps/sync_controller_slice_privileges.py
index 948ea57..b78e4a0 100644
--- a/xos/openstack_observer/steps/sync_controller_slice_privileges.py
+++ b/xos/synchronizers/base/steps/sync_controller_slice_privileges.py
@@ -3,13 +3,13 @@
 from collections import defaultdict
 from django.db.models import F, Q
 from xos.config import Config
-from observer.openstacksyncstep import OpenStackSyncStep
-from observer.syncstep import *
+from synchronizers.base.openstacksyncstep import OpenStackSyncStep
+from synchronizers.base.syncstep import *
 from core.models.slice import Controller, SlicePrivilege 
 from core.models.user import User
 from core.models.controlleruser import ControllerUser, ControllerSlicePrivilege
-from observer.ansible import *
-from util.logger import observer_logger as logger
+from synchronizers.base.ansible import *
+from xos.logger import observer_logger as logger
 import json
 
 class SyncControllerSlicePrivileges(OpenStackSyncStep):
diff --git a/xos/openstack_observer/steps/sync_controller_slices.py b/xos/synchronizers/base/steps/sync_controller_slices.py
similarity index 94%
rename from xos/openstack_observer/steps/sync_controller_slices.py
rename to xos/synchronizers/base/steps/sync_controller_slices.py
index 9904aef..97d8c29 100644
--- a/xos/openstack_observer/steps/sync_controller_slices.py
+++ b/xos/synchronizers/base/steps/sync_controller_slices.py
@@ -4,12 +4,12 @@
 from netaddr import IPAddress, IPNetwork
 from django.db.models import F, Q
 from xos.config import Config
-from observer.openstacksyncstep import OpenStackSyncStep
-from observer.syncstep import *
+from synchronizers.base.openstacksyncstep import OpenStackSyncStep
+from synchronizers.base.syncstep import *
 from core.models import *
-from observer.ansible import *
+from synchronizers.base.ansible import *
 from openstack.driver import OpenStackDriver
-from util.logger import observer_logger as logger
+from xos.logger import observer_logger as logger
 import json
 
 class SyncControllerSlices(OpenStackSyncStep):
diff --git a/xos/synchronizers/base/steps/sync_controller_slices.py.bak b/xos/synchronizers/base/steps/sync_controller_slices.py.bak
new file mode 100644
index 0000000..e04da8e
--- /dev/null
+++ b/xos/synchronizers/base/steps/sync_controller_slices.py.bak
@@ -0,0 +1,95 @@
+import os
+import base64
+from collections import defaultdict
+from netaddr import IPAddress, IPNetwork
+from django.db.models import F, Q
+from xos.config import Config
+from observer.openstacksyncstep import OpenStackSyncStep
+from core.models import *
+from observer.ansible import *
+from openstack.driver import OpenStackDriver
+from util.logger import observer_logger as logger
+import json
+
+class SyncControllerSlices(OpenStackSyncStep):
+    provides=[Slice]
+    requested_interval=0
+    observes=ControllerSlice
+
+    def fetch_pending(self, deleted):
+        if (deleted):
+            return ControllerSlice.deleted_objects.all()
+        else:
+            return ControllerSlice.objects.filter(Q(enacted__lt=F('updated')) | Q(enacted=None))
+
+    def sync_record(self, controller_slice):
+        logger.info("sync'ing slice controller %s" % controller_slice)
+
+	controller_register = json.loads(controller_slice.controller.backend_register)
+	if (controller_register.get('disabled',False)):
+		raise Exception('Controller %s is disabled'%controller_slice.controller.name)
+
+        if not controller_slice.controller.admin_user:
+            logger.info("controller %r has no admin_user, skipping" % controller_slice.controller)
+            return
+
+        controller_users = ControllerUser.objects.filter(user=controller_slice.slice.creator,
+                                                             controller=controller_slice.controller)
+        if not controller_users:
+            raise Exception("slice createor %s has not accout at controller %s" % (controller_slice.slice.creator, controller_slice.controller.name))
+        else:
+            controller_user = controller_users[0]
+            roles = ['Admin']
+
+        max_instances=int(controller_slice.slice.max_slivers)
+        tenant_fields = {'endpoint':controller_slice.controller.auth_url,
+                         'admin_user': controller_slice.controller.admin_user,
+                         'admin_password': controller_slice.controller.admin_password,
+                         'admin_tenant': 'admin',
+                         'tenant': controller_slice.slice.name,
+                         'tenant_description': controller_slice.slice.description,
+                         'roles':roles,
+                         'name':controller_user.user.email,
+                         'ansible_tag':'%s@%s'%(controller_slice.slice.name,controller_slice.controller.name),
+                         'max_instances':max_instances}
+
+        expected_num = len(roles)+1
+        res = run_template('sync_controller_slices.yaml', tenant_fields, path='controller_slices', expected_num=expected_num)
+        tenant_id = res[0]['id']
+        if (not controller_slice.tenant_id):
+            try:
+                    driver = OpenStackDriver().admin_driver(controller=controller_slice.controller)
+                    driver.shell.nova.quotas.update(tenant_id=controller_slice.tenant_id, instances=int(controller_slice.slice.max_slivers))
+            except:
+                    logger.log_exc('Could not update quota for %s'%controller_slice.slice.name)
+                    raise Exception('Could not update quota for %s'%controller_slice.slice.name)
+                
+            controller_slice.tenant_id = tenant_id
+            controller_slice.backend_status = '1 - OK'
+            controller_slice.save()
+
+
+    def delete_record(self, controller_slice):
+        controller_register = json.loads(controller_slice.controller.backend_register)
+ 	if (controller_register.get('disabled',False)):
+ 		raise Exception('Controller %s is disabled'%controller_slice.controller.name)
+ 
+ 	controller_users = ControllerUser.objects.filter(user=controller_slice.slice.creator,
+                                                              controller=controller_slice.controller)
+         if not controller_users:
+             raise Exception("slice createor %s has not accout at controller %s" % (controller_slice.slice.creator, controller_slice.controller.name))
+         else:
+             controller_user = controller_users[0]
+ 
+ 	tenant_fields = {'endpoint':controller_slice.controller.auth_url,
+                          'admin_user': controller_slice.controller.admin_user,
+                          'admin_password': controller_slice.controller.admin_password,
+                          'admin_tenant': 'admin',
+                          'tenant': controller_slice.slice.name,
+                          'tenant_description': controller_slice.slice.description,
+                          'name':controller_user.user.email,
+                          'ansible_tag':'%s@%s'%(controller_slice.slice.name,controller_slice.controller.name),
+ 			 'delete': True}
+ 
+         expected_num = 1
+         res = run_template('sync_controller_slices.yaml', tenant_fields, path='controller_slices', expected_num=expected_num)
diff --git a/xos/openstack_observer/steps/sync_controller_slices.yaml b/xos/synchronizers/base/steps/sync_controller_slices.yaml
similarity index 100%
rename from xos/openstack_observer/steps/sync_controller_slices.yaml
rename to xos/synchronizers/base/steps/sync_controller_slices.yaml
diff --git a/xos/openstack_observer/steps/sync_controller_users.py b/xos/synchronizers/base/steps/sync_controller_users.py
similarity index 93%
rename from xos/openstack_observer/steps/sync_controller_users.py
rename to xos/synchronizers/base/steps/sync_controller_users.py
index 4062453..9af48e5 100644
--- a/xos/openstack_observer/steps/sync_controller_users.py
+++ b/xos/synchronizers/base/steps/sync_controller_users.py
@@ -3,13 +3,13 @@
 from collections import defaultdict
 from django.db.models import F, Q
 from xos.config import Config
-from observer.openstacksyncstep import OpenStackSyncStep
-from observer.syncstep import *
+from synchronizers.base.openstacksyncstep import OpenStackSyncStep
+from synchronizers.base.syncstep import *
 from core.models.site import Controller, SiteDeployment, SiteDeployment
 from core.models.user import User
 from core.models.controlleruser import ControllerUser
-from observer.ansible import *
-from util.logger import observer_logger as logger
+from synchronizers.base.ansible import *
+from xos.logger import observer_logger as logger
 import json
 
 class SyncControllerUsers(OpenStackSyncStep):
diff --git a/xos/openstack_observer/steps/sync_controller_users.yaml b/xos/synchronizers/base/steps/sync_controller_users.yaml
similarity index 100%
rename from xos/openstack_observer/steps/sync_controller_users.yaml
rename to xos/synchronizers/base/steps/sync_controller_users.yaml
diff --git a/xos/openstack_observer/steps/sync_images.py b/xos/synchronizers/base/steps/sync_images.py
similarity index 93%
rename from xos/openstack_observer/steps/sync_images.py
rename to xos/synchronizers/base/steps/sync_images.py
index d126834..8049ac1 100644
--- a/xos/openstack_observer/steps/sync_images.py
+++ b/xos/synchronizers/base/steps/sync_images.py
@@ -2,9 +2,9 @@
 import base64
 from django.db.models import F, Q
 from xos.config import Config
-from observer.openstacksyncstep import OpenStackSyncStep
+from synchronizers.base.openstacksyncstep import OpenStackSyncStep
 from core.models.image import Image
-from util.logger import observer_logger as logger
+from xos.logger import observer_logger as logger
 
 class SyncImages(OpenStackSyncStep):
     provides=[Image]
diff --git a/xos/openstack_observer/steps/sync_instances.py b/xos/synchronizers/base/steps/sync_instances.py
similarity index 96%
rename from xos/openstack_observer/steps/sync_instances.py
rename to xos/synchronizers/base/steps/sync_instances.py
index 815c83e..335ca4a 100644
--- a/xos/openstack_observer/steps/sync_instances.py
+++ b/xos/synchronizers/base/steps/sync_instances.py
@@ -4,13 +4,13 @@
 from django.db.models import F, Q
 from xos.config import Config
 from xos.settings import RESTAPI_HOSTNAME, RESTAPI_PORT
-from observer.openstacksyncstep import OpenStackSyncStep
+from synchronizers.base.openstacksyncstep import OpenStackSyncStep
 from core.models.instance import Instance
 from core.models.slice import Slice, SlicePrivilege, ControllerSlice
 from core.models.network import Network, NetworkSlice, ControllerNetwork
-from observer.ansible import *
-from observer.syncstep import *
-from util.logger import observer_logger as logger
+from synchronizers.base.ansible import *
+from synchronizers.base.syncstep import *
+from xos.logger import observer_logger as logger
 
 def escape(s):
     s = s.replace('\n',r'\n').replace('"',r'\"')
diff --git a/xos/openstack_observer/steps/sync_instances.yaml b/xos/synchronizers/base/steps/sync_instances.yaml
similarity index 100%
rename from xos/openstack_observer/steps/sync_instances.yaml
rename to xos/synchronizers/base/steps/sync_instances.yaml
diff --git a/xos/openstack_observer/steps/sync_object.py b/xos/synchronizers/base/steps/sync_object.py
similarity index 69%
rename from xos/openstack_observer/steps/sync_object.py
rename to xos/synchronizers/base/steps/sync_object.py
index a289c95..a6a939f 100644
--- a/xos/openstack_observer/steps/sync_object.py
+++ b/xos/synchronizers/base/steps/sync_object.py
@@ -3,12 +3,12 @@
 from collections import defaultdict
 from django.db.models import F, Q
 from xos.config import Config
-from observer.openstacksyncstep import OpenStackSyncStep
-from observer.syncstep import *
+from synchronizers.base.openstacksyncstep import OpenStackSyncStep
+from synchronizers.base.syncstep import *
 from core.models import *
-from observer.ansible import *
+from synchronizers.base.ansible import *
 from openstack.driver import OpenStackDriver
-from util.logger import observer_logger as logger
+from xos.logger import observer_logger as logger
 import json
 
 class SyncObject(OpenStackSyncStep):
diff --git a/xos/openstack_observer/steps/sync_ports.py b/xos/synchronizers/base/steps/sync_ports.py
similarity index 98%
rename from xos/openstack_observer/steps/sync_ports.py
rename to xos/synchronizers/base/steps/sync_ports.py
index bfdde8c..21376e5 100644
--- a/xos/openstack_observer/steps/sync_ports.py
+++ b/xos/synchronizers/base/steps/sync_ports.py
@@ -2,10 +2,10 @@
 import base64
 from django.db.models import F, Q
 from xos.config import Config
-from observer.openstacksyncstep import OpenStackSyncStep
+from synchronizers.base.openstacksyncstep import OpenStackSyncStep
 from core.models import Controller
 from core.models.network import *
-from util.logger import observer_logger as logger
+from xos.logger import observer_logger as logger
 
 class SyncPorts(OpenStackSyncStep):
     requested_interval = 0 # 3600
diff --git a/xos/openstack_observer/steps/sync_roles.py b/xos/synchronizers/base/steps/sync_roles.py
similarity index 84%
rename from xos/openstack_observer/steps/sync_roles.py
rename to xos/synchronizers/base/steps/sync_roles.py
index c4bbe3f..e859316 100644
--- a/xos/openstack_observer/steps/sync_roles.py
+++ b/xos/synchronizers/base/steps/sync_roles.py
@@ -2,11 +2,11 @@
 import base64
 from django.db.models import F, Q
 from xos.config import Config
-from observer.openstacksyncstep import OpenStackSyncStep
+from synchronizers.base.openstacksyncstep import OpenStackSyncStep
 from core.models.role import Role
 from core.models.site import SiteRole, Controller, ControllerRole
 from core.models.slice import SliceRole
-from util.logger import observer_logger as logger
+from xos.logger import observer_logger as logger
 
 class SyncRoles(OpenStackSyncStep):
     provides=[Role]
diff --git a/xos/synchronizers/base/steps/sync_slivers.py.bak b/xos/synchronizers/base/steps/sync_slivers.py.bak
new file mode 100644
index 0000000..c4240fa
--- /dev/null
+++ b/xos/synchronizers/base/steps/sync_slivers.py.bak
@@ -0,0 +1,179 @@
+import os
+import base64
+import socket
+from django.db.models import F, Q
+from xos.config import Config
+from xos.settings import RESTAPI_HOSTNAME, RESTAPI_PORT
+from observer.openstacksyncstep import OpenStackSyncStep
+from core.models.sliver import Sliver
+from core.models.slice import Slice, SlicePrivilege, ControllerSlice
+from core.models.network import Network, NetworkSlice, ControllerNetwork
+from observer.ansible import *
+from util.logger import observer_logger as logger
+
+def escape(s):
+    s = s.replace('\n',r'\n').replace('"',r'\"')
+    return s
+
+class SyncSlivers(OpenStackSyncStep):
+    provides=[Sliver]
+    requested_interval=0
+    observes=Sliver
+
+    def get_userdata(self, sliver, pubkeys):
+        userdata = '#cloud-config\n\nopencloud:\n   slicename: "%s"\n   hostname: "%s"\n   restapi_hostname: "%s"\n   restapi_port: "%s"\n' % (sliver.slice.name, sliver.node.name, RESTAPI_HOSTNAME, str(RESTAPI_PORT))
+        userdata += 'ssh_authorized_keys:\n'
+        for key in pubkeys:
+            userdata += '  - %s\n' % key
+        return userdata
+
+    def sync_record(self, sliver):
+        logger.info("sync'ing sliver:%s slice:%s controller:%s " % (sliver, sliver.slice.name, sliver.node.site_deployment.controller))
+    	controller_register = json.loads(sliver.node.site_deployment.controller.backend_register)
+ 
+        if (controller_register.get('disabled',False)):
+                raise Exception('Controller %s is disabled'%sliver.node.site_deployment.controller.name)
+
+        metadata_update = {}
+        if (sliver.numberCores):
+            metadata_update["cpu_cores"] = str(sliver.numberCores)
+
+        for tag in sliver.slice.tags.all():
+            if tag.name.startswith("sysctl-"):
+                metadata_update[tag.name] = tag.value
+
+        # public keys
+        slice_memberships = SlicePrivilege.objects.filter(slice=sliver.slice)
+        pubkeys = set([sm.user.public_key for sm in slice_memberships if sm.user.public_key])
+        if sliver.creator.public_key:
+            pubkeys.add(sliver.creator.public_key)
+
+        if sliver.slice.creator.public_key:
+            pubkeys.add(sliver.slice.creator.public_key)
+
+        if sliver.slice.service and sliver.slice.service.public_key:
+            pubkeys.add(sliver.slice.service.public_key)
+
+        if sliver.slice.service and sliver.slice.service.public_key:
+            pubkeys.add(sliver.slice.service.public_key)
+
+        nics = []
+        networks = [ns.network for ns in NetworkSlice.objects.filter(slice=sliver.slice)]
+        controller_networks = ControllerNetwork.objects.filter(network__in=networks,
+                                                                controller=sliver.node.site_deployment.controller)
+
+        for controller_network in controller_networks:
+            if controller_network.network.template.visibility == 'private' and \
+               controller_network.network.template.translation == 'none':
+                   if not controller_network.net_id:
+                        raise Exception("Private Network %s has no id; Try again later" % controller_network.network.name)
+                   nics.append(controller_network.net_id)
+
+        # now include network template
+        network_templates = [network.template.shared_network_name for network in networks \
+                             if network.template.shared_network_name]
+
+        #driver = self.driver.client_driver(caller=sliver.creator, tenant=sliver.slice.name, controller=sliver.controllerNetwork)
+        driver = self.driver.admin_driver(tenant='admin', controller=sliver.node.site_deployment.controller)
+        nets = driver.shell.quantum.list_networks()['networks']
+        for net in nets:
+            if net['name'] in network_templates:
+                nics.append(net['id'])
+
+        if (not nics):
+            for net in nets:
+                if net['name']=='public':
+                    nics.append(net['id'])
+
+        image_id = None
+        controller_images = sliver.image.controllerimages.filter(controller=sliver.node.site_deployment.controller)
+        if controller_images:
+            image_id = controller_images[0].glance_image_id
+            logger.info("using image_id from ControllerImage object: " + str(image_id))
+
+        if image_id is None:
+            controller_driver = self.driver.admin_driver(controller=sliver.node.site_deployment.controller)
+            image_id = None
+            images = controller_driver.shell.glanceclient.images.list()
+            for image in images:
+                if image.name == sliver.image.name or not image_id:
+                    image_id = image.id
+                    logger.info("using image_id from glance: " + str(image_id))
+
+        try:
+            legacy = Config().observer_legacy
+        except:
+            legacy = False
+
+        if (legacy):
+            host_filter = sliver.node.name.split('.',1)[0]
+        else:
+            host_filter = sliver.node.name.strip()
+
+        availability_zone_filter = 'nova:%s'%host_filter
+        sliver_name = '%s-%d'%(sliver.slice.name,sliver.id)
+
+        userData = self.get_userdata(sliver, pubkeys)
+        if sliver.userData:
+            userData = sliver.userData
+
+        controller = sliver.node.site_deployment.controller
+        tenant_fields = {'endpoint':controller.auth_url,
+                     'admin_user': sliver.creator.email,
+                     'admin_password': sliver.creator.remote_password,
+                     'admin_tenant': sliver.slice.name,
+                     'tenant': sliver.slice.name,
+                     'tenant_description': sliver.slice.description,
+                     'name':sliver_name,
+                     'ansible_tag':sliver_name,
+                     'availability_zone': availability_zone_filter,
+                     'image_id':image_id,
+                     'flavor_id':sliver.flavor.id,
+                     'nics':nics,
+                     'meta':metadata_update,
+                     'user_data':r'%s'%escape(userData)}
+
+        res = run_template('sync_slivers.yaml', tenant_fields,path='slivers', expected_num=1)
+        sliver_id = res[0]['info']['OS-EXT-SRV-ATTR:instance_name']
+        sliver_uuid = res[0]['id']
+
+        try:
+            hostname = res[0]['info']['OS-EXT-SRV-ATTR:hypervisor_hostname']
+            ip = socket.gethostbyname(hostname)
+            sliver.ip = ip
+        except:
+            pass
+
+        sliver.instance_id = sliver_id
+        sliver.instance_uuid = sliver_uuid
+        sliver.instance_name = sliver_name
+        sliver.save()
+
+    def delete_record(self, sliver):
+	controller_register = json.loads(sliver.node.site_deployment.controller.backend_register)
+
+        if (controller_register.get('disabled',False)):
+                raise Exception('Controller %s is disabled'%sliver.node.site_deployment.controller.name)
+
+        sliver_name = '%s-%d'%(sliver.slice.name,sliver.id)
+        controller = sliver.node.site_deployment.controller
+        tenant_fields = {'endpoint':controller.auth_url,
+                     'admin_user': sliver.creator.email,
+                     'admin_password': sliver.creator.remote_password,
+                     'admin_tenant': sliver.slice.name,
+                     'tenant': sliver.slice.name,
+                     'tenant_description': sliver.slice.description,
+                     'name':sliver_name,
+                     'ansible_tag':sliver_name,
+                     'delete': True}
+
+        try:
+               res = run_template('sync_slivers.yaml', tenant_fields,path='slivers', expected_num=1)

+        except Exception,e:

+               print "Could not sync %s"%sliver_name

+               #import traceback

+               #traceback.print_exc()

+               raise e

+
+        if (len(res)!=1):
+            raise Exception('Could not delete sliver %s'%sliver.slice.name)
diff --git a/xos/openstack_observer/steps/teardown_container.yaml b/xos/synchronizers/base/steps/teardown_container.yaml
similarity index 100%
rename from xos/openstack_observer/steps/teardown_container.yaml
rename to xos/synchronizers/base/steps/teardown_container.yaml
diff --git a/xos/synchronizers/base/syncstep-portal.py b/xos/synchronizers/base/syncstep-portal.py
new file mode 100644
index 0000000..66ec1af
--- /dev/null
+++ b/xos/synchronizers/base/syncstep-portal.py
@@ -0,0 +1,221 @@
+import os
+import base64
+from datetime import datetime
+from xos.config import Config
+from xos.logger import Logger, logging
+from synchronizers.base.steps import *
+from django.db.models import F, Q
+from core.models import * 
+from django.db import reset_queries
+import json
+import time
+import pdb
+import traceback
+
+logger = Logger(level=logging.INFO)
+
+def f7(seq):
+    seen = set()
+    seen_add = seen.add
+    return [ x for x in seq if not (x in seen or seen_add(x))]
+
+def elim_dups(backend_str):
+    strs = backend_str.split('/')
+    strs = map(lambda x:x.split('(')[0],strs) 
+    strs2 = f7(strs)
+    return '/'.join(strs2)
+    
+def deepgetattr(obj, attr):
+    return reduce(getattr, attr.split('.'), obj)
+
+
+class InnocuousException(Exception):
+    pass
+
+class FailedDependency(Exception):
+    pass
+
+class SyncStep(object):
+    """ An XOS Sync step. 
+
+    Attributes:
+        psmodel        Model name the step synchronizes 
+        dependencies    list of names of models that must be synchronized first if the current model depends on them
+    """ 
+    slow=False
+    def get_prop(prop):
+        try:
+            sync_config_dir = Config().sync_config_dir
+        except:
+            sync_config_dir = '/etc/xos/sync'
+        prop_config_path = '/'.join(sync_config_dir,self.name,prop)
+        return open(prop_config_path).read().rstrip()
+
+    def __init__(self, **args):
+        """Initialize a sync step
+           Keyword arguments:
+                   name -- Name of the step
+                provides -- XOS models sync'd by this step
+        """
+        dependencies = []
+        self.driver = args.get('driver')
+        self.error_map = args.get('error_map')
+
+        try:
+            self.soft_deadline = int(self.get_prop('soft_deadline_seconds'))
+        except:
+            self.soft_deadline = 5 # 5 seconds
+
+        return
+
+    def fetch_pending(self, deletion=False):
+        # This is the most common implementation of fetch_pending
+        # Steps should override it if they have their own logic
+        # for figuring out what objects are outstanding.
+        main_obj = self.observes
+        if (not deletion):
+            objs = main_obj.objects.filter(Q(enacted__lt=F('updated')) | Q(enacted=None),Q(lazy_blocked=False))
+        else:
+            objs = main_obj.deleted_objects.all()
+
+        return objs
+        #return Sliver.objects.filter(ip=None)
+    
+    def check_dependencies(self, obj, failed):
+        for dep in self.dependencies:
+            peer_name = dep[0].lower() + dep[1:]    # django names are camelCased with the first letter lower
+ 
+            try:
+                peer_object = deepgetattr(obj, peer_name)
+                try: 
+                    peer_objects = peer_object.all() 
+                except AttributeError:
+                    peer_objects = [peer_object] 
+            except:
+                peer_objects = []
+
+            if (hasattr(obj,'controller')):
+                try:
+                	peer_objects = filter(lambda o:o.controller==obj.controller, peer_objects)
+                except AttributeError:
+                        pass
+
+            if (failed in peer_objects):
+                if (obj.backend_status!=failed.backend_status):
+                    obj.backend_status = failed.backend_status
+                    obj.save(update_fields=['backend_status'])
+                raise FailedDependency("Failed dependency for %s:%s peer %s:%s failed  %s:%s" % (obj.__class__.__name__, str(getattr(obj,"pk","no_pk")), peer_object.__class__.__name__, str(getattr(peer_object,"pk","no_pk")), failed.__class__.__name__, str(getattr(failed,"pk","no_pk"))))
+
+    def call(self, failed=[], deletion=False):
+        pending = self.fetch_pending(deletion)
+        for o in pending:
+            # another spot to clean up debug state
+            try:
+                reset_queries()
+            except:
+                # this shouldn't happen, but in case it does, catch it...
+                logger.log_exc("exception in reset_queries")
+
+            sync_failed = False
+            try:
+                backoff_disabled = Config().observer_backoff_disabled
+            except:
+                backoff_disabled = 0
+
+            try:
+                scratchpad = json.loads(o.backend_register)
+                if (scratchpad):
+                    next_run = scratchpad['next_run']
+                    if (not backoff_disabled and next_run>time.time()):
+                        sync_failed = True
+            except:
+                logger.log_exc("Exception while loading scratchpad")
+                pass
+
+            if (not sync_failed):
+                try:
+                    for f in failed:
+                        self.check_dependencies(o,f) # Raises exception if failed
+                    if (deletion):
+                        self.delete_record(o)
+                        o.delete(purge=True)
+                    else:
+                        self.sync_record(o)
+                        o.enacted = datetime.now() # Is this the same timezone? XXX
+                        scratchpad = {'next_run':0, 'exponent':0}
+                        o.backend_register = json.dumps(scratchpad)
+                        o.backend_status = "1 - OK"
+                        o.save(update_fields=['enacted','backend_status','backend_register'])
+		except (InnocuousException,Exception) as e:
+                    logger.log_exc("Syncstep caught exception")
+
+                    force_error = False
+                    try:
+                        if (o.backend_status.startswith('2 - ')):
+                            force_error = False # Already in error state
+                            str_e = '%s/%s'%(o.backend_status[4:],str(e))
+			    str_e = elim_dups(str_e)
+                        else:
+                            str_e = str(e)
+                    except:
+                        str_e = str(e)
+
+                    if (not str_e):
+                        str_e = 'Unknown'
+
+                    try:
+                        error = self.error_map.map(str_e)
+                    except:
+                        error = str_e
+
+                    if isinstance(e, InnocuousException) and not force_error:
+ 		    	o.backend_status = '1 - %s'%error
+		    else:	
+ 		    	o.backend_status = '2 - %s'%error 
+
+                    cmd = 'wget -O /dev/null -q "http://xoslnprof.appspot.com/command?action=pushlog&node=1&log_path=/%s/%s"'%(self.__class__.__name__,error)
+		    os.system(cmd)	
+                     
+                    try:
+                        scratchpad = json.loads(o.backend_register)
+                        scratchpad['exponent']
+                    except:
+                        logger.log_exc("Exception while updating scratchpad")
+                        scratchpad = {'next_run':0, 'exponent':0}
+
+                    # Second failure
+                    if (scratchpad['exponent']):
+                        delay = scratchpad['exponent'] * 600 # 10 minutes
+                        if (delay<1440):
+                            delay = 1440
+                        scratchpad['next_run'] = time.time() + delay
+
+                    scratchpad['exponent']+=1
+
+                    o.backend_register = json.dumps(scratchpad)
+
+                    # TOFIX:
+                    # DatabaseError: value too long for type character varying(140)
+                    if (o.pk):
+                        try:
+                            o.backend_status = o.backend_status[:1024]
+                            o.save(update_fields=['backend_status','backend_register','updated'])
+                        except:
+                            print "Could not update backend status field!"
+                            pass
+                    sync_failed = True
+
+
+            if (sync_failed):
+                failed.append(o)
+
+        return failed
+
+    def sync_record(self, o):
+        return
+
+    def delete_record(self, o):
+        return
+
+    def __call__(self, **args):
+        return self.call(**args)
\ No newline at end of file
diff --git a/xos/openstack_observer/syncstep.py b/xos/synchronizers/base/syncstep.py
similarity index 98%
rename from xos/openstack_observer/syncstep.py
rename to xos/synchronizers/base/syncstep.py
index 0a25c58..bdab8f3 100644
--- a/xos/openstack_observer/syncstep.py
+++ b/xos/synchronizers/base/syncstep.py
@@ -2,13 +2,13 @@
 import base64
 from datetime import datetime
 from xos.config import Config
-from util.logger import Logger, logging
-from observer.steps import *
+from xos.logger import Logger, logging
+from synchronizers.base.steps import *
 from django.db.models import F, Q
 from core.models import *
 from django.db import reset_queries
-from observer.ansible import *
-from dependency_walker import *
+from synchronizers.base.ansible import *
+from generate.dependency_walker import *
 
 from time import time
 import json
diff --git a/xos/synchronizers/base/syncstep.py.bak b/xos/synchronizers/base/syncstep.py.bak
new file mode 100644
index 0000000..a1f242b
--- /dev/null
+++ b/xos/synchronizers/base/syncstep.py.bak
@@ -0,0 +1,203 @@
+import os
+import base64
+from datetime import datetime
+from xos.config import Config
+from util.logger import Logger, logging
+from observer.steps import *
+from django.db.models import F, Q
+from core.models import * 
+import json
+import time
+import pdb
+import traceback
+
+logger = Logger(level=logging.INFO)
+
+def f7(seq):
+    seen = set()
+    seen_add = seen.add
+    return [ x for x in seq if not (x in seen or seen_add(x))]
+
+def elim_dups(backend_str):
+    strs = backend_str.split(' // ')
+    strs2 = f7(strs)
+    return ' // '.join(strs2)
+    
+def deepgetattr(obj, attr):
+    return reduce(getattr, attr.split('.'), obj)
+
+
+class InnocuousException(Exception):
+    pass
+
+class FailedDependency(Exception):
+    pass
+
+class SyncStep(object):
+    """ An XOS Sync step. 
+
+    Attributes:
+        psmodel        Model name the step synchronizes 
+        dependencies    list of names of models that must be synchronized first if the current model depends on them
+    """ 
+    slow=False
+    def get_prop(self, prop):
+        try:
+            sync_config_dir = Config().sync_config_dir
+        except:
+            sync_config_dir = '/etc/xos/sync'
+        prop_config_path = '/'.join(sync_config_dir,self.name,prop)
+        return open(prop_config_path).read().rstrip()
+
+    def __init__(self, **args):
+        """Initialize a sync step
+           Keyword arguments:
+                   name -- Name of the step
+                provides -- XOS models sync'd by this step
+        """
+        dependencies = []
+        self.driver = args.get('driver')
+        self.error_map = args.get('error_map')
+
+        try:
+            self.soft_deadline = int(self.get_prop('soft_deadline_seconds'))
+        except:
+            self.soft_deadline = 5 # 5 seconds
+
+        return
+
+    def fetch_pending(self, deletion=False):
+        # This is the most common implementation of fetch_pending
+        # Steps should override it if they have their own logic
+        # for figuring out what objects are outstanding.
+        main_obj = self.observes
+        if (not deletion):
+            objs = main_obj.objects.filter(Q(enacted__lt=F('updated')) | Q(enacted=None),Q(lazy_blocked=False))
+        else:
+            objs = main_obj.deleted_objects.all()
+
+        return objs
+        #return Sliver.objects.filter(ip=None)
+    
+    def check_dependencies(self, obj, failed):
+        for dep in self.dependencies:
+            peer_name = dep[0].lower() + dep[1:]    # django names are camelCased with the first letter lower
+ 
+            try:
+                peer_object = deepgetattr(obj, peer_name)
+                try: 
+                    peer_objects = peer_object.all() 
+                except AttributeError:
+                    peer_objects = [peer_object] 
+            except:
+                peer_objects = []
+
+            if (hasattr(obj,'controller')):
+                try:
+                	peer_objects = filter(lambda o:o.controller==obj.controller, peer_objects)
+                except AttributeError:
+                        pass
+
+            if (failed in peer_objects):
+                if (obj.backend_status!=failed.backend_status):
+                    obj.backend_status = failed.backend_status
+                    obj.save(update_fields=['backend_status'])
+                raise FailedDependency("Failed dependency for %s:%s peer %s:%s failed  %s:%s" % (obj.__class__.__name__, str(getattr(obj,"pk","no_pk")), peer_object.__class__.__name__, str(getattr(peer_object,"pk","no_pk")), failed.__class__.__name__, str(getattr(failed,"pk","no_pk"))))
+
+    def call(self, failed=[], deletion=False):
+        pending = self.fetch_pending(deletion)
+        for o in pending:
+            sync_failed = False
+            try:
+                backoff_disabled = Config().observer_backoff_disabled
+            except:
+                backoff_disabled = 0
+
+            try:
+                scratchpad = json.loads(o.backend_register)
+                if (scratchpad):
+                    next_run = scratchpad['next_run']
+                    if (not backoff_disabled and next_run>time.time()):
+                        sync_failed = True
+            except:
+                logger.log_exc("Exception while loading scratchpad")
+                pass
+
+            if (not sync_failed):
+                try:
+                    for f in failed:
+                        self.check_dependencies(o,f) # Raises exception if failed
+                    if (deletion):
+                        self.delete_record(o)
+                        o.delete(purge=True)
+                    else:
+                        self.sync_record(o)
+                        o.enacted = datetime.now() # Is this the same timezone? XXX
+                        scratchpad = {'next_run':0, 'exponent':0}
+                        o.backend_register = json.dumps(scratchpad)
+                        o.backend_status = "1 - OK"
+                        o.save(update_fields=['enacted','backend_status','backend_register'])
+                except (InnocuousException,Exception) as e:
+                    logger.log_exc("sync step failed!")
+                    try:
+                        if (o.backend_status.startswith('2 - ')):
+                            str_e = '%s // %r'%(o.backend_status[4:],e)
+			    str_e = elim_dups(str_e)
+                        else:
+                            str_e = '%r'%e
+                    except:
+                        str_e = '%r'%e
+
+                    try:
+                        error = self.error_map.map(str_e)
+                    except:
+                        error = '2 - %s'%str_e
+
+                    if isinstance(e, InnocuousException) and not force_error:
+                        o.backend_status = '1 - %s'%error
+                    else:
+                        o.backend_status = '3 - %s'%error
+
+                    try:
+                        scratchpad = json.loads(o.backend_register)
+                        scratchpad['exponent']
+                    except:
+                        logger.log_exc("Exception while updating scratchpad")
+                        scratchpad = {'next_run':0, 'exponent':0}
+
+                    # Second failure
+                    if (scratchpad['exponent']):
+                        delay = scratchpad['exponent'] * 600 # 10 minutes
+                        if (delay<1440):
+                            delay = 1440
+                        scratchpad['next_run'] = time.time() + delay
+
+                    scratchpad['exponent']+=1
+
+                    o.backend_register = json.dumps(scratchpad)
+
+                    # TOFIX:
+                    # DatabaseError: value too long for type character varying(140)
+                    if (o.pk):
+                        try:
+                            o.backend_status = o.backend_status[:1024]
+                            o.save(update_fields=['backend_status','backend_register','updated'])
+                        except:
+                            print "Could not update backend status field!"
+                            pass
+                    sync_failed = True
+
+
+            if (sync_failed):
+                failed.append(o)
+
+        return failed
+
+    def sync_record(self, o):
+        return
+
+    def delete_record(self, o):
+        return
+
+    def __call__(self, **args):
+        return self.call(**args)
diff --git a/xos/openstack_observer/templates/container.conf.j2 b/xos/synchronizers/base/templates/container.conf.j2
similarity index 100%
rename from xos/openstack_observer/templates/container.conf.j2
rename to xos/synchronizers/base/templates/container.conf.j2
diff --git a/xos/openstack_observer/templates/container.service.j2 b/xos/synchronizers/base/templates/container.service.j2
similarity index 100%
rename from xos/openstack_observer/templates/container.service.j2
rename to xos/synchronizers/base/templates/container.service.j2
diff --git a/xos/openstack_observer/templates/start-container.sh.j2 b/xos/synchronizers/base/templates/start-container.sh.j2
similarity index 100%
rename from xos/openstack_observer/templates/start-container.sh.j2
rename to xos/synchronizers/base/templates/start-container.sh.j2
diff --git a/xos/openstack_observer/templates/stop-container.sh.j2 b/xos/synchronizers/base/templates/stop-container.sh.j2
similarity index 100%
rename from xos/openstack_observer/templates/stop-container.sh.j2
rename to xos/synchronizers/base/templates/stop-container.sh.j2
diff --git a/xos/openstack_observer/toposort.py b/xos/synchronizers/base/toposort.py
similarity index 100%
rename from xos/openstack_observer/toposort.py
rename to xos/synchronizers/base/toposort.py
diff --git a/xos/xos-observer.py b/xos/synchronizers/base/xos-synchronizer.py
similarity index 75%
rename from xos/xos-observer.py
rename to xos/synchronizers/base/xos-synchronizer.py
index b85b29b..3fffd33 100644
--- a/xos/xos-observer.py
+++ b/xos/synchronizers/base/xos-synchronizer.py
@@ -1,9 +1,17 @@
 #!/usr/bin/env python
 import os
 import argparse
+import sys
+
+sys.path.append('/opt/xos')
+
 os.environ.setdefault("DJANGO_SETTINGS_MODULE", "xos.settings")
-from observer.backend import Backend
+from synchronizers.base.backend import Backend
 from xos.config import Config, DEFAULT_CONFIG_FN
+from core.models import Instance
+from xos.logger import Logger, logging, logger
+from django.db import ProgrammingError
+import time
 
 try:
     from django import setup as django_setup # django 1.7
@@ -54,6 +62,18 @@
     if django_setup: # 1.7
         django_setup()
 
+    models_active = False
+    wait = False
+    while not models_active:
+        try:
+            _ = Instance.objects.first()
+            models_active = True
+        except ProgrammingError:
+            logger.info('Waiting for data model to come up before starting...')
+            wait = True
+
+    if (wait):
+        time.sleep(60) # Safety factor, seeing that we stumbled waiting for the data model to come up.
     backend = Backend()
     backend.run()    
 
diff --git a/xos/ec2_observer/__init__.py b/xos/synchronizers/ec2/__init__.py
similarity index 100%
rename from xos/ec2_observer/__init__.py
rename to xos/synchronizers/ec2/__init__.py
diff --git a/xos/ec2_observer/aws_lib.py b/xos/synchronizers/ec2/aws_lib.py
similarity index 100%
rename from xos/ec2_observer/aws_lib.py
rename to xos/synchronizers/ec2/aws_lib.py
diff --git a/xos/ec2_observer/awslib.py b/xos/synchronizers/ec2/awslib.py
similarity index 100%
rename from xos/ec2_observer/awslib.py
rename to xos/synchronizers/ec2/awslib.py
diff --git a/xos/ec2_observer/backend.py b/xos/synchronizers/ec2/backend.py
similarity index 93%
rename from xos/ec2_observer/backend.py
rename to xos/synchronizers/ec2/backend.py
index 1a2545d..7288e61 100644
--- a/xos/ec2_observer/backend.py
+++ b/xos/synchronizers/ec2/backend.py
@@ -2,7 +2,7 @@
 import time
 from ec2_observer.event_loop import XOSObserver
 from ec2_observer.event_manager import EventListener
-from util.logger import Logger, logging
+from xos.logger import Logger, logging
 
 logger = Logger(level=logging.INFO)
 
diff --git a/xos/ec2_observer/creds.py b/xos/synchronizers/ec2/creds.py
similarity index 100%
rename from xos/ec2_observer/creds.py
rename to xos/synchronizers/ec2/creds.py
diff --git a/xos/ec2_observer/deleter.py b/xos/synchronizers/ec2/deleter.py
similarity index 100%
copy from xos/ec2_observer/deleter.py
copy to xos/synchronizers/ec2/deleter.py
diff --git a/xos/ec2_observer/deleters/__init__.py b/xos/synchronizers/ec2/deleters/__init__.py
similarity index 100%
rename from xos/ec2_observer/deleters/__init__.py
rename to xos/synchronizers/ec2/deleters/__init__.py
diff --git a/xos/ec2_observer/deleters/instance_deleter.py b/xos/synchronizers/ec2/deleters/instance_deleter.py
similarity index 91%
rename from xos/ec2_observer/deleters/instance_deleter.py
rename to xos/synchronizers/ec2/deleters/instance_deleter.py
index 60f9e47..ba454e7 100644
--- a/xos/ec2_observer/deleters/instance_deleter.py
+++ b/xos/synchronizers/ec2/deleters/instance_deleter.py
@@ -1,5 +1,5 @@
 from core.models import Instance, SliceDeployments
-from observer.deleter import Deleter
+from synchronizers.base.deleter import Deleter
 
 class InstanceDeleter(Deleter):
     model='Instance'
diff --git a/xos/ec2_observer/deleters/network_deleter.py b/xos/synchronizers/ec2/deleters/network_deleter.py
similarity index 76%
rename from xos/ec2_observer/deleters/network_deleter.py
rename to xos/synchronizers/ec2/deleters/network_deleter.py
index 0d21fda..aa9ef59 100644
--- a/xos/ec2_observer/deleters/network_deleter.py
+++ b/xos/synchronizers/ec2/deleters/network_deleter.py
@@ -1,7 +1,7 @@
 from core.models import Network, NetworkDeployments
-from observer.deleter import Deleter
-from observer.deleters.network_deployment_deleter import NetworkDeploymentDeleter
-from util.logger import Logger, logging
+from synchronizers.base.deleter import Deleter
+from synchronizers.base.deleters.network_deployment_deleter import NetworkDeploymentDeleter
+from xos.logger import Logger, logging
 
 logger = Logger(level=logging.INFO)
 
diff --git a/xos/ec2_observer/deleters/network_deployment_deleter.py b/xos/synchronizers/ec2/deleters/network_deployment_deleter.py
similarity index 95%
rename from xos/ec2_observer/deleters/network_deployment_deleter.py
rename to xos/synchronizers/ec2/deleters/network_deployment_deleter.py
index 72b10b2..f8aaa29 100644
--- a/xos/ec2_observer/deleters/network_deployment_deleter.py
+++ b/xos/synchronizers/ec2/deleters/network_deployment_deleter.py
@@ -1,5 +1,5 @@
 from core.models import Network, NetworkDeployments
-from observer.deleter import Deleter
+from synchronizers.base.deleter import Deleter
 from openstack.driver import OpenStackDriver
 
 class NetworkDeploymentDeleter(Deleter):
diff --git a/xos/ec2_observer/deleters/network_instance_deleter.py b/xos/synchronizers/ec2/deleters/network_instance_deleter.py
similarity index 85%
rename from xos/ec2_observer/deleters/network_instance_deleter.py
rename to xos/synchronizers/ec2/deleters/network_instance_deleter.py
index 8a8f516..21fe87f 100644
--- a/xos/ec2_observer/deleters/network_instance_deleter.py
+++ b/xos/synchronizers/ec2/deleters/network_instance_deleter.py
@@ -1,5 +1,5 @@
 from core.models import NetworkInstance
-from observer.deleter import Deleter
+from synchronizers.base.deleter import Deleter
 
 class NetworkInstanceDeleter(Deleter):
     model='NetworkInstance'
diff --git a/xos/ec2_observer/deleters/site_deleter.py b/xos/synchronizers/ec2/deleters/site_deleter.py
similarity index 75%
rename from xos/ec2_observer/deleters/site_deleter.py
rename to xos/synchronizers/ec2/deleters/site_deleter.py
index 88a4008..832baf9 100644
--- a/xos/ec2_observer/deleters/site_deleter.py
+++ b/xos/synchronizers/ec2/deleters/site_deleter.py
@@ -1,6 +1,6 @@
 from core.models import Site, SiteDeployment
-from observer.deleter import Deleter
-from observer.deleters.site_deployment_deleter import SiteDeploymentDeleter
+from synchronizers.base.deleter import Deleter
+from synchronizers.base.deleters.site_deployment_deleter import SiteDeploymentDeleter
 
 class SiteDeleter(Deleter):
     model='Site'
diff --git a/xos/ec2_observer/deleters/site_deployment_deleter.py b/xos/synchronizers/ec2/deleters/site_deployment_deleter.py
similarity index 89%
rename from xos/ec2_observer/deleters/site_deployment_deleter.py
rename to xos/synchronizers/ec2/deleters/site_deployment_deleter.py
index db344cd..794b438 100644
--- a/xos/ec2_observer/deleters/site_deployment_deleter.py
+++ b/xos/synchronizers/ec2/deleters/site_deployment_deleter.py
@@ -1,5 +1,5 @@
 from core.models import Site, SiteDeployment
-from observer.deleter import Deleter
+from synchronizers.base.deleter import Deleter
 
 class SiteDeploymentDeleter(Deleter):
     model='SiteDeployment'
diff --git a/xos/ec2_observer/deleters/slice_deleter.py b/xos/synchronizers/ec2/deleters/slice_deleter.py
similarity index 75%
rename from xos/ec2_observer/deleters/slice_deleter.py
rename to xos/synchronizers/ec2/deleters/slice_deleter.py
index 7e9dfd4..49bf692 100644
--- a/xos/ec2_observer/deleters/slice_deleter.py
+++ b/xos/synchronizers/ec2/deleters/slice_deleter.py
@@ -1,7 +1,7 @@
 from core.models import Slice, SliceDeployments, User
-from observer.deleter import Deleter
-from observer.deleters.slice_deployment_deleter import SliceDeploymentsDeleter
-from util.logger import Logger, logging
+from synchronizers.base.deleter import Deleter
+from synchronizers.base.deleters.slice_deployment_deleter import SliceDeploymentsDeleter
+from xos.logger import Logger, logging
 
 logger = Logger(level=logging.INFO)
 
diff --git a/xos/ec2_observer/deleters/slice_deployment_deleter.py b/xos/synchronizers/ec2/deleters/slice_deployment_deleter.py
similarity index 96%
rename from xos/ec2_observer/deleters/slice_deployment_deleter.py
rename to xos/synchronizers/ec2/deleters/slice_deployment_deleter.py
index 6f1aec0..39c557a 100644
--- a/xos/ec2_observer/deleters/slice_deployment_deleter.py
+++ b/xos/synchronizers/ec2/deleters/slice_deployment_deleter.py
@@ -1,5 +1,5 @@
 from core.models import Slice, SliceDeployments, User
-from observer.deleter import Deleter
+from synchronizers.base.deleter import Deleter
 from openstack.driver import OpenStackDriver
 
 class SliceDeploymentsDeleter(Deleter):
diff --git a/xos/ec2_observer/deleters/user_deleter.py b/xos/synchronizers/ec2/deleters/user_deleter.py
similarity index 73%
rename from xos/ec2_observer/deleters/user_deleter.py
rename to xos/synchronizers/ec2/deleters/user_deleter.py
index 3930eb0..12c8224 100644
--- a/xos/ec2_observer/deleters/user_deleter.py
+++ b/xos/synchronizers/ec2/deleters/user_deleter.py
@@ -1,6 +1,6 @@
 from core.models import User, UserDeployments
-from observer.deleter import Deleter
-from observer.deleters.user_deployment_deleter import UserDeploymentsDeleter
+from synchronizers.base.deleter import Deleter
+from synchronizers.base.deleters.user_deployment_deleter import UserDeploymentsDeleter
 
 class UserDeleter(Deleter):
     model='User'
diff --git a/xos/ec2_observer/deleters/user_deployment_deleter.py b/xos/synchronizers/ec2/deleters/user_deployment_deleter.py
similarity index 89%
rename from xos/ec2_observer/deleters/user_deployment_deleter.py
rename to xos/synchronizers/ec2/deleters/user_deployment_deleter.py
index 4bc7619..3b6113b 100644
--- a/xos/ec2_observer/deleters/user_deployment_deleter.py
+++ b/xos/synchronizers/ec2/deleters/user_deployment_deleter.py
@@ -1,5 +1,5 @@
 from core.models import User, UserDeployments
-from observer.deleter import Deleter
+from synchronizers.base.deleter import Deleter
 
 class UserDeploymentsDeleter(Deleter):
     model='UserDeployments'
diff --git a/xos/ec2_observer/dmdot b/xos/synchronizers/ec2/dmdot
similarity index 100%
rename from xos/ec2_observer/dmdot
rename to xos/synchronizers/ec2/dmdot
diff --git a/xos/ec2_observer/ec2_backend.py b/xos/synchronizers/ec2/ec2_backend.py
similarity index 94%
rename from xos/ec2_observer/ec2_backend.py
rename to xos/synchronizers/ec2/ec2_backend.py
index a26ddfd..7edf63c 100644
--- a/xos/ec2_observer/ec2_backend.py
+++ b/xos/synchronizers/ec2/ec2_backend.py
@@ -2,7 +2,7 @@
 import time
 from ec2_observer.event_loop import XOSObserver
 from ec2_observer.event_manager import EventListener
-from util.logger import Logger, logging
+from xos.logger import Logger, logging
 
 logger = Logger(level=logging.INFO)
 
diff --git a/xos/ec2_observer/error_mapper.py b/xos/synchronizers/ec2/error_mapper.py
similarity index 90%
copy from xos/ec2_observer/error_mapper.py
copy to xos/synchronizers/ec2/error_mapper.py
index 3039a56..9eb878d 100644
--- a/xos/ec2_observer/error_mapper.py
+++ b/xos/synchronizers/ec2/error_mapper.py
@@ -1,5 +1,5 @@
 from xos.config import Config
-from util.logger import Logger, logging, logger
+from xos.logger import Logger, logging, logger
 
 class ErrorMapper:
 	def __init__(self, error_map_file):
diff --git a/xos/ec2_observer/event_loop.py b/xos/synchronizers/ec2/event_loop.py
similarity index 98%
rename from xos/ec2_observer/event_loop.py
rename to xos/synchronizers/ec2/event_loop.py
index fb91ee8..cfeb212 100644
--- a/xos/ec2_observer/event_loop.py
+++ b/xos/synchronizers/ec2/event_loop.py
@@ -14,13 +14,13 @@
 from django.db.models import F, Q
 #from openstack.manager import OpenStackManager
 from openstack.driver import OpenStackDriver
-from util.logger import Logger, logging, logger
+from xos.logger import Logger, logging, logger
 #from timeout import timeout
 from xos.config import Config, XOS_DIR
-from observer.steps import *
+from synchronizers.base.steps import *
 from syncstep import SyncStep
 from toposort import toposort
-from observer.error_mapper import *
+from synchronizers.base.error_mapper import *
 
 debug_mode = False
 
diff --git a/xos/ec2_observer/event_manager.py b/xos/synchronizers/ec2/event_manager.py
similarity index 100%
rename from xos/ec2_observer/event_manager.py
rename to xos/synchronizers/ec2/event_manager.py
diff --git a/xos/ec2_observer/steps/__init__.py b/xos/synchronizers/ec2/steps/__init__.py
similarity index 100%
rename from xos/ec2_observer/steps/__init__.py
rename to xos/synchronizers/ec2/steps/__init__.py
diff --git a/xos/ec2_observer/steps/sync_deployments.py b/xos/synchronizers/ec2/steps/sync_deployments.py
similarity index 100%
rename from xos/ec2_observer/steps/sync_deployments.py
rename to xos/synchronizers/ec2/steps/sync_deployments.py
diff --git a/xos/ec2_observer/steps/sync_images.py b/xos/synchronizers/ec2/steps/sync_images.py
similarity index 100%
rename from xos/ec2_observer/steps/sync_images.py
rename to xos/synchronizers/ec2/steps/sync_images.py
diff --git a/xos/ec2_observer/steps/sync_instances.py b/xos/synchronizers/ec2/steps/sync_instances.py
similarity index 98%
rename from xos/ec2_observer/steps/sync_instances.py
rename to xos/synchronizers/ec2/steps/sync_instances.py
index 3dc5f0e..fc11e05 100644
--- a/xos/ec2_observer/steps/sync_instances.py
+++ b/xos/synchronizers/ec2/steps/sync_instances.py
@@ -7,7 +7,7 @@
 from core.models.instance import Instance
 from core.models.slice import SlicePrivilege, SliceDeployments
 from core.models.network import Network, NetworkSlice, NetworkDeployments
-from util.logger import Logger, logging
+from xos.logger import Logger, logging
 from ec2_observer.awslib import *
 from core.models.site import *
 from core.models.slice import *
diff --git a/xos/ec2_observer/steps/sync_site_deployments.py b/xos/synchronizers/ec2/steps/sync_site_deployments.py
similarity index 100%
rename from xos/ec2_observer/steps/sync_site_deployments.py
rename to xos/synchronizers/ec2/steps/sync_site_deployments.py
diff --git a/xos/ec2_observer/steps/sync_sites.py b/xos/synchronizers/ec2/steps/sync_sites.py
similarity index 100%
rename from xos/ec2_observer/steps/sync_sites.py
rename to xos/synchronizers/ec2/steps/sync_sites.py
diff --git a/xos/ec2_observer/steps/sync_users.py b/xos/synchronizers/ec2/steps/sync_users.py
similarity index 100%
rename from xos/ec2_observer/steps/sync_users.py
rename to xos/synchronizers/ec2/steps/sync_users.py
diff --git a/xos/ec2_observer/syncstep.py b/xos/synchronizers/ec2/syncstep.py
similarity index 97%
rename from xos/ec2_observer/syncstep.py
rename to xos/synchronizers/ec2/syncstep.py
index e15e719..3cba48b 100644
--- a/xos/ec2_observer/syncstep.py
+++ b/xos/synchronizers/ec2/syncstep.py
@@ -5,8 +5,8 @@
 from django.db.models import F, Q
 
 from xos.config import Config
-from util.logger import Logger, logging
-from observer.steps import *
+from xos.logger import Logger, logging
+from synchronizers.base.steps import *
 
 logger = Logger(level=logging.INFO)
 
diff --git a/xos/ec2_observer/toposort.py b/xos/synchronizers/ec2/toposort.py
similarity index 100%
rename from xos/ec2_observer/toposort.py
rename to xos/synchronizers/ec2/toposort.py
diff --git a/xos/ec2_observer/xos.deps b/xos/synchronizers/ec2/xos.deps
similarity index 100%
rename from xos/ec2_observer/xos.deps
rename to xos/synchronizers/ec2/xos.deps
diff --git a/xos/observers/helloworld/helloworld-observer.py b/xos/synchronizers/helloworld/helloworld-synchronizer.py
similarity index 70%
rename from xos/observers/helloworld/helloworld-observer.py
rename to xos/synchronizers/helloworld/helloworld-synchronizer.py
index d6a71ff..84bec4f 100755
--- a/xos/observers/helloworld/helloworld-observer.py
+++ b/xos/synchronizers/helloworld/helloworld-synchronizer.py
@@ -5,7 +5,7 @@
 import importlib
 import os
 import sys
-observer_path = os.path.join(os.path.dirname(os.path.realpath(__file__)),"../..")
+observer_path = os.path.join(os.path.dirname(os.path.realpath(__file__)),"../../synchronizers/base")
 sys.path.append(observer_path)
-mod = importlib.import_module("xos-observer")
+mod = importlib.import_module("xos-synchronizer")
 mod.main()
diff --git a/xos/observers/helloworld/helloworld_config b/xos/synchronizers/helloworld/helloworld_config
similarity index 93%
rename from xos/observers/helloworld/helloworld_config
rename to xos/synchronizers/helloworld/helloworld_config
index e32ee0c..1f67242 100644
--- a/xos/observers/helloworld/helloworld_config
+++ b/xos/synchronizers/helloworld/helloworld_config
@@ -37,7 +37,7 @@
 images_directory=/opt/xos/images
 dependency_graph=/opt/xos/model-deps
 logfile=/var/log/xos_backend.log
-steps_dir=/opt/xos/observers/helloworld/steps
+steps_dir=/opt/xos/synchronizers/helloworld/steps
 applist=helloworld
 
 [gui]
diff --git a/xos/observers/helloworld/model-deps b/xos/synchronizers/helloworld/model-deps
similarity index 100%
rename from xos/observers/helloworld/model-deps
rename to xos/synchronizers/helloworld/model-deps
diff --git a/xos/observers/helloworld/nohup.out b/xos/synchronizers/helloworld/nohup.out
similarity index 100%
rename from xos/observers/helloworld/nohup.out
rename to xos/synchronizers/helloworld/nohup.out
diff --git a/xos/observers/helloworld/run.sh b/xos/synchronizers/helloworld/run.sh
similarity index 100%
rename from xos/observers/helloworld/run.sh
rename to xos/synchronizers/helloworld/run.sh
diff --git a/xos/observers/helloworld/start.sh b/xos/synchronizers/helloworld/start.sh
similarity index 100%
rename from xos/observers/helloworld/start.sh
rename to xos/synchronizers/helloworld/start.sh
diff --git a/xos/observers/helloworld/steps/sync_hello.py b/xos/synchronizers/helloworld/steps/sync_hello.py
similarity index 89%
rename from xos/observers/helloworld/steps/sync_hello.py
rename to xos/synchronizers/helloworld/steps/sync_hello.py
index 880d570..55d318a 100644
--- a/xos/observers/helloworld/steps/sync_hello.py
+++ b/xos/synchronizers/helloworld/steps/sync_hello.py
@@ -3,9 +3,9 @@
 import base64
 from django.db.models import F, Q
 from xos.config import Config
-from observer.syncstep import SyncStep
+from synchronizers.base.syncstep import SyncStep
 from services.helloworld.models import Hello,World
-from util.logger import Logger, logging
+from xos.logger import Logger, logging
 
 parentdir = os.path.join(os.path.dirname(__file__),"..")
 sys.path.insert(0,parentdir)
diff --git a/xos/observers/helloworld/steps/sync_world.py b/xos/synchronizers/helloworld/steps/sync_world.py
similarity index 86%
rename from xos/observers/helloworld/steps/sync_world.py
rename to xos/synchronizers/helloworld/steps/sync_world.py
index a97d320..a4e7e3c 100644
--- a/xos/observers/helloworld/steps/sync_world.py
+++ b/xos/synchronizers/helloworld/steps/sync_world.py
@@ -3,9 +3,9 @@
 import base64
 from django.db.models import F, Q
 from xos.config import Config
-from observer.syncstep import SyncStep
+from synchronizers.base.syncstep import SyncStep
 from services.helloworld.models import Hello,World
-from util.logger import Logger, logging
+from xos.logger import Logger, logging
 
 # hpclibrary will be in steps/..
 parentdir = os.path.join(os.path.dirname(__file__),"..")
diff --git a/xos/observers/helloworld/stop.sh b/xos/synchronizers/helloworld/stop.sh
similarity index 100%
rename from xos/observers/helloworld/stop.sh
rename to xos/synchronizers/helloworld/stop.sh
diff --git a/xos/observers/helloworldservice_complete/helloworldservice-observer.py b/xos/synchronizers/helloworldservice_complete/helloworldservice-synchronizer.py
similarity index 66%
rename from xos/observers/helloworldservice_complete/helloworldservice-observer.py
rename to xos/synchronizers/helloworldservice_complete/helloworldservice-synchronizer.py
index 75dcc46..95f4081 100755
--- a/xos/observers/helloworldservice_complete/helloworldservice-observer.py
+++ b/xos/synchronizers/helloworldservice_complete/helloworldservice-synchronizer.py
@@ -7,7 +7,7 @@
 import os
 import sys
 observer_path = os.path.join(os.path.dirname(
-    os.path.realpath(__file__)), "../..")
+    os.path.realpath(__file__)), "../../synchronizers/base")
 sys.path.append(observer_path)
-mod = importlib.import_module("xos-observer")
+mod = importlib.import_module("xos-synchronizer")
 mod.main()
diff --git a/xos/observers/helloworldservice_complete/helloworldservice_config b/xos/synchronizers/helloworldservice_complete/helloworldservice_config
similarity index 94%
rename from xos/observers/helloworldservice_complete/helloworldservice_config
rename to xos/synchronizers/helloworldservice_complete/helloworldservice_config
index 716e3a0..b779d0e 100644
--- a/xos/observers/helloworldservice_complete/helloworldservice_config
+++ b/xos/synchronizers/helloworldservice_complete/helloworldservice_config
@@ -17,7 +17,7 @@
 # This is the location to the dependency graph you generate
 dependency_graph=/opt/xos/observers/helloworldservice_complete/model-deps
 # The location of your SyncSteps
-steps_dir=/opt/xos/observers/helloworldservice_complete/steps
+steps_dir=/opt/xos/synchronizers/helloworldservice_complete/steps
 # A temporary directory that will be used by ansible
 sys_dir=/opt/xos/observers/helloworldservice_complete/sys
 # Location of the file to save logging messages to the backend log is often used
diff --git a/xos/observers/helloworldservice_complete/model-deps b/xos/synchronizers/helloworldservice_complete/model-deps
similarity index 100%
rename from xos/observers/helloworldservice_complete/model-deps
rename to xos/synchronizers/helloworldservice_complete/model-deps
diff --git a/xos/observers/helloworldservice_complete/run.sh b/xos/synchronizers/helloworldservice_complete/run.sh
similarity index 100%
rename from xos/observers/helloworldservice_complete/run.sh
rename to xos/synchronizers/helloworldservice_complete/run.sh
diff --git a/xos/observers/helloworldservice_complete/steps/sync_helloworldtenant.py b/xos/synchronizers/helloworldservice_complete/steps/sync_helloworldtenant.py
similarity index 96%
rename from xos/observers/helloworldservice_complete/steps/sync_helloworldtenant.py
rename to xos/synchronizers/helloworldservice_complete/steps/sync_helloworldtenant.py
index 5604296..b7ed2a8 100644
--- a/xos/observers/helloworldservice_complete/steps/sync_helloworldtenant.py
+++ b/xos/synchronizers/helloworldservice_complete/steps/sync_helloworldtenant.py
@@ -2,7 +2,7 @@
 import sys
 from django.db.models import Q, F
 from services.helloworldservice_complete.models import HelloWorldServiceComplete, HelloWorldTenantComplete
-from observers.base.SyncInstanceUsingAnsible import SyncInstanceUsingAnsible
+from synchronizers.base.SyncInstanceUsingAnsible import SyncInstanceUsingAnsible
 
 parentdir = os.path.join(os.path.dirname(__file__), "..")
 sys.path.insert(0, parentdir)
diff --git a/xos/observers/helloworldservice_complete/steps/sync_helloworldtenant.yaml b/xos/synchronizers/helloworldservice_complete/steps/sync_helloworldtenant.yaml
similarity index 100%
rename from xos/observers/helloworldservice_complete/steps/sync_helloworldtenant.yaml
rename to xos/synchronizers/helloworldservice_complete/steps/sync_helloworldtenant.yaml
diff --git a/xos/observers/helloworldservice_complete/stop.sh b/xos/synchronizers/helloworldservice_complete/stop.sh
similarity index 100%
rename from xos/observers/helloworldservice_complete/stop.sh
rename to xos/synchronizers/helloworldservice_complete/stop.sh
diff --git a/xos/observers/hpc/Makefile b/xos/synchronizers/hpc/Makefile
similarity index 100%
rename from xos/observers/hpc/Makefile
rename to xos/synchronizers/hpc/Makefile
diff --git a/xos/observers/hpc/fsck.py b/xos/synchronizers/hpc/fsck.py
similarity index 96%
rename from xos/observers/hpc/fsck.py
rename to xos/synchronizers/hpc/fsck.py
index 0c551f8..448bfb7 100644
--- a/xos/observers/hpc/fsck.py
+++ b/xos/synchronizers/hpc/fsck.py
@@ -7,8 +7,8 @@
 os.environ.setdefault("DJANGO_SETTINGS_MODULE", "xos.settings")
 sys.path.append("/opt/xos")
 from xos.config import Config, DEFAULT_CONFIG_FN, XOS_DIR
-from util.logger import Logger, logging
-from observer.syncstep import SyncStep
+from xos.logger import Logger, logging
+from synchronizers.base.syncstep import SyncStep
 
 try:
     from django import setup as django_setup # django 1.7
diff --git a/xos/observers/helloworld/helloworld-observer.py b/xos/synchronizers/hpc/hpc-synchronizer.py
similarity index 70%
copy from xos/observers/helloworld/helloworld-observer.py
copy to xos/synchronizers/hpc/hpc-synchronizer.py
index d6a71ff..84bec4f 100755
--- a/xos/observers/helloworld/helloworld-observer.py
+++ b/xos/synchronizers/hpc/hpc-synchronizer.py
@@ -5,7 +5,7 @@
 import importlib
 import os
 import sys
-observer_path = os.path.join(os.path.dirname(os.path.realpath(__file__)),"../..")
+observer_path = os.path.join(os.path.dirname(os.path.realpath(__file__)),"../../synchronizers/base")
 sys.path.append(observer_path)
-mod = importlib.import_module("xos-observer")
+mod = importlib.import_module("xos-synchronizer")
 mod.main()
diff --git a/xos/observers/hpc/hpc_observer_config b/xos/synchronizers/hpc/hpc_synchronizer_config
similarity index 74%
rename from xos/observers/hpc/hpc_observer_config
rename to xos/synchronizers/hpc/hpc_synchronizer_config
index 326e731..9d4e70a 100644
--- a/xos/observers/hpc/hpc_observer_config
+++ b/xos/synchronizers/hpc/hpc_synchronizer_config
@@ -23,9 +23,9 @@
 
 [observer]
 name=hpc
-dependency_graph=/opt/xos/observers/hpc/model-deps
-steps_dir=/opt/xos/observers/hpc/steps
-deleters_dir=/opt/xos/observers/hpc/deleters
+dependency_graph=/opt/xos/synchronizers/hpc/model-deps
+steps_dir=/opt/xos/synchronizers/hpc/steps
+deleters_dir=/opt/xos/synchronizers/hpc/deleters
 log_file=console
 #/var/log/hpc.log
 driver=None
diff --git a/xos/observers/hpc/hpc_watcher.py b/xos/synchronizers/hpc/hpc_watcher.py
similarity index 100%
rename from xos/observers/hpc/hpc_watcher.py
rename to xos/synchronizers/hpc/hpc_watcher.py
diff --git a/xos/observers/hpc/hpclib.py b/xos/synchronizers/hpc/hpclib.py
similarity index 98%
rename from xos/observers/hpc/hpclib.py
rename to xos/synchronizers/hpc/hpclib.py
index 88abf23..bb1c263 100644
--- a/xos/observers/hpc/hpclib.py
+++ b/xos/synchronizers/hpc/hpclib.py
@@ -12,7 +12,7 @@
 from core.models import Service
 from services.hpc.models import HpcService
 from services.requestrouter.models import RequestRouterService
-from util.logger import Logger, logging
+from xos.logger import Logger, logging
 
 logger = Logger(level=logging.INFO)
 
diff --git a/xos/observers/hpc/model-deps b/xos/synchronizers/hpc/model-deps
similarity index 100%
rename from xos/observers/hpc/model-deps
rename to xos/synchronizers/hpc/model-deps
diff --git a/xos/observers/hpc/run.sh b/xos/synchronizers/hpc/run.sh
similarity index 100%
rename from xos/observers/hpc/run.sh
rename to xos/synchronizers/hpc/run.sh
diff --git a/xos/observers/hpc/start.sh b/xos/synchronizers/hpc/start.sh
similarity index 100%
rename from xos/observers/hpc/start.sh
rename to xos/synchronizers/hpc/start.sh
diff --git a/xos/observers/hpc/steps/garbage_collector.py b/xos/synchronizers/hpc/steps/garbage_collector.py
similarity index 95%
rename from xos/observers/hpc/steps/garbage_collector.py
rename to xos/synchronizers/hpc/steps/garbage_collector.py
index 259762b..658f7a1 100644
--- a/xos/observers/hpc/steps/garbage_collector.py
+++ b/xos/synchronizers/hpc/steps/garbage_collector.py
@@ -5,8 +5,8 @@
 from collections import defaultdict
 from django.db.models import F, Q
 from xos.config import Config
-from util.logger import Logger, logging
-from observer.syncstep import SyncStep
+from xos.logger import Logger, logging
+from synchronizers.base.syncstep import SyncStep
 from services.hpc.models import ServiceProvider, ContentProvider, CDNPrefix, OriginServer
 from core.models import *
 
diff --git a/xos/observers/hpc/steps/sync_cdnprefix.py b/xos/synchronizers/hpc/steps/sync_cdnprefix.py
similarity index 97%
rename from xos/observers/hpc/steps/sync_cdnprefix.py
rename to xos/synchronizers/hpc/steps/sync_cdnprefix.py
index a6382bd..7439633 100644
--- a/xos/observers/hpc/steps/sync_cdnprefix.py
+++ b/xos/synchronizers/hpc/steps/sync_cdnprefix.py
@@ -3,10 +3,10 @@
 import base64
 from django.db.models import F, Q
 from xos.config import Config
-from observer.syncstep import SyncStep
+from synchronizers.base.syncstep import SyncStep
 from core.models import Service
 from services.hpc.models import ServiceProvider, ContentProvider, CDNPrefix
-from util.logger import Logger, logging
+from xos.logger import Logger, logging
 
 # hpclibrary will be in steps/..
 parentdir = os.path.join(os.path.dirname(__file__),"..")
diff --git a/xos/observers/hpc/steps/sync_contentprovider.py b/xos/synchronizers/hpc/steps/sync_contentprovider.py
similarity index 96%
rename from xos/observers/hpc/steps/sync_contentprovider.py
rename to xos/synchronizers/hpc/steps/sync_contentprovider.py
index 0f86e2e..c58cb5e 100644
--- a/xos/observers/hpc/steps/sync_contentprovider.py
+++ b/xos/synchronizers/hpc/steps/sync_contentprovider.py
@@ -3,10 +3,10 @@
 import base64
 from django.db.models import F, Q
 from xos.config import Config
-from observer.syncstep import SyncStep
+from synchronizers.base.syncstep import SyncStep
 from core.models import Service
 from services.hpc.models import ServiceProvider, ContentProvider
-from util.logger import Logger, logging
+from xos.logger import Logger, logging
 
 # hpclibrary will be in steps/..
 parentdir = os.path.join(os.path.dirname(__file__),"..")
diff --git a/xos/observers/hpc/steps/sync_hpcservices.py b/xos/synchronizers/hpc/steps/sync_hpcservices.py
similarity index 92%
rename from xos/observers/hpc/steps/sync_hpcservices.py
rename to xos/synchronizers/hpc/steps/sync_hpcservices.py
index 4ceb096..e49f93f 100644
--- a/xos/observers/hpc/steps/sync_hpcservices.py
+++ b/xos/synchronizers/hpc/steps/sync_hpcservices.py
@@ -3,11 +3,11 @@
 import base64
 from django.db.models import F, Q
 from xos.config import Config
-from observer.syncstep import SyncStep
+from synchronizers.base.syncstep import SyncStep
 from core.models import Service
 from services.hpc.models import HpcService
 from services.requestrouter.models import RequestRouterService
-from util.logger import Logger, logging
+from xos.logger import Logger, logging
 
 # hpclibrary will be in steps/..
 parentdir = os.path.join(os.path.dirname(__file__),"..")
diff --git a/xos/observers/hpc/steps/sync_originserver.py b/xos/synchronizers/hpc/steps/sync_originserver.py
similarity index 97%
rename from xos/observers/hpc/steps/sync_originserver.py
rename to xos/synchronizers/hpc/steps/sync_originserver.py
index 01bd56a..0a675e1 100644
--- a/xos/observers/hpc/steps/sync_originserver.py
+++ b/xos/synchronizers/hpc/steps/sync_originserver.py
@@ -4,10 +4,10 @@
 
 from django.db.models import F, Q
 from xos.config import Config
-from observer.syncstep import SyncStep
+from synchronizers.base.syncstep import SyncStep
 from core.models import Service
 from services.hpc.models import ServiceProvider, ContentProvider, CDNPrefix, OriginServer
-from util.logger import Logger, logging
+from xos.logger import Logger, logging
 
 # hpclibrary will be in steps/..
 parentdir = os.path.join(os.path.dirname(__file__),"..")
diff --git a/xos/observers/hpc/steps/sync_serviceprovider.py b/xos/synchronizers/hpc/steps/sync_serviceprovider.py
similarity index 95%
rename from xos/observers/hpc/steps/sync_serviceprovider.py
rename to xos/synchronizers/hpc/steps/sync_serviceprovider.py
index 68c36ef..0cf145f 100644
--- a/xos/observers/hpc/steps/sync_serviceprovider.py
+++ b/xos/synchronizers/hpc/steps/sync_serviceprovider.py
@@ -3,10 +3,10 @@
 import base64
 from django.db.models import F, Q
 from xos.config import Config
-from observer.syncstep import SyncStep
+from synchronizers.base.syncstep import SyncStep
 from core.models import Service
 from services.hpc.models import ServiceProvider
-from util.logger import Logger, logging
+from xos.logger import Logger, logging
 
 # hpclibrary will be in steps/..
 parentdir = os.path.join(os.path.dirname(__file__),"..")
diff --git a/xos/observers/hpc/steps/sync_sitemap.py b/xos/synchronizers/hpc/steps/sync_sitemap.py
similarity index 97%
rename from xos/observers/hpc/steps/sync_sitemap.py
rename to xos/synchronizers/hpc/steps/sync_sitemap.py
index 3fd4b16..885c616 100644
--- a/xos/observers/hpc/steps/sync_sitemap.py
+++ b/xos/synchronizers/hpc/steps/sync_sitemap.py
@@ -3,10 +3,10 @@
 import base64
 from django.db.models import F, Q
 from xos.config import Config
-from observer.syncstep import SyncStep
+from synchronizers.base.syncstep import SyncStep
 from core.models import Service
 from services.hpc.models import ServiceProvider, ContentProvider, CDNPrefix, SiteMap
-from util.logger import Logger, logging
+from xos.logger import Logger, logging
 
 # hpclibrary will be in steps/..
 parentdir = os.path.join(os.path.dirname(__file__),"..")
diff --git a/xos/observers/hpc/stop.sh b/xos/synchronizers/hpc/stop.sh
similarity index 100%
rename from xos/observers/hpc/stop.sh
rename to xos/synchronizers/hpc/stop.sh
diff --git a/xos/observers/hpc/supervisor/hpc-observer.conf b/xos/synchronizers/hpc/supervisor/hpc-observer.conf
similarity index 100%
rename from xos/observers/hpc/supervisor/hpc-observer.conf
rename to xos/synchronizers/hpc/supervisor/hpc-observer.conf
diff --git a/xos/observers/hpc/supervisor/hpc-watcher.conf b/xos/synchronizers/hpc/supervisor/hpc-watcher.conf
similarity index 100%
rename from xos/observers/hpc/supervisor/hpc-watcher.conf
rename to xos/synchronizers/hpc/supervisor/hpc-watcher.conf
diff --git a/xos/model_policy.py b/xos/synchronizers/model_policy.py
similarity index 96%
rename from xos/model_policy.py
rename to xos/synchronizers/model_policy.py
index 9462b35..b8fdd5d 100644
--- a/xos/model_policy.py
+++ b/xos/synchronizers/model_policy.py
@@ -1,9 +1,9 @@
 from django.db.models.signals import post_save
 from django.dispatch import receiver
 import pdb
-from dependency_walker import *
-import model_policies
-from util.logger import logger
+from generate.dependency_walker import *
+from synchronizers.openstack import model_policies
+from xos.logger import logger
 from datetime import datetime
 import time
 from core.models import *
diff --git a/xos/observers/monitoring_channel/files/docker.list b/xos/synchronizers/monitoring_channel/files/docker.list
similarity index 100%
rename from xos/observers/monitoring_channel/files/docker.list
rename to xos/synchronizers/monitoring_channel/files/docker.list
diff --git a/xos/observers/monitoring_channel/files/vm-resolv.conf b/xos/synchronizers/monitoring_channel/files/vm-resolv.conf
similarity index 100%
rename from xos/observers/monitoring_channel/files/vm-resolv.conf
rename to xos/synchronizers/monitoring_channel/files/vm-resolv.conf
diff --git a/xos/observers/monitoring_channel/model-deps b/xos/synchronizers/monitoring_channel/model-deps
similarity index 100%
rename from xos/observers/monitoring_channel/model-deps
rename to xos/synchronizers/monitoring_channel/model-deps
diff --git a/xos/observers/helloworld/helloworld-observer.py b/xos/synchronizers/monitoring_channel/monitoring_channel_synchronizer.py
similarity index 70%
copy from xos/observers/helloworld/helloworld-observer.py
copy to xos/synchronizers/monitoring_channel/monitoring_channel_synchronizer.py
index d6a71ff..84bec4f 100755
--- a/xos/observers/helloworld/helloworld-observer.py
+++ b/xos/synchronizers/monitoring_channel/monitoring_channel_synchronizer.py
@@ -5,7 +5,7 @@
 import importlib
 import os
 import sys
-observer_path = os.path.join(os.path.dirname(os.path.realpath(__file__)),"../..")
+observer_path = os.path.join(os.path.dirname(os.path.realpath(__file__)),"../../synchronizers/base")
 sys.path.append(observer_path)
-mod = importlib.import_module("xos-observer")
+mod = importlib.import_module("xos-synchronizer")
 mod.main()
diff --git a/xos/observers/monitoring_channel/monitoring_channel_observer_config b/xos/synchronizers/monitoring_channel/monitoring_channel_synchronizer_config
similarity index 67%
rename from xos/observers/monitoring_channel/monitoring_channel_observer_config
rename to xos/synchronizers/monitoring_channel/monitoring_channel_synchronizer_config
index 5657e1d..8c6578f 100644
--- a/xos/observers/monitoring_channel/monitoring_channel_observer_config
+++ b/xos/synchronizers/monitoring_channel/monitoring_channel_synchronizer_config
@@ -23,10 +23,10 @@
 
 [observer]
 name=monitoring_channel
-dependency_graph=/opt/xos/observers/monitoring_channel/model-deps
-steps_dir=/opt/xos/observers/monitoring_channel/steps
-sys_dir=/opt/xos/observers/monitoring_channel/sys
-deleters_dir=/opt/xos/observers/monitoring_channel/deleters
+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
diff --git a/xos/observers/monitoring_channel/steps/sync_monitoringchannel.py b/xos/synchronizers/monitoring_channel/steps/sync_monitoringchannel.py
similarity index 91%
rename from xos/observers/monitoring_channel/steps/sync_monitoringchannel.py
rename to xos/synchronizers/monitoring_channel/steps/sync_monitoringchannel.py
index 78ad45e..2e4eca8 100644
--- a/xos/observers/monitoring_channel/steps/sync_monitoringchannel.py
+++ b/xos/synchronizers/monitoring_channel/steps/sync_monitoringchannel.py
@@ -6,12 +6,12 @@
 import time
 from django.db.models import F, Q
 from xos.config import Config
-from observer.syncstep import SyncStep
-from observer.ansible import run_template_ssh
-from observers.base.SyncInstanceUsingAnsible import SyncInstanceUsingAnsible
+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
 from services.ceilometer.models import MonitoringChannel
-from util.logger import Logger, logging
+from xos.logger import Logger, logging
 
 parentdir = os.path.join(os.path.dirname(__file__),"..")
 sys.path.insert(0,parentdir)
diff --git a/xos/observers/monitoring_channel/steps/sync_monitoringchannel.yaml b/xos/synchronizers/monitoring_channel/steps/sync_monitoringchannel.yaml
similarity index 96%
rename from xos/observers/monitoring_channel/steps/sync_monitoringchannel.yaml
rename to xos/synchronizers/monitoring_channel/steps/sync_monitoringchannel.yaml
index c2705ba..6c5fc8c 100644
--- a/xos/observers/monitoring_channel/steps/sync_monitoringchannel.yaml
+++ b/xos/synchronizers/monitoring_channel/steps/sync_monitoringchannel.yaml
@@ -67,6 +67,11 @@
 
   - name: ceilometer proxy config
     template: src=/opt/xos/observers/monitoring_channel/templates/ceilometer_proxy_config.j2 dest=/usr/local/share/monitoring-channel-{{ unique_id }}_ceilometer_proxy_config mode=0777
+    notify:
+#    - restart monitoring-channel
+     - stop monitoring-channel
+     - remove container
+     - start monitoring-channel
 
   - name: Monitoring channel upstart
     template: src=/opt/xos/observers/monitoring_channel/templates/monitoring-channel.conf.j2 dest=/etc/init/monitoring-channel-{{ unique_id }}.conf
diff --git a/xos/observers/monitoring_channel/supervisor/monitoring_channel_observer.conf b/xos/synchronizers/monitoring_channel/supervisor/monitoring_channel_observer.conf
similarity index 100%
rename from xos/observers/monitoring_channel/supervisor/monitoring_channel_observer.conf
rename to xos/synchronizers/monitoring_channel/supervisor/monitoring_channel_observer.conf
diff --git a/xos/observers/monitoring_channel/templates/Dockerfile.monitoring_channel b/xos/synchronizers/monitoring_channel/templates/Dockerfile.monitoring_channel
similarity index 100%
rename from xos/observers/monitoring_channel/templates/Dockerfile.monitoring_channel
rename to xos/synchronizers/monitoring_channel/templates/Dockerfile.monitoring_channel
diff --git a/xos/observers/monitoring_channel/templates/ceilometer_proxy_config.j2 b/xos/synchronizers/monitoring_channel/templates/ceilometer_proxy_config.j2
similarity index 100%
rename from xos/observers/monitoring_channel/templates/ceilometer_proxy_config.j2
rename to xos/synchronizers/monitoring_channel/templates/ceilometer_proxy_config.j2
diff --git a/xos/observers/monitoring_channel/templates/ceilometer_proxy_server.py b/xos/synchronizers/monitoring_channel/templates/ceilometer_proxy_server.py
similarity index 100%
rename from xos/observers/monitoring_channel/templates/ceilometer_proxy_server.py
rename to xos/synchronizers/monitoring_channel/templates/ceilometer_proxy_server.py
diff --git a/xos/observers/monitoring_channel/templates/monitoring-channel.conf.j2 b/xos/synchronizers/monitoring_channel/templates/monitoring-channel.conf.j2
similarity index 100%
rename from xos/observers/monitoring_channel/templates/monitoring-channel.conf.j2
rename to xos/synchronizers/monitoring_channel/templates/monitoring-channel.conf.j2
diff --git a/xos/observers/monitoring_channel/templates/start-monitoring-channel.sh.j2 b/xos/synchronizers/monitoring_channel/templates/start-monitoring-channel.sh.j2
similarity index 100%
rename from xos/observers/monitoring_channel/templates/start-monitoring-channel.sh.j2
rename to xos/synchronizers/monitoring_channel/templates/start-monitoring-channel.sh.j2
diff --git a/xos/observers/monitoring_channel/templates/start_ceilometer_proxy b/xos/synchronizers/monitoring_channel/templates/start_ceilometer_proxy
similarity index 100%
rename from xos/observers/monitoring_channel/templates/start_ceilometer_proxy
rename to xos/synchronizers/monitoring_channel/templates/start_ceilometer_proxy
diff --git a/xos/observers/onos/model-deps b/xos/synchronizers/onos/model-deps
similarity index 100%
rename from xos/observers/onos/model-deps
rename to xos/synchronizers/onos/model-deps
diff --git a/xos/observers/helloworld/helloworld-observer.py b/xos/synchronizers/onos/onos-synchronizer.py
similarity index 70%
copy from xos/observers/helloworld/helloworld-observer.py
copy to xos/synchronizers/onos/onos-synchronizer.py
index d6a71ff..84bec4f 100755
--- a/xos/observers/helloworld/helloworld-observer.py
+++ b/xos/synchronizers/onos/onos-synchronizer.py
@@ -5,7 +5,7 @@
 import importlib
 import os
 import sys
-observer_path = os.path.join(os.path.dirname(os.path.realpath(__file__)),"../..")
+observer_path = os.path.join(os.path.dirname(os.path.realpath(__file__)),"../../synchronizers/base")
 sys.path.append(observer_path)
-mod = importlib.import_module("xos-observer")
+mod = importlib.import_module("xos-synchronizer")
 mod.main()
diff --git a/xos/observers/onos/onos_observer_config b/xos/synchronizers/onos/onos_synchronizer_config
similarity index 72%
rename from xos/observers/onos/onos_observer_config
rename to xos/synchronizers/onos/onos_synchronizer_config
index 3c6d63d..c6ceece 100644
--- a/xos/observers/onos/onos_observer_config
+++ b/xos/synchronizers/onos/onos_synchronizer_config
@@ -23,10 +23,10 @@
 
 [observer]
 name=onos
-dependency_graph=/opt/xos/observers/onos/model-deps
-steps_dir=/opt/xos/observers/onos/steps
-sys_dir=/opt/xos/observers/onos/sys
-deleters_dir=/opt/xos/observers/onos/deleters
+dependency_graph=/opt/xos/synchronizers/onos/model-deps
+steps_dir=/opt/xos/synchronizers/onos/steps
+sys_dir=/opt/xos/synchronizers/onos/sys
+deleters_dir=/opt/xos/synchronizers/onos/deleters
 log_file=console
 driver=None
 pretend=False
diff --git a/xos/observers/onos/run.sh b/xos/synchronizers/onos/run.sh
similarity index 100%
rename from xos/observers/onos/run.sh
rename to xos/synchronizers/onos/run.sh
diff --git a/xos/observers/onos/scripts/dockerip.sh b/xos/synchronizers/onos/scripts/dockerip.sh
similarity index 100%
rename from xos/observers/onos/scripts/dockerip.sh
rename to xos/synchronizers/onos/scripts/dockerip.sh
diff --git a/xos/observers/onos/start.sh b/xos/synchronizers/onos/start.sh
similarity index 100%
rename from xos/observers/onos/start.sh
rename to xos/synchronizers/onos/start.sh
diff --git a/xos/observers/onos/steps/sync_onosapp.py b/xos/synchronizers/onos/steps/sync_onosapp.py
similarity index 95%
rename from xos/observers/onos/steps/sync_onosapp.py
rename to xos/synchronizers/onos/steps/sync_onosapp.py
index cfe1041..91eec44 100644
--- a/xos/observers/onos/steps/sync_onosapp.py
+++ b/xos/synchronizers/onos/steps/sync_onosapp.py
@@ -7,12 +7,12 @@
 import time
 from django.db.models import F, Q
 from xos.config import Config
-from observer.syncstep import SyncStep
-from observer.ansible import run_template_ssh
-from observers.base.SyncInstanceUsingAnsible import SyncInstanceUsingAnsible
+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
 from services.onos.models import ONOSService, ONOSApp
-from util.logger import Logger, logging
+from xos.logger import Logger, logging
 
 # hpclibrary will be in steps/..
 parentdir = os.path.join(os.path.dirname(__file__),"..")
diff --git a/xos/observers/onos/steps/sync_onosapp.yaml b/xos/synchronizers/onos/steps/sync_onosapp.yaml
similarity index 100%
rename from xos/observers/onos/steps/sync_onosapp.yaml
rename to xos/synchronizers/onos/steps/sync_onosapp.yaml
diff --git a/xos/observers/onos/steps/sync_onosservice.py b/xos/synchronizers/onos/steps/sync_onosservice.py
similarity index 90%
rename from xos/observers/onos/steps/sync_onosservice.py
rename to xos/synchronizers/onos/steps/sync_onosservice.py
index 420904a..0474dc6 100644
--- a/xos/observers/onos/steps/sync_onosservice.py
+++ b/xos/synchronizers/onos/steps/sync_onosservice.py
@@ -6,12 +6,12 @@
 import time
 from django.db.models import F, Q
 from xos.config import Config
-from observer.syncstep import SyncStep
-from observer.ansible import run_template_ssh
-from observers.base.SyncInstanceUsingAnsible import SyncInstanceUsingAnsible
+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
 from services.onos.models import ONOSService, ONOSApp
-from util.logger import Logger, logging
+from xos.logger import Logger, logging
 
 # hpclibrary will be in steps/..
 parentdir = os.path.join(os.path.dirname(__file__),"..")
diff --git a/xos/observers/onos/steps/sync_onosservice.yaml b/xos/synchronizers/onos/steps/sync_onosservice.yaml
similarity index 100%
rename from xos/observers/onos/steps/sync_onosservice.yaml
rename to xos/synchronizers/onos/steps/sync_onosservice.yaml
diff --git a/xos/observers/onos/stop.sh b/xos/synchronizers/onos/stop.sh
similarity index 100%
rename from xos/observers/onos/stop.sh
rename to xos/synchronizers/onos/stop.sh
diff --git a/xos/observers/onos/supervisor/onos-observer.conf b/xos/synchronizers/onos/supervisor/onos-observer.conf
similarity index 100%
rename from xos/observers/onos/supervisor/onos-observer.conf
rename to xos/synchronizers/onos/supervisor/onos-observer.conf
diff --git a/xos/openstack_observer/__init__.py b/xos/synchronizers/openstack/__init__.py
similarity index 100%
copy from xos/openstack_observer/__init__.py
copy to xos/synchronizers/openstack/__init__.py
diff --git a/xos/synchronizers/openstack/ansible.py b/xos/synchronizers/openstack/ansible.py
new file mode 120000
index 0000000..c20dc8b
--- /dev/null
+++ b/xos/synchronizers/openstack/ansible.py
@@ -0,0 +1 @@
+../base/ansible.py
\ No newline at end of file
diff --git a/xos/openstack_observer/backend.py b/xos/synchronizers/openstack/backend.py
similarity index 86%
copy from xos/openstack_observer/backend.py
copy to xos/synchronizers/openstack/backend.py
index 5657491..5f11d46 100644
--- a/xos/openstack_observer/backend.py
+++ b/xos/synchronizers/openstack/backend.py
@@ -2,10 +2,10 @@
 import sys
 import threading
 import time
-from observer.event_loop import XOSObserver
-from observer.event_manager import EventListener
-from util.logger import Logger, logging
-from model_policy import run_policy
+from synchronizers.base.event_loop import XOSObserver
+from synchronizers.base.event_manager import EventListener
+from xos.logger import Logger, logging
+from synchronizers.model_policy import run_policy
 from xos.config import Config
 
 logger = Logger(level=logging.INFO)
diff --git a/xos/ec2_observer/deleter.py b/xos/synchronizers/openstack/deleter.py
similarity index 100%
copy from xos/ec2_observer/deleter.py
copy to xos/synchronizers/openstack/deleter.py
diff --git a/xos/ec2_observer/error_mapper.py b/xos/synchronizers/openstack/error_mapper.py
similarity index 90%
copy from xos/ec2_observer/error_mapper.py
copy to xos/synchronizers/openstack/error_mapper.py
index 3039a56..9eb878d 100644
--- a/xos/ec2_observer/error_mapper.py
+++ b/xos/synchronizers/openstack/error_mapper.py
@@ -1,5 +1,5 @@
 from xos.config import Config
-from util.logger import Logger, logging, logger
+from xos.logger import Logger, logging, logger
 
 class ErrorMapper:
 	def __init__(self, error_map_file):
diff --git a/xos/openstack_observer/event_loop.py b/xos/synchronizers/openstack/event_loop.py
similarity index 97%
copy from xos/openstack_observer/event_loop.py
copy to xos/synchronizers/openstack/event_loop.py
index 0ac626b..6cfc9f6 100644
--- a/xos/openstack_observer/event_loop.py
+++ b/xos/synchronizers/openstack/event_loop.py
@@ -19,15 +19,15 @@
 from django.db import reset_queries
 #from openstack.manager import OpenStackManager
 from openstack.driver import OpenStackDriver
-from util.logger import Logger, logging, logger
+from xos.logger import Logger, logging, logger
 #from timeout import timeout
 from xos.config import Config, XOS_DIR
-from observer.steps import *
+from synchronizers.base.steps import *
 from syncstep import SyncStep
 from toposort import toposort
-from observer.error_mapper import *
-from openstack_observer.openstacksyncstep import OpenStackSyncStep
-from observer.steps.sync_object import SyncObject
+from synchronizers.base.error_mapper import *
+from synchronizers.openstack.openstacksyncstep import OpenStackSyncStep
+from synchronizers.base.steps.sync_object import SyncObject
 
 # Load app models
 
@@ -121,7 +121,7 @@
 			if hasattr(Config(), "observer_steps_dir"):
 				step_dir = Config().observer_steps_dir
 			else:
-				step_dir = XOS_DIR + "/observer/steps"
+				step_dir = XOS_DIR + "/synchronizers/openstack/steps"
 
 		for fn in os.listdir(step_dir):
 			pathname = os.path.join(step_dir,fn)
diff --git a/xos/openstack_observer/event_manager.py b/xos/synchronizers/openstack/event_manager.py
similarity index 100%
copy from xos/openstack_observer/event_manager.py
copy to xos/synchronizers/openstack/event_manager.py
diff --git a/xos/model_policies/__init__.py b/xos/synchronizers/openstack/model_policies/__init__.py
similarity index 100%
rename from xos/model_policies/__init__.py
rename to xos/synchronizers/openstack/model_policies/__init__.py
diff --git a/xos/model_policies/model_policy_Controller.py b/xos/synchronizers/openstack/model_policies/model_policy_Controller.py
similarity index 100%
rename from xos/model_policies/model_policy_Controller.py
rename to xos/synchronizers/openstack/model_policies/model_policy_Controller.py
diff --git a/xos/model_policies/model_policy_ControllerSite.py b/xos/synchronizers/openstack/model_policies/model_policy_ControllerSite.py
similarity index 100%
rename from xos/model_policies/model_policy_ControllerSite.py
rename to xos/synchronizers/openstack/model_policies/model_policy_ControllerSite.py
diff --git a/xos/model_policies/model_policy_ControllerSlice.py b/xos/synchronizers/openstack/model_policies/model_policy_ControllerSlice.py
similarity index 100%
rename from xos/model_policies/model_policy_ControllerSlice.py
rename to xos/synchronizers/openstack/model_policies/model_policy_ControllerSlice.py
diff --git a/xos/model_policies/model_policy_ControllerUser.py b/xos/synchronizers/openstack/model_policies/model_policy_ControllerUser.py
similarity index 100%
rename from xos/model_policies/model_policy_ControllerUser.py
rename to xos/synchronizers/openstack/model_policies/model_policy_ControllerUser.py
diff --git a/xos/model_policies/model_policy_Image.py b/xos/synchronizers/openstack/model_policies/model_policy_Image.py
similarity index 100%
rename from xos/model_policies/model_policy_Image.py
rename to xos/synchronizers/openstack/model_policies/model_policy_Image.py
diff --git a/xos/model_policies/model_policy_Instance.py b/xos/synchronizers/openstack/model_policies/model_policy_Instance.py
similarity index 100%
rename from xos/model_policies/model_policy_Instance.py
rename to xos/synchronizers/openstack/model_policies/model_policy_Instance.py
diff --git a/xos/model_policies/model_policy_Network.py b/xos/synchronizers/openstack/model_policies/model_policy_Network.py
similarity index 100%
rename from xos/model_policies/model_policy_Network.py
rename to xos/synchronizers/openstack/model_policies/model_policy_Network.py
diff --git a/xos/model_policies/model_policy_Site.py b/xos/synchronizers/openstack/model_policies/model_policy_Site.py
similarity index 100%
rename from xos/model_policies/model_policy_Site.py
rename to xos/synchronizers/openstack/model_policies/model_policy_Site.py
diff --git a/xos/model_policies/model_policy_SitePrivilege.py b/xos/synchronizers/openstack/model_policies/model_policy_SitePrivilege.py
similarity index 100%
rename from xos/model_policies/model_policy_SitePrivilege.py
rename to xos/synchronizers/openstack/model_policies/model_policy_SitePrivilege.py
diff --git a/xos/model_policies/model_policy_Slice.py b/xos/synchronizers/openstack/model_policies/model_policy_Slice.py
similarity index 100%
rename from xos/model_policies/model_policy_Slice.py
rename to xos/synchronizers/openstack/model_policies/model_policy_Slice.py
diff --git a/xos/model_policies/model_policy_SlicePrivilege.py b/xos/synchronizers/openstack/model_policies/model_policy_SlicePrivilege.py
similarity index 100%
rename from xos/model_policies/model_policy_SlicePrivilege.py
rename to xos/synchronizers/openstack/model_policies/model_policy_SlicePrivilege.py
diff --git a/xos/model_policies/model_policy_Sliver.py b/xos/synchronizers/openstack/model_policies/model_policy_Sliver.py
similarity index 100%
rename from xos/model_policies/model_policy_Sliver.py
rename to xos/synchronizers/openstack/model_policies/model_policy_Sliver.py
diff --git a/xos/model_policies/model_policy_User.py b/xos/synchronizers/openstack/model_policies/model_policy_User.py
similarity index 100%
rename from xos/model_policies/model_policy_User.py
rename to xos/synchronizers/openstack/model_policies/model_policy_User.py
diff --git a/xos/openstack_observer/openstacksyncstep.py b/xos/synchronizers/openstack/openstacksyncstep.py
similarity index 100%
copy from xos/openstack_observer/openstacksyncstep.py
copy to xos/synchronizers/openstack/openstacksyncstep.py
diff --git a/xos/openstack_observer/run_ansible b/xos/synchronizers/openstack/run_ansible
similarity index 100%
copy from xos/openstack_observer/run_ansible
copy to xos/synchronizers/openstack/run_ansible
diff --git a/xos/openstack_observer/run_ansible_verbose b/xos/synchronizers/openstack/run_ansible_verbose
similarity index 100%
copy from xos/openstack_observer/run_ansible_verbose
copy to xos/synchronizers/openstack/run_ansible_verbose
diff --git a/xos/openstack_observer/steps/__init__.py b/xos/synchronizers/openstack/steps/__init__.py
similarity index 100%
copy from xos/openstack_observer/steps/__init__.py
copy to xos/synchronizers/openstack/steps/__init__.py
diff --git a/xos/openstack_observer/steps/delete_slivers.yaml b/xos/synchronizers/openstack/steps/delete_slivers.yaml
similarity index 100%
copy from xos/openstack_observer/steps/delete_slivers.yaml
copy to xos/synchronizers/openstack/steps/delete_slivers.yaml
diff --git a/xos/openstack_observer/steps/purge_disabled_users.py b/xos/synchronizers/openstack/steps/purge_disabled_users.py
similarity index 85%
copy from xos/openstack_observer/steps/purge_disabled_users.py
copy to xos/synchronizers/openstack/steps/purge_disabled_users.py
index b5168e3..0973b8c 100644
--- a/xos/openstack_observer/steps/purge_disabled_users.py
+++ b/xos/synchronizers/openstack/steps/purge_disabled_users.py
@@ -3,9 +3,9 @@
 import datetime
 from django.db.models import F, Q
 from xos.config import Config
-from observer.openstacksyncstep import OpenStackSyncStep
+from synchronizers.base.openstacksyncstep import OpenStackSyncStep
 from core.models.user import User
-from util.logger import observer_logger as logger
+from xos.logger import observer_logger as logger
 
 class SyncRoles(OpenStackSyncStep):
     provides=[User]
diff --git a/xos/openstack_observer/steps/sliver.yaml b/xos/synchronizers/openstack/steps/sliver.yaml
similarity index 100%
copy from xos/openstack_observer/steps/sliver.yaml
copy to xos/synchronizers/openstack/steps/sliver.yaml
diff --git a/xos/openstack_observer/steps/sync_container.py b/xos/synchronizers/openstack/steps/sync_container.py
similarity index 95%
copy from xos/openstack_observer/steps/sync_container.py
copy to xos/synchronizers/openstack/steps/sync_container.py
index adb81c9..d647aef 100644
--- a/xos/openstack_observer/steps/sync_container.py
+++ b/xos/synchronizers/openstack/steps/sync_container.py
@@ -6,12 +6,12 @@
 import time
 from django.db.models import F, Q
 from xos.config import Config
-from observers.base.SyncInstanceUsingAnsible import SyncInstanceUsingAnsible
-from observer.syncstep import SyncStep, DeferredException
-from observer.ansible import run_template_ssh
+from synchronizers.base.SyncInstanceUsingAnsible import SyncInstanceUsingAnsible
+from synchronizers.base.syncstep import SyncStep, DeferredException
+from synchronizers.base.ansible import run_template_ssh
 from core.models import Service, Slice, Instance
 from services.onos.models import ONOSService, ONOSApp
-from util.logger import Logger, logging
+from xos.logger import Logger, logging
 
 # hpclibrary will be in steps/..
 parentdir = os.path.join(os.path.dirname(__file__),"..")
diff --git a/xos/openstack_observer/steps/sync_container.yaml b/xos/synchronizers/openstack/steps/sync_container.yaml
similarity index 100%
copy from xos/openstack_observer/steps/sync_container.yaml
copy to xos/synchronizers/openstack/steps/sync_container.yaml
diff --git a/xos/openstack_observer/steps/sync_controller_images.py b/xos/synchronizers/openstack/steps/sync_controller_images.py
similarity index 88%
copy from xos/openstack_observer/steps/sync_controller_images.py
copy to xos/synchronizers/openstack/steps/sync_controller_images.py
index 551d9ac..c1e5136 100644
--- a/xos/openstack_observer/steps/sync_controller_images.py
+++ b/xos/synchronizers/openstack/steps/sync_controller_images.py
@@ -3,12 +3,12 @@
 from collections import defaultdict
 from django.db.models import F, Q
 from xos.config import Config
-from observer.openstacksyncstep import OpenStackSyncStep
-from observer.syncstep import *
+from synchronizers.base.openstacksyncstep import OpenStackSyncStep
+from synchronizers.base.syncstep import *
 from core.models import Controller
 from core.models import Image, ControllerImages
-from util.logger import observer_logger as logger 
-from observer.ansible import *
+from xos.logger import observer_logger as logger 
+from synchronizers.base.ansible import *
 import json
 
 class SyncControllerImages(OpenStackSyncStep):
diff --git a/xos/openstack_observer/steps/sync_controller_images.yaml b/xos/synchronizers/openstack/steps/sync_controller_images.yaml
similarity index 100%
copy from xos/openstack_observer/steps/sync_controller_images.yaml
copy to xos/synchronizers/openstack/steps/sync_controller_images.yaml
diff --git a/xos/openstack_observer/steps/sync_controller_networks.py b/xos/synchronizers/openstack/steps/sync_controller_networks.py
similarity index 96%
copy from xos/openstack_observer/steps/sync_controller_networks.py
copy to xos/synchronizers/openstack/steps/sync_controller_networks.py
index ad1604b..990cb87 100644
--- a/xos/openstack_observer/steps/sync_controller_networks.py
+++ b/xos/synchronizers/openstack/steps/sync_controller_networks.py
@@ -4,13 +4,13 @@
 from netaddr import IPAddress, IPNetwork
 from django.db.models import F, Q
 from xos.config import Config
-from observer.openstacksyncstep import OpenStackSyncStep
-from observer.syncstep import *
+from synchronizers.base.openstacksyncstep import OpenStackSyncStep
+from synchronizers.base.syncstep import *
 from core.models.network import *
 from core.models.slice import *
 from core.models.instance import Instance
-from util.logger import observer_logger as logger
-from observer.ansible import *
+from xos.logger import observer_logger as logger
+from synchronizers.base.ansible import *
 from openstack.driver import OpenStackDriver
 from xos.config import Config
 import json
diff --git a/xos/openstack_observer/steps/sync_controller_networks.yaml b/xos/synchronizers/openstack/steps/sync_controller_networks.yaml
similarity index 100%
copy from xos/openstack_observer/steps/sync_controller_networks.yaml
copy to xos/synchronizers/openstack/steps/sync_controller_networks.yaml
diff --git a/xos/openstack_observer/steps/sync_controller_site_privileges.py b/xos/synchronizers/openstack/steps/sync_controller_site_privileges.py
similarity index 95%
copy from xos/openstack_observer/steps/sync_controller_site_privileges.py
copy to xos/synchronizers/openstack/steps/sync_controller_site_privileges.py
index d257536..59919fe 100644
--- a/xos/openstack_observer/steps/sync_controller_site_privileges.py
+++ b/xos/synchronizers/openstack/steps/sync_controller_site_privileges.py
@@ -3,13 +3,13 @@
 from collections import defaultdict
 from django.db.models import F, Q
 from xos.config import Config
-from observer.openstacksyncstep import OpenStackSyncStep
-from observer.syncstep import *
+from synchronizers.base.openstacksyncstep import OpenStackSyncStep
+from synchronizers.base.syncstep import *
 from core.models.site import Controller, SitePrivilege 
 from core.models.user import User
 from core.models.controlleruser import ControllerUser, ControllerSitePrivilege
-from util.logger import observer_logger as logger
-from observer.ansible import *
+from xos.logger import observer_logger as logger
+from synchronizers.base.ansible import *
 import json
 
 class SyncControllerSitePrivileges(OpenStackSyncStep):
diff --git a/xos/openstack_observer/steps/sync_controller_sites.py b/xos/synchronizers/openstack/steps/sync_controller_sites.py
similarity index 92%
copy from xos/openstack_observer/steps/sync_controller_sites.py
copy to xos/synchronizers/openstack/steps/sync_controller_sites.py
index 614d435..1b3c2ba 100644
--- a/xos/openstack_observer/steps/sync_controller_sites.py
+++ b/xos/synchronizers/openstack/steps/sync_controller_sites.py
@@ -2,11 +2,11 @@
 import base64
 from django.db.models import F, Q
 from xos.config import Config
-from openstack_observer.openstacksyncstep import OpenStackSyncStep
+from synchronizers.openstack.openstacksyncstep import OpenStackSyncStep
 from core.models.site import *
-from observer.syncstep import *
-from observer.ansible import *
-from util.logger import observer_logger as logger
+from synchronizers.base.syncstep import *
+from synchronizers.base.ansible import *
+from xos.logger import observer_logger as logger
 import json
 
 class SyncControllerSites(OpenStackSyncStep):
diff --git a/xos/openstack_observer/steps/sync_controller_sites.yaml b/xos/synchronizers/openstack/steps/sync_controller_sites.yaml
similarity index 100%
copy from xos/openstack_observer/steps/sync_controller_sites.yaml
copy to xos/synchronizers/openstack/steps/sync_controller_sites.yaml
diff --git a/xos/openstack_observer/steps/sync_controller_slice_privileges.py b/xos/synchronizers/openstack/steps/sync_controller_slice_privileges.py
similarity index 94%
copy from xos/openstack_observer/steps/sync_controller_slice_privileges.py
copy to xos/synchronizers/openstack/steps/sync_controller_slice_privileges.py
index 948ea57..b78e4a0 100644
--- a/xos/openstack_observer/steps/sync_controller_slice_privileges.py
+++ b/xos/synchronizers/openstack/steps/sync_controller_slice_privileges.py
@@ -3,13 +3,13 @@
 from collections import defaultdict
 from django.db.models import F, Q
 from xos.config import Config
-from observer.openstacksyncstep import OpenStackSyncStep
-from observer.syncstep import *
+from synchronizers.base.openstacksyncstep import OpenStackSyncStep
+from synchronizers.base.syncstep import *
 from core.models.slice import Controller, SlicePrivilege 
 from core.models.user import User
 from core.models.controlleruser import ControllerUser, ControllerSlicePrivilege
-from observer.ansible import *
-from util.logger import observer_logger as logger
+from synchronizers.base.ansible import *
+from xos.logger import observer_logger as logger
 import json
 
 class SyncControllerSlicePrivileges(OpenStackSyncStep):
diff --git a/xos/openstack_observer/steps/sync_controller_slices.py b/xos/synchronizers/openstack/steps/sync_controller_slices.py
similarity index 94%
copy from xos/openstack_observer/steps/sync_controller_slices.py
copy to xos/synchronizers/openstack/steps/sync_controller_slices.py
index 9904aef..97d8c29 100644
--- a/xos/openstack_observer/steps/sync_controller_slices.py
+++ b/xos/synchronizers/openstack/steps/sync_controller_slices.py
@@ -4,12 +4,12 @@
 from netaddr import IPAddress, IPNetwork
 from django.db.models import F, Q
 from xos.config import Config
-from observer.openstacksyncstep import OpenStackSyncStep
-from observer.syncstep import *
+from synchronizers.base.openstacksyncstep import OpenStackSyncStep
+from synchronizers.base.syncstep import *
 from core.models import *
-from observer.ansible import *
+from synchronizers.base.ansible import *
 from openstack.driver import OpenStackDriver
-from util.logger import observer_logger as logger
+from xos.logger import observer_logger as logger
 import json
 
 class SyncControllerSlices(OpenStackSyncStep):
diff --git a/xos/openstack_observer/steps/sync_controller_slices.yaml b/xos/synchronizers/openstack/steps/sync_controller_slices.yaml
similarity index 100%
copy from xos/openstack_observer/steps/sync_controller_slices.yaml
copy to xos/synchronizers/openstack/steps/sync_controller_slices.yaml
diff --git a/xos/openstack_observer/steps/sync_controller_users.py b/xos/synchronizers/openstack/steps/sync_controller_users.py
similarity index 93%
copy from xos/openstack_observer/steps/sync_controller_users.py
copy to xos/synchronizers/openstack/steps/sync_controller_users.py
index 4062453..9af48e5 100644
--- a/xos/openstack_observer/steps/sync_controller_users.py
+++ b/xos/synchronizers/openstack/steps/sync_controller_users.py
@@ -3,13 +3,13 @@
 from collections import defaultdict
 from django.db.models import F, Q
 from xos.config import Config
-from observer.openstacksyncstep import OpenStackSyncStep
-from observer.syncstep import *
+from synchronizers.base.openstacksyncstep import OpenStackSyncStep
+from synchronizers.base.syncstep import *
 from core.models.site import Controller, SiteDeployment, SiteDeployment
 from core.models.user import User
 from core.models.controlleruser import ControllerUser
-from observer.ansible import *
-from util.logger import observer_logger as logger
+from synchronizers.base.ansible import *
+from xos.logger import observer_logger as logger
 import json
 
 class SyncControllerUsers(OpenStackSyncStep):
diff --git a/xos/openstack_observer/steps/sync_controller_users.yaml b/xos/synchronizers/openstack/steps/sync_controller_users.yaml
similarity index 100%
copy from xos/openstack_observer/steps/sync_controller_users.yaml
copy to xos/synchronizers/openstack/steps/sync_controller_users.yaml
diff --git a/xos/openstack_observer/steps/sync_images.py b/xos/synchronizers/openstack/steps/sync_images.py
similarity index 93%
copy from xos/openstack_observer/steps/sync_images.py
copy to xos/synchronizers/openstack/steps/sync_images.py
index d126834..8049ac1 100644
--- a/xos/openstack_observer/steps/sync_images.py
+++ b/xos/synchronizers/openstack/steps/sync_images.py
@@ -2,9 +2,9 @@
 import base64
 from django.db.models import F, Q
 from xos.config import Config
-from observer.openstacksyncstep import OpenStackSyncStep
+from synchronizers.base.openstacksyncstep import OpenStackSyncStep
 from core.models.image import Image
-from util.logger import observer_logger as logger
+from xos.logger import observer_logger as logger
 
 class SyncImages(OpenStackSyncStep):
     provides=[Image]
diff --git a/xos/openstack_observer/steps/sync_instances.py b/xos/synchronizers/openstack/steps/sync_instances.py
similarity index 96%
copy from xos/openstack_observer/steps/sync_instances.py
copy to xos/synchronizers/openstack/steps/sync_instances.py
index 815c83e..335ca4a 100644
--- a/xos/openstack_observer/steps/sync_instances.py
+++ b/xos/synchronizers/openstack/steps/sync_instances.py
@@ -4,13 +4,13 @@
 from django.db.models import F, Q
 from xos.config import Config
 from xos.settings import RESTAPI_HOSTNAME, RESTAPI_PORT
-from observer.openstacksyncstep import OpenStackSyncStep
+from synchronizers.base.openstacksyncstep import OpenStackSyncStep
 from core.models.instance import Instance
 from core.models.slice import Slice, SlicePrivilege, ControllerSlice
 from core.models.network import Network, NetworkSlice, ControllerNetwork
-from observer.ansible import *
-from observer.syncstep import *
-from util.logger import observer_logger as logger
+from synchronizers.base.ansible import *
+from synchronizers.base.syncstep import *
+from xos.logger import observer_logger as logger
 
 def escape(s):
     s = s.replace('\n',r'\n').replace('"',r'\"')
diff --git a/xos/openstack_observer/steps/sync_instances.yaml b/xos/synchronizers/openstack/steps/sync_instances.yaml
similarity index 100%
copy from xos/openstack_observer/steps/sync_instances.yaml
copy to xos/synchronizers/openstack/steps/sync_instances.yaml
diff --git a/xos/openstack_observer/steps/sync_object.py b/xos/synchronizers/openstack/steps/sync_object.py
similarity index 69%
copy from xos/openstack_observer/steps/sync_object.py
copy to xos/synchronizers/openstack/steps/sync_object.py
index a289c95..a6a939f 100644
--- a/xos/openstack_observer/steps/sync_object.py
+++ b/xos/synchronizers/openstack/steps/sync_object.py
@@ -3,12 +3,12 @@
 from collections import defaultdict
 from django.db.models import F, Q
 from xos.config import Config
-from observer.openstacksyncstep import OpenStackSyncStep
-from observer.syncstep import *
+from synchronizers.base.openstacksyncstep import OpenStackSyncStep
+from synchronizers.base.syncstep import *
 from core.models import *
-from observer.ansible import *
+from synchronizers.base.ansible import *
 from openstack.driver import OpenStackDriver
-from util.logger import observer_logger as logger
+from xos.logger import observer_logger as logger
 import json
 
 class SyncObject(OpenStackSyncStep):
diff --git a/xos/openstack_observer/steps/sync_ports.py b/xos/synchronizers/openstack/steps/sync_ports.py
similarity index 98%
copy from xos/openstack_observer/steps/sync_ports.py
copy to xos/synchronizers/openstack/steps/sync_ports.py
index bfdde8c..21376e5 100644
--- a/xos/openstack_observer/steps/sync_ports.py
+++ b/xos/synchronizers/openstack/steps/sync_ports.py
@@ -2,10 +2,10 @@
 import base64
 from django.db.models import F, Q
 from xos.config import Config
-from observer.openstacksyncstep import OpenStackSyncStep
+from synchronizers.base.openstacksyncstep import OpenStackSyncStep
 from core.models import Controller
 from core.models.network import *
-from util.logger import observer_logger as logger
+from xos.logger import observer_logger as logger
 
 class SyncPorts(OpenStackSyncStep):
     requested_interval = 0 # 3600
diff --git a/xos/openstack_observer/steps/sync_roles.py b/xos/synchronizers/openstack/steps/sync_roles.py
similarity index 84%
copy from xos/openstack_observer/steps/sync_roles.py
copy to xos/synchronizers/openstack/steps/sync_roles.py
index c4bbe3f..e859316 100644
--- a/xos/openstack_observer/steps/sync_roles.py
+++ b/xos/synchronizers/openstack/steps/sync_roles.py
@@ -2,11 +2,11 @@
 import base64
 from django.db.models import F, Q
 from xos.config import Config
-from observer.openstacksyncstep import OpenStackSyncStep
+from synchronizers.base.openstacksyncstep import OpenStackSyncStep
 from core.models.role import Role
 from core.models.site import SiteRole, Controller, ControllerRole
 from core.models.slice import SliceRole
-from util.logger import observer_logger as logger
+from xos.logger import observer_logger as logger
 
 class SyncRoles(OpenStackSyncStep):
     provides=[Role]
diff --git a/xos/openstack_observer/steps/teardown_container.yaml b/xos/synchronizers/openstack/steps/teardown_container.yaml
similarity index 100%
copy from xos/openstack_observer/steps/teardown_container.yaml
copy to xos/synchronizers/openstack/steps/teardown_container.yaml
diff --git a/xos/openstack_observer/syncstep.py b/xos/synchronizers/openstack/syncstep.py
similarity index 98%
copy from xos/openstack_observer/syncstep.py
copy to xos/synchronizers/openstack/syncstep.py
index 0a25c58..bdab8f3 100644
--- a/xos/openstack_observer/syncstep.py
+++ b/xos/synchronizers/openstack/syncstep.py
@@ -2,13 +2,13 @@
 import base64
 from datetime import datetime
 from xos.config import Config
-from util.logger import Logger, logging
-from observer.steps import *
+from xos.logger import Logger, logging
+from synchronizers.base.steps import *
 from django.db.models import F, Q
 from core.models import *
 from django.db import reset_queries
-from observer.ansible import *
-from dependency_walker import *
+from synchronizers.base.ansible import *
+from generate.dependency_walker import *
 
 from time import time
 import json
diff --git a/xos/openstack_observer/templates/container.conf.j2 b/xos/synchronizers/openstack/templates/container.conf.j2
similarity index 100%
copy from xos/openstack_observer/templates/container.conf.j2
copy to xos/synchronizers/openstack/templates/container.conf.j2
diff --git a/xos/openstack_observer/templates/container.service.j2 b/xos/synchronizers/openstack/templates/container.service.j2
similarity index 100%
copy from xos/openstack_observer/templates/container.service.j2
copy to xos/synchronizers/openstack/templates/container.service.j2
diff --git a/xos/openstack_observer/templates/start-container.sh.j2 b/xos/synchronizers/openstack/templates/start-container.sh.j2
similarity index 100%
copy from xos/openstack_observer/templates/start-container.sh.j2
copy to xos/synchronizers/openstack/templates/start-container.sh.j2
diff --git a/xos/openstack_observer/templates/stop-container.sh.j2 b/xos/synchronizers/openstack/templates/stop-container.sh.j2
similarity index 100%
copy from xos/openstack_observer/templates/stop-container.sh.j2
copy to xos/synchronizers/openstack/templates/stop-container.sh.j2
diff --git a/xos/openstack_observer/toposort.py b/xos/synchronizers/openstack/toposort.py
similarity index 100%
copy from xos/openstack_observer/toposort.py
copy to xos/synchronizers/openstack/toposort.py
diff --git a/xos/xos-observer.py b/xos/synchronizers/openstack/xos-synchronizer.py
similarity index 75%
copy from xos/xos-observer.py
copy to xos/synchronizers/openstack/xos-synchronizer.py
index b85b29b..3fffd33 100644
--- a/xos/xos-observer.py
+++ b/xos/synchronizers/openstack/xos-synchronizer.py
@@ -1,9 +1,17 @@
 #!/usr/bin/env python
 import os
 import argparse
+import sys
+
+sys.path.append('/opt/xos')
+
 os.environ.setdefault("DJANGO_SETTINGS_MODULE", "xos.settings")
-from observer.backend import Backend
+from synchronizers.base.backend import Backend
 from xos.config import Config, DEFAULT_CONFIG_FN
+from core.models import Instance
+from xos.logger import Logger, logging, logger
+from django.db import ProgrammingError
+import time
 
 try:
     from django import setup as django_setup # django 1.7
@@ -54,6 +62,18 @@
     if django_setup: # 1.7
         django_setup()
 
+    models_active = False
+    wait = False
+    while not models_active:
+        try:
+            _ = Instance.objects.first()
+            models_active = True
+        except ProgrammingError:
+            logger.info('Waiting for data model to come up before starting...')
+            wait = True
+
+    if (wait):
+        time.sleep(60) # Safety factor, seeing that we stumbled waiting for the data model to come up.
     backend = Backend()
     backend.run()    
 
diff --git a/xos/observers/requestrouter/configurationPush.py b/xos/synchronizers/requestrouter/configurationPush.py
similarity index 100%
rename from xos/observers/requestrouter/configurationPush.py
rename to xos/synchronizers/requestrouter/configurationPush.py
diff --git a/xos/observers/requestrouter/deleters/servicemap_deleter.py b/xos/synchronizers/requestrouter/deleters/servicemap_deleter.py
similarity index 94%
rename from xos/observers/requestrouter/deleters/servicemap_deleter.py
rename to xos/synchronizers/requestrouter/deleters/servicemap_deleter.py
index 5e4b5a4..d2efd64 100644
--- a/xos/observers/requestrouter/deleters/servicemap_deleter.py
+++ b/xos/synchronizers/requestrouter/deleters/servicemap_deleter.py
@@ -2,8 +2,8 @@
 import sys
 import traceback
 from services.requestrouter.models import ServiceMap
-from observer.deleter import Deleter
-from util.logger import Logger, logging
+from synchronizers.base.deleter import Deleter
+from xos.logger import Logger, logging
 from xos.config import Config, XOS_DIR
 
 parentdir = os.path.join(os.path.dirname(__file__),"..")
diff --git a/xos/observers/requestrouter/model-deps b/xos/synchronizers/requestrouter/model-deps
similarity index 100%
rename from xos/observers/requestrouter/model-deps
rename to xos/synchronizers/requestrouter/model-deps
diff --git a/xos/observers/requestrouter/playbook/roles/delete_demux/handlers/main.yml b/xos/synchronizers/requestrouter/playbook/roles/delete_demux/handlers/main.yml
similarity index 100%
rename from xos/observers/requestrouter/playbook/roles/delete_demux/handlers/main.yml
rename to xos/synchronizers/requestrouter/playbook/roles/delete_demux/handlers/main.yml
diff --git a/xos/observers/requestrouter/playbook/roles/delete_demux/tasks/main.yml b/xos/synchronizers/requestrouter/playbook/roles/delete_demux/tasks/main.yml
similarity index 100%
rename from xos/observers/requestrouter/playbook/roles/delete_demux/tasks/main.yml
rename to xos/synchronizers/requestrouter/playbook/roles/delete_demux/tasks/main.yml
diff --git a/xos/observers/requestrouter/playbook/roles/delete_demux/vars/main.yml b/xos/synchronizers/requestrouter/playbook/roles/delete_demux/vars/main.yml
similarity index 100%
rename from xos/observers/requestrouter/playbook/roles/delete_demux/vars/main.yml
rename to xos/synchronizers/requestrouter/playbook/roles/delete_demux/vars/main.yml
diff --git a/xos/observers/requestrouter/playbook/roles/delete_redir/handlers/main.yml b/xos/synchronizers/requestrouter/playbook/roles/delete_redir/handlers/main.yml
similarity index 100%
rename from xos/observers/requestrouter/playbook/roles/delete_redir/handlers/main.yml
rename to xos/synchronizers/requestrouter/playbook/roles/delete_redir/handlers/main.yml
diff --git a/xos/observers/requestrouter/playbook/roles/delete_redir/tasks/main.yml b/xos/synchronizers/requestrouter/playbook/roles/delete_redir/tasks/main.yml
similarity index 100%
rename from xos/observers/requestrouter/playbook/roles/delete_redir/tasks/main.yml
rename to xos/synchronizers/requestrouter/playbook/roles/delete_redir/tasks/main.yml
diff --git a/xos/observers/requestrouter/playbook/roles/delete_redir/vars/main.yml b/xos/synchronizers/requestrouter/playbook/roles/delete_redir/vars/main.yml
similarity index 100%
rename from xos/observers/requestrouter/playbook/roles/delete_redir/vars/main.yml
rename to xos/synchronizers/requestrouter/playbook/roles/delete_redir/vars/main.yml
diff --git a/xos/observers/requestrouter/playbook/roles/demux/handlers/main.yml b/xos/synchronizers/requestrouter/playbook/roles/demux/handlers/main.yml
similarity index 100%
rename from xos/observers/requestrouter/playbook/roles/demux/handlers/main.yml
rename to xos/synchronizers/requestrouter/playbook/roles/demux/handlers/main.yml
diff --git a/xos/observers/requestrouter/playbook/roles/demux/tasks/main.yml b/xos/synchronizers/requestrouter/playbook/roles/demux/tasks/main.yml
similarity index 100%
rename from xos/observers/requestrouter/playbook/roles/demux/tasks/main.yml
rename to xos/synchronizers/requestrouter/playbook/roles/demux/tasks/main.yml
diff --git a/xos/observers/requestrouter/playbook/roles/demux/vars/main.yml b/xos/synchronizers/requestrouter/playbook/roles/demux/vars/main.yml
similarity index 100%
rename from xos/observers/requestrouter/playbook/roles/demux/vars/main.yml
rename to xos/synchronizers/requestrouter/playbook/roles/demux/vars/main.yml
diff --git a/xos/observers/requestrouter/playbook/roles/redir/handlers/main.yml b/xos/synchronizers/requestrouter/playbook/roles/redir/handlers/main.yml
similarity index 100%
rename from xos/observers/requestrouter/playbook/roles/redir/handlers/main.yml
rename to xos/synchronizers/requestrouter/playbook/roles/redir/handlers/main.yml
diff --git a/xos/observers/requestrouter/playbook/roles/redir/tasks/main.yml b/xos/synchronizers/requestrouter/playbook/roles/redir/tasks/main.yml
similarity index 100%
rename from xos/observers/requestrouter/playbook/roles/redir/tasks/main.yml
rename to xos/synchronizers/requestrouter/playbook/roles/redir/tasks/main.yml
diff --git a/xos/observers/requestrouter/playbook/roles/redir/vars/main.yml b/xos/synchronizers/requestrouter/playbook/roles/redir/vars/main.yml
similarity index 100%
rename from xos/observers/requestrouter/playbook/roles/redir/vars/main.yml
rename to xos/synchronizers/requestrouter/playbook/roles/redir/vars/main.yml
diff --git a/xos/observers/requestrouter/playbook/site_demux.yml b/xos/synchronizers/requestrouter/playbook/site_demux.yml
similarity index 100%
rename from xos/observers/requestrouter/playbook/site_demux.yml
rename to xos/synchronizers/requestrouter/playbook/site_demux.yml
diff --git a/xos/observers/requestrouter/playbook/site_demux_delete.yml b/xos/synchronizers/requestrouter/playbook/site_demux_delete.yml
similarity index 100%
rename from xos/observers/requestrouter/playbook/site_demux_delete.yml
rename to xos/synchronizers/requestrouter/playbook/site_demux_delete.yml
diff --git a/xos/observers/requestrouter/playbook/site_redir.yml b/xos/synchronizers/requestrouter/playbook/site_redir.yml
similarity index 100%
rename from xos/observers/requestrouter/playbook/site_redir.yml
rename to xos/synchronizers/requestrouter/playbook/site_redir.yml
diff --git a/xos/observers/requestrouter/playbook/site_redir_delete.yml b/xos/synchronizers/requestrouter/playbook/site_redir_delete.yml
similarity index 100%
rename from xos/observers/requestrouter/playbook/site_redir_delete.yml
rename to xos/synchronizers/requestrouter/playbook/site_redir_delete.yml
diff --git a/xos/observers/requestrouter/rr_observer_config b/xos/synchronizers/requestrouter/rr_synchronizer_config
similarity index 70%
rename from xos/observers/requestrouter/rr_observer_config
rename to xos/synchronizers/requestrouter/rr_synchronizer_config
index ec3a1ba..179540e 100644
--- a/xos/observers/requestrouter/rr_observer_config
+++ b/xos/synchronizers/requestrouter/rr_synchronizer_config
@@ -24,9 +24,9 @@
 nova_enabled=True
 
 [observer]
-dependency_graph=/opt/xos/observers/requestrouter/model-deps
-steps_dir=/opt/xos/observers/requestrouter/steps
-deleters_dir=/opt/xos/observers/requestrouter/deleters
+dependency_graph=/opt/xos/synchronizers/requestrouter/model-deps
+steps_dir=/opt/xos/synchronizers/requestrouter/steps
+deleters_dir=/opt/xos/synchronizers/requestrouter/deleters
 log_file=console
 #/var/log/hpc.log
 driver=None
diff --git a/xos/observers/requestrouter/rrlib.py b/xos/synchronizers/requestrouter/rrlib.py
similarity index 99%
rename from xos/observers/requestrouter/rrlib.py
rename to xos/synchronizers/requestrouter/rrlib.py
index 9faca4a..e2100b0 100644
--- a/xos/observers/requestrouter/rrlib.py
+++ b/xos/synchronizers/requestrouter/rrlib.py
@@ -11,7 +11,7 @@
 from xos.config import Config
 from core.models import Service
 from services.requestrouter.models import RequestRouterService, ServiceMap
-from util.logger import Logger, logging
+from xos.logger import Logger, logging
 import rrlib_config
 
 logger = Logger(level=logging.INFO)
diff --git a/xos/observers/requestrouter/rrlib_config.py b/xos/synchronizers/requestrouter/rrlib_config.py
similarity index 100%
rename from xos/observers/requestrouter/rrlib_config.py
rename to xos/synchronizers/requestrouter/rrlib_config.py
diff --git a/xos/observers/requestrouter/steps/sync_requestrouterservices.py b/xos/synchronizers/requestrouter/steps/sync_requestrouterservices.py
similarity index 92%
rename from xos/observers/requestrouter/steps/sync_requestrouterservices.py
rename to xos/synchronizers/requestrouter/steps/sync_requestrouterservices.py
index ccf9291..c9648ff 100644
--- a/xos/observers/requestrouter/steps/sync_requestrouterservices.py
+++ b/xos/synchronizers/requestrouter/steps/sync_requestrouterservices.py
@@ -4,10 +4,10 @@
 import traceback
 from django.db.models import F, Q
 from xos.config import Config
-from observer.syncstep import SyncStep
+from synchronizers.base.syncstep import SyncStep
 from core.models import Service
 from services.requestrouter.models import RequestRouterService
-from util.logger import Logger, logging
+from xos.logger import Logger, logging
 
 parentdir = os.path.join(os.path.dirname(__file__),"..")
 sys.path.insert(0,parentdir)
diff --git a/xos/observers/requestrouter/steps/sync_servicemap.py b/xos/synchronizers/requestrouter/steps/sync_servicemap.py
similarity index 95%
rename from xos/observers/requestrouter/steps/sync_servicemap.py
rename to xos/synchronizers/requestrouter/steps/sync_servicemap.py
index 094e5f1..bef7e42 100644
--- a/xos/observers/requestrouter/steps/sync_servicemap.py
+++ b/xos/synchronizers/requestrouter/steps/sync_servicemap.py
@@ -6,10 +6,10 @@
 import traceback
 from django.db.models import F, Q
 from xos.config import Config, XOS_DIR
-from observer.syncstep import SyncStep
+from synchronizers.base.syncstep import SyncStep
 from core.models import Service
 from services.requestrouter.models import ServiceMap
-from util.logger import Logger, logging
+from xos.logger import Logger, logging
 
 parentdir = os.path.join(os.path.dirname(__file__),"..")
 sys.path.insert(0,parentdir)
diff --git a/xos/observers/syndicate/__init__.py b/xos/synchronizers/syndicate/__init__.py
similarity index 100%
rename from xos/observers/syndicate/__init__.py
rename to xos/synchronizers/syndicate/__init__.py
diff --git a/xos/observers/syndicate/model-deps b/xos/synchronizers/syndicate/model-deps
similarity index 100%
rename from xos/observers/syndicate/model-deps
rename to xos/synchronizers/syndicate/model-deps
diff --git a/xos/observers/syndicate/requirements.py b/xos/synchronizers/syndicate/requirements.py
similarity index 100%
rename from xos/observers/syndicate/requirements.py
rename to xos/synchronizers/syndicate/requirements.py
diff --git a/xos/observers/syndicate/run.sh b/xos/synchronizers/syndicate/run.sh
similarity index 100%
rename from xos/observers/syndicate/run.sh
rename to xos/synchronizers/syndicate/run.sh
diff --git a/xos/observers/syndicate/start.sh b/xos/synchronizers/syndicate/start.sh
similarity index 100%
rename from xos/observers/syndicate/start.sh
rename to xos/synchronizers/syndicate/start.sh
diff --git a/xos/observers/syndicate/steps/sync_volume.py b/xos/synchronizers/syndicate/steps/sync_volume.py
similarity index 98%
rename from xos/observers/syndicate/steps/sync_volume.py
rename to xos/synchronizers/syndicate/steps/sync_volume.py
index c973e8a..e6dc90b 100644
--- a/xos/observers/syndicate/steps/sync_volume.py
+++ b/xos/synchronizers/syndicate/steps/sync_volume.py
@@ -17,7 +17,7 @@
 
 from django.db.models import F, Q
 from xos.config import Config
-from observer.syncstep import SyncStep
+from synchronizers.base.syncstep import SyncStep
 from core.models import Service
 from services.syndicate_storage.models import Volume
 
diff --git a/xos/observers/syndicate/steps/sync_volumeaccessright.py b/xos/synchronizers/syndicate/steps/sync_volumeaccessright.py
similarity index 98%
rename from xos/observers/syndicate/steps/sync_volumeaccessright.py
rename to xos/synchronizers/syndicate/steps/sync_volumeaccessright.py
index c135237..2889502 100644
--- a/xos/observers/syndicate/steps/sync_volumeaccessright.py
+++ b/xos/synchronizers/syndicate/steps/sync_volumeaccessright.py
@@ -16,7 +16,7 @@
 
 from django.db.models import F, Q
 from xos.config import Config
-from observer.syncstep import SyncStep
+from synchronizers.base.syncstep import SyncStep
 from core.models import Service
 
 import logging
diff --git a/xos/observers/syndicate/steps/sync_volumeslice.py b/xos/synchronizers/syndicate/steps/sync_volumeslice.py
similarity index 98%
rename from xos/observers/syndicate/steps/sync_volumeslice.py
rename to xos/synchronizers/syndicate/steps/sync_volumeslice.py
index e88d4c1..1be61b9 100644
--- a/xos/observers/syndicate/steps/sync_volumeslice.py
+++ b/xos/synchronizers/syndicate/steps/sync_volumeslice.py
@@ -16,7 +16,7 @@
 
 from django.db.models import F, Q
 from xos.config import Config
-from observer.syncstep import SyncStep
+from synchronizers.base.syncstep import SyncStep
 from core.models import Service, Slice
 
 import logging
diff --git a/xos/observers/syndicate/stop.sh b/xos/synchronizers/syndicate/stop.sh
similarity index 100%
rename from xos/observers/syndicate/stop.sh
rename to xos/synchronizers/syndicate/stop.sh
diff --git a/xos/observers/syndicate/syndicate-backend.py b/xos/synchronizers/syndicate/syndicate-backend.py
similarity index 77%
rename from xos/observers/syndicate/syndicate-backend.py
rename to xos/synchronizers/syndicate/syndicate-backend.py
index 32670d9..9b53c77 100644
--- a/xos/observers/syndicate/syndicate-backend.py
+++ b/xos/synchronizers/syndicate/syndicate-backend.py
@@ -1,7 +1,7 @@
 #!/usr/bin/env python
 import os
 os.environ.setdefault("DJANGO_SETTINGS_MODULE", "xos.settings")
-from observer.backend import Backend 
+from synchronizers.base.backend import Backend 
 
 if __name__ == '__main__':
 
diff --git a/xos/observers/syndicate/syndicate_observer_config b/xos/synchronizers/syndicate/syndicate_synchronizer_config
similarity index 70%
rename from xos/observers/syndicate/syndicate_observer_config
rename to xos/synchronizers/syndicate/syndicate_synchronizer_config
index 7e6d78a..7c9d2d2 100644
--- a/xos/observers/syndicate/syndicate_observer_config
+++ b/xos/synchronizers/syndicate/syndicate_synchronizer_config
@@ -24,9 +24,9 @@
 nova_enabled=True
 
 [observer]
-dependency_graph=/opt/xos/observers/syndicate/model-deps
-steps_dir=/opt/xos/observers/syndicate/steps
-deleters_dir=/opt/xos/observers/syndicate/deleters
+dependency_graph=/opt/xos/synchronizers/syndicate/model-deps
+steps_dir=/opt/xos/synchronizers/syndicate/steps
+deleters_dir=/opt/xos/synchronizers/syndicate/deleters
 log_file=console
 driver=None
 
diff --git a/xos/observers/syndicate/syndicatelib.py b/xos/synchronizers/syndicate/syndicatelib.py
similarity index 100%
rename from xos/observers/syndicate/syndicatelib.py
rename to xos/synchronizers/syndicate/syndicatelib.py
diff --git a/xos/observers/syndicate/syndicatelib_config/__init__.py b/xos/synchronizers/syndicate/syndicatelib_config/__init__.py
similarity index 100%
rename from xos/observers/syndicate/syndicatelib_config/__init__.py
rename to xos/synchronizers/syndicate/syndicatelib_config/__init__.py
diff --git a/xos/observers/syndicate/syndicatelib_config/config-jude.py b/xos/synchronizers/syndicate/syndicatelib_config/config-jude.py
similarity index 100%
rename from xos/observers/syndicate/syndicatelib_config/config-jude.py
rename to xos/synchronizers/syndicate/syndicatelib_config/config-jude.py
diff --git a/xos/observers/syndicate/syndicatelib_config/config-opencloud.py b/xos/synchronizers/syndicate/syndicatelib_config/config-opencloud.py
similarity index 100%
rename from xos/observers/syndicate/syndicatelib_config/config-opencloud.py
rename to xos/synchronizers/syndicate/syndicatelib_config/config-opencloud.py
diff --git a/xos/observers/syndicate/syndicatelib_config/config.py b/xos/synchronizers/syndicate/syndicatelib_config/config.py
similarity index 100%
rename from xos/observers/syndicate/syndicatelib_config/config.py
rename to xos/synchronizers/syndicate/syndicatelib_config/config.py
diff --git a/xos/observers/syndicate/syndicatelib_config/pollserver.pem b/xos/synchronizers/syndicate/syndicatelib_config/pollserver.pem
similarity index 100%
rename from xos/observers/syndicate/syndicatelib_config/pollserver.pem
rename to xos/synchronizers/syndicate/syndicatelib_config/pollserver.pem
diff --git a/xos/observers/vbng/model-deps b/xos/synchronizers/vbng/model-deps
similarity index 100%
rename from xos/observers/vbng/model-deps
rename to xos/synchronizers/vbng/model-deps
diff --git a/xos/observers/vbng/run.sh b/xos/synchronizers/vbng/run.sh
similarity index 100%
rename from xos/observers/vbng/run.sh
rename to xos/synchronizers/vbng/run.sh
diff --git a/xos/observers/vbng/start.sh b/xos/synchronizers/vbng/start.sh
similarity index 100%
rename from xos/observers/vbng/start.sh
rename to xos/synchronizers/vbng/start.sh
diff --git a/xos/observers/vbng/steps/sync_vbngtenant.py b/xos/synchronizers/vbng/steps/sync_vbngtenant.py
similarity index 97%
rename from xos/observers/vbng/steps/sync_vbngtenant.py
rename to xos/synchronizers/vbng/steps/sync_vbngtenant.py
index de404ff..94875f4 100644
--- a/xos/observers/vbng/steps/sync_vbngtenant.py
+++ b/xos/synchronizers/vbng/steps/sync_vbngtenant.py
@@ -5,12 +5,12 @@
 import base64
 from django.db.models import F, Q
 from xos.config import Config
-from observer.syncstep import SyncStep
-from observer.ansible import run_template_ssh
+from synchronizers.base.syncstep import SyncStep
+from synchronizers.base.ansible import run_template_ssh
 from core.models import Service
 from services.cord.models import VCPEService, VCPETenant, VBNGTenant, VBNGService
 from services.hpc.models import HpcService, CDNPrefix
-from util.logger import Logger, logging
+from xos.logger import Logger, logging
 
 # VBNG_API = "http://10.0.3.136:8181/onos/virtualbng/privateip/"
 
diff --git a/xos/observers/vbng/stop.sh b/xos/synchronizers/vbng/stop.sh
similarity index 100%
rename from xos/observers/vbng/stop.sh
rename to xos/synchronizers/vbng/stop.sh
diff --git a/xos/observers/vbng/supervisor/vbng-observer.conf b/xos/synchronizers/vbng/supervisor/vbng-observer.conf
similarity index 100%
rename from xos/observers/vbng/supervisor/vbng-observer.conf
rename to xos/synchronizers/vbng/supervisor/vbng-observer.conf
diff --git a/xos/observers/helloworld/helloworld-observer.py b/xos/synchronizers/vbng/vbng-synchronizer.py
similarity index 70%
copy from xos/observers/helloworld/helloworld-observer.py
copy to xos/synchronizers/vbng/vbng-synchronizer.py
index d6a71ff..84bec4f 100755
--- a/xos/observers/helloworld/helloworld-observer.py
+++ b/xos/synchronizers/vbng/vbng-synchronizer.py
@@ -5,7 +5,7 @@
 import importlib
 import os
 import sys
-observer_path = os.path.join(os.path.dirname(os.path.realpath(__file__)),"../..")
+observer_path = os.path.join(os.path.dirname(os.path.realpath(__file__)),"../../synchronizers/base")
 sys.path.append(observer_path)
-mod = importlib.import_module("xos-observer")
+mod = importlib.import_module("xos-synchronizer")
 mod.main()
diff --git a/xos/observers/vbng/vbng_observer_config b/xos/synchronizers/vbng/vbng_synchronizer_config
similarity index 69%
rename from xos/observers/vbng/vbng_observer_config
rename to xos/synchronizers/vbng/vbng_synchronizer_config
index b75d498..d613ce3 100644
--- a/xos/observers/vbng/vbng_observer_config
+++ b/xos/synchronizers/vbng/vbng_synchronizer_config
@@ -23,10 +23,10 @@
 
 [observer]
 name=vbng
-dependency_graph=/opt/xos/observers/vbng/model-deps
-steps_dir=/opt/xos/observers/vbng/steps
-sys_dir=/opt/xos/observers/vbng/sys
-deleters_dir=/opt/xos/observers/vbng/deleters
+dependency_graph=/opt/xos/synchronizers/vbng/model-deps
+steps_dir=/opt/xos/synchronizers/vbng/steps
+sys_dir=/opt/xos/synchronizers/vbng/sys
+deleters_dir=/opt/xos/synchronizers/vbng/deleters
 log_file=console
 #/var/log/hpc.log
 driver=None
diff --git a/xos/observers/vcpe/broadbandshield.py b/xos/synchronizers/vcpe/broadbandshield.py
similarity index 100%
rename from xos/observers/vcpe/broadbandshield.py
rename to xos/synchronizers/vcpe/broadbandshield.py
diff --git a/xos/observers/vcpe/files/docker.list b/xos/synchronizers/vcpe/files/docker.list
similarity index 100%
rename from xos/observers/vcpe/files/docker.list
rename to xos/synchronizers/vcpe/files/docker.list
diff --git a/xos/observers/vcpe/files/etc/rc.local b/xos/synchronizers/vcpe/files/etc/rc.local
similarity index 100%
rename from xos/observers/vcpe/files/etc/rc.local
rename to xos/synchronizers/vcpe/files/etc/rc.local
diff --git a/xos/observers/vcpe/files/etc/ufw/after.init b/xos/synchronizers/vcpe/files/etc/ufw/after.init
similarity index 100%
rename from xos/observers/vcpe/files/etc/ufw/after.init
rename to xos/synchronizers/vcpe/files/etc/ufw/after.init
diff --git a/xos/observers/vcpe/files/etc/ufw/after.rules b/xos/synchronizers/vcpe/files/etc/ufw/after.rules
similarity index 100%
rename from xos/observers/vcpe/files/etc/ufw/after.rules
rename to xos/synchronizers/vcpe/files/etc/ufw/after.rules
diff --git a/xos/observers/vcpe/files/etc/ufw/after6.rules b/xos/synchronizers/vcpe/files/etc/ufw/after6.rules
similarity index 100%
rename from xos/observers/vcpe/files/etc/ufw/after6.rules
rename to xos/synchronizers/vcpe/files/etc/ufw/after6.rules
diff --git a/xos/observers/vcpe/files/etc/ufw/applications.d/openssh-server b/xos/synchronizers/vcpe/files/etc/ufw/applications.d/openssh-server
similarity index 100%
rename from xos/observers/vcpe/files/etc/ufw/applications.d/openssh-server
rename to xos/synchronizers/vcpe/files/etc/ufw/applications.d/openssh-server
diff --git a/xos/observers/vcpe/files/etc/ufw/before.init b/xos/synchronizers/vcpe/files/etc/ufw/before.init
similarity index 100%
rename from xos/observers/vcpe/files/etc/ufw/before.init
rename to xos/synchronizers/vcpe/files/etc/ufw/before.init
diff --git a/xos/observers/vcpe/files/etc/ufw/before6.rules b/xos/synchronizers/vcpe/files/etc/ufw/before6.rules
similarity index 100%
rename from xos/observers/vcpe/files/etc/ufw/before6.rules
rename to xos/synchronizers/vcpe/files/etc/ufw/before6.rules
diff --git a/xos/observers/vcpe/files/etc/ufw/sysctl.conf b/xos/synchronizers/vcpe/files/etc/ufw/sysctl.conf
similarity index 100%
rename from xos/observers/vcpe/files/etc/ufw/sysctl.conf
rename to xos/synchronizers/vcpe/files/etc/ufw/sysctl.conf
diff --git a/xos/observers/vcpe/files/etc/ufw/ufw.conf b/xos/synchronizers/vcpe/files/etc/ufw/ufw.conf
similarity index 100%
rename from xos/observers/vcpe/files/etc/ufw/ufw.conf
rename to xos/synchronizers/vcpe/files/etc/ufw/ufw.conf
diff --git a/xos/observers/vcpe/files/vcpe.conf b/xos/synchronizers/vcpe/files/vcpe.conf
similarity index 100%
rename from xos/observers/vcpe/files/vcpe.conf
rename to xos/synchronizers/vcpe/files/vcpe.conf
diff --git a/xos/observers/vcpe/files/vcpe.dnsmasq b/xos/synchronizers/vcpe/files/vcpe.dnsmasq
similarity index 100%
rename from xos/observers/vcpe/files/vcpe.dnsmasq
rename to xos/synchronizers/vcpe/files/vcpe.dnsmasq
diff --git a/xos/observers/vcpe/files/vm-resolv.conf b/xos/synchronizers/vcpe/files/vm-resolv.conf
similarity index 100%
rename from xos/observers/vcpe/files/vm-resolv.conf
rename to xos/synchronizers/vcpe/files/vm-resolv.conf
diff --git a/xos/observers/vcpe/model-deps b/xos/synchronizers/vcpe/model-deps
similarity index 100%
rename from xos/observers/vcpe/model-deps
rename to xos/synchronizers/vcpe/model-deps
diff --git a/xos/observers/vcpe/observer_ansible_test.py b/xos/synchronizers/vcpe/observer_ansible_test.py
similarity index 98%
rename from xos/observers/vcpe/observer_ansible_test.py
rename to xos/synchronizers/vcpe/observer_ansible_test.py
index 77715af..b28da63 100644
--- a/xos/observers/vcpe/observer_ansible_test.py
+++ b/xos/synchronizers/vcpe/observer_ansible_test.py
@@ -3,36 +3,36 @@
 import sys
 
 sys.path.append("../..")
-import observer.ansible
+import synchronizers.base.ansible
 
 print sys.argv
 
 private_key="""-----BEGIN RSA PRIVATE KEY-----
-MIIEpQIBAAKCAQEAtJiuarud5S4Y2quDeWyaS0UCQGQtfuSzzNhplFwujYnJGL65

-e14REtv+UuHGymyr/SfkTrBd8vH5NI2UZ/4sZW13ieI/1d97OeVe2+ct0Y4BaFEI

-3Hja6DIpsY3Q2cBQsWUwcQzbMIF9jIq8SzwR1zk8UtZi09fNxqjCchRPlBvbiLKX

-g0/yirN237WbaKzK++8EPy3nuv83216MXHFFSjuxfICe/RhjaqMzVp7isSbv1suU

-geyvNNzU71c/K13gTggdcIXeRQBiJYio2Sn3h2nsV6AFqFH4fjERxWG55Q4e3jeE

-tWM/Dw+hqYKg/25UcmM862a6sUmuDCmM5S3VEQIDAQABAoIBACH88iZoNOki6c6N

-pOq/Q7KSxD+2GtHc3PHacNRZHPHKUqxziJjtNS1lddHHaBBEr4GvdkpQ6v2ECLCZ

-TKrdrSFRnsO2bukjbB+TSWz9byQXI7CsP4yuuhQlDK+7zuiMRyN7tcgw8TeJx0Uh

-/xnxrjHhNbcpXeQcoz+WFzI9HFT1MEGmMS4Lyp/zLB/pmfY9h7V9d+EeRZDi78jq

-Vir6MI6iCTa0T02dvHUFOg+wXLb0nb8V1xKDL+6cAJla7LzwoG8lTnvp5DSYCojI

-5JrILYafeO8RbBV2GWmaE5mkHgeBkFZ+qZQ7K0MjR30Yh6tajB7P3+F/Max8FUgW

-xLHr8AECgYEA2+o0ge3HtZcepEFBKKYnLTwoEpPCfLElWZHzUJYDz259s4JLsfak

-tROANFEdsJUjpmWG52MCL+bgKFFOedDkt4p1jgcIneaHk0jvoU11wG7W3jZZVy1q

-WjQNH5vDU+hg5tm/CREwm7lbUxR9Xuj9K63CNAAGp8KO7h2tOH8woIECgYEA0jrb

-LUg30RxO3+vrq9dUYohrDRisk5zKXuRLfxRA+E+ruvZ7CctG2OpM+658/qZM/w95

-7pOj6zz3//w7tAvH9erY+JOISnzaYKx04sYC1MfbFiFkq5j0gpuYm/MULDYNvFqr

-NU2Buj4dW+ZB+SeficsQOqm5QeNxh1kgiDCs7JECgYEAjSLGCAzeesA9vhTTCI95

-3SIaZbHGw9e8rLtqeHGOiHXU3nvksJYmJsAZK3pTn5xXgNbvuVhlcvCtM7LatntG

-DjUiNMB22z+0CuZoRBE+XP3FkF84/yX6d2Goenyw4wzkA8QDQoJxu789yRgBTgQh

-VwLw/AZ4PvoyWMdbAENApgECgYEAvFikosYP09XTyIPaKaOKY5iqqBoSC1GucSOB

-jAG+T3k5dxB6nQS0nYQUomvqak7drqnT6O33Lrr5ySrW5nCjnmvgJZwvv+Rp1bDM

-K5uRT8caPpJ+Wcp4TUdPi3BVA2MOHVDyEJg3AH/D1+DL/IgGQ/JcwOHsKt61iLhO

-EBXj5zECgYEAk+HuwksUPkSxg/AiJGbapGDK6XGymEUzo2duWlnofRqGcZ3NT3bB

-/kDI1KxQdlpODXSi4/BuTpbQiFOrzcEq5e5ytoMxlCHh3Fl3Jxl+JlgO21vAUvP6

-4SET7Q/6LxmfBlCVRg0dXDwcfJLgbnWxyvprIcz4e0FSFVZTBs/6tFk=

+MIIEpQIBAAKCAQEAtJiuarud5S4Y2quDeWyaS0UCQGQtfuSzzNhplFwujYnJGL65
+e14REtv+UuHGymyr/SfkTrBd8vH5NI2UZ/4sZW13ieI/1d97OeVe2+ct0Y4BaFEI
+3Hja6DIpsY3Q2cBQsWUwcQzbMIF9jIq8SzwR1zk8UtZi09fNxqjCchRPlBvbiLKX
+g0/yirN237WbaKzK++8EPy3nuv83216MXHFFSjuxfICe/RhjaqMzVp7isSbv1suU
+geyvNNzU71c/K13gTggdcIXeRQBiJYio2Sn3h2nsV6AFqFH4fjERxWG55Q4e3jeE
+tWM/Dw+hqYKg/25UcmM862a6sUmuDCmM5S3VEQIDAQABAoIBACH88iZoNOki6c6N
+pOq/Q7KSxD+2GtHc3PHacNRZHPHKUqxziJjtNS1lddHHaBBEr4GvdkpQ6v2ECLCZ
+TKrdrSFRnsO2bukjbB+TSWz9byQXI7CsP4yuuhQlDK+7zuiMRyN7tcgw8TeJx0Uh
+/xnxrjHhNbcpXeQcoz+WFzI9HFT1MEGmMS4Lyp/zLB/pmfY9h7V9d+EeRZDi78jq
+Vir6MI6iCTa0T02dvHUFOg+wXLb0nb8V1xKDL+6cAJla7LzwoG8lTnvp5DSYCojI
+5JrILYafeO8RbBV2GWmaE5mkHgeBkFZ+qZQ7K0MjR30Yh6tajB7P3+F/Max8FUgW
+xLHr8AECgYEA2+o0ge3HtZcepEFBKKYnLTwoEpPCfLElWZHzUJYDz259s4JLsfak
+tROANFEdsJUjpmWG52MCL+bgKFFOedDkt4p1jgcIneaHk0jvoU11wG7W3jZZVy1q
+WjQNH5vDU+hg5tm/CREwm7lbUxR9Xuj9K63CNAAGp8KO7h2tOH8woIECgYEA0jrb
+LUg30RxO3+vrq9dUYohrDRisk5zKXuRLfxRA+E+ruvZ7CctG2OpM+658/qZM/w95
+7pOj6zz3//w7tAvH9erY+JOISnzaYKx04sYC1MfbFiFkq5j0gpuYm/MULDYNvFqr
+NU2Buj4dW+ZB+SeficsQOqm5QeNxh1kgiDCs7JECgYEAjSLGCAzeesA9vhTTCI95
+3SIaZbHGw9e8rLtqeHGOiHXU3nvksJYmJsAZK3pTn5xXgNbvuVhlcvCtM7LatntG
+DjUiNMB22z+0CuZoRBE+XP3FkF84/yX6d2Goenyw4wzkA8QDQoJxu789yRgBTgQh
+VwLw/AZ4PvoyWMdbAENApgECgYEAvFikosYP09XTyIPaKaOKY5iqqBoSC1GucSOB
+jAG+T3k5dxB6nQS0nYQUomvqak7drqnT6O33Lrr5ySrW5nCjnmvgJZwvv+Rp1bDM
+K5uRT8caPpJ+Wcp4TUdPi3BVA2MOHVDyEJg3AH/D1+DL/IgGQ/JcwOHsKt61iLhO
+EBXj5zECgYEAk+HuwksUPkSxg/AiJGbapGDK6XGymEUzo2duWlnofRqGcZ3NT3bB
+/kDI1KxQdlpODXSi4/BuTpbQiFOrzcEq5e5ytoMxlCHh3Fl3Jxl+JlgO21vAUvP6
+4SET7Q/6LxmfBlCVRg0dXDwcfJLgbnWxyvprIcz4e0FSFVZTBs/6tFk=
 -----END RSA PRIVATE KEY-----
 """
 
diff --git a/xos/observers/vcpe/run.sh b/xos/synchronizers/vcpe/run.sh
similarity index 100%
rename from xos/observers/vcpe/run.sh
rename to xos/synchronizers/vcpe/run.sh
diff --git a/xos/observers/vcpe/start-bbs.sh b/xos/synchronizers/vcpe/start-bbs.sh
similarity index 100%
rename from xos/observers/vcpe/start-bbs.sh
rename to xos/synchronizers/vcpe/start-bbs.sh
diff --git a/xos/observers/vcpe/start.sh b/xos/synchronizers/vcpe/start.sh
similarity index 100%
rename from xos/observers/vcpe/start.sh
rename to xos/synchronizers/vcpe/start.sh
diff --git a/xos/observers/vcpe/steps/ansible_test/README b/xos/synchronizers/vcpe/steps/ansible_test/README
similarity index 100%
rename from xos/observers/vcpe/steps/ansible_test/README
rename to xos/synchronizers/vcpe/steps/ansible_test/README
diff --git a/xos/observers/vcpe/steps/ansible_test/inventory.txt b/xos/synchronizers/vcpe/steps/ansible_test/inventory.txt
similarity index 100%
rename from xos/observers/vcpe/steps/ansible_test/inventory.txt
rename to xos/synchronizers/vcpe/steps/ansible_test/inventory.txt
diff --git a/xos/observers/vcpe/steps/ansible_test/test.sh b/xos/synchronizers/vcpe/steps/ansible_test/test.sh
similarity index 100%
rename from xos/observers/vcpe/steps/ansible_test/test.sh
rename to xos/synchronizers/vcpe/steps/ansible_test/test.sh
diff --git a/xos/observers/vcpe/steps/ansible_test/test.yaml b/xos/synchronizers/vcpe/steps/ansible_test/test.yaml
similarity index 100%
rename from xos/observers/vcpe/steps/ansible_test/test.yaml
rename to xos/synchronizers/vcpe/steps/ansible_test/test.yaml
diff --git a/xos/observers/vcpe/steps/ansible_test/xos.py b/xos/synchronizers/vcpe/steps/ansible_test/xos.py
similarity index 100%
rename from xos/observers/vcpe/steps/ansible_test/xos.py
rename to xos/synchronizers/vcpe/steps/ansible_test/xos.py
diff --git a/xos/observers/vcpe/steps/sync_vcpetenant.py b/xos/synchronizers/vcpe/steps/sync_vcpetenant.py
similarity index 97%
rename from xos/observers/vcpe/steps/sync_vcpetenant.py
rename to xos/synchronizers/vcpe/steps/sync_vcpetenant.py
index 477c250..691671a 100644
--- a/xos/observers/vcpe/steps/sync_vcpetenant.py
+++ b/xos/synchronizers/vcpe/steps/sync_vcpetenant.py
@@ -6,13 +6,13 @@
 import time
 from django.db.models import F, Q
 from xos.config import Config
-from observer.syncstep import SyncStep
-from observer.ansible import run_template_ssh
-from observers.base.SyncInstanceUsingAnsible import SyncInstanceUsingAnsible
+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
 from services.cord.models import VCPEService, VCPETenant, VOLTTenant
 from services.hpc.models import HpcService, CDNPrefix
-from util.logger import Logger, logging
+from xos.logger import Logger, logging
 
 # hpclibrary will be in steps/..
 parentdir = os.path.join(os.path.dirname(__file__),"..")
diff --git a/xos/observers/vcpe/steps/sync_vcpetenant.yaml b/xos/synchronizers/vcpe/steps/sync_vcpetenant.yaml
similarity index 100%
rename from xos/observers/vcpe/steps/sync_vcpetenant.yaml
rename to xos/synchronizers/vcpe/steps/sync_vcpetenant.yaml
diff --git a/xos/observers/vcpe/steps/sync_vcpetenant_new.yaml b/xos/synchronizers/vcpe/steps/sync_vcpetenant_new.yaml
similarity index 77%
rename from xos/observers/vcpe/steps/sync_vcpetenant_new.yaml
rename to xos/synchronizers/vcpe/steps/sync_vcpetenant_new.yaml
index eb647b6..6c7166f 100644
--- a/xos/observers/vcpe/steps/sync_vcpetenant_new.yaml
+++ b/xos/synchronizers/vcpe/steps/sync_vcpetenant_new.yaml
@@ -57,6 +57,32 @@
         {% endfor %}
 
   tasks:
+  - name: Verify if vcpe_stats_notifier ([] is to avoid capturing the shell process) cron job is already running
+    shell: pgrep -f [v]cpe_stats_notifier | wc -l
+    register: cron_job_pids_count
+
+#  - name: DEBUG
+#    debug: var=cron_job_pids_count.stdout
+
+  - name: make sure ~/bin exists
+    file: path=~/bin state=directory owner=root group=root
+    when: cron_job_pids_count.stdout == "0"
+
+  - name: Copy cron job to destination
+    copy: src=/opt/xos/observers/vcpe/vcpe_stats_notifier.py
+      dest=~/bin/vcpe_stats_notifier.py
+    when: cron_job_pids_count.stdout == "0"
+
+  - name: install python-kombu
+    apt: name=python-kombu state=present
+    when: cron_job_pids_count.stdout == "0"
+
+  - name: Initiate vcpe_stats_notifier cron job
+    command: python ~/bin/vcpe_stats_notifier.py --keystone_tenant_id={{ keystone_tenant_id }} --keystone_user_id={{ keystone_user_id }} --rabbit_user={{ rabbit_user }} --rabbit_password={{ rabbit_password }} --rabbit_host={{ rabbit_host }} --vcpeservice_rabbit_exchange='vcpeservice'
+    async: 9999999999999999
+    poll: 0
+    when: cron_job_pids_count.stdout == "0"
+
   - name: vCPE basic dnsmasq config
     copy: src=/opt/xos/observers/vcpe/files/vcpe.dnsmasq dest=/var/container_volumes/{{ container_name }}/etc/dnsmasq.d/vcpe.conf owner=root group=root
     notify:
diff --git a/xos/observers/vcpe/steps/test.yaml b/xos/synchronizers/vcpe/steps/test.yaml
similarity index 100%
rename from xos/observers/vcpe/steps/test.yaml
rename to xos/synchronizers/vcpe/steps/test.yaml
diff --git a/xos/observers/vcpe/stop.sh b/xos/synchronizers/vcpe/stop.sh
similarity index 100%
rename from xos/observers/vcpe/stop.sh
rename to xos/synchronizers/vcpe/stop.sh
diff --git a/xos/observers/vcpe/supervisor/vcpe-observer.conf b/xos/synchronizers/vcpe/supervisor/vcpe-observer.conf
similarity index 100%
rename from xos/observers/vcpe/supervisor/vcpe-observer.conf
rename to xos/synchronizers/vcpe/supervisor/vcpe-observer.conf
diff --git a/xos/observers/vcpe/templates/before.rules.j2 b/xos/synchronizers/vcpe/templates/before.rules.j2
similarity index 100%
rename from xos/observers/vcpe/templates/before.rules.j2
rename to xos/synchronizers/vcpe/templates/before.rules.j2
diff --git a/xos/observers/vcpe/templates/dnsmasq_safe_servers.j2 b/xos/synchronizers/vcpe/templates/dnsmasq_safe_servers.j2
similarity index 100%
rename from xos/observers/vcpe/templates/dnsmasq_safe_servers.j2
rename to xos/synchronizers/vcpe/templates/dnsmasq_safe_servers.j2
diff --git a/xos/observers/vcpe/templates/dnsmasq_servers.j2 b/xos/synchronizers/vcpe/templates/dnsmasq_servers.j2
similarity index 100%
rename from xos/observers/vcpe/templates/dnsmasq_servers.j2
rename to xos/synchronizers/vcpe/templates/dnsmasq_servers.j2
diff --git a/xos/observers/vcpe/templates/firewall_sample.j2 b/xos/synchronizers/vcpe/templates/firewall_sample.j2
similarity index 100%
rename from xos/observers/vcpe/templates/firewall_sample.j2
rename to xos/synchronizers/vcpe/templates/firewall_sample.j2
diff --git a/xos/observers/vcpe/templates/start-vcpe.sh.j2 b/xos/synchronizers/vcpe/templates/start-vcpe.sh.j2
similarity index 100%
rename from xos/observers/vcpe/templates/start-vcpe.sh.j2
rename to xos/synchronizers/vcpe/templates/start-vcpe.sh.j2
diff --git a/xos/observers/vcpe/templates/vcpe.conf.j2 b/xos/synchronizers/vcpe/templates/vcpe.conf.j2
similarity index 100%
rename from xos/observers/vcpe/templates/vcpe.conf.j2
rename to xos/synchronizers/vcpe/templates/vcpe.conf.j2
diff --git a/xos/observers/vcpe/templates/vlan_sample.j2 b/xos/synchronizers/vcpe/templates/vlan_sample.j2
similarity index 100%
rename from xos/observers/vcpe/templates/vlan_sample.j2
rename to xos/synchronizers/vcpe/templates/vlan_sample.j2
diff --git a/xos/observers/helloworld/helloworld-observer.py b/xos/synchronizers/vcpe/vcpe-synchronizer.py
similarity index 70%
copy from xos/observers/helloworld/helloworld-observer.py
copy to xos/synchronizers/vcpe/vcpe-synchronizer.py
index d6a71ff..84bec4f 100755
--- a/xos/observers/helloworld/helloworld-observer.py
+++ b/xos/synchronizers/vcpe/vcpe-synchronizer.py
@@ -5,7 +5,7 @@
 import importlib
 import os
 import sys
-observer_path = os.path.join(os.path.dirname(os.path.realpath(__file__)),"../..")
+observer_path = os.path.join(os.path.dirname(os.path.realpath(__file__)),"../../synchronizers/base")
 sys.path.append(observer_path)
-mod = importlib.import_module("xos-observer")
+mod = importlib.import_module("xos-synchronizer")
 mod.main()
diff --git a/xos/observers/vcpe/vcpe_stats_notifier.py b/xos/synchronizers/vcpe/vcpe_stats_notifier.py
similarity index 100%
rename from xos/observers/vcpe/vcpe_stats_notifier.py
rename to xos/synchronizers/vcpe/vcpe_stats_notifier.py
diff --git a/xos/observers/vcpe/vcpe_observer_config b/xos/synchronizers/vcpe/vcpe_synchronizer_config
similarity index 73%
rename from xos/observers/vcpe/vcpe_observer_config
rename to xos/synchronizers/vcpe/vcpe_synchronizer_config
index d2c9239..110b8e2 100644
--- a/xos/observers/vcpe/vcpe_observer_config
+++ b/xos/synchronizers/vcpe/vcpe_synchronizer_config
@@ -23,10 +23,10 @@
 
 [observer]
 name=vcpe
-dependency_graph=/opt/xos/observers/vcpe/model-deps
-steps_dir=/opt/xos/observers/vcpe/steps
-sys_dir=/opt/xos/observers/vcpe/sys
-deleters_dir=/opt/xos/observers/vcpe/deleters
+dependency_graph=/opt/xos/synchronizers/vcpe/model-deps
+steps_dir=/opt/xos/synchronizers/vcpe/steps
+sys_dir=/opt/xos/synchronizers/vcpe/sys
+deleters_dir=/opt/xos/synchronizers/vcpe/deleters
 log_file=console
 #/var/log/hpc.log
 driver=None
diff --git a/xos/observers/vtn/model-deps b/xos/synchronizers/vtn/model-deps
similarity index 100%
rename from xos/observers/vtn/model-deps
rename to xos/synchronizers/vtn/model-deps
diff --git a/xos/observers/vtn/run.sh b/xos/synchronizers/vtn/run.sh
similarity index 100%
rename from xos/observers/vtn/run.sh
rename to xos/synchronizers/vtn/run.sh
diff --git a/xos/observers/vtn/start.sh b/xos/synchronizers/vtn/start.sh
similarity index 100%
rename from xos/observers/vtn/start.sh
rename to xos/synchronizers/vtn/start.sh
diff --git a/xos/synchronizers/vtn/steps/sync_tenant.py b/xos/synchronizers/vtn/steps/sync_tenant.py
new file mode 100644
index 0000000..cc374be
--- /dev/null
+++ b/xos/synchronizers/vtn/steps/sync_tenant.py
@@ -0,0 +1,95 @@
+import os
+import requests
+import socket
+import sys
+import base64
+from django.db.models import F, Q
+from xos.config import Config
+from synchronizers.base.syncstep import SyncStep
+from core.models import Service
+from core.models.service import COARSE_KIND
+from services.cord.models import Tenant
+from xos.logger import Logger, logging
+from requests.auth import HTTPBasicAuth
+
+# hpclibrary will be in steps/..
+parentdir = os.path.join(os.path.dirname(__file__),"..")
+sys.path.insert(0,parentdir)
+
+logger = Logger(level=logging.INFO)
+
+# XXX should save and load this
+glo_saved_vtn_maps = []
+
+class SyncTenant(SyncStep):
+    provides=[Tenant]
+    observes=Tenant
+    requested_interval=0
+
+    def __init__(self, **args):
+        SyncStep.__init__(self, **args)
+
+    def get_vtn_onos_service(self):
+#        vtn_tenant = Tenant.objects.filter(name="VTN_ONOS_app")   # XXX fixme - hardcoded
+#        if not vtn_tenant:
+#            raise "No VTN Onos App found"
+#        vtn_tenant = vtn_tenant[0]
+#
+#        vtn_service = vtn_tenant.provider_service
+        vtn_service = Service.objects.filter(name="service_ONOS_VTN")  # XXX fixme - harcoded
+        if not vtn_service:
+            raise "No VTN Onos Service"
+
+        return vtn_service[0]
+
+    def get_vtn_addr(self):
+        vtn_service = self.get_vtn_onos_service()
+
+        if not vtn_service.slices.exists():
+            raise "VTN Service has no slices"
+
+        vtn_slice = vtn_service.slices.all()[0]
+
+        if not vtn_slice.instances.exists():
+            raise "VTN Slice has no instances"
+
+        vtn_instance = vtn_slice.instances.all()[0]
+
+        return vtn_instance.node.name
+
+    def call(self, **args):
+        global glo_saved_vtn_maps
+
+        logger.info("sync'ing vtn services")
+
+        vtn_maps = []
+        for service in Service.objects.all():
+           for id in service.get_vtn_src_ids():
+               dependencies = service.get_vtn_dependencies_ids()
+               if dependencies:
+                   for dependency in dependencies:
+                       vtn_maps.append( (id, dependency) )
+
+        for vtn_map in vtn_maps:
+            if not (vtn_map in glo_saved_vtn_maps):
+                # call vtn rest api to add map
+                url = "http://" + self.get_vtn_addr() + ":8181/onos/cordvtn/service-dependency/%s/%s" % (vtn_map[0], vtn_map[1])
+
+                print "POST %s" % url
+                r = requests.post(url, auth=HTTPBasicAuth('karaf', 'karaf') )    # XXX fixme - hardcoded auth
+                if (r.status_code != 200):
+                    raise Exception("Received error from vtn service (%d)" % r.status_code)
+
+        for vtn_map in glo_saved_vtn_maps:
+            if not vtn_map in vtn_maps:
+                # call vtn rest api to delete map
+                url = "http://" + self.get_vtn_addr() + ":8181/onos/cordvtn/service-dependency/%s/%s" % (vtn_map[0],vtn_map[1])
+
+                print "DELETE %s" % url
+                r = requests.delete(url, auth=HTTPBasicAuth('karaf', 'karaf') )    # XXX fixme - hardcoded auth
+                if (r.status_code != 200):
+                    raise Exception("Received error from vtn service (%d)" % r.status_code)
+
+        glo_saved_vtn_maps = vtn_maps
+        # TODO: save this
+
diff --git a/xos/observers/vtn/stop.sh b/xos/synchronizers/vtn/stop.sh
similarity index 100%
rename from xos/observers/vtn/stop.sh
rename to xos/synchronizers/vtn/stop.sh
diff --git a/xos/observers/vtn/supervisor/vtn-observer.conf b/xos/synchronizers/vtn/supervisor/vtn-observer.conf
similarity index 100%
rename from xos/observers/vtn/supervisor/vtn-observer.conf
rename to xos/synchronizers/vtn/supervisor/vtn-observer.conf
diff --git a/xos/observers/helloworld/helloworld-observer.py b/xos/synchronizers/vtn/vtn-synchronizer.py
similarity index 70%
copy from xos/observers/helloworld/helloworld-observer.py
copy to xos/synchronizers/vtn/vtn-synchronizer.py
index d6a71ff..84bec4f 100755
--- a/xos/observers/helloworld/helloworld-observer.py
+++ b/xos/synchronizers/vtn/vtn-synchronizer.py
@@ -5,7 +5,7 @@
 import importlib
 import os
 import sys
-observer_path = os.path.join(os.path.dirname(os.path.realpath(__file__)),"../..")
+observer_path = os.path.join(os.path.dirname(os.path.realpath(__file__)),"../../synchronizers/base")
 sys.path.append(observer_path)
-mod = importlib.import_module("xos-observer")
+mod = importlib.import_module("xos-synchronizer")
 mod.main()
diff --git a/xos/observers/vtn/vtn_observer_config b/xos/synchronizers/vtn/vtn_synchronizer_config
similarity index 69%
rename from xos/observers/vtn/vtn_observer_config
rename to xos/synchronizers/vtn/vtn_synchronizer_config
index 19e9a39..302a096 100644
--- a/xos/observers/vtn/vtn_observer_config
+++ b/xos/synchronizers/vtn/vtn_synchronizer_config
@@ -23,10 +23,10 @@
 
 [observer]
 name=vtn
-dependency_graph=/opt/xos/observers/vtn/model-deps
-steps_dir=/opt/xos/observers/vtn/steps
-sys_dir=/opt/xos/observers/vtn/sys
-deleters_dir=/opt/xos/observers/vtn/deleters
+dependency_graph=/opt/xos/synchronizers/vtn/model-deps
+steps_dir=/opt/xos/synchronizers/vtn/steps
+sys_dir=/opt/xos/synchronizers/vtn/sys
+deleters_dir=/opt/xos/synchronizers/vtn/deleters
 log_file=console
 #/var/log/hpc.log
 driver=None
diff --git a/xos/templates/README.md b/xos/templates/README.md
new file mode 100644
index 0000000..af46be9
--- /dev/null
+++ b/xos/templates/README.md
@@ -0,0 +1,5 @@
+# DJANGO TEMPLATES
+
+These are the templates used by the Django Application to render the UI.
+
+More information are available in the [Django Documentation](https://docs.djangoproject.com/es/1.9/topics/templates/)
\ No newline at end of file
diff --git a/xos/templates/admin/base.html b/xos/templates/admin/base.html
index f049da9..a9f0f21 100644
--- a/xos/templates/admin/base.html
+++ b/xos/templates/admin/base.html
@@ -66,7 +66,8 @@
         <a href="{% url 'admin:index' %}" class="hidden-xs">
           <img class="logo" src="{% static XOS_BRANDING_ICON %}"/>
         </a>
-        {% include 'suit/menu.html' %}
+        <!--{% include 'suit/menu.html' %}-->
+        {% include 'admin/menu.html' %}
         <button class="navbar-toggle collapsed visible-xs" type="button">
           <i class="glyphicon glyphicon-arrow-left"></i>
         </button>
diff --git a/xos/templates/admin/menu.html b/xos/templates/admin/menu.html
new file mode 100644
index 0000000..e1176e3
--- /dev/null
+++ b/xos/templates/admin/menu.html
@@ -0,0 +1,52 @@
+{#{% load sitetree %}#}
+{% load i18n suit_menu suit_tags %}
+{% load url from future %}
+
+{% with menu_position='menu_position'|suit_conf %}
+<ul class="nav nav-suit-menu nav-pills{% if menu_position == 'vertical' %} nav-stacked {% endif %}">
+    {% block menu_home %}
+    {% url 'admin:index' as index_url %}
+    <li{% if index_url == request.path %} class="active"{% endif %}>
+        <a href="{{ index_url }}"><i class="icon-home"></i>{% trans 'Home' %}
+    </a>
+    </li>
+    {% endblock %}
+
+    {% get_menu request as app_list %}
+        {% if app_list %}
+            {% for app in app_list %}
+                {% if app.separator %}
+                <li class="separator"></li>
+                {% else %}
+                <li{{ app.is_active|yesno:' class=active,' }}>
+                    <a href="{{ app.url }}"{{ app.blank|yesno:' target=_blank,' }}>
+                        <i class="{% firstof app.icon 'icon-chevron-right' %}"></i>
+                        {% trans app.label|capfirst %}
+                    </a>
+                    {% if app.models and not app.is_active %}
+                    <ul class="nav nav-pills nav-stacked">
+                        {% for model in app.models %}
+                            <li{{ model.is_active|yesno:' class=active,' }}>
+                                <a href="{{ model.url }}"{{ model.blank|yesno:' target=_blank,' }}>{{ model.label }}</a>
+                            </li>
+                        {% endfor %}
+                    </ul>
+                {% endif %}
+                </li>
+            {% endif %}
+            {% endfor %}
+        {% endif %}
+</ul>
+{% if app_list and menu_position == 'horizontal' %}
+    {% get_sub_menu app_list as active_app_nodels %}
+    <ul class="nav nav-suit-sub-menu nav-pills">
+        {% if active_app_nodels %}
+            {% for model in active_app_nodels %}
+            <li{{ model.is_active|yesno:' class=active,' }}>
+                <a href="{{ model.url }}"{{ model.blank|yesno:' target=_blank,' }}>{{ model.label }}</a>
+            </li>
+            {% endfor %}
+        {% endif %}
+    </ul>
+    {% endif %}
+{% endwith %}
\ No newline at end of file
diff --git a/xos/templates/cord_admin/base.html b/xos/templates/cord_admin/base.html
deleted file mode 100644
index db5ccbf..0000000
--- a/xos/templates/cord_admin/base.html
+++ /dev/null
@@ -1,287 +0,0 @@
-{% load admin_static %}{% load suit_tags %}{% load url from future %}<!DOCTYPE html>
-<html lang="{{ LANGUAGE_CODE|default:"en-us" }}" {% if LANGUAGE_BIDI %}dir="rtl"{% endif %}>
-<head>
-  <title>{% block title %}  {%if title %} {{ title }} | {% endif %} CORD {% endblock %}</title>
-  <link rel="stylesheet" type="text/css" href="{% block stylesheet %}{% endblock %}"/>
-  <link rel="stylesheet" type="text/css" href="{% static 'suit/bootstrap/css/bootstrap.min.css' %}" media="all"/>
-  <link rel="stylesheet" type="text/css" href="{% static 'suit/css/suit.css' %}" media="all">
-  <link rel="stylesheet" type="text/css" href="{% static 'xos.css' %}" media="all">
-  <link rel="stylesheet" type="text/css" href="{% static 'cord.css' %}" media="all">
-  {% block extrastyle %}{% endblock %}
-  {% if LANGUAGE_BIDI %}<link rel="stylesheet" type="text/css" href="{% block stylesheet_rtl %}{% static "admin/css/rtl.css" %}{% endblock %}"/>{% endif %}
-  <script type="text/javascript">window.__admin_media_prefix__ = "{% filter escapejs %}{% static "admin/" %}{% endfilter %}";</script>
-  <script src="{% static 'suit/js/jquery-1.9.1.min.js' %}"></script>
-  <script src="http://code.jquery.com/ui/1.10.4/jquery-ui.js"></script>
-  <link rel="stylesheet" href="http://code.jquery.com/ui/1.10.4/themes/smoothness/jquery-ui.css">
-  <script type="text/javascript" src="{% static 'log4javascript-1.4.6/log4javascript.js' %}"></script>
-  <script type="text/javascript" src="{% static 'uploadTextarea.js' %}"></script>
-  <script type="text/javascript" src="{% static 'observer_status.js' %}"></script>
-
-  <script type="text/javascript">var Suit = { $: $.noConflict() }; if (!$) $ = Suit.$; </script>
-  {% if 'SHOW_REQUIRED_ASTERISK'|suit_conf %}
-  <style type="text/css">.required:after { content: '*'; margin: 0 0 0 5px; position: absolute; color: #ccc;}</style>
-  {% endif %}
-  {% block extrahead %}{% endblock %}
-  {% block blockbots %}
-    <meta name="robots" content="NONE,NOARCHIVE"/>{% endblock %}
-  <link rel="shortcut icon" href="{% static 'favicon.png' %}">
-</head>
-{% load i18n %}
-
-<body class="{% if is_popup %}popup {% endif %}{% block bodyclass %}{% endblock %}">
-
-<div id="dialog-placeholder">
-<!-- This is a placeholder for dialog boxes, like the observer calendar -->
-</div>
-
-<!-- Sticky footer wrap -->
-<div id="wrap">
-
-  <!-- Container -->
-  {% block container %}
-    <div id="container">
-
-      {% block logo %}
-      <a href="{% url 'admin:index' %}"><h1 id="site-name"><img class="logo" height="70" width="259" src="{% static 'open-cloud-login-themed-light.png' %}"/></h1></a>
-      {% endblock %}
-      {% block header %}
-        {% if not is_popup %}
-          <!-- Header -->
-          <div id="header" class="header">
-            
-            <div id="branding">
-                  {% block quick-search %}
-                {% with 'SEARCH_URL'|suit_conf as search_url %}
-                  {% if search_url %}
-                    <form class="form-search nav-quick-search" autocomplete="off" action="{% if '/' in search_url %}{{ search_url }}{% else %}{% url search_url %}{% endif %}" method="GET">
-                      <i class="input-icon icon-search"></i>
-                      <input type="text" name="q" class="input-medium search-query" id="quick-search">
-                      <input type="submit" class="submit" value="">
-                    </form>
-                  {% endif %}
-                {% endwith %}
-              {% endblock %}
-            </div>
-          
-            {% block header_time %}
-            <div id="branding2">
-            <!--<div class="header-content header-content-first">
-              <div class="header-column icon">
-                <i class="icon-time"></i>
-              </div>
-              <div class="header-column">
-                <span class="date"> {% suit_date %}</span><br>
-                <span class="time" id="clock">{% suit_time %}</span>
-              </div>
-            </div>-->
-          
-            {% endblock %}
-
-            {% block header_content %}
-              <!--<div class="header-content">
-                <div class="header-column icon">
-                  <i class="icon-comment"></i>
-                </div>
-                <div class="header-column">
-                  <a href="" class="grey"><b>2</b> new messages</a>
-                </div>
-              </div>-->
-            {% endblock %}
-
-            {% if user.is_active and user.is_staff %}
-              <div id="user-tools">
-                {% trans 'Welcome,' %}
-                <a href="http://{{ request.get_host}}/admin/core/user/{{user.id}}">{{user.email}}</a>
-                <span id="observer-status"></span>
-                <span class="user-links">
-                {% block userlinks %}
-                  {% url 'django-admindocs-docroot' as docsroot %}
-                  {% if docsroot %}
-                    <a href="http://guide.xosproject.org/">{% trans 'Documentation' %}</a>
-                   <span class="separator">|</span>
-                  {% endif %}
-                  <a href="{% url 'admin:password_change' %}">{% trans 'Change password' %}</a>
-                  <span class="separator">|</span>
-                  <a href="{% url 'admin:logout' %}">{% trans 'Log out' %}</a>
-                  </span>
-                {% endblock %}
-              </div>
-            {% endif %}
-
-            {% block nav-global %}{% endblock %}
-
-          </div>
-           </div>
-        {% endif %}
-        <!-- END Header -->
-      {% endblock %}
-
-
-      <div class="suit-columns {{ is_popup|yesno:'one-column,two-columns' }}">
-
-        {% block content-center %}
-          <div id="suit-center" class="suit-column">
-
-            {% if not is_popup %}
-            {% block minidash %}
-            <div id=openCloudTopPage>
-            {% include "admin/newminidashboard.html" %}
-            </div>
-            {% endblock %} 
-
-              {% block breadcrumbs %}
-                <ul class="breadcrumb"> 
-                  <li><a href="{% url 'admin:index' %}">{% trans 'Home' %}</a>
-                    {% if title %}
-                      <span class="divider">&raquo;</span>
-                      </li>
-                      <li class="active">
-                      {{ title }}
-                    {% endif %}
-                    </li>
-                </ul>
-              {% endblock %}
-            {% endif %}
-
-            {% block messages %}
-              {% if messages %}
-
-                {% for message in messages %}
-                  <div class="alert alert-{% firstof message.tags 'info' %}">
-                    <button class="close" data-dismiss="alert">×</button>
-                    <strong>
-                      {% if message.tags %}{{ message.tags|capfirst }}{% else %}
-                        Message{% endif %}!</strong>
-                    {{ message }}
-                  </div>
-                {% endfor %}
-              {% endif %}
-            {% endblock messages %}
-
-            <!-- Content -->
-            <div id="content" class="{% block coltype %}colM{% endblock %} row-fluid">
-              {% block pretitle %}{% endblock %}
-              {% block content_title %}{% if title %}
-                <h2 class="content-title">{{ title }}</h2>
-              {% endif %}{% endblock %}
-              {% block content %}
-                {% block object-tools %}{% endblock %}
-                {{ content }}
-              {% endblock %}
-              {% block sidebar_content %}
-                {% block sidebar %}{% endblock %}
-              {% endblock %}
-            </div>
-            <!-- END Content -->
-          <span class="clearfix"></span>
-          </div>
-        {% endblock %}
-
-
-        {% block content-left %}
-          {% if not user.is_appuser %}
-              {% if not is_popup %}
-                <div id="suit-left" class="suit-column">
-
-
-                  {% include 'suit/menu.html' %}
-
-                </div>
-              {% endif %}
-          {% endif %}
-        {% endblock %}
-
-      </div>
-    </div>
-  {% endblock %}
-
-  {% if not is_popup %}
-  <!-- Sticky footer push -->
-  <div id="push"></div>
-  {% endif %}
-
-</div>
-
-{% block footer %}
-  {% if not is_popup %}
-  <div id="footer" class="footer">
-    <div class="content">
-      <div class="tools">
-        {% block footer_links %}
-          <a href="http://djangosuit.com/support/" target="_blank" class="icon"><i class="icon-question-sign"></i>Support</a>
-          <a href="http://djangosuit.com/pricing/" target="_blank" class="icon"><i class="icon-bookmark"></i>Licence</a>
-          <a href="http://github.com/darklow/django-suit/issues" target="_blank" class="icon"><i class="icon-comment"></i>Report a bug</a>
-        {% endblock %}
-      </div>
-
-      <div class="statusMsg" id="statusMsg">
-      <!-- this is a placeholder for xoslib views to display status messages -->
-      </div>
-
-      <!-- <div class="copyright">
-        {% block copyright %}
-          Copyright &copy; 2013 DjangoSuit.com<br>Developed by <a href="http://djangosuit.com" target="_blank">DjangoSuit.com</a>
-        {% endblock %}
-      </div> -->
-
-      <div class="branding">{% block footer_branding %}
-        CORD
-      {% endblock %}</div>
-    </div>
-  </div>
-  {% endif %}
-{% endblock %}
-
-  <script src="{% static 'suit/bootstrap/js/bootstrap.min.js' %}"></script>
-  <script src="{% static 'suit/js/suit.js' %}"></script>
-  <script type="text/javascript" src="//www.google.com/jsapi"></script>
-  <!-- src="{% static 'xos_graphs.js' %}" -->
-
-  {% block extrajs %}{% endblock %}
-<script src="http://d3js.org/d3.v3.js"></script>
-	<div class="modal fade hide" id="chartsModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
-	  <div class="modal-dialog">
-	    <div class="modal-content">
-	      <!--<div class="modal-header">
-		<button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
-		<h4 class="modal-title" id="myModalLabel">OpenCloud</h4>
-	      </div>-->
-	      <div class="modal-body" style="overflow-y:hidden; overflow-x:hidden;">
-		<div class="chartContainer">
-			<div class="row">
-				<div class=" padding">
-				</div>
-			</div>
-
-			<div class="row">
-				<div class=" heading">
-					<p id="chartHeading" class="heading">OpenCloud</p>	
-				</div>
-			</div>
-			<div class="row">
-				<div class="padding"></div>
-				<div class="padding"></div>
-			</div>
-			<div class="row">
-				<div id="graph" class="graph">
-				</div>
-			</div>
-		</div>
-                <div id="graph_work" style="display:none"></div>
-	      </div>
-	      <!--<div class="modal-footer">
-		<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
-	      </div>-->
-	    </div><!-- /.modal-content -->
-	  </div><!-- /.modal-dialog -->
-	</div><!-- /.modal -->
-
-
-<script>
-
-
-
-
-</script>
-</body>
-</html>
diff --git a/xos/templates/cord_admin/base_site.html b/xos/templates/cord_admin/base_site.html
deleted file mode 100644
index 80d39fe..0000000
--- a/xos/templates/cord_admin/base_site.html
+++ /dev/null
@@ -1,57 +0,0 @@
-{% extends "admin/base.html" %}
-{% load admin_static %}
-
-{# Additional <head> content here, some extra meta tags or favicon #}
-{#{% block extrahead %}#}
-{#{% endblock %}#}
-
-
-{# Additional CSS includes #}
-{# {% block extrastyle %} #}
-{# {% endblock %} #}
-
-
-{# Additional JS files in footer, right before </body> #}
-{#{% block extrajs %}#}
-{#  <script type="text/javascript" src="{% static 'js/my_project.js' %}"></script>#}
-{#{% endblock %}#}
-
-
-{# Footer links (left side) #}
-{#{% block footer_links %}#}
-{#  <a href="/docs/" class="icon"><i class="icon-question-sign"></i>Documentation</a>#}
-{#{% endblock %}#}
-
-{# Additional header content like notifications or language switcher #}
-{#{% block header_content %}#}
-{#    {{ block.super }}#}
-{#    <div class="header-content">#}
-{#        <!-- First icon column -->#}
-{#        <div class="header-column icon">#}
-{#            <i class="icon-home"></i><br>#}
-{#            <i class="icon-cog"></i>#}
-{#        </div>#}
-{#        <div class="header-column" style="margin-right: 20px">#}
-{#            <a href="/" class="grey">Front-end</a><br>#}
-{#            <a href="" class="grey">One more link</a>#}
-{#        </div>#}
-{#        <!-- Second icon column -->#}
-{#        <div class="header-column icon">#}
-{#            <i class="icon-comment"></i>#}
-{#        </div>#}
-{#        <div class="header-column">#}
-{#            <a href="" class="grey">5 new messages</a>#}
-{#        </div>#}
-{#    </div>#}
-{#{% endblock %}#}
-
-{# Footer branding name (center) #}
-{% block footer_branding %}
-CORD
-{% endblock %}
-
-
-{# Footer copyright (right side) #}
-{% block copyright %}
-{#  Copyright &copy; 2013 Client<br>Developed by <a href="http://yoursite.com" target="_blank">YourName</a> #}
-{% endblock %}
diff --git a/xos/templates/cord_admin/dashboard_base.html b/xos/templates/cord_admin/dashboard_base.html
deleted file mode 100644
index bde87c2..0000000
--- a/xos/templates/cord_admin/dashboard_base.html
+++ /dev/null
@@ -1,92 +0,0 @@
-{% extends "admin/base.html" %}
-{% load admin_static %}
-
-{% block extrahead %}
-<link rel="stylesheet"  href="http://ajax.aspnetcdn.com/ajax/jquery.dataTables/1.9.0/css/jquery.dataTables.css">
-<link rel="stylesheet" type="text/css" href="{% static 'suit/css/suit.css' %}" media="all">
-<link rel="stylesheet" type="text/css" href="http://ajax.aspnetcdn.com/ajax/jquery.dataTables/1.9.0/css/jquery.dataTables_themeroller.css">
-<link rel="stylesheet" type="text/css" href="{% static 'xos.css' %}" media="all">
-<link rel="stylesheet" type="text/css" href="{% static 'cord.css' %}" media="all">
-<link rel="stylesheet" href="http://code.jquery.com/ui/1.10.4/themes/smoothness/jquery-ui.css">
-<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.7.2/leaflet.css" />
-<script src="http://cdn.leafletjs.com/leaflet-0.7.2/leaflet.js"></script>
-
-
-<!-- no need to include jquery here as it's already included by base.html. Including it multiple times will break mtuity statistics. -->
-<!-- src="http://code.jquery.com/jquery-1.9.1.js" -->
-
-<script src="http://code.jquery.com/ui/1.10.4/jquery-ui.js"></script>
-<script src="http://ajax.aspnetcdn.com/ajax/jquery.dataTables/1.9.4/jquery.dataTables.min.js"></script>
-<script type="text/javascript" src="{% static 'log4javascript-1.4.6/log4javascript.js' %}"></script>
-<script src="{% static 'js/Leaflet.MakiMarkers.js' %}" > </script>
-  
-<script>
-  $(function() {
-    $( "#hometabs" ).tabs({active: 0, //event: "mouseover"
-      //collapsible: true
-    });
-  });
-
-var consoleAppender = new log4javascript.BrowserConsoleAppender();
-var patternLayout = new log4javascript.PatternLayout("%d{HH:mm:ss,SSS} %l{s:l} %-5p - %m{1}%n");
-consoleAppender.setLayout(patternLayout);
-//var log  = log4javascript.getDefaultLogger();
-var log  = log4javascript.getRootLogger();
-log.addAppender(consoleAppender);
-log.setLevel(log4javascript.Level.ERROR);
-
-function confirmDialog(title,msg) {
-    var dialog = $('<div>'+msg+'</div>');
-    var def = $.Deferred();
-
-    $(dialog).dialog({
-        resizable: false,
-        title: title,
-        autoOpen: true,
-        modal: true,
-        dialogClass: "dashboard-hpc-instance",
-        buttons: {
-            'OK': function() {
-                def.resolve();
-                log.debug("Chose to add a instance");
-                $( this ).dialog( "close" );
-            },
-            'Cancel': function() {
-                def.reject();
-                $( this ).dialog( "close" );
-            }
-        },
-        close: {
-        }
-    });
-    return def.promise();
-}
-
-function errorDialog(title,msg) {
-    var dialog = $('<div>'+msg+'</div>');
-    var def = $.Deferred();
-
-    $(dialog).dialog({
-        resizable: false,
-        title: title,
-        autoOpen: true,
-        modal: true,
-        dialogClass: "dashboard-hpc-instance",
-        buttons: {
-            'OK': function() {
-                def.resolve();
-                $( this ).dialog( "close" );
-            },
-        },
-        close: {
-        }
-    });
-    return def.promise();
-}
-
-</script>
-{% endblock %}
-
-{% block content %}
-dashboard goes here
-{% endblock %}
diff --git a/xos/templates/cord_admin/login.html b/xos/templates/cord_admin/login.html
deleted file mode 100644
index a586acf..0000000
--- a/xos/templates/cord_admin/login.html
+++ /dev/null
@@ -1,161 +0,0 @@
-{% extends "admin/base_site_login.html" %}
-{% load i18n admin_static %}
-
-{% block extrastyle %}{{ block.super }}
-<link rel="stylesheet" type="text/css" href="/static/suit/bootstrap/css/bootstrap.min.css" media="all"/>
-<link rel="stylesheet" type="text/css" href="{% static "xos.css" %}" />
-<link rel="stylesheet" type="text/css" href="{% static "cord.css" %}" />
-<script src="{% static 'suit/js/jquery-1.9.1.min.js' %}"></script>
-<script src="http://code.jquery.com/ui/1.11.0/jquery-ui.js"></script>
-{% endblock %}
-
-
-{% block bodyclass %}login{% endblock %}
-
-{% block nav-global %}{% endblock %}
-
-{% block content_title %}{% endblock %}
-
-{% block breadcrumbs %}{% endblock %}
-
-{% block content %}
-{% if form.errors and not form.non_field_errors and not form.this_is_the_login_form.errors %}
-<p class="errornote">
-{% blocktrans count counter=form.errors.items|length %}Please correct the error below.{% plural %}Please correct the errors below.{% endblocktrans %}
-</p>
-{% endif %}
-
-{% if form.non_field_errors or form.this_is_the_login_form.errors %}
-{% for error in form.non_field_errors %}
-<p class="errornote">
-    {{ error }}
-</p>
-{% endfor %}
-{% for error in form.this_is_the_login_form.errors %}
-<p class="errornote">
-    {{ error }}
-</p>
-{% endfor %}
-{% endif %}
-<div id="wrap">
-<div id="content-main">
-<h1><i class="icon-lock icon-white"></i> OpenCloud</h1>
-<form action="{{ app_path }}" method="post" id="login-form">{% csrf_token %}
-  <div class="form-row">
-    {% if not form.this_is_the_login_form.errors %}{{ form.username.errors }}{% endif %}
-     {{ form.username }}
-  </div>
-  <div class="form-row">
-    {% if not form.this_is_the_login_form.errors %}{{ form.password.errors }}{% endif %}
-     {{ form.password }}
-    <input type="hidden" name="this_is_the_login_form" value="1" />
-    <input type="hidden" name="old_next" value="{{ next }}" />
-    <input type="hidden" name="next" value="/loggedin/?orig_next={{ next }}" />
-  </div>
-  <div class="submit-row">
-    <input type="submit" class="btn btn-info" value="{% trans 'SIGN IN' %}" />
-  </div>
-        <div id="requestAccountLink">{% trans 'Request a new Account' %}</div>
-</form>
-
-<div id="request-account-form" title="Request an Account" style="display: none;">
-	<form>
-		<fieldset>
-			<div class="request-form-row">
-				<label for="request-first-name">First Name</label>
-				<input type="text" name="request-first-name" id="request-first-name">
-			</div>
-			 <div class="request-form-row">
-                                <label for="request-last-name">Last Name</label>
-                                <input type="text" name="request-last-name" id="request-last-name">
-                        </div>
-			 <div class="request-form-row">
-                                <label for="request-email">Email</label>
-                                <input type="text" name="request-email" id="request-email">
-                        </div>
-			 <div class="request-form-row">
-                                <label for="request-site-name">Site</label><br>
-				<select id="request-site-name" name="request-site-name">
-                                    <option>---------</option>
-                                    {% for site in sites %}
-                                        {% if site.allowNewUsers %}
-                                            <option>{{ site.name }}</option>
-                                        {% endif %}
-                                    {% endfor %}
-				</select>
-                        </div>
-			<div class="submit-row">
-    				<input id ="request-signup" class="btn btn-info" value="SIGN UP">
-  			</div>
-		</fieldset>
-	</form>
-</div>
-</div>
-</div>
-
-
-<script type="text/javascript">
-$(function() {
-	initRequest();
-});
-function initRequest(){
-	$.ajax({
-			url: '/tenantview',
-			dataType: 'json',
-			success: function (data) {
-				var sites = data['sitesToBeRequested'];
-				console.log(sites);
-				for (site in sites){
-					$("#request-site-name").append("<option>" + site + "</option>");
-				}
-			}
-		});
-}
-$("#requestAccountLink").unbind().click(function(){
-	$("#request-account-form").dialog({
-					autoOpen: false,
-					modal: true,
-					dialogClass: "requestDialog",
-				});
-				$("#request-account-form").dialog("open");
-})
-$("#request-signup").unbind().click(function(){
-							$.ajax({
-								url: '/requestaccess/',
-								dataType: 'json',
-								data: {
-									email: $("#request-email").val(),
-									firstname: $("#request-first-name").val(),
-									lastname: $("#request-last-name").val(),
-									site: $("#request-site-name").val(),
-									csrfmiddlewaretoken: "{{ csrf_token }}", // < here 
-									state: "inactive"
-								},
-								async: false,
-								type: 'POST',
-								success: function (response) {
-                                                                    if (response && response.error) {
-                                                                        if (response.error == "already_approved") {
-                                                                            alert("Your request has already been proccessed and approved. We are sending you another email with a new temporary password");
-                                                                            return;
-                                                                        } else if (response.error == "already_pending") {
-                                                                            alert("Your request is already pending and awaiting approval");
-                                                                            return;
-                                                                        } else if (response.error == "is_deleted") {
-                                                                            alert("Your user record is in a deleted state. Please contact OpenCloud support");
-                                                                            return;
-                                                                        }
-                                                                    }
-								    $("#request-account-form").dialog("close");
-								    alert("Your request has been submitted");
-								},
-								error:function (xhr, textStatus, thrownError){
-         							   alert("Error:", textStatus + " " + xhr.responseText);
-        						        }
-							});
-})
-document.getElementById('id_username').focus()
-</script>
-</div>
-</div>
-{% endblock %}
diff --git a/xos/templates/registration/logged_out.html b/xos/templates/registration/logged_out.html
deleted file mode 100644
index 476a713..0000000
--- a/xos/templates/registration/logged_out.html
+++ /dev/null
@@ -1,12 +0,0 @@
-{% extends "admin/base_site.html" %}
-{% load i18n %}
-
-{% block breadcrumbs %}<div class="breadcrumbs"><a href="{% url 'admin:index' %}">{% trans 'Home' %}</a></div>{% endblock %}
-
-{% block content %}
-
-<p>{% trans "Thanks for spending some quality time with the Web site today." %}</p>
-
-<p><a href="{% url 'admin:loggedin' %}">{% trans 'Log in again' %}</a></p>
-
-{% endblock %}
diff --git a/xos/tools/chuckmove b/xos/tools/chuckmove
new file mode 100755
index 0000000..5a77876
--- /dev/null
+++ b/xos/tools/chuckmove
@@ -0,0 +1,82 @@
+#!/usr/bin/python
+
+from pyparsing import *
+from optparse import OptionParser
+import os
+from os.path import join,exists
+from shutil import copy
+
+usage = "usage: %prog --old <old namespace> --new <new namespace> <directory root>"
+
+parser = OptionParser(usage=usage)
+
+parser.add_option("-q", "--quiet",
+                          action="store_false", dest="verbose",
+                          help="be vewwy quiet (I'm hunting wabbits)")
+
+parser.add_option("-r", "--reuse",
+                          action="store_false", dest="reuse",
+                          help="Reuse .orig files. Dangerous!")
+
+parser.add_option("-o", "--old", 
+                          metavar="old", help="Old namespace")
+
+parser.add_option("-n", "--new",
+                          default="new", help="New namespace")
+
+(options, args) = parser.parse_args()
+
+old_ns = options.old
+new_ns = options.new
+
+# grammar
+
+comment = '#' + SkipTo(lineEnd)
+
+module_ns = Word(alphanums + '-' + '_' + '.' + '*')
+old_module_ns = Combine(old_ns + Optional(Combine('.'+module_ns)))
+end_of_python_line = Or([lineEnd,comment])
+
+as_suffix = 'as' + module_ns
+
+import_pure = 'import' + old_module_ns 
+import_pure_line = import_pure + Optional(as_suffix) + end_of_python_line
+
+import_from = 'from' + old_module_ns + 'import' + commaSeparatedList
+import_from_line = import_from + Optional(as_suffix) + end_of_python_line
+
+import_line = Or([import_pure_line, import_from_line])
+
+# Make a list of Python files to deal with
+
+try:
+    f = args[0]
+except IndexError:
+    print 'Specify a directory root'
+    exit(1)
+
+for root, dirs, files in os.walk(f):
+    for n in files:
+        if (n.endswith('.py')):
+            full_path = '/'.join([root,n])
+            orig_path = full_path + '.orig'
+            if (options.verbose):
+                print 'Working on %s:'%full_path
+            if (not os.path.exists(orig_path) or not options.reuse):
+                if (options.verbose):
+                    print 'Copying %s->%s:'%(full_path,orig_path)
+                copy(full_path, orig_path)
+            f_contents = open(orig_path).read()
+            new_contents = []
+            for l in f_contents.splitlines():
+                try:
+                    match = import_line.parseString(l)
+                    l = l.replace(old_ns, new_ns)
+                except ParseException:
+                    pass
+                new_contents.append(l)
+
+            new_file = '\n'.join(new_contents)
+            if (f_contents.endswith('\n')):
+                new_file+='\n'
+            open(full_path,'w').write(new_file)
diff --git a/xos/tools/chuckmove.README b/xos/tools/chuckmove.README
new file mode 100644
index 0000000..5039548
--- /dev/null
+++ b/xos/tools/chuckmove.README
@@ -0,0 +1,27 @@
+Hi,
+
+I've written a tool called 'chuckmove' for helping move Python modules around in a source tree. You use it as follows. Lets say you want to relocate a module to a different location in the tree, and also rename it. So for instance, x is to become y.z. The syntax you use is:
+
+chuckmove -o x -n y.z <root directory>
+
+Invoking this command makes the tool recursively descend into the root directory, make a backup copy of each file (adding the prefix '.orig') and rewrite the imports in it, so that "import x" gets turned into "import y.z"
+
+It recognizes Python grammar, so it works with all of these forms:
+
+from x import a
+from x.b import c 
+import x.d.e.f as foo # Comments are also handled
+
+...with the nit that lines with syntax/grammatical errors are left as is.
+
+For example, for the observer/synchronizer changes, I just had to do the following:
+
+chuckmove -o observer -n synchronizers.base xos
+
+...and then to generate a patch with the changes:
+
+gendiff xos .orig
+
+It's checked into the xos repository under tools (with a README file!).
+
+Sapan
diff --git a/xos/scripts/destroy-all-networks.sh b/xos/tools/destroy-all-networks.sh
similarity index 100%
rename from xos/scripts/destroy-all-networks.sh
rename to xos/tools/destroy-all-networks.sh
diff --git a/xos/scripts/docker_setup_xos b/xos/tools/docker_setup_xos
similarity index 100%
rename from xos/scripts/docker_setup_xos
rename to xos/tools/docker_setup_xos
diff --git a/xos/tools/docker_start_xos b/xos/tools/docker_start_xos
new file mode 100755
index 0000000..3b82e71
--- /dev/null
+++ b/xos/tools/docker_start_xos
@@ -0,0 +1,7 @@
+#! /bin/bash
+
+bash /opt/xos/tools/docker_setup_xos
+
+cd /opt/xos
+PUBLIC_HOSTNAME="0.0.0.0"
+python manage.py runserver $PUBLIC_HOSTNAME:8000 --insecure
diff --git a/xos/xos-config.py b/xos/tools/xos-config.py
similarity index 68%
rename from xos/xos-config.py
rename to xos/tools/xos-config.py
index 66f48f8..67ca4f6 100755
--- a/xos/xos-config.py
+++ b/xos/tools/xos-config.py
@@ -1,5 +1,12 @@
 #!/usr/bin/env python
 import sys
+
+# add the parent directory to sys.path
+import os,sys,inspect
+currentdir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))
+parentdir = os.path.dirname(currentdir)
+sys.path.append(parentdir)
+
 from xos.config import Config
 
 def help():
diff --git a/xos/scripts/opencloud b/xos/tools/xos-manage
similarity index 91%
rename from xos/scripts/opencloud
rename to xos/tools/xos-manage
index 966ad9b..37827b5 100755
--- a/xos/scripts/opencloud
+++ b/xos/tools/xos-manage
@@ -82,7 +82,7 @@
     python $XOS_DIR/manage.py syncdb --noinput
     if [[ $DJANGO_17 ]]; then
         echo "Loading initial data from fixture..."
-        python $XOS_DIR/manage.py --noobserver --nomodelpolicy loaddata $XOS_DIR/core/fixtures/initial_data.json
+        python $XOS_DIR/manage.py --noobserver --nomodelpolicy loaddata $XOS_DIR/core/fixtures/core_initial_data.json
     fi
 }
 function evolvedb {
@@ -99,7 +99,7 @@
 }
 function runserver {
     ensure_postgres_running
-    PUBLIC_HOSTNAME=`$XOS_DIR/xos-config.py get server_hostname $HOSTNAME`
+    PUBLIC_HOSTNAME="0.0.0.0"
     echo "Starting XOS Service on $PUBLIC_HOSTNAME:8000"
     python manage.py runserver $PUBLIC_HOSTNAME:8000 --insecure&
 }
@@ -171,8 +171,8 @@
     dumpdata
     # TODO: This is where we could run migration scripts to upgrade the
     #   dumped data to the new models.
-    mv $XOS_DIR/core/fixtures/initial_data.json $XOS_DIR/core/fixtures/initial_data.json-old
-    cp $BACKUP_DIR/dumpdata-latest.json $XOS_DIR/core/fixtures/initial_data.json
+    mv $XOS_DIR/core/fixtures/core_initial_data.json $XOS_DIR/core/fixtures/core_initial_data.json-old
+    cp $BACKUP_DIR/dumpdata-latest.json $XOS_DIR/core/fixtures/core_initial_data.json
     dropdb
     createdb
     syncdb
@@ -184,8 +184,8 @@
     fi
     stopserver
     ensure_postgres_running
-    mv $XOS_DIR/core/fixtures/initial_data.json $XOS_DIR/core/fixtures/initial_data.json-old
-    cp $BACKUP_DIR/dumpdata-latest.json $XOS_DIR/core/fixtures/initial_data.json
+    mv $XOS_DIR/core/fixtures/core_initial_data.json $XOS_DIR/core/fixtures/core_initial_data.json-old
+    cp $BACKUP_DIR/dumpdata-latest.json $XOS_DIR/core/fixtures/core_initial_data.json
     dropdb
     createdb
     syncdb
diff --git a/xos/tosca/resources/xosresource.py b/xos/tosca/resources/xosresource.py
index 9c4f479..fa14380 100644
--- a/xos/tosca/resources/xosresource.py
+++ b/xos/tosca/resources/xosresource.py
@@ -62,7 +62,7 @@
 
     def get_property_default(self, name, default=None):
         props = self.nodetemplate.get_properties()
-        if props and name in props.keys():

+        if props and name in props.keys():
             return props[name].value
         return default
 
diff --git a/xos/tosca/tests/basetest.py b/xos/tosca/tests/basetest.py
index d9701d7..7dda96f 100644
--- a/xos/tosca/tests/basetest.py
+++ b/xos/tosca/tests/basetest.py
@@ -1,19 +1,19 @@
 import os
 import random
 import string
-import sys

-

-# add the parent parent directory to sys.path

-# XXX this is very hackish :(

-import os,sys,inspect

-currentdir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))

-parentdir = os.path.dirname(currentdir)

-sys.path.append(parentdir)

-parentparentdir = os.path.dirname(parentdir)

-sys.path.append(parentparentdir)

-

-os.environ.setdefault("DJANGO_SETTINGS_MODULE", "xos.settings")

-import django

+import sys
+
+# add the parent parent directory to sys.path
+# XXX this is very hackish :(
+import os,sys,inspect
+currentdir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))
+parentdir = os.path.dirname(currentdir)
+sys.path.append(parentdir)
+parentparentdir = os.path.dirname(parentdir)
+sys.path.append(parentparentdir)
+
+os.environ.setdefault("DJANGO_SETTINGS_MODULE", "xos.settings")
+import django
 django.setup()
 
 from tosca.engine import XOSTosca
diff --git a/xos/tosca/tests/observerUserTest.py b/xos/tosca/tests/observerUserTest.py
index 44b47d3..a6b5897 100644
--- a/xos/tosca/tests/observerUserTest.py
+++ b/xos/tosca/tests/observerUserTest.py
@@ -48,14 +48,14 @@
                        node: %s
                        relationship: tosca.relationships.UsesController
     johndoe@foo.bar:
-      type: tosca.nodes.User

-      properties:

-          password: letmein

-          firstname: john

-          lastname: doe

-      requirements:

-          - site:

-              node: testsite

+      type: tosca.nodes.User
+      properties:
+          password: letmein
+          firstname: john
+          lastname: doe
+      requirements:
+          - site:
+              node: testsite
               relationship: tosca.relationships.MemberOfSite
 """ % (self.get_usable_deployment(), self.get_usable_controller()))
 
diff --git a/xos/tosca/tests/observertest.py b/xos/tosca/tests/observertest.py
index 1ec8797..4c8d5df 100644
--- a/xos/tosca/tests/observertest.py
+++ b/xos/tosca/tests/observertest.py
@@ -5,10 +5,10 @@
 import subprocess
 import sys
 
-from observer.event_loop import XOSObserver
-from model_policy import run_policy_once
+from synchronizers.base.event_loop import XOSObserver
+from synchronizers.model_policy import run_policy_once
 from xos.config import set_override
-from util.logger import Logger, observer_logger
+from xos.logger import Logger, observer_logger
 
 class BaseObserverToscaTest(BaseToscaTest):
     hide_observer_output = True
diff --git a/xos/util/__init__.py b/xos/util/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/xos/util/__init__.py
+++ /dev/null
diff --git a/xos/util/glob.py b/xos/util/glob.py
deleted file mode 100644
index 833ce35..0000000
--- a/xos/util/glob.py
+++ /dev/null
@@ -1,8 +0,0 @@
-import os, fnmatch
-
-def recursive_glob(treeroot, pattern):
-  results = []
-  for base, dirs, files in os.walk(treeroot):
-    goodfiles = fnmatch.filter(files, pattern)
-    results.extend(os.path.join(base, f) for f in goodfiles)
-  return results
diff --git a/xos/util/request.py b/xos/util/request.py
deleted file mode 100644
index 3769b19..0000000
--- a/xos/util/request.py
+++ /dev/null
@@ -1,14 +0,0 @@
-import ast
-from django.http.request import QueryDict
-
-def parse_request(request):
-    d = {}
-    if isinstance(request, unicode):
-        d = ast.literal_eval(request)
-    elif isinstance(request, QueryDict):
-        for (k,v) in request.items():
-            d[k] = ast.literal_eval(v)
-    elif isinstance(request, dict):
-        d = request    
-
-    return d
diff --git a/xos/xos/admin_customize/README.md b/xos/xos/admin_customize/README.md
new file mode 100644
index 0000000..ecc4520
--- /dev/null
+++ b/xos/xos/admin_customize/README.md
@@ -0,0 +1 @@
+admin_customize contains django UI elements (such as templatetags) that are common to all django apps within XOS.
diff --git a/xos/admin_customize/__init__.py b/xos/xos/admin_customize/__init__.py
similarity index 100%
rename from xos/admin_customize/__init__.py
rename to xos/xos/admin_customize/__init__.py
diff --git a/xos/admin_customize/templatetags/__init__.py b/xos/xos/admin_customize/templatetags/__init__.py
similarity index 100%
rename from xos/admin_customize/templatetags/__init__.py
rename to xos/xos/admin_customize/templatetags/__init__.py
diff --git a/xos/admin_customize/templatetags/admin_modify.py b/xos/xos/admin_customize/templatetags/admin_modify.py
similarity index 100%
rename from xos/admin_customize/templatetags/admin_modify.py
rename to xos/xos/admin_customize/templatetags/admin_modify.py
diff --git a/xos/xos/config.py b/xos/xos/config.py
index 7a64de9..8ae7816 100644
--- a/xos/xos/config.py
+++ b/xos/xos/config.py
@@ -6,7 +6,7 @@
 import tempfile
 import codecs
 from StringIO import StringIO
-from util.xml import Xml
+from xml_util import Xml
 
 default_config = \
 """
@@ -82,6 +82,7 @@
 			try:
 				if os.path.isdir(filename):
 					config_list = list(reversed(os.listdir(filename)))
+ 					config_list.remove('README.md')
 					config_list = [os.path.join(filename, s) for s in config_list]
 					self.config.read(config_list)
 				else:
diff --git a/xos/util/logger.py b/xos/xos/logger.py
similarity index 100%
rename from xos/util/logger.py
rename to xos/xos/logger.py
diff --git a/xos/xos/settings.py b/xos/xos/settings.py
index 5c1e88e..9486148 100644
--- a/xos/xos/settings.py
+++ b/xos/xos/settings.py
@@ -166,7 +166,7 @@
     # Uncomment the next line to enable the admin:
     # 'suit',
     'xos.apps.MyDjangoSuitConfig',
-    'admin_customize',
+    'xos.admin_customize',
     'django.contrib.admin',
     # Uncomment the next line to enable admin documentation:
     'django.contrib.admindocs',
diff --git a/xos/xos/urls.py b/xos/xos/urls.py
index 809aef3..4c3f07d 100644
--- a/xos/xos/urls.py
+++ b/xos/xos/urls.py
@@ -27,7 +27,6 @@
 
 urlpatterns = patterns('',
     # Examples:
-    url(r'^stats', 'core.views.stats.Stats', name='stats'),
     url(r'^observer', 'core.views.observer.Observer', name='observer'),
     url(r'^helloworld', HelloWorldView.as_view(), name='helloWorld'),
     url(r'^serviceGrid', ServiceGridView.as_view(), name='serviceGrid'),
diff --git a/xos/util/xml.py b/xos/xos/xml_util.py
similarity index 100%
rename from xos/util/xml.py
rename to xos/xos/xml_util.py
diff --git a/xos/xos_configuration/README.md b/xos/xos_configuration/README.md
new file mode 100644
index 0000000..044d7e0
--- /dev/null
+++ b/xos/xos_configuration/README.md
@@ -0,0 +1,99 @@
+# Managing Configurations
+
+XOS comes with several pre-configured envirnments. The main available configurations are:
+
+- Frontend Only
+- - CORD
+Every configurations come with different settings and different features, from GUI elements to Services.
+
+__NOTE: in this folder files should not be added. They will broke the configuration system.__
+
+## Basic configuration
+
+A common configuration file is saved in `xos/configurations/common/xos_common_config`. In this file are stored all the common configurations for XOS.
+
+This is the base config:
+``
+[plc]
+name=plc
+deployment=plc
+
+[db]
+name=xos
+user=postgres
+password=password
+host=localhost
+port=5432
+
+[api]
+host=localhost
+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
+logfile=/var/log/xos.log
+
+[nova]
+admin_user=admin@domain.com
+admin_password=admin
+admin_tenant=admin
+url=http://localhost:5000/v2.0/
+default_image=None
+default_flavor=m1.small
+default_security_group=default
+ca_ssl_cert=/etc/ssl/certs/ca-certificates.crt
+
+[observer]
+pretend=False
+backoff_disabled=False
+images_directory=/opt/xos/images
+dependency_graph=/opt/xos/model-deps
+logfile=/var/log/xos_backend.log
+
+[gui]
+disable_minidashboard=True
+branding_name=Open Cloud
+#branding_css= #no branding css is provided by default
+branding_icon=/static/logo.png
+
+``
+
+## Extending configuration
+
+### How it works
+
+In some environment some changes to the configuration are needed, to achieve this XOS reads configurations from a `xos/xos_configuration`.
+
+All the configuration files in this folder will be parsed with [ConfigParser](https://docs.python.org/2/library/configparser.html).
+
+### Exetending a configuration
+
+_An example is available in the CORD config_
+
+These are the basic step to extend a configuration. 
+_From now we'll use `myConf` as placeholder for the current configuration._
+
+**Local Config**
+
+- In your configuration create a new config file named: `xos_<myConf>_config`
+Sample local config:
+``
+[gui]
+branding_name=A BRAND NAME
+branding_icon=/static/my_logo.png
+``
+
+_The file above will change the displayed brand name and the logo in the UI_
+
+**Makefile Changes**
+- Clean the configuration folder: `rm ../../xos_configuration/*`
+- - Add the common config: `cp ../common/xos_common_config ../../xos_configuration/`
+- - Add the local config: `cp ./xos_<myConf>_config ../../xos_configuration/`
+_IMPORTANT: this instructions have to be executed before `docker build`_
+
+
+