Merge branch 'master' of github.com:open-cloud/xos
diff --git a/xos/configurations/cord/README-VTN.md b/xos/configurations/cord/README-VTN.md
index cd1abf6..a8feeac 100644
--- a/xos/configurations/cord/README-VTN.md
+++ b/xos/configurations/cord/README-VTN.md
@@ -63,6 +63,10 @@
     ip link set br-int up
     ip route add <network-that-was-assigned-to-flat-lan-1> dev br-int
     
+To get the management network working, we need to create management network template, slice, and network. configurations/cord/vtn.yaml will do this for you. Then add a connection to the management network for any slice that needs management connectivity. Note the subnet that gets assigned to the management network. Management-gateway-ip is the .1 address on the subnet. On the compute node:
+
+    ip addr add <management-gateway-ip>/24 dev br-int
+    
 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. 
 
diff --git a/xos/configurations/cord/vtn.yaml b/xos/configurations/cord/vtn.yaml
new file mode 100644
index 0000000..68c0fdb
--- /dev/null
+++ b/xos/configurations/cord/vtn.yaml
@@ -0,0 +1,40 @@
+tosca_definitions_version: tosca_simple_yaml_1_0
+
+description: Some VTN related stuff
+
+imports:
+   - custom_types/xos.yaml
+
+topology_template:
+  node_templates:
+    management_template:
+      type: tosca.nodes.NetworkTemplate
+      properties:
+          visibility: private
+          translation: none
+
+    management:
+      type: tosca.nodes.network.Network
+      properties:
+          ip_version: 4
+      requirements:
+          - network_template:
+              node: management_template
+              relationship: tosca.relationships.UsesNetworkTemplate
+          - owner:
+              node: mysite_management
+              relationship: tosca.relationships.MemberOfSlice
+
+    mysite:
+      type: tosca.nodes.Site
+
+    mysite_management:
+      description: This slice exists solely to own the management network
+      type: tosca.nodes.Slice
+      properties:
+          network: noauto
+      requirements:
+          - site:
+              node: mysite
+              relationship: tosca.relationships.MemberOfSite
+
diff --git a/xos/configurations/opencloud/cdn-content.yaml b/xos/configurations/opencloud/cdn-content.yaml
new file mode 100644
index 0000000..d4d1445
--- /dev/null
+++ b/xos/configurations/opencloud/cdn-content.yaml
@@ -0,0 +1,147 @@
+tosca_definitions_version: tosca_simple_yaml_1_0
+
+description: Template for deploying a single server with predefined properties.
+
+imports:
+   - custom_types/xos.yaml
+   - custom_types/cdn.yaml
+
+topology_template:
+  node_templates:
+    HyperCache:
+      type: tosca.nodes.CDNService
+      properties:
+          # HyperCache service must already exist before running this recipe
+          no-create: true
+          no-delete: true
+          no-update: true
+
+    # Setup the CDN Service Provider
+
+    main_service_provider:
+        type: tosca.nodes.ServiceProvider
+        requirements:
+           - hpc_service:
+                 node: HyperCache
+                 relationship: tosca.relationships.MemberOfService
+
+    # Wall Street Journal Content Provider
+
+    wsj_content:
+        type: tosca.nodes.ContentProvider
+        requirements:
+            - service_provider:
+                  node: main_service_provider
+                  relationship: tosca.relationships.MemberOfServiceProvider
+
+    www.wsj.com:
+        type: tosca.nodes.CDNPrefix
+        requirements:
+             - content_provider:
+                   node: wsj_content
+                   relationship: tosca.relationships.MemberOfContentProvider
+             - default_origin_server:
+                   node: http_www.wsj.com
+                   relationship: tosca.relationships.DefaultOriginServer
+
+    si.wsj.net:
+        type: tosca.nodes.CDNPrefix
+        requirements:
+             - content_provider:
+                   node: wsj_content
+                   relationship: tosca.relationships.MemberOfContentProvider
+             - default_origin_server:
+                   node: http_si.wsj.net
+                   relationship: tosca.relationships.DefaultOriginServer
+
+    s.wsj.net:
+        type: tosca.nodes.CDNPrefix
+        requirements:
+             - content_provider:
+                   node: wsj_content
+                   relationship: tosca.relationships.MemberOfContentProvider
+             - default_origin_server:
+                   node: http_s.wsj.net
+                   relationship: tosca.relationships.DefaultOriginServer
+
+    ore.wsj.net:
+        type: tosca.nodes.CDNPrefix
+        requirements:
+             - content_provider:
+                   node: wsj_content
+                   relationship: tosca.relationships.MemberOfContentProvider
+             - default_origin_server:
+                   node: http_ore.wsj.net
+                   relationship: tosca.relationships.DefaultOriginServer
+
+    http_www.wsj.com:
+        type: tosca.nodes.OriginServer
+        requirements:
+             - content_provider:
+                   node: wsj_content
+                   relationship: tosca.relationships.MemberOfContentProvider
+
+    http_si.wsj.net:
+        type: tosca.nodes.OriginServer
+        requirements:
+             - content_provider:
+                   node: wsj_content
+                   relationship: tosca.relationships.MemberOfContentProvider
+
+    http_s.wsj.net:
+        type: tosca.nodes.OriginServer
+        requirements:
+             - content_provider:
+                   node: wsj_content
+                   relationship: tosca.relationships.MemberOfContentProvider
+
+    http_ore.wsj.net:
+        type: tosca.nodes.OriginServer
+        requirements:
+             - content_provider:
+                   node: wsj_content
+                   relationship: tosca.relationships.MemberOfContentProvider
+
+    # ON.Lab content provider
+
+    on_lab_content:
+        type: tosca.nodes.ContentProvider
+        requirements:
+            - service_provider:
+                  node: main_service_provider
+                  relationship: tosca.relationships.MemberOfServiceProvider
+
+    downloads.onosproject.org:
+        type: tosca.nodes.CDNPrefix
+        requirements:
+             - content_provider:
+                   node: on_lab_content
+                   relationship: tosca.relationships.MemberOfContentProvider
+             - default_origin_server:
+                   node: http_downloads.onosproject.org
+                   relationship: tosca.relationships.DefaultOriginServer
+
+    onlab.vicci.org:
+        type: tosca.nodes.CDNPrefix
+        requirements:
+             - content_provider:
+                   node: on_lab_content
+                   relationship: tosca.relationships.MemberOfContentProvider
+             - default_origin_server:
+                   node: http_onlab.vicci.org
+                   relationship: tosca.relationships.DefaultOriginServer
+
+    http_downloads.onosproject.org:
+        type: tosca.nodes.OriginServer
+        requirements:
+             - content_provider:
+                   node: on_lab_content
+                   relationship: tosca.relationships.MemberOfContentProvider
+
+    http_onlab.vicci.org:
+        type: tosca.nodes.OriginServer
+        requirements:
+             - content_provider:
+                   node: on_lab_content
+                   relationship: tosca.relationships.MemberOfContentProvider
+
diff --git a/xos/configurations/opencloud/cdn-opencloud.yaml b/xos/configurations/opencloud/cdn-opencloud.yaml
new file mode 100644
index 0000000..29d60d5
--- /dev/null
+++ b/xos/configurations/opencloud/cdn-opencloud.yaml
@@ -0,0 +1,69 @@
+tosca_definitions_version: tosca_simple_yaml_1_0
+
+description: Template for deploying a single server with predefined properties.
+
+imports:
+   - custom_types/xos.yaml
+   - custom_types/cdn.yaml
+
+topology_template:
+  node_templates:
+    HyperCache:
+      type: tosca.nodes.CDNService
+      description: Content Delivery Network
+      properties:
+          view_url: /admin/hpc/hpcservice/$id$/
+          icon_url: /static/primarycons_blue/network.png
+
+    onlab:
+      type: tosca.nodes.Site
+      properties:
+          # Assume the onlab site exists, and don't touch it
+          no-create: true
+          no-update: true
+          no-delete: true
+
+    onlab_cmi:
+      description: CMI Slice
+      type: tosca.nodes.Slice
+      requirements:
+          - cdn_service:
+              node: HyperCache
+              relationship: tosca.relationships.MemberOfService
+          - site:
+              node: onlab
+              relationship: tosca.relationships.MemberOfSite
+
+    onlab_hpc:
+      description: HyperCache Slice
+      type: tosca.nodes.Slice
+      requirements:
+          - cdn_service:
+              node: HyperCache
+              relationship: tosca.relationships.MemberOfService
+          - site:
+              node: onlab
+              relationship: tosca.relationships.MemberOfSite
+
+    onlab_dnsredir:
+      description: HyperCache Slice
+      type: tosca.nodes.Slice
+      requirements:
+          - cdn_service:
+              node: HyperCache
+              relationship: tosca.relationships.MemberOfService
+          - site:
+              node: onlab
+              relationship: tosca.relationships.MemberOfSite
+
+    onlab_dnsdemux:
+      description: HyperCache Slice
+      type: tosca.nodes.Slice
+      requirements:
+          - cdn_service:
+              node: HyperCache
+              relationship: tosca.relationships.MemberOfService
+          - site:
+              node: onlab
+              relationship: tosca.relationships.MemberOfSite
+
diff --git a/xos/configurations/opencloud/opencloud.yaml b/xos/configurations/opencloud/opencloud.yaml
index c3a2c01..c71369a 100644
--- a/xos/configurations/opencloud/opencloud.yaml
+++ b/xos/configurations/opencloud/opencloud.yaml
@@ -753,34 +753,6 @@
 
 
 # Slices
