Merge branch 'master' into feature/ceilometerDashboard
diff --git a/xos/configurations/bash/Makefile b/xos/configurations/bash/Makefile
index f33ea56..a668a55 100644
--- a/xos/configurations/bash/Makefile
+++ b/xos/configurations/bash/Makefile
@@ -1,6 +1,8 @@
MYIP:=$(shell hostname -i)
test: common_cloudlab
+ rm ../../xos_configuration/*
+ cp ../common/xos_common_config ../../xos_configuration/
cat ../common/Dockerfile.common Dockerfile.bash > Dockerfile
cd ../../..; sudo docker build -t xos -f xos/configurations/bash/Dockerfile .
sudo docker run -i --tty --add-host="ctl:$(MYIP)" -p 9999:8000 xos
diff --git a/xos/configurations/common/xos_common_config b/xos/configurations/common/xos_common_config
new file mode 100644
index 0000000..df30b54
--- /dev/null
+++ b/xos/configurations/common/xos_common_config
@@ -0,0 +1,44 @@
+[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_icon=/static/logo.png
diff --git a/xos/configurations/cord/Makefile b/xos/configurations/cord/Makefile
index 701e92f..ef823cd 100644
--- a/xos/configurations/cord/Makefile
+++ b/xos/configurations/cord/Makefile
@@ -3,8 +3,11 @@
LAST_CONTAINER=$(shell sudo docker ps -l -q)
cord: common_cloudlab ceilometer_dashboard virtualbng_json
+ rm ../../xos_configuration/*
echo "# Autogenerated -- do not edit" > Dockerfile
cat ../common/Dockerfile.common Dockerfile.cord >> Dockerfile
+ cp ../common/xos_common_config ../../xos_configuration/
+ cp ./xos_cord_config ../../xos_configuration/
cd ../../..; sudo docker build -t xos -f xos/configurations/cord/Dockerfile .
sudo docker run -d --add-host="ctl:$(MYIP)" -p 9999:8000 xos
bash ../common/wait_for_xos.sh
diff --git a/xos/configurations/cord/cord.yaml b/xos/configurations/cord/cord.yaml
index a35454b..2a61cf9 100644
--- a/xos/configurations/cord/cord.yaml
+++ b/xos/configurations/cord/cord.yaml
@@ -203,6 +203,16 @@
node: mysite_vbng
relationship: tosca.relationships.ConnectsToSlice
+ Private-Direct:
+ type: tosca.nodes.NetworkTemplate
+ properties:
+ access: direct
+
+ Private-Indirect:
+ type: tosca.nodes.NetworkTemplate
+ properties:
+ access: indirect
+
subscriber_network:
type: tosca.nodes.network.Network
properties:
diff --git a/xos/configurations/cord/xos_cord_config b/xos/configurations/cord/xos_cord_config
new file mode 100644
index 0000000..8dd0ae5
--- /dev/null
+++ b/xos/configurations/cord/xos_cord_config
@@ -0,0 +1,4 @@
+[gui]
+branding_name=CORD
+#branding_css=/static/cord.css
+branding_icon=/static/cord_logo_3.png
diff --git a/xos/configurations/devel/Makefile b/xos/configurations/devel/Makefile
index 24b7be7..216673d 100644
--- a/xos/configurations/devel/Makefile
+++ b/xos/configurations/devel/Makefile
@@ -7,6 +7,8 @@
devstack: common_devstack xos
xos:
+ rm ../../xos_configuration/*
+ cp ../common/xos_common_config ../../xos_configuration/
echo "# Autogenerated -- do not edit" > Dockerfile
cat ../common/Dockerfile.common Dockerfile.devel >> Dockerfile
cd ../../..; sudo docker build -t xosproject/xos-devel -f xos/configurations/devel/Dockerfile .
diff --git a/xos/configurations/frontend/Makefile b/xos/configurations/frontend/Makefile
index 0a1f04a..e30877a 100644
--- a/xos/configurations/frontend/Makefile
+++ b/xos/configurations/frontend/Makefile
@@ -6,15 +6,20 @@
all: frontend
frontend:
+ rm ../../xos_configuration/*
sudo apt-get -y install httpie
cat ../common/Dockerfile.common Dockerfile.frontend > Dockerfile
+ cp ../common/xos_common_config ../../xos_configuration/
cd ../../..; sudo docker build -t xos -f xos/configurations/frontend/Dockerfile .
sudo docker run -v $(XOS_FOLDER)/../../core/xoslib:/opt/xos/core/xoslib -p 9999:8000 --add-host="0.0.0.0:127.0.0.1" xos
bash ../common/wait_for_xos.sh
echo $(RUNNING_CONTAINER)
interactive:
+ rm ../../xos_configuration/*
cat ../common/Dockerfile.common Dockerfile.frontend > Dockerfile
+ cp ../common/xos_common_config ../../xos_configuration/
+ #cp ../cord/xos_cord_config ../../xos_configuration/
cd ../../..; sudo docker build -t xos -f xos/configurations/frontend/Dockerfile .
echo "Inside the container run: /usr/bin/make -C /opt/xos/configurations/frontend -f Makefile.inside"
sudo docker run -it -v $(shell pwd)/../..:/opt/xos -p 9999:8000 --add-host="0.0.0.0:127.0.0.1" xos
diff --git a/xos/configurations/frontend/Makefile.inside b/xos/configurations/frontend/Makefile.inside
index f3fc898..48046b2 100644
--- a/xos/configurations/frontend/Makefile.inside
+++ b/xos/configurations/frontend/Makefile.inside
@@ -3,7 +3,7 @@
setup_xos:
chmod +x /opt/xos/scripts/opencloud;
/opt/xos/scripts/opencloud genkeys;
- /opt/xos/scripts/opencloud remigrate;
+# /opt/xos/scripts/opencloud remigrate;
bash /opt/xos/tosca/install_tosca.sh;
bash /opt/xos/scripts/docker_setup_xos
python /opt/xos/tosca/run.py padmin@vicci.org /opt/xos/configurations/frontend/sample.yaml
diff --git a/xos/core/admin.py b/xos/core/admin.py
index be9dcc0..e41ad1d 100644
--- a/xos/core/admin.py
+++ b/xos/core/admin.py
@@ -1848,7 +1848,7 @@
user_readonly_inlines = []
inlines = [NetworkParameterInline,]
fieldsets = [
- (None, {'fields': ['name', 'description', 'guaranteed_bandwidth', 'visibility', 'translation', 'shared_network_name', 'shared_network_id', 'topology_kind', 'controller_kind'],
+ (None, {'fields': ['name', 'description', 'guaranteed_bandwidth', 'visibility', 'translation', 'access', 'shared_network_name', 'shared_network_id', 'topology_kind', 'controller_kind'],
'classes':['suit-tab suit-tab-general']}),]
suit_form_tabs = (('general','Network Template Details'), ('netparams', 'Parameters') )
diff --git a/xos/core/models/network.py b/xos/core/models/network.py
index 6894f9f..a019091 100644
--- a/xos/core/models/network.py
+++ b/xos/core/models/network.py
@@ -100,15 +100,17 @@
TRANSLATION_CHOICES = (('none', 'none'), ('NAT', 'NAT'))
TOPOLOGY_CHOICES = (('bigswitch', 'BigSwitch'), ('physical', 'Physical'), ('custom', 'Custom'))
CONTROLLER_CHOICES = ((None, 'None'), ('onos', 'ONOS'), ('custom', 'Custom'))
+ ACCESS_CHOICES = ((None, 'None'), ('indirect', 'Indirect'), ('direct', 'Direct'))
name = models.CharField(max_length=32)
description = models.CharField(max_length=1024, blank=True, null=True)
guaranteed_bandwidth = models.IntegerField(default=0)
visibility = models.CharField(max_length=30, choices=VISIBILITY_CHOICES, default="private")
translation = models.CharField(max_length=30, choices=TRANSLATION_CHOICES, default="none")
+ access = models.CharField(max_length=30, null=True, blank=True, choices=ACCESS_CHOICES, help_text="Advertise this network as a means for other slices to contact this slice")
shared_network_name = models.CharField(max_length=30, blank=True, null=True)
shared_network_id = models.CharField(null=True, blank=True, max_length=256, help_text="Quantum network")
- topology_kind = models.CharField(null=False, blank=False, max_length=30, choices=TOPOLOGY_CHOICES, default="BigSwitch")
+ topology_kind = models.CharField(null=False, blank=False, max_length=30, choices=TOPOLOGY_CHOICES, default="bigswitch")
controller_kind = models.CharField(null=True, blank=True, max_length=30, choices=CONTROLLER_CHOICES, default=None)
def __init__(self, *args, **kwargs):
@@ -126,6 +128,10 @@
print >> sys.stderr, "XXX warning: topology_kind invalid case"
self.toplogy_kind="custom"
+ def save(self, *args, **kwargs):
+ self.enforce_choices(self.access, self.ACCESS_CHOICES)
+ super(NetworkTemplate, self).save(*args, **kwargs)
+
def __unicode__(self): return u'%s' % (self.name)
class Network(PlCoreBase, ParameterMixin):
diff --git a/xos/core/models/plcorebase.py b/xos/core/models/plcorebase.py
index 1a2c37c..360792f 100644
--- a/xos/core/models/plcorebase.py
+++ b/xos/core/models/plcorebase.py
@@ -132,6 +132,16 @@
else:
return ("error", html_escape(self.backend_status, quote=True))
+ def enforce_choices(self, field, choices):
+ choices = [x[0] for x in choices]
+ for choice in choices:
+ if field==choice:
+ return
+ if (choice==None) and (field==""):
+ # allow "" and None to be equivalent
+ return
+ raise Exception("Field value %s is not in %s" % (field, str(choices)))
+
class PlCoreBase(models.Model, PlModelMixIn):
objects = PlCoreBaseManager()
deleted_objects = PlCoreBaseDeletionManager()
diff --git a/xos/core/models/service.py b/xos/core/models/service.py
index 2b450e0..135dce9 100644
--- a/xos/core/models/service.py
+++ b/xos/core/models/service.py
@@ -168,12 +168,35 @@
# print "add instance", s
+ def get_vtn_src_nets(self):
+ nets=[]
+ for slice in self.slices.all():
+ 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.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
+ # TODO: fix hard-coding of network name
+ continue
+ for cn in ns.network.controllernetworks.all():
+ if cn.net_id:
+ net = {"name": ns.network.name, "net_id": cn.net_id}
+ nets.append(net)
+ return nets
+
def get_vtn_nets(self):
nets=[]
for slice in self.slices.all():
for ns in slice.networkslices.all():
if not ns.network:
continue
+ if ns.network.template.access not in ["direct", "indirect"]:
+ # skip anything that's not an access network
+ continue
for cn in ns.network.controllernetworks.all():
if cn.net_id:
net = {"name": ns.network.name, "net_id": cn.net_id}
@@ -195,11 +218,11 @@
def get_vtn_dependencies_names(self):
return [x["name"]+"_"+x["net_id"] for x in self.get_vtn_dependencies_nets()]
- def get_vtn_ids(self):
- return [x["net_id"] for x in self.get_vtn_nets()]
+ def get_vtn_src_ids(self):
+ return [x["net_id"] for x in self.get_vtn_src_nets()]
- def get_vtn_names(self):
- return [x["name"]+"_"+x["net_id"] for x in self.get_vtn_nets()]
+ def get_vtn_src_names(self):
+ return [x["name"]+"_"+x["net_id"] for x in self.get_vtn_src_nets()]
class ServiceAttribute(PlCoreBase):
diff --git a/xos/core/static/xos.css b/xos/core/static/xos.css
index 60140ce..40cfcc3 100644
--- a/xos/core/static/xos.css
+++ b/xos/core/static/xos.css
@@ -1,4 +1,4 @@
-************************
+/************************
colors:
tab - active/focus color
background-color: #105E9E !important;
@@ -12,8 +12,8 @@
*************************/
-html, body {
- /*height: 100%;*/
+html, body, body.login {
+ height: 100%;
min-height: 100%;
margin: 0;
}
@@ -27,6 +27,15 @@
min-height: 100%;
}*/
+/* ************************* LOGIN PAGE ************************* */
+
+body.login img.logo{
+ width: 250px;
+ display: block;
+ margin: 20px auto;
+ padding-top: 20px;
+}
+
/* ************************* SIDENAV TOGGLE ************************* */
#wrapper {
@@ -1361,4 +1370,4 @@
width: auto;
padding: 10px;
border-radius: 5px;
-}
\ No newline at end of file
+}
diff --git a/xos/core/xoslib/methods/vtn.py b/xos/core/xoslib/methods/vtn.py
index a912613..14dd458 100644
--- a/xos/core/xoslib/methods/vtn.py
+++ b/xos/core/xoslib/methods/vtn.py
@@ -38,7 +38,7 @@
def get_services_names(self, request, pk=None):
result = {}
for service in Service.objects.all():
- for id in service.get_vtn_names():
+ for id in service.get_vtn_src_names():
dependencies = service.get_vtn_dependencies_names()
if dependencies:
result[id] = dependencies
@@ -47,7 +47,7 @@
def get_services(self, request, pk=None):
result = {}
for service in Service.objects.all():
- for id in service.get_vtn_ids():
+ for id in service.get_vtn_src_ids():
dependencies = service.get_vtn_dependencies_ids()
if dependencies:
result[id] = dependencies
diff --git a/xos/openstack_observer/steps/sync_controller_networks.py b/xos/openstack_observer/steps/sync_controller_networks.py
index ef238ee..b646936 100644
--- a/xos/openstack_observer/steps/sync_controller_networks.py
+++ b/xos/openstack_observer/steps/sync_controller_networks.py
@@ -66,7 +66,8 @@
def map_sync_inputs(self, controller_network):
- if (controller_network.network.template.name!='Private'):
+ # 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
return SyncStep.SYNC_WITHOUT_RUNNING
@@ -81,7 +82,8 @@
raise Exception('Could not save network controller %s'%controller_network)
def map_delete_inputs(self, controller_network):
- if (controller_network.network.template.name!='Private'):
+ # 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']):
# We only sync private networks
return
try:
diff --git a/xos/templates/admin/base.html b/xos/templates/admin/base.html
index cae98ac..f049da9 100644
--- a/xos/templates/admin/base.html
+++ b/xos/templates/admin/base.html
@@ -64,7 +64,7 @@
{% if not is_popup %}
<div id="sidebar-wrapper">
<a href="{% url 'admin:index' %}" class="hidden-xs">
- <img class="logo" src="{% static 'cord_logo_3.png' %}"/>
+ <img class="logo" src="{% static XOS_BRANDING_ICON %}"/>
</a>
{% include 'suit/menu.html' %}
<button class="navbar-toggle collapsed visible-xs" type="button">
@@ -328,4 +328,4 @@
});
</script>
</body>
-</html>
\ No newline at end of file
+</html>
diff --git a/xos/templates/admin/login.html b/xos/templates/admin/login.html
index 5b7ec4d..87bccd0 100644
--- a/xos/templates/admin/login.html
+++ b/xos/templates/admin/login.html
@@ -40,7 +40,7 @@
{% endif %}
<div id="wrap">
<div id="content-main">
-<h1><i class="icon-lock icon-white"></i> OpenCloud</h1>
+ <img class="logo" src="{% static XOS_BRANDING_ICON %}"/>
<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 %}
diff --git a/xos/tosca/custom_types/xos.m4 b/xos/tosca/custom_types/xos.m4
index a806327..907d54c 100644
--- a/xos/tosca/custom_types/xos.m4
+++ b/xos/tosca/custom_types/xos.m4
@@ -350,6 +350,10 @@
type: string
required: false
description: Indicates the type of controller that the network is connected to.
+ access:
+ type: string
+ required: false
+ description: The type of access semantics for this network
tosca.nodes.network.Network.XOS:
# Due to bug? in implementation, we have to copy everything from
diff --git a/xos/tosca/custom_types/xos.yaml b/xos/tosca/custom_types/xos.yaml
index 3339fdf..60968a5 100644
--- a/xos/tosca/custom_types/xos.yaml
+++ b/xos/tosca/custom_types/xos.yaml
@@ -494,6 +494,10 @@
type: string
required: false
description: Indicates the type of controller that the network is connected to.
+ access:
+ type: string
+ required: false
+ description: The type of access semantics for this network
tosca.nodes.network.Network.XOS:
# Due to bug? in implementation, we have to copy everything from
diff --git a/xos/tosca/resources/networktemplate.py b/xos/tosca/resources/networktemplate.py
index 557964e..3a5ce59 100644
--- a/xos/tosca/resources/networktemplate.py
+++ b/xos/tosca/resources/networktemplate.py
@@ -12,7 +12,7 @@
class XOSNetworkTemplate(XOSResource):
provides = "tosca.nodes.NetworkTemplate"
xos_model = NetworkTemplate
- copyin_props = ["visibility", "translation", "shared_network_name", "shared_network_id", "toplogy_kind", "controller_kind"]
+ copyin_props = ["visibility", "translation", "shared_network_name", "shared_network_id", "toplogy_kind", "controller_kind", "access"]
def get_xos_args(self):
args = super(XOSNetworkTemplate, self).get_xos_args()
diff --git a/xos/tosca/samples/helloworld-chain.yaml b/xos/tosca/samples/helloworld-chain.yaml
new file mode 100644
index 0000000..decd3cf
--- /dev/null
+++ b/xos/tosca/samples/helloworld-chain.yaml
@@ -0,0 +1,76 @@
+tosca_definitions_version: tosca_simple_yaml_1_0
+
+description: Two services "service_one" and "service_two" with a tenancy relationship.
+
+imports:
+ - custom_types/xos.yaml
+
+topology_template:
+ node_templates:
+
+ Private-Indirect:
+ type: tosca.nodes.NetworkTemplate
+ properties:
+ access: indirect
+
+ mysite:
+ type: tosca.nodes.Site
+
+ service_vcpe:
+ type: tosca.nodes.Service
+ requirements:
+ - helloworld_tenant:
+ node: service_helloworld
+ relationship: tosca.relationships.TenantOfService
+
+ service_helloworld:
+ type: tosca.nodes.Service
+
+ mysite_helloworld:
+ type: tosca.nodes.Slice
+ requirements:
+ - service:
+ node: service_helloworld
+ relationship: tosca.relationships.MemberOfService
+ - site:
+ node: mysite
+ relationship: tosca.relationships.MemberOfSite
+
+ helloworld_access:
+ type: tosca.nodes.network.Network
+ properties:
+ ip_version: 4
+ requirements:
+ - network_template:
+ node: Private-Indirect
+ relationship: tosca.relationships.UsesNetworkTemplate
+ - owner:
+ node: mysite_helloworld
+ relationship: tosca.relationships.MemberOfSlice
+ - connection:
+ node: mysite_helloworld
+ relationship: tosca.relationships.ConnectsToSlice
+
+ # we need at least one instance to make the Networks instantiate
+ helloworld_instance:
+ type: tosca.nodes.Compute
+ capabilities:
+ # Host container properties
+ host:
+ properties:
+ num_cpus: 1
+ disk_size: 10 GB
+ mem_size: 4 MB
+ # Guest Operating System properties
+ os:
+ properties:
+ # host Operating System image properties
+ architecture: x86_64
+ type: linux
+ distribution: rhel
+ version: 6.5
+ requirements:
+ - slice:
+ node: mysite_helloworld
+ relationship: tosca.relationships.MemberOfSlice
+
diff --git a/xos/xos/config.py b/xos/xos/config.py
index 83d69cb..7a64de9 100644
--- a/xos/xos/config.py
+++ b/xos/xos/config.py
@@ -13,7 +13,7 @@
"""
XOS_DIR = "/opt/xos"
-DEFAULT_CONFIG_FN = os.path.join(XOS_DIR, "xos_config")
+DEFAULT_CONFIG_FN = os.path.join(XOS_DIR, "xos_configuration/")
# warning for now, remove once we're sure everyone has made the change
if (os.path.exists("/opt/planetstack/plstackapi_config") and (not os.path.exists(DEFAULT_CONFIG_FN))):
@@ -40,7 +40,7 @@
self.config_path = os.path.dirname(config_file)
self.config = ConfigParser.ConfigParser()
self.filename = config_file
- if not os.path.isfile(self.filename):
+ if not os.path.isfile(self.filename) and not os.path.isdir(self.filename):
self.create(self.filename)
self.load(self.filename)
@@ -80,7 +80,12 @@
def load(self, filename):
if filename:
try:
- self.config.read(filename)
+ if os.path.isdir(filename):
+ config_list = list(reversed(os.listdir(filename)))
+ config_list = [os.path.join(filename, s) for s in config_list]
+ self.config.read(config_list)
+ else:
+ self.config.read(filename)
except ConfigParser.MissingSectionHeaderError:
if filename.endswith('.xml'):
self.load_xml(filename)
diff --git a/xos/xos_config b/xos/xos_configuration/xos_common_config
old mode 100644
new mode 100755
similarity index 100%
rename from xos/xos_config
rename to xos/xos_configuration/xos_common_config
diff --git a/xos/xos_configuration/xos_frontend_config b/xos/xos_configuration/xos_frontend_config
new file mode 100755
index 0000000..13fe53b
--- /dev/null
+++ b/xos/xos_configuration/xos_frontend_config
@@ -0,0 +1,4 @@
+[gui]
+branding_name=CORD
+branding_css=/static/cord.css
+branding_icon=/static/onos-logo.png