def __init__(self, *args, **kwargs):
super(SlicePlus, self).__init__(*args, **kwargs)
- self._update_site_allocation = None
self._update_users = None
+ self._sliceInfo = None
+ self.getSliceInfo()
+ self._site_allocation = self._sliceInfo["sitesUsed"]
+ self._initial_site_allocation = self._site_allocation
+ self._network_ports = self._sliceInfo["networkPorts"]
+ self._initial_network_ports = self._network_ports
def getSliceInfo(self, user=None):
- used_sites = {}
- used_deployments = {}
- sliverCount = 0
- for sliver in self.slivers.all():
- site = sliver.node.site_deployment.site
- deployment = sliver.node.site_deployment.deployment
- used_sites[site.name] = used_sites.get(site.name, 0) + 1
- used_deployments[deployment.name] = used_deployments.get(deployment.name, 0) + 1
- sliverCount = sliverCount + 1
-
- roles = []
- if (user!=None):
- roles = [x.role.role for x in self.sliceprivileges.filter(user=user)]
-
- return {"sitesUsed": used_sites,
- "deploymentsUsed": used_deployments,
- "sliverCount": sliverCount,
- "siteCount": len(used_sites.keys()),
- "roles": roles}
+ if not self._sliceInfo:
+ used_sites = {}
+ used_deployments = {}
+ sliverCount = 0
+ sshCommands = []
+ for sliver in self.slivers.all():
+ site = sliver.node.site_deployment.site
+ deployment = sliver.node.site_deployment.deployment
+ used_sites[site.name] = used_sites.get(site.name, 0) + 1
+ used_deployments[deployment.name] = used_deployments.get(deployment.name, 0) + 1
+ sliverCount = sliverCount + 1
+
+ if (sliver.instance_id and sliver.instance_name):
+ sshCommand = 'ssh -o "ProxyCommand ssh -q %s@%s" ubuntu@%s' % (sliver.instance_id, sliver.node.name, sliver.instance_name)
+ sshCommands.append(sshCommand);
+
+ users = {}
+ for priv in SlicePrivilege.objects.filter(slice=self):
+ if not (priv.user.id in users.keys()):
+ users[priv.user.id] = {"name": priv.user.email, "id": priv.user.id, "roles": []}
+ users[priv.user.id]["roles"].append(priv.role.role)
+
+ # XXX this assumes there is only one network that can have ports bound
+ # to it for a given slice. This is intended for the tenant view, which
+ # will obey this field.
+ networkPorts = ""
+ for networkSlice in self.networkslices.all():
+ network = networkSlice.network
+ if (network.owner.id != self.id):
+ continue
+ if network.ports:
+ networkPorts = network.ports
+
+ self._sliceInfo= {"sitesUsed": used_sites,
+ "deploymentsUsed": used_deployments,
+ "sliverCount": sliverCount,
+ "siteCount": len(used_sites.keys()),
+ "users": users,
+ "roles": [],
+ "sshCommands": sshCommands,
+ "networkPorts": networkPorts}
+
+ if user:
+ auser = self._sliceInfo["users"].get(user.id, None)
+ if (auser):
+ self._sliceInfo["roles"] = auser["roles"]
+
+ return self._sliceInfo
@property
def site_allocation(self):
- return self.getSliceInfo()["sitesUsed"]
+ return self._site_allocation
@site_allocation.setter
def site_allocation(self, value):
- self._update_site_allocation = value
- #print "XXX set sitesUsed to", value
+ self._site_allocation = value
+
+ @property
+ def user_names(self):
+ return [user["name"] for user in self.getSliceInfo()["users"].values()]
+
+ @user_names.setter
+ def user_names(self, value):
+ pass # it's read-only
@property
def users(self):
- user_ids = []
- for priv in SlicePrivilege.objects.filter(slice=self):
- if not (priv.user.id in user_ids):
- user_ids.append(priv.user.id)
- return user_ids
+ return [user["id"] for user in self.getSliceInfo()["users"].values()]
@users.setter
def users(self, value):
@property
def network_ports(self):
- # XXX this assumes there is only one network that can have ports bound
- # to it for a given slice. This is intended for the tenant view, which
- # will obey this field.
- networkPorts = ""
- for networkSlice in self.networkslices.all():
- network = networkSlice.network
- if network.ports:
- networkPorts = network.ports
-
- return networkPorts
+ return self._network_ports
@network_ports.setter
def network_ports(self, value):
- print "XXX set networkPorts to", value
+ self._network_ports = value
+ #print "XXX set networkPorts to", value
@staticmethod
def select_by_user(user):
return nodeList
def save(self, *args, **kwargs):
+ updated_image = self.has_field_changed("default_image")
+ updated_flavor = self.has_field_changed("default_flavor")
+
super(SlicePlus, self).save(*args, **kwargs)
- if self._update_site_allocation:
- self.save_site_allocation(noAct=True)
+ # try things out first
+
+ updated_sites = (self._site_allocation != self._initial_site_allocation) or updated_image or updated_flavor
+ if updated_sites:
+ self.save_site_allocation(noAct=True, reset=(updated_image or updated_flavor))
if self._update_users:
self.save_users(noAct=True)
- if self._update_site_allocation:
- self.save_site_allocation()
+ if (self._network_ports != self._initial_network_ports):
+ self.save_network_ports(noAct=True)
+
+ # now actually save them
+
+ if updated_sites:
+ self.save_site_allocation(reset=(updated_image or updated_flavor))
if self._update_users:
self.save_users()
- def save_site_allocation(self, noAct = False):
- new_site_allocation = self._update_site_allocation
+ if (self._network_ports != self._initial_network_ports):
+ self.save_network_ports()
+
+ def save_site_allocation(self, noAct = False, reset=False):
+ print "save_site_allocation, reset=",reset
+
+ if (not self._site_allocation):
+ # Must be a sliver that was just created, and has not site_allocation
+ # field.
+ return
all_slice_slivers = self.slivers.all()
- for site_name in new_site_allocation.keys():
- desired_allocation = new_site_allocation[site_name]
+ for site_name in self._site_allocation.keys():
+ desired_allocation = self._site_allocation[site_name]
# make a list of the slivers for this site
slivers = []
slivers.append(sliver)
# delete extra slivers
- while (len(slivers) > desired_allocation):
+ while (reset and len(slivers)>0) or (len(slivers) > desired_allocation):
sliver = slivers.pop()
- print "deleting sliver", sliver
if (not noAct):
+ print "deleting sliver", sliver
sliver.delete()
+ else:
+ print "would delete sliver", sliver
# add more slivers
if (len(slivers) < desired_allocation):
deployment = node.site_deployment.deployment)
slivers.append(sliver)
if (not noAct):
+ print "added sliver", sliver
sliver.save()
-
- print "added sliver", sliver
+ else:
+ print "would add sliver", sliver
node.sliverCount = node.sliverCount + 1
for user_id in new_users:
if (user_id not in slice_user_ids):
- print "XXX", user_id
priv = SlicePrivilege(slice=self, user=User.objects.get(id=user_id), role=default_role)
if (not noAct):
priv.save()
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'
+ # field. We'll assume there can only be one, so it must be the right
+ # one.
+ for networkSlice in self.networkslices.all():
+ network = networkSlice.network
+ if (network.owner.id != self.id):
+ continue
+ if network.ports:
+ network.ports = self._network_ports
+ if (not noAct):
+ network.save()
+ return
+
+ # Now try a network that is a "NAT", since setting ports on a non-NAT
+ # network doesn't make much sense.
+ for networkSlice in self.networkslices.all():
+ network = networkSlice.network
+ if (network.owner.id != self.id):
+ continue
+ if network.template.translation=="NAT":
+ network.ports = self._network_ports
+ if (not noAct):
+ network.save()
+ return
+
+ # uh oh, we didn't find a network
+
+ raise ValueError("No network was found that ports could be set on")
+