-    onlab_cmi:
-      type: tosca.nodes.Slice
-      requirements:
-          - site:
-              node: onlab
-              relationship: tosca.relationships.MemberOfSite
-
-    onlab_hpc:
-      type: tosca.nodes.Slice
-      requirements:
-          - site:
-              node: onlab
-              relationship: tosca.relationships.MemberOfSite
-
-    onlab_dnsredir:
-      type: tosca.nodes.Slice
-      requirements:
-          - site:
-              node: onlab
-              relationship: tosca.relationships.MemberOfSite
-
-    onlab_dnsdemux:
-      type: tosca.nodes.Slice
-      requirements:
-          - site:
-              node: onlab
-              relationship: tosca.relationships.MemberOfSite
-
     princeton_publicdata:
       type: tosca.nodes.Slice
       requirements:
@@ -789,15 +761,6 @@
               relationship: tosca.relationships.MemberOfSite
 
 # Services
-    hypercache:
-      type: tosca.nodes.Service
-      capabilities:
-          scalable:
-              properties:
-                  max_instances: 25
-                  min_instances: 1
-                  default_instances: 1
-
     syndicate:
       type: tosca.nodes.Service
       capabilities:
diff --git a/xos/core/models/slice.py b/xos/core/models/slice.py
index 42e3a25..2679eb7 100644
--- a/xos/core/models/slice.py
+++ b/xos/core/models/slice.py
@@ -21,7 +21,7 @@
 
 class Slice(PlCoreBase):
     ISOLATION_CHOICES = (('vm', 'Virtual Machine'), ('container', 'Container'), ('container_vm', 'Container In VM'))
