fix conflict
diff --git a/xos/api/utility/sliceplus.py b/xos/api/utility/sliceplus.py
index ca52125..cecea4d 100644
--- a/xos/api/utility/sliceplus.py
+++ b/xos/api/utility/sliceplus.py
@@ -19,6 +19,7 @@
DictionaryField = serializers.DictField
ListField = serializers.ListField
+
class SlicePlus(Slice, PlusObjectMixin):
class Meta:
proxy = True
@@ -82,7 +83,8 @@
if network.ports:
networkPorts = network.ports
- self._sliceInfo= {"sitesUsed": used_sites,
+ self._sliceInfo = {
+ "sitesUsed": used_sites,
"sitesReady": ready_sites,
"instanceStatus": instance_status,
"deploymentsUsed": used_deployments,
@@ -134,7 +136,7 @@
@user_names.setter
def user_names(self, value):
- pass # it's read-only
+ pass # it's read-only
@property
def users(self):
@@ -168,13 +170,13 @@
if (node.site_deployment.site.id in siteIDList):
node.instanceCount = 0
for instance in node.instances.all():
- if instance.slice.id == self.id:
- node.instanceCount = node.instanceCount + 1
+ if instance.slice.id == self.id:
+ node.instanceCount = node.instanceCount + 1
nodeList.append(node)
return nodeList
def save(self, *args, **kwargs):
- if (not hasattr(self,"caller")) or self.caller==None:
+ if (not hasattr(self, "caller")) or self.caller==None:
raise APIException("no self.caller in SlicePlus.save")
updated_image = self.has_field_changed("default_image")
@@ -224,7 +226,7 @@
instances.append(instance)
# delete extra instances
- while (reset and len(instances)>0) or (len(instances) > desired_allocation):
+ while (reset and len(instances) > 0) or (len(instances) > desired_allocation):
instance = instances.pop()
if (not noAct):
print "deleting instance", instance
@@ -234,7 +236,7 @@
# add more instances
if (len(instances) < desired_allocation):
- site = Site.objects.get(name = site_name)
+ site = Site.objects.get(name=site_name)
nodes = self.get_node_allocation([site])
if (not nodes):
@@ -246,12 +248,12 @@
node = nodes[0]
instance = Instance(name=node.name,
- slice=self,
- node=node,
- image = self.default_image,
- flavor = self.default_flavor,
- creator = self.creator,
- deployment = node.site_deployment.deployment)
+ slice=self,
+ node=node,
+ image=self.default_image,
+ flavor=self.default_flavor,
+ creator=self.creator,
+ deployment=node.site_deployment.deployment)
instance.caller = self.caller
instances.append(instance)
if (not noAct):
@@ -262,7 +264,7 @@
node.instanceCount = node.instanceCount + 1
- def save_users(self, noAct = False):
+ def save_users(self, noAct=False):
new_users = self._update_users
try:
@@ -283,15 +285,15 @@
print "added user id", user_id
for priv in slice_privs:
- if (priv.role.id != default_role.id):
- # only mess with 'default' users; don't kill an admin
- continue
+ if (priv.role.id != default_role.id):
+ # only mess with 'default' users; don't kill an admin
+ continue
- if (priv.user.id not in new_users):
- if (not noAct):
- priv.delete()
+ if (priv.user.id not in new_users):
+ if (not noAct):
+ priv.delete()
- print "deleted user id", user_id
+ print "deleted user id", user_id
def save_network_ports(self, noAct=False):
# First search for any network that already has a filled in 'ports'
@@ -314,7 +316,7 @@
network = networkSlice.network
if (network.owner.id != self.id):
continue
- if network.template.translation=="NAT":
+ if network.template.translation == "NAT":
network.ports = self._network_ports
network.caller = self.caller
if (not noAct):
@@ -325,6 +327,7 @@
raise APIException(detail="No network was found that ports could be set on")
+
class SlicePlusIdSerializer(PlusModelSerializer):
id = IdField()
@@ -336,14 +339,14 @@
instance_total_ready = serializers.IntegerField(read_only=True)
instance_status = DictionaryField(read_only=True)
users = ListField(required=False)
- user_names = ListField(required=False) # readonly = True ?
+ user_names = ListField(required=False) # readonly = True ?
current_user_can_see = serializers.SerializerMethodField("getCurrentUserCanSee")
def getCurrentUserCanSee(self, slice):
# user can 'see' the slice if he is the creator or he has a role
current_user = self.context['request'].user
- if (slice.creator and slice.creator==current_user):
- return True;
+ if (slice.creator and slice.creator == current_user):
+ return True
return (len(slice.getSliceInfo(current_user)["roles"]) > 0)
def getSliceInfo(self, slice):
@@ -356,13 +359,16 @@
class Meta:
model = SlicePlus
- fields = ('humanReadableName', 'id','created','updated','enacted','name','enabled','omf_friendly','description','slice_url','site','max_instances','service','network','mount_data_sets',
+ fields = ('humanReadableName', 'id', 'created', 'updated', 'enacted', 'name', 'enabled', 'omf_friendly',
+ 'description', 'slice_url', 'site', 'max_instances', 'service', 'network', 'mount_data_sets',
'default_image', 'default_flavor',
- 'serviceClass','creator',
+ 'serviceClass', 'creator',
# these are the value-added fields from SlicePlus
- 'networks','network_ports','backendIcon','backendHtml',
- 'current_user_roles', 'instance_distribution','instance_distribution_ready','instance_total','instance_total_ready','instance_status','users',"user_names","current_user_can_see")
+ 'networks', 'network_ports', 'backendIcon', 'backendHtml',
+ 'current_user_roles', 'instance_distribution', 'instance_distribution_ready', 'instance_total',
+ 'instance_total_ready', 'instance_status', 'users', "user_names", "current_user_can_see")
+
class SlicePlusList(XOSListCreateAPIView):
queryset = SlicePlus.objects.select_related().all()
@@ -373,12 +379,16 @@
def get_queryset(self):
current_user_can_see = self.request.query_params.get('current_user_can_see', False)
+ site_filter = self.request.query_params.get('site', False)
if (not self.request.user.is_authenticated()):
raise XOSPermissionDenied("You must be authenticated in order to use this API")
slices = SlicePlus.select_by_user(self.request.user)
+ if (site_filter and not current_user_can_see):
+ slices = SlicePlus.objects.filter(site=site_filter)
+
# If current_user_can_see is set, then filter the queryset to return
# only those slices that the user is either creator or has privilege
# on.
@@ -387,11 +397,14 @@
for slice in slices:
if (self.request.user == slice.creator) or (len(slice.getSliceInfo(self.request.user)["roles"]) > 0):
slice_ids.append(slice.id)
-
- slices = SlicePlus.objects.filter(id__in=slice_ids)
+ if (site_filter):
+ slices = SlicePlus.objects.filter(id__in=slice_ids, site=site_filter)
+ else:
+ slices = SlicePlus.objects.filter(id__in=slice_ids)
return slices
+
class SlicePlusDetail(XOSRetrieveUpdateDestroyAPIView):
queryset = SlicePlus.objects.select_related().all()
serializer_class = SlicePlusIdSerializer
@@ -403,5 +416,3 @@
if (not self.request.user.is_authenticated()):
raise XOSPermissionDenied("You must be authenticated in order to use this API")
return SlicePlus.select_by_user(self.request.user)
-
-
diff --git a/xos/configurations/cord-pod/docker-compose.yml b/xos/configurations/cord-pod/docker-compose.yml
index e2a5768..fa8660a 100644
--- a/xos/configurations/cord-pod/docker-compose.yml
+++ b/xos/configurations/cord-pod/docker-compose.yml
@@ -17,6 +17,10 @@
- .:/root/setup:ro
- ../vtn/files/xos_vtn_config:/opt/xos/xos_configuration/xos_vtn_config:ro
- ./images:/opt/xos/images:ro
+ log_driver: "json-file"
+ log_opt:
+ max-size: "100k"
+ max-file: "5"
xos_synchronizer_onos:
image: xosproject/xos-synchronizer-openstack
@@ -29,6 +33,10 @@
volumes:
- .:/root/setup:ro
- ./id_rsa:/opt/xos/synchronizers/onos/onos_key:ro # private key
+ log_driver: "json-file"
+ log_opt:
+ max-size: "100k"
+ max-file: "5"
xos_synchronizer_vcpe:
image: xosproject/xos-synchronizer-openstack
@@ -41,6 +49,10 @@
volumes:
- .:/root/setup:ro
- ./id_rsa:/opt/xos/synchronizers/vcpe/vcpe_private_key:ro # private key
+ log_driver: "json-file"
+ log_opt:
+ max-size: "100k"
+ max-file: "5"
xos_synchronizer_vtn:
image: xosproject/xos-synchronizer-openstack
@@ -52,15 +64,10 @@
- xos_db
volumes:
- .:/root/setup:ro
-
-#xos_synchronizer_vbng:
-# image: xosproject/xos-synchronizer-openstack
-# 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
-# links:
-# - xos_db
+ log_driver: "json-file"
+ log_opt:
+ max-size: "100k"
+ max-file: "5"
xos_synchronizer_monitoring_channel:
image: xosproject/xos-synchronizer-openstack
@@ -73,6 +80,10 @@
volumes:
- .:/root/setup:ro
- ./id_rsa:/opt/xos/synchronizers/monitoring_channel/monitoring_channel_private_key:ro # private key
+ log_driver: "json-file"
+ log_opt:
+ max-size: "100k"
+ max-file: "5"
xos_synchronizer_vtr:
image: xosproject/xos-synchronizer-openstack
@@ -85,6 +96,10 @@
volumes:
- .:/root/setup:ro
- ./id_rsa:/opt/xos/synchronizers/vtr/vcpe_private_key:ro # private key
+ log_driver: "json-file"
+ log_opt:
+ max-size: "100k"
+ max-file: "5"
xos:
command: python /opt/xos/manage.py runserver 0.0.0.0:80 --insecure --makemigrations
@@ -101,3 +116,8 @@
- ./id_rsa.pub:/opt/xos/synchronizers/onos/onos_key.pub:ro
- ./id_rsa.pub:/opt/xos/synchronizers/vcpe/vcpe_public_key:ro
- ./id_rsa.pub:/opt/xos/synchronizers/monitoring_channel/monitoring_channel_public_key:ro
+ log_driver: "json-file"
+ log_opt:
+ max-size: "100k"
+ max-file: "5"
+
diff --git a/xos/configurations/frontend/docker-compose.yml b/xos/configurations/frontend/docker-compose.yml
index 9feb193..39b8faa 100644
--- a/xos/configurations/frontend/docker-compose.yml
+++ b/xos/configurations/frontend/docker-compose.yml
@@ -30,5 +30,7 @@
- ../../templates:/opt/xos/templates
- ../../configurations:/opt/xos/configurations
- ../../xos:/opt/xos/xos
+ - ../../api:/opt/xos/api
- ../../core/views:/opt/xos/core/views
- ../../services:/opt/xos/services
+
diff --git a/xos/core/xoslib/methods/sliceplus.py b/xos/core/xoslib/methods/sliceplus.py
index 9e5b4a1..6908d3c 100644
--- a/xos/core/xoslib/methods/sliceplus.py
+++ b/xos/core/xoslib/methods/sliceplus.py
@@ -77,12 +77,16 @@
def get_queryset(self):
current_user_can_see = self.request.query_params.get('current_user_can_see', False)
+ site_filter = self.request.query_params.get('site', False)
if (not self.request.user.is_authenticated()):
raise XOSPermissionDenied("You must be authenticated in order to use this API")
slices = SlicePlus.select_by_user(self.request.user)
+ if (site_filter and not current_user_can_see):
+ slices = SlicePlus.objects.filter(site=site_filter)
+
# If current_user_can_see is set, then filter the queryset to return
# only those slices that the user is either creator or has privilege
# on.
@@ -91,11 +95,14 @@
for slice in slices:
if (self.request.user == slice.creator) or (len(slice.getSliceInfo(self.request.user)["roles"]) > 0):
slice_ids.append(slice.id)
-
- slices = SlicePlus.objects.filter(id__in=slice_ids)
+ if (site_filter):
+ slices = SlicePlus.objects.filter(id__in=slice_ids, site=site_filter)
+ else:
+ slices = SlicePlus.objects.filter(id__in=slice_ids)
return slices
+
class SlicePlusDetail(XOSRetrieveUpdateDestroyAPIView):
queryset = SlicePlus.objects.select_related().all()
serializer_class = SlicePlusIdSerializer
diff --git a/xos/synchronizers/base/syncstep.py b/xos/synchronizers/base/syncstep.py
index 42a9db4..d505481 100644
--- a/xos/synchronizers/base/syncstep.py
+++ b/xos/synchronizers/base/syncstep.py
@@ -229,8 +229,16 @@
o.delete(purge=True)
else:
new_enacted = timezone.now()
+ try:
+ run_always = self.run_always
+ except AttributeError:
+ run_always = False
+
self.sync_record(o)
- o.enacted = new_enacted
+
+ if (not run_always):
+ o.enacted = new_enacted
+
scratchpad = {'next_run':0, 'exponent':0, 'last_success':time.time()}
o.backend_register = json.dumps(scratchpad)
o.backend_status = "1 - OK"