def set_owner(self): if hasattr(self, "OWNER_CLASS_NAME"): owner_class = self.get_model_class_by_name(self.OWNER_CLASS_NAME) if not owner_class: raise XOSValidationError("Cannot find owner class %s" % self.OWNER_CLASS_NAME) need_set_owner = True if self.owner_id: # Check to see if owner is set to a valid instance of owner_class. If it is, then we already have an # owner. If it is not, then some other misbehaving class must have altered the ServiceInstance.meta # to point to its own default (these services are being cleaned up). if owner_class.objects.filter(id=self.owner_id).exists(): need_set_owner = False if need_set_owner: owners = owner_class.objects.all() if not owners: raise XOSValidationError( "Cannot find eligible owner of class %s" % self.OWNER_CLASS_NAME) self.owner = owners[0] else: # Deal with legacy services that specify their owner as _meta field default. This is a workaround for # what is probably a django bug (if a SerivceInstance without a default is created before a ServiceInstance # that does have a default, then the later service's default is not honored by django). # TODO: Delete this after all services have been migrated away from using field defaults if ((not self.owner_id) and (self._meta.get_field("owner").default) and (self._meta.get_field("owner").default != NOT_PROVIDED)): self.owner = Service.objects.get( id=self._meta.get_field("owner").default)
def get_next_available_port(self, protocol): """Gets the next free port for the given protocol. Parameters: protocol (str): The protocol to get a port for, must be tcp or udp. Returns: int: a port number. Raises: xos.exceptions.XOSValidationError: If there the protocol is not udp or tcp. xos.exceptions.XOSValidationError: If there are no available ports for the protocol. """ if protocol != "udp" and protocol != "tcp": raise XOSValidationError("Port protocol must be udp or tcp") if not self.exposed_ports[protocol]: raise XOSValidationError("No availble ports for protocol: " + protocol) tenants = [ tenant for tenant in OpenVPNTenant.get_tenant_objects().all() if tenant.protocol == protocol ] port_numbers = self.exposed_ports[protocol] for port_number in port_numbers: if (len([ tenant for tenant in tenants if tenant.port_number == port_number ]) == 0): return port_number
def clean_exposed_ports(self): exposed_ports = self.cleaned_data['exposed_ports'] self.instance.exposed_ports_str = exposed_ports port_mapping = {"udp": [], "tcp": []} parts = exposed_ports.split(",") for part in parts: part = part.strip() if "/" in part: (protocol, ports) = part.split("/", 1) elif " " in part: (protocol, ports) = part.split(None, 1) else: raise XOSValidationError( 'malformed port specifier %s, format example: ' + '"tcp 123, tcp 201:206, udp 333"' % part) protocol = protocol.strip() ports = ports.strip() if not (protocol in ["udp", "tcp"]): raise XOSValidationError('unknown protocol %s' % protocol) if "-" in ports: port_mapping[protocol].extend(self.parse_port_range( ports, "-")) elif ":" in ports: port_mapping[protocol].extend(self.parse_port_range( ports, ":")) else: port_mapping[protocol].append(int(ports)) return port_mapping
def delete(self, *args, **kwargs): onus = [] pon_ports = self.pon_ports.all() for port in pon_ports: onus = onus + list(port.onu_devices.all()) if len(onus) > 0: onus = [o.id for o in onus] # find the ONUs used by VOLTServiceInstances used_onus = [o.onu_device_id for o in self.get_volt_si()] # find the intersection between the onus associated with this OLT and the used one used_onus_to_delete = [o for o in onus if o in used_onus] if len(used_onus_to_delete) > 0: if hasattr(self, "device_id") and self.device_id: item = self.device_id elif hasattr(self, "name") and self.name: item = self.name else: item = self.id raise XOSValidationError( 'OLT "%s" can\'t be deleted as it has subscribers associated with its ONUs' % item) super(OLTDevice, self).delete(*args, **kwargs)
def validate_range(self, pattern): for this_range in pattern.split(","): this_range = this_range.strip() if "-" in this_range: (first, last) = this_range.split("-") try: int(first.strip()) int(last.strip()) except ValueError: raise XOSValidationError("Malformed range %s" % pattern) elif this_range.lower() == "any": pass else: try: int(this_range) except ValueError: raise XOSValidationError("Malformed range %s" % pattern)
def save(self, *args, **kwargs): if (self.host or self.port) and self.mac_address: raise XOSValidationError( "You can't specify both host/port and mac_address for OLTDevice [host=%s, port=%s, mac_address=%s]" % (self.host, self.port, self.mac_address)) super(OLTDevice, self).save(*args, **kwargs)
def delete(self, *args, **kwargs): if len(self.volt_service_instances.all()) > 0: raise XOSValidationError( 'ONU "%s" can\'t be deleted as it has subscribers associated with it' % self.serial_number) super(ONUDevice, self).delete(*args, **kwargs)
def save(self, *args, **kwargs): if self.url and not self.version: raise XOSValidationError( "If you specify a url, you also need to specify a version. ONOSApp: %s" % self.name) super(ONOSApp, self).save(*args, **kwargs)
def save(self, *args, **kwargs): existing_services = ProgranService.objects.all() if len(existing_services) > 0 and not self.delete: raise XOSValidationError( "A ProgranService already exists, you should not have more than one" ) super(ProgranService, self).save(*args, **kwargs)
def save(self, *args, **kwargs): try: if ":" in self.ip: # it's an IPv6 address socket.inet_pton(socket.AF_INET6, self.ip) else: # it's an IPv4 address socket.inet_pton(socket.AF_INET, self.ip) except socket.error: raise XOSValidationError("The IP specified is not valid: %s" % self.ip) super(RCORDIpAddress, self).save(*args, **kwargs) return
def save(self, *args, **kwargs): # remove all the profiles related to this enodeb (clearing the relation, not the models) if self.deleted: self.profiles.clear() # prevent enbId duplicates try: instance_with_same_id = ENodeB.objects.get(enbId=self.enbId) if (not self.pk and instance_with_same_id) or ( self.pk and self.pk != instance_with_same_id.pk): raise XOSValidationError( "A ENodeB with enbId '%s' already exists" % self.enbId) except self.DoesNotExist: pass if self.is_new and not self.created_by: # NOTE if created_by is null it has been created by XOS self.created_by = "XOS" super(ENodeB, self).save(*args, **kwargs)
def save(self, *args, **kwargs): self.validate_unique_service_specific_id(none_okay=True) # VSGServiceInstance will extract the creator from the Subscriber, as it needs a creator to create its # Instance. if not self.creator: # If we weren't passed an explicit creator, then we will assume the caller is the creator. if not getattr(self, "caller", None): raise XOSProgrammingError( "RCORDSubscriber's self.caller was not set") self.creator = self.caller # validate MAC Address if hasattr(self, 'mac_address') and self.mac_address: if not re.match( "[0-9a-f]{2}([-:]?)[0-9a-f]{2}(\\1[0-9a-f]{2}){4}$", self.mac_address.lower()): raise XOSValidationError( "The MAC address specified is not valid: %s" % self.mac_address) # validate c_tag if self.c_tag: is_update_with_same_tag = False if not self.is_new: # if it is an update, but the tag is the same, skip validation existing = RCORDSubscriber.objects.filter(id=self.id) if len(existing) > 0 and existing[ 0].c_tag == self.c_tag and existing[0].id == self.id: is_update_with_same_tag = True if self.c_tag in self.get_used_c_tags( ) and not is_update_with_same_tag: raise XOSValidationError( "The c_tag you specified (%s) has already been used on device %s" % (self.c_tag, self.onu_device)) # validate s_tag and c_tag combination if self.c_tag and self.s_tag: is_update_with_same_tag = False if not self.is_new: # if it is an update, but the tags are the same, skip validation existing = RCORDSubscriber.objects.filter(id=self.id) if len( existing ) > 0 and existing[0].c_tag == self.c_tag and existing[ 0].s_tag == self.s_tag and existing[0].id == self.id: is_update_with_same_tag = True id = self.get_used_s_c_tag_subscriber_id() if None != id and not is_update_with_same_tag: raise XOSValidationError( "The c_tag(%s) and s_tag(%s) pair you specified,has already been used by Subscriber with Id (%s)" % (self.c_tag, self.s_tag, id)) if not self.c_tag: self.c_tag = self.generate_c_tag() elif not self.s_tag: self.s_tag = self.generate_s_tag() self.set_owner() if self.status != "pre-provisioned" and \ hasattr(self.owner.leaf_model, "access") and \ self.owner.leaf_model.access == "voltha" and \ not self.deleted: # if the access network is managed by voltha, validate that onu_device actually exist # we assume RCORDService is connected only to the vOLTService for ps in self.owner.provider_services: provider_service = ps.leaf_model if provider_service.name.lower() == "volt": volt_service = provider_service # When interacting with VOLT-service remove the -X from onu_device if not volt_service.has_access_device( self.onu_device.split('-')[0]): raise XOSValidationError( "The onu_device you specified (%s) does not exists" % self.onu_device) # if the access network is managed by voltha, validate that the tech_profile_id actually exists if not self.validate_tech_profile_id(): raise XOSValidationError( "The technology profile you specified [%s] does not exist" % self.tech_profile_id) super(RCORDSubscriber, self).save(*args, **kwargs) self.invalidate_related_objects() return
def save(self, *args, **kwargs): # TODO we should not allow name changes as name is the mapping with the backend # name is mandatory if not self.name: raise XOSValidationError( "name is mandatory for ProgranServiceInstances") # NOTE this check is disabled as when Progran create a profile it fails # if self.DlUeAllocRbRate > self.DlAllocRBRate: # raise XOSValidationError("DlUeAllocRbRate (%s) cannot be bigger than DlAllocRBRate (%s)" % (self.DlUeAllocRbRate, self.DlAllocRBRate)) # prevent name duplicates try: instances_with_same_name = ProgranServiceInstance.objects.get( name=self.name) if (not self.pk and instances_with_same_name) or ( self.pk and self.pk != instances_with_same_name.pk): raise XOSValidationError( "A ProgranServiceInstance with name '%s' already exists" % self.name) except self.DoesNotExist: pass if self.is_new and not self.created_by: # NOTE if created_by is null it has been created by XOS self.created_by = "XOS" # check that the sum of upload and download rate for a single enodeb is not greater than 95 if not self.deleted: limit = 95 same_enodeb = ProgranServiceInstance.objects.filter( enodeb_id=self.enodeb_id) total_up = self.UlAllocRBRate total_down = self.DlAllocRBRate for p in same_enodeb: if p.pk != self.pk: total_up = total_up + p.UlAllocRBRate total_down = total_down + p.DlAllocRBRate if total_up > limit: raise XOSValidationError( "UlAllocRBRate for the enodeb associated with this profile is greater than %s" % limit) if total_down > limit: raise XOSValidationError( "DlAllocRBRate for the enodeb associated with this profile is greater than %s" % limit) caller_kind = "xos" if "caller_kind" in kwargs: caller_kind = kwargs.pop("caller_kind") print "Profile %s has been saved by %s" % (self.name, caller_kind) if caller_kind == "xos": print "Setting no_sync to false for profile %s" % self.name self.no_sync = False super(ProgranServiceInstance, self).save(*args, **kwargs)