-    NETWORK_CHOICES = ((None, 'Default'), ('host', 'Host'), ('bridged', 'Bridged'))
+    NETWORK_CHOICES = ((None, 'Default'), ('host', 'Host'), ('bridged', 'Bridged'), ('noauto', 'No Automatic Networks'))
 
     name = StrippedCharField(unique=True, help_text="The Name of the Slice", max_length=80)
     enabled = models.BooleanField(default=True, help_text="Status for this Slice")
diff --git a/xos/synchronizers/openstack/model_policies/model_policy_Slice.py b/xos/synchronizers/openstack/model_policies/model_policy_Slice.py
index dfdcb4f..bb95b54 100644
--- a/xos/synchronizers/openstack/model_policies/model_policy_Slice.py
+++ b/xos/synchronizers/openstack/model_policies/model_policy_Slice.py
@@ -40,6 +40,9 @@
         # Host and Bridged docker containers need no networks and they will
         # only get in the way.
         print "MODEL POLICY: Skipping network creation"
+    elif slice.network in ["noauto"]:
+        # do nothing
+        pass
     else:
         # make sure slice has at least 1 public and 1 private networkd
         public_nets = []
diff --git a/xos/synchronizers/openstack/steps/sync_controller_networks.py b/xos/synchronizers/openstack/steps/sync_controller_networks.py
index 990cb87..0b876fa 100644
--- a/xos/synchronizers/openstack/steps/sync_controller_networks.py
+++ b/xos/synchronizers/openstack/steps/sync_controller_networks.py
@@ -81,9 +81,13 @@
 
     def map_sync_inputs(self, controller_network):
         # XXX This check should really be made from booleans, rather than using hardcoded network names
-        if (controller_network.network.template.name not in ['Private', 'Private-Indirect', 'Private-Direct']):
-            logger.info("skipping network controller %s because it is not private" % controller_network)
-            # We only sync private networks
+        #if (controller_network.network.template.name not in ['Private', 'Private-Indirect', 'Private-Direct', 'management_template'):
+        #    logger.info("skipping network controller %s because it is not private" % controller_network)
+        #    # We only sync private networks
+        #    return SyncStep.SYNC_WITHOUT_RUNNING
+
+        # hopefully a better approach than above
+        if (controller_network.network.template.shared_network_name or controller_network.network.template.shared_network_id):
             return SyncStep.SYNC_WITHOUT_RUNNING
         
         if not controller_network.controller.admin_user:
diff --git a/xos/synchronizers/openstack/steps/sync_instances.py b/xos/synchronizers/openstack/steps/sync_instances.py
index 335ca4a..22aa45c 100644
--- a/xos/synchronizers/openstack/steps/sync_instances.py
+++ b/xos/synchronizers/openstack/steps/sync_instances.py
@@ -34,6 +34,35 @@
             userdata += '  - %s\n' % key
         return userdata
 
+    def sort_controller_networks(self, nets):
+        nets = list(nets)
+        result = []
+
+        # Enforce VTN's network order requirement. The access network must be
+        # inserted into the first slot. The management network must be inserted
+        # into the second slot.
+
+        # move the private and/or access network to the first spot
+        for net in nets[:]:
+            tem = net.network.template
+            if (tem.visibility == "private") and (tem.translation=="none") and ("management" not in tem.name):
+                result.append(net)
+                nets.remove(net)
+
+        # move the management network to the second spot
+        for net in nets[:]:
+            tem = net.network.template
+            if (tem.visibility == "private") and (tem.translation=="none") and ("management" in tem.name):
+                if len(result)!=1:
+                    raise Exception("Management network needs to be inserted in slot 1, but there are %d private nets" % len(result))
+                result.append(net)
+                nets.remove(net)
+
+        # add everything else. For VTN there probably shouldn't be any more.
+        result.extend(nets)
+
+        return result
+
     def map_sync_inputs(self, instance):
         inputs = {}
 	metadata_update = {}
@@ -60,8 +89,8 @@
         controller_networks = ControllerNetwork.objects.filter(network__in=networks,
                                                                 controller=instance.node.site_deployment.controller)
 
+        controller_networks = self.sort_controller_networks(controller_networks)
         for controller_network in controller_networks:
-
             # Lenient exception - causes slow backoff
             if controller_network.network.template.visibility == 'private' and \
                controller_network.network.template.translation == 'none':
diff --git a/xos/tosca/custom_types/xos.m4 b/xos/tosca/custom_types/xos.m4
index 39e4d99..0c817c9 100644
--- a/xos/tosca/custom_types/xos.m4
+++ b/xos/tosca/custom_types/xos.m4
@@ -91,6 +91,7 @@
         capabilities:
             xos_base_service_caps
         properties:
+            xos_base_props
             xos_base_service_props
 
     tosca.nodes.Tenant:
@@ -115,6 +116,7 @@
         capabilities:
             xos_base_service_caps
         properties:
+            xos_base_props
             xos_base_service_props
             rest_onos/v1/network/configuration/:
                 type: string
@@ -198,6 +200,7 @@
         capabilities:
             xos_base_service_caps
         properties:
+            xos_base_props
             xos_base_service_props
             backend_network_label:
                 type: string
@@ -211,6 +214,7 @@
         capabilities:
             xos_base_service_caps
         properties:
+            xos_base_props
             xos_base_service_props
             vbng_url:
                 type: string
@@ -224,6 +228,7 @@
         capabilities:
             xos_base_service_caps
         properties:
+            xos_base_props
             xos_base_service_props
 
     tosca.nodes.Subscriber:
diff --git a/xos/tosca/custom_types/xos.yaml b/xos/tosca/custom_types/xos.yaml
index 613db70..a4f5d97 100644
--- a/xos/tosca/custom_types/xos.yaml
+++ b/xos/tosca/custom_types/xos.yaml
@@ -29,6 +29,18 @@
             service:
                 type: tosca.capabilities.xos.Service
         properties:
+            no-delete:
+                type: boolean
+                default: false
+                description: Do not allow Tosca to delete this object
+            no-create:
+                type: boolean
+                default: false
+                description: Do not allow Tosca to create this object
+            no-update:
+                type: boolean
+                default: false
+                description: Do not allow Tosca to update this object
             kind:
                 type: string
                 default: generic
@@ -93,6 +105,18 @@
             service:
                 type: tosca.capabilities.xos.Service
         properties:
+            no-delete:
+                type: boolean
+                default: false
+                description: Do not allow Tosca to delete this object
+            no-create:
+                type: boolean
+                default: false
+                description: Do not allow Tosca to create this object
+            no-update:
+                type: boolean
+                default: false
+                description: Do not allow Tosca to update this object
             kind:
                 type: string
                 default: generic
@@ -145,12 +169,6 @@
             dependencies:
                 type: string
                 required: false
-            install_dependencies:
-                type: string
-                required: false
-            component_config:
-                type: string
-                required: false
 
     tosca.nodes.ONOSvBNGApp:
         derived_from: tosca.nodes.Root
@@ -243,6 +261,18 @@
             service:
                 type: tosca.capabilities.xos.Service
         properties:
+            no-delete:
+                type: boolean
+                default: false
+                description: Do not allow Tosca to delete this object
+            no-create:
+                type: boolean
+                default: false
+                description: Do not allow Tosca to create this object
+            no-update:
+                type: boolean
+                default: false
+                description: Do not allow Tosca to update this object
             kind:
                 type: string
                 default: generic
@@ -289,6 +319,18 @@
             service:
                 type: tosca.capabilities.xos.Service
         properties:
+            no-delete:
+                type: boolean
+                default: false
+                description: Do not allow Tosca to delete this object
+            no-create:
+                type: boolean
+                default: false
+                description: Do not allow Tosca to create this object
+            no-update:
+                type: boolean
+                default: false
+                description: Do not allow Tosca to update this object
             kind:
                 type: string
                 default: generic
@@ -335,6 +377,18 @@
             service:
                 type: tosca.capabilities.xos.Service
         properties:
+            no-delete:
+                type: boolean
+                default: false
+                description: Do not allow Tosca to delete this object
+            no-create:
+                type: boolean
+                default: false
+                description: Do not allow Tosca to create this object
+            no-update:
+                type: boolean
+                default: false
+                description: Do not allow Tosca to update this object
             kind:
                 type: string
                 default: generic