Merge branch 'master' of github.com:open-cloud/xos
diff --git a/xos/configurations/common/base.yaml b/xos/configurations/common/base.yaml
index 3638dd9..3f13c94 100644
--- a/xos/configurations/common/base.yaml
+++ b/xos/configurations/common/base.yaml
@@ -20,6 +20,12 @@
disk_format: QCOW2
container_format: BARE
+ trusty-server-multi-nic-docker:
+ type: tosca.nodes.Image
+ properties:
+ disk_format: QCOW2
+ container_format: BARE
+
MyDeployment:
type: tosca.nodes.Deployment
properties:
@@ -28,6 +34,9 @@
- image:
node: trusty-server-multi-nic
relationship: tosca.relationships.SupportsImage
+ - image:
+ node: trusty-server-multi-nic-docker
+ relationship: tosca.relationships.SupportsImage
CloudLab:
type: tosca.nodes.Controller
diff --git a/xos/configurations/cord/ceilometer.yaml b/xos/configurations/cord/ceilometer.yaml
index 6fcd132..f8192fb 100644
--- a/xos/configurations/cord/ceilometer.yaml
+++ b/xos/configurations/cord/ceilometer.yaml
@@ -161,6 +161,9 @@
trusty-server-multi-nic:
type: tosca.nodes.Image
+ trusty-server-multi-nic-docker:
+ type: tosca.nodes.Image
+
mysite_ceilometer:
description: Ceilometer Proxy Slice
type: tosca.nodes.Slice
@@ -172,7 +175,7 @@
node: mysite
relationship: tosca.relationships.MemberOfSite
- default_image:
- node: trusty-server-multi-nic
+ node: trusty-server-multi-nic-docker
relationship: tosca.relationships.DefaultImage
properties:
default_flavor: m1.small
diff --git a/xos/configurations/vtn/Makefile b/xos/configurations/vtn/Makefile
index 2746f31..1315b39 100644
--- a/xos/configurations/vtn/Makefile
+++ b/xos/configurations/vtn/Makefile
@@ -8,6 +8,7 @@
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/fixtures.yaml
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/configurations/vtn/vtn.yaml
diff --git a/xos/configurations/vtn/cord-vtn-vsg.yaml b/xos/configurations/vtn/cord-vtn-vsg.yaml
new file mode 100644
index 0000000..bcb6847
--- /dev/null
+++ b/xos/configurations/vtn/cord-vtn-vsg.yaml
@@ -0,0 +1,172 @@
+tosca_definitions_version: tosca_simple_yaml_1_0
+
+description: Just enough Tosca to get the vSG slice running on VTN-Cloudlab
+
+imports:
+ - custom_types/xos.yaml
+
+topology_template:
+ node_templates:
+ # CORD Services
+ service_volt:
+ type: tosca.nodes.Service
+ requirements:
+ - vsg_tenant:
+ node: service_vsg
+ relationship: tosca.relationships.TenantOfService
+ properties:
+ view_url: /admin/cord/voltservice/$id$/
+ kind: vOLT
+
+ public_addresses:
+ type: tosca.nodes.AddressPool
+ properties:
+ addresses: 10.123.0.0/24 10.124.0.0/24
+
+ service_vsg:
+ type: tosca.nodes.VSGService
+ requirements:
+ - vbng_tenant:
+ node: service_vbng
+ relationship: tosca.relationships.TenantOfService
+ properties:
+ view_url: /admin/cord/vsgservice/$id$/
+ backend_network_label: hpc_client
+ public_key: { get_artifact: [ SELF, pubkey, LOCAL_FILE] }
+ private_key_fn: /opt/xos/synchronizers/vcpe/vcpe_private_key
+ artifacts:
+ pubkey: /opt/xos/synchronizers/vcpe/vcpe_public_key
+
+ service_vbng:
+ type: tosca.nodes.VBNGService
+ properties:
+ view_url: /admin/cord/vbngservice/$id$/
+# if unspecified, vbng observer will look for an ONOSApp Tenant and
+# generate a URL from its IP address
+# vbng_url: http://10.11.10.24:8181/onos/virtualbng/
+
+ Private:
+ type: tosca.nodes.NetworkTemplate
+
+ management:
+ type: tosca.nodes.network.Network.XOS
+ properties:
+ no-create: true
+ no-delete: true
+ no-update: true
+
+ mysite:
+ type: tosca.nodes.Site
+
+ # Networks required by the CORD setup
+ mysite_vsg-access:
+ type: tosca.nodes.network.Network
+ properties:
+ ip_version: 4
+ requirements:
+ - network_template:
+ node: Private
+ relationship: tosca.relationships.UsesNetworkTemplate
+ - owner:
+ node: mysite_vsg
+ relationship: tosca.relationships.MemberOfSlice
+ - connection:
+ node: mysite_vsg
+ relationship: tosca.relationships.ConnectsToSlice
+
+ # CORD Slices
+ mysite_vsg:
+ description: vSG Controller Slice
+ type: tosca.nodes.Slice
+ properties:
+ network: noauto
+ requirements:
+ - vsg_service:
+ node: service_vsg
+ relationship: tosca.relationships.MemberOfService
+ - site:
+ node: mysite
+ relationship: tosca.relationships.MemberOfSite
+ - management:
+ node: management
+ relationship: tosca.relationships.ConnectsToNetwork
+
+ # Let's add a user who can be administrator of the household
+ johndoe@myhouse.com:
+ type: tosca.nodes.User
+ properties:
+ password: letmein
+ firstname: john
+ lastname: doe
+ requirements:
+ - site:
+ node: mysite
+ relationship: tosca.relationships.MemberOfSite
+
+ # A subscriber
+ My House:
+ type: tosca.nodes.CORDSubscriber
+ properties:
+ service_specific_id: 123
+ firewall_enable: false
+ cdn_enable: false
+ url_filter_enable: false
+ url_filter_level: R
+ requirements:
+ - house_admin:
+ node: johndoe@myhouse.com
+ relationship: tosca.relationships.AdminPrivilege
+
+ Mom's PC:
+ type: tosca.nodes.CORDUser
+ properties:
+ mac: 01:02:03:04:05:06
+ level: PG_13
+ requirements:
+ - household:
+ node: My House
+ relationship: tosca.relationships.SubscriberDevice
+
+ Dad's PC:
+ type: tosca.nodes.CORDUser
+ properties:
+ mac: 90:E2:BA:82:F9:75
+ level: PG_13
+ requirements:
+ - household:
+ node: My House
+ relationship: tosca.relationships.SubscriberDevice
+
+ Jack's Laptop:
+ type: tosca.nodes.CORDUser
+ properties:
+ mac: 68:5B:35:9D:91:D5
+ level: PG_13
+ requirements:
+ - household:
+ node: My House
+ relationship: tosca.relationships.SubscriberDevice
+
+ Jill's Laptop:
+ type: tosca.nodes.CORDUser
+ properties:
+ mac: 34:36:3B:C9:B6:A6
+ level: PG_13
+ requirements:
+ - household:
+ node: My House
+ relationship: tosca.relationships.SubscriberDevice
+
+ My Volt:
+ type: tosca.nodes.VOLTTenant
+ properties:
+ service_specific_id: 123
+ s_tag: 222
+ c_tag: 432
+ requirements:
+ - provider_service:
+ node: service_volt
+ relationship: tosca.relationships.MemberOfService
+ - subscriber:
+ node: My House
+ relationship: tosca.relationships.BelongsToSubscriber
diff --git a/xos/configurations/vtn/docker-compose.yml b/xos/configurations/vtn/docker-compose.yml
index e7bb6b1..7fb68f1 100644
--- a/xos/configurations/vtn/docker-compose.yml
+++ b/xos/configurations/vtn/docker-compose.yml
@@ -21,7 +21,7 @@
xos_synchronizer_onos:
image: xosproject/xos-synchronizer-openstack
- command: bash -c "python /opt/xos/synchronizers/onos/onos-observer.py -C /opt/xos/synchronizers/onos/onos_observer_config"
+ command: bash -c "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
diff --git a/xos/core/models/service.py b/xos/core/models/service.py
index 1a1b6ef..6ece1b3 100644
--- a/xos/core/models/service.py
+++ b/xos/core/models/service.py
@@ -661,12 +661,15 @@
instance = self.pick_least_loaded_instance_in_slice(slices)
if not instance:
- flavors = Flavor.objects.filter(name="m1.small")
- if not flavors:
- raise XOSConfigurationError("No m1.small flavor")
-
slice = self.provider_service.slices.all()[0]
+ flavor = slice.default_flavor
+ if not flavor:
+ flavors = Flavor.objects.filter(name="m1.small")
+ if not flavors:
+ raise XOSConfigurationError("No m1.small flavor")
+ flavor = flavors[0]
+
if slice.default_isolation == "container_vm":
(node, parent) = ContainerVmScheduler(slice).pick()
else:
@@ -677,7 +680,7 @@
image = self.image,
creator = self.creator,
deployment = node.site_deployment.deployment,
- flavor = flavors[0],
+ flavor = flavor,
isolation = slice.default_isolation,
parent = parent)
self.save_instance(instance)
diff --git a/xos/services/ceilometer/models.py b/xos/services/ceilometer/models.py
index 42734de..2684097 100644
--- a/xos/services/ceilometer/models.py
+++ b/xos/services/ceilometer/models.py
@@ -35,6 +35,10 @@
proxy = True
KIND = CEILOMETER_KIND
+ LOOK_FOR_IMAGES=[ "trusty-server-multi-nic-docker", # CloudLab
+ "trusty-server-multi-nic",
+ ]
+
sync_attributes = ("private_ip", "private_mac",
"ceilometer_ip", "ceilometer_mac",
diff --git a/xos/services/cord/admin.py b/xos/services/cord/admin.py
index 5cf6b29..71cae5f 100644
--- a/xos/services/cord/admin.py
+++ b/xos/services/cord/admin.py
@@ -163,6 +163,7 @@
creator = forms.ModelChoiceField(queryset=User.objects.all())
instance = forms.ModelChoiceField(queryset=Instance.objects.all(),required=False)
last_ansible_hash = forms.CharField(required=False)
+ wan_container_ip = forms.CharField(required=False)
def __init__(self,*args,**kwargs):
super (VSGTenantForm,self ).__init__(*args,**kwargs)
@@ -174,6 +175,7 @@
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
+ self.fields['wan_container_ip'].initial = self.instance.wan_container_ip
if (not self.instance) or (not self.instance.pk):
# default fields for an 'add' form
self.fields['kind'].initial = VCPE_KIND
@@ -194,7 +196,7 @@
list_display = ('backend_status_icon', 'id', 'subscriber_tenant' )
list_display_links = ('backend_status_icon', 'id')
fieldsets = [ (None, {'fields': ['backend_status_text', 'kind', 'provider_service', 'subscriber_tenant', 'service_specific_id', # 'service_specific_attribute',
- 'bbs_account', 'creator', 'instance', 'last_ansible_hash'],
+ 'wan_container_ip', 'bbs_account', 'creator', 'instance', 'last_ansible_hash'],
'classes':['suit-tab suit-tab-general']})]
readonly_fields = ('backend_status_text', 'service_specific_attribute', 'bbs_account')
form = VSGTenantForm
diff --git a/xos/services/cord/models.py b/xos/services/cord/models.py
index 6d26048..2f29d81 100644
--- a/xos/services/cord/models.py
+++ b/xos/services/cord/models.py
@@ -1,5 +1,5 @@
from django.db import models
-from core.models import Service, PlCoreBase, Slice, Instance, Tenant, TenantWithContainer, Node, Image, User, Flavor, Subscriber, NetworkParameter, NetworkParameterType, Port
+from core.models import Service, PlCoreBase, Slice, Instance, Tenant, TenantWithContainer, Node, Image, User, Flavor, Subscriber, NetworkParameter, NetworkParameterType, Port, AddressPool
from core.models.plcorebase import StrippedCharField
import os
from django.db import models, transaction
@@ -10,6 +10,7 @@
from core.models.service import LeastLoadedNodeScheduler
import traceback
from xos.exceptions import *
+from xos.config import Config
class ConfigurationError(Exception):
pass
@@ -19,6 +20,8 @@
VBNG_KIND = "vBNG"
CORD_SUBSCRIBER_KIND = "CordSubscriberRoot"
+CORD_USE_VTN = getattr(Config(), "networking_use_vtn", False)
+
# -------------------------------------------
# CordSubscriberRoot
# -------------------------------------------
@@ -453,7 +456,8 @@
sync_attributes = ("nat_ip", "nat_mac",
"lan_ip", "lan_mac",
- "wan_ip", "wan_mac", "wan_container_mac",
+ "wan_ip", "wan_mac",
+ "wan_container_ip", "wan_container_mac",
"private_ip", "private_mac",
"hpc_client_ip", "hpc_client_mac")
@@ -461,7 +465,8 @@
"container_id": None,
"users": [],
"bbs_account": None,
- "last_ansible_hash": None}
+ "last_ansible_hash": None,
+ "wan_container_ip": None}
def __init__(self, *args, **kwargs):
super(VSGTenant, self).__init__(*args, **kwargs)
@@ -544,6 +549,10 @@
addresses["hpc_client"] = (ns.ip, ns.mac)
return addresses
+ # ------------------------------------------------------------------------
+ # The following IP addresses all come from the VM
+ # Note: They might not be useful for the VTN-vSG
+
@property
def nat_ip(self):
return self.addresses.get("nat", (None,None) )[0]
@@ -568,10 +577,33 @@
def wan_mac(self):
return self.addresses.get("wan", (None, None) )[1]
+ # end of VM IP address stubs
+ # ------------------------------------------------------------------------
+
+ @property
+ def wan_container_ip(self):
+ if CORD_USE_VTN:
+ # When using VTN, wan_container_ip is stored and maintained inside
+ # of the vSG object.
+ return self.get_attribute("wan_container_ip", self.default_attributes["wan_container_ip"])
+ else:
+ # When not using VTN, wan_container_ip is the same as wan_ip.
+ # XXX Is this broken for multiple-containers-per-VM?
+ return self.wan_ip
+
+ @wan_container_ip.setter
+ def wan_container_ip(self, value):
+ if CORD_USE_VTN:
+ self.set_attribute("wan_container_ip", value)
+ else:
+ raise Exception("wan_container_ip.setter called on non-VTN CORD")
+
# Generate the MAC for the container interface connected to WAN
@property
def wan_container_mac(self):
- (a, b, c, d) = self.wan_ip.split('.')
+ if not self.wan_container_ip:
+ return None
+ (a, b, c, d) = self.wan_container_ip.split('.')
return "02:42:%02x:%02x:%02x:%02x" % (int(a), int(b), int(c), int(d))
@property
@@ -721,6 +753,25 @@
self.bbs_account = None
super(VSGTenant, self).save()
+ def manage_wan_container_ip(self):
+ if CORD_USE_VTN:
+ if not self.wan_container_ip:
+ ap = AddressPool.objects.filter(name="public_addresses")
+ if not ap:
+ raise Exception("AddressPool 'public_addresses' does not exist. Please configure it.")
+ ap = ap[0]
+
+ addr = ap.get_address()
+ if not addr:
+ raise Exception("AddressPool 'public_addresses' has run out of addresses.")
+
+ self.wan_container_ip = addr
+
+ def cleanup_wan_container_ip(self):
+ if CORD_USE_VTN and self.wan_container_ip:
+ AddressPool.objects.filter(name="public_addresses")[0].put_address(self.wan_container_ip)
+ self.wan_container_ip = None
+
def find_or_make_port(self, instance, network, **kwargs):
port = Port.objects.filter(instance=instance, network=network)
if port:
@@ -731,10 +782,14 @@
return port
def get_lan_network(self, instance):
- # TODO: for VTN, pick the access network
-
slice = self.provider_service.slices.all()[0]
- lan_networks = [x for x in slice.networks.all() if "lan" in x.name]
+ if CORD_USE_VTN:
+ # there should only be one network private network, and its template should not be the management template
+ lan_networks = [x for x in slice.networks.all() if x.template.visibility=="private" and (not "management" in x.template.name)]
+ if len(lan_networks)>1:
+ raise XOSProgrammingError("The vSG slice should only have one non-management private network")
+ else:
+ lan_networks = [x for x in slice.networks.all() if "lan" in x.name]
if not lan_networks:
raise XOSProgrammingError("No lan_network")
return lan_networks[0]
@@ -786,14 +841,11 @@
super(VSGTenant, self).save(*args, **kwargs)
model_policy_vcpe(self.pk)
- #self.manage_instance()
- #self.manage_vbng()
- #self.manage_bbs_account()
- #self.cleanup_orphans()
def delete(self, *args, **kwargs):
self.cleanup_vbng()
self.cleanup_container()
+ self.cleanup_wan_container_ip()
super(VSGTenant, self).delete(*args, **kwargs)
def model_policy_vcpe(pk):
@@ -803,6 +855,7 @@
if not vcpe:
return
vcpe = vcpe[0]
+ vcpe.manage_wan_container_ip()
vcpe.manage_container()
vcpe.manage_vbng()
vcpe.manage_bbs_account()
diff --git a/xos/synchronizers/monitoring_channel/steps/sync_monitoringchannel.yaml b/xos/synchronizers/monitoring_channel/steps/sync_monitoringchannel.yaml
index 6cda511..c868be9 100644
--- a/xos/synchronizers/monitoring_channel/steps/sync_monitoringchannel.yaml
+++ b/xos/synchronizers/monitoring_channel/steps/sync_monitoringchannel.yaml
@@ -32,24 +32,24 @@
- remove container
{% else %}
{% if full_setup %}
- - name: Docker repository
- copy: src=/opt/xos/synchronizers/monitoring_channel/files/docker.list
- dest=/etc/apt/sources.list.d/docker.list
-
- - name: Import the repository key
- apt_key: keyserver=keyserver.ubuntu.com id=36A1D7869245C8950F966E92D8576A8BA88D21E9
-
- - name: install Docker
- apt: name=lxc-docker state=present update_cache=yes
-
- - name: install python-setuptools
- apt: name=python-setuptools state=present
-
- - name: install pip
- easy_install: name=pip
-
- - name: install docker-py
- pip: name=docker-py version=0.5.3
+# - name: Docker repository
+# copy: src=/opt/xos/synchronizers/monitoring_channel/files/docker.list
+# dest=/etc/apt/sources.list.d/docker.list
+#
+# - name: Import the repository key
+# apt_key: keyserver=keyserver.ubuntu.com id=36A1D7869245C8950F966E92D8576A8BA88D21E9
+#
+# - name: install Docker
+# apt: name=lxc-docker state=present update_cache=yes
+#
+# - name: install python-setuptools
+# apt: name=python-setuptools state=present
+#
+# - name: install pip
+# easy_install: name=pip
+#
+# - name: install docker-py
+# pip: name=docker-py version=0.5.3
- name: install Pipework
get_url: url=https://raw.githubusercontent.com/jpetazzo/pipework/master/pipework
@@ -85,6 +85,32 @@
- remove container
- start monitoring-channel
+# - name: Start monitoring-channel container
+# docker:
+# docker_api_version: "1.18"
+# name: monitoring-channel-{{ unique_id }}
+# # was: reloaded
+# state: running
+# image: srikanthvavila/monitoring-channel
+# expose:
+# - 8000
+# ports:
+# - "{{ ceilometer_port }}:8000"
+# volumes:
+# - /usr/local/share/monitoring-channel-{{ unique_id }}_ceilometer_proxy_config:/usr/local/share/ceilometer_proxy_config
+#
+# - name: Get Docker IP
+# #TODO: copy dockerip.sh to monitoring service synchronizer
+# script: /opt/xos/synchronizers/onos/scripts/dockerip.sh monitoring-channel-{{ unique_id }}
+# register: dockerip
+#
+# - name: Wait for Monitoring channel to come up
+# wait_for:
+# host={{ '{{' }} dockerip.stdout {{ '}}' }}
+# port={{ '{{' }} item {{ '}}' }}
+# state=present
+# with_items:
+# - {{ ceilometer_port }}
# These are samples, not necessary for correct function of demo
- name: Make sure Monitoring channel service is running
diff --git a/xos/synchronizers/monitoring_channel/templates/start-monitoring-channel.sh.j2 b/xos/synchronizers/monitoring_channel/templates/start-monitoring-channel.sh.j2
index f56c247..ea5b639 100755
--- a/xos/synchronizers/monitoring_channel/templates/start-monitoring-channel.sh.j2
+++ b/xos/synchronizers/monitoring_channel/templates/start-monitoring-channel.sh.j2
@@ -22,7 +22,12 @@
then
#sudo docker build -t monitoring-channel -f Dockerfile.monitoring_channel .
sudo docker pull srikanthvavila/monitoring-channel
+if [ -z "$HEADNODEFLATLANIP" ] || [ "$HEADNODEFLATLANIP" == "None" ]
+then
+ docker run -d --name=$MONITORING_CHANNEL --privileged=true -p $HOST_FORWARDING_PORT_FOR_CEILOMETER:8000 srikanthvavila/monitoring-channel
+else
docker run -d --name=$MONITORING_CHANNEL --add-host="ctl:$HEADNODEFLATLANIP" --privileged=true -p $HOST_FORWARDING_PORT_FOR_CEILOMETER:8000 srikanthvavila/monitoring-channel
+fi
else
docker start $MONITORING_CHANNEL
fi
diff --git a/xos/synchronizers/openstack/steps/sync_instances.py b/xos/synchronizers/openstack/steps/sync_instances.py
index 73624a3..884bcf5 100644
--- a/xos/synchronizers/openstack/steps/sync_instances.py
+++ b/xos/synchronizers/openstack/steps/sync_instances.py
@@ -34,8 +34,7 @@
userdata += ' - %s\n' % key
return userdata
- def sort_controller_networks(self, nets):
- nets = list(nets)
+ def sort_nics(self, nics):
result = []
# Enforce VTN's network order requirement. The access network must be
@@ -43,23 +42,27 @@
# 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)
+ for nic in nics[:]:
+ network=nic.get("network", None)
+ if network:
+ tem = network.template
+ if (tem.visibility == "private") and (tem.translation=="none") and ("management" not in tem.name):
+ result.append(nic)
+ nics.remove(nic)
# 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)
+ for net in nics[:]:
+ network=nic.get("network", None)
+ if network:
+ tem = 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 nics" % len(result))
+ result.append(nic)
+ nics.remove(nic)
# add everything else. For VTN there probably shouldn't be any more.
- result.extend(nets)
+ result.extend(nics)
return result
@@ -84,29 +87,30 @@
if instance.slice.service and instance.slice.service.public_key:
pubkeys.add(instance.slice.service.public_key)
+ nics=[]
+
# handle ports the were created by the user
port_ids=[]
for port in Port.objects.filter(instance=instance):
if not port.port_id:
raise DeferredException("Instance %s waiting on port %s" % (instance, port))
- port_ids.append(port.port_id)
+ nics.append({"kind": "port", "value": port.port_id, "network": port.network})
# we want to exclude from 'nics' any network that already has a Port
existing_port_networks = [port.network for network in Port.objects.filter(instance=instance)]
- nics = []
networks = [ns.network for ns in NetworkSlice.objects.filter(slice=instance.slice) if ns.network not in existing_port_networks]
controller_networks = ControllerNetwork.objects.filter(network__in=networks,
controller=instance.node.site_deployment.controller)
- controller_networks = self.sort_controller_networks(controller_networks)
+ #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':
if not controller_network.net_id:
raise DeferredException("Instance %s Private Network %s has no id; Try again later" % (instance, controller_network.network.name))
- nics.append(controller_network.net_id)
+ nics.append({"kind": "net", "value": controller_network.net_id, "network": controller_network.network})
# now include network template
network_templates = [network.template.shared_network_name for network in networks \
@@ -117,12 +121,14 @@
nets = driver.shell.quantum.list_networks()['networks']
for net in nets:
if net['name'] in network_templates:
- nics.append(net['id'])
+ nics.append({"kind": "net", "value": net['id'], "network": None})
if (not nics):
for net in nets:
if net['name']=='public':
- nics.append(net['id'])
+ nics.append({"kind": "net", "value": net['id'], "network": None})
+
+ nics = self.sort_nics(nics)
image_name = None
controller_images = instance.image.controllerimages.filter(controller=instance.node.site_deployment.controller)
diff --git a/xos/synchronizers/openstack/steps/sync_instances.yaml b/xos/synchronizers/openstack/steps/sync_instances.yaml
index a61e5cf..3e7182a 100644
--- a/xos/synchronizers/openstack/steps/sync_instances.yaml
+++ b/xos/synchronizers/openstack/steps/sync_instances.yaml
@@ -19,11 +19,8 @@
user_data: "{{ user_data }}"
config_drive: yes
nics:
- {% for net in nics %}
- - net-id: {{ net }}
- {% endfor %}
- {% for port in ports %}
- - port-id: {{ port }}
+ {% for nic in nics %}
+ - {{ nic.kind }}-id: {{ nic.value }}
{% endfor %}
{% if meta %}
diff --git a/xos/tosca/custom_types/xos.m4 b/xos/tosca/custom_types/xos.m4
index c9cea49..2f5b537 100644
--- a/xos/tosca/custom_types/xos.m4
+++ b/xos/tosca/custom_types/xos.m4
@@ -421,6 +421,7 @@
This is a variant of the TOSCA Network object that includes additional
XOS-specific properties.
properties:
+ xos_base_props
ip_version:
type: integer
required: no
diff --git a/xos/tosca/custom_types/xos.yaml b/xos/tosca/custom_types/xos.yaml
index ce8a1ac..d466180 100644
--- a/xos/tosca/custom_types/xos.yaml
+++ b/xos/tosca/custom_types/xos.yaml
@@ -634,6 +634,18 @@
This is a variant of the TOSCA Network object that includes additional
XOS-specific properties.
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
ip_version:
type: integer
required: no
diff --git a/xos/tosca/resources/slice.py b/xos/tosca/resources/slice.py
index 7dcbd59..48e5eb0 100644
--- a/xos/tosca/resources/slice.py
+++ b/xos/tosca/resources/slice.py
@@ -12,7 +12,7 @@
class XOSSlice(XOSResource):
provides = "tosca.nodes.Slice"
xos_model = Slice
- copyin_props = ["enabled", "description", "slice_url", "max_instances", "default_isolation", "network", "exposed_ports"]
+ copyin_props = ["enabled", "description", "slice_url", "max_instances", "default_isolation", "default_flavor", "network", "exposed_ports"]
def get_xos_args(self):
args = super(XOSSlice, self).get_xos_args()