Ejemplo n.º 1
0
    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)
Ejemplo n.º 2
0
    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
Ejemplo n.º 3
0
    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
Ejemplo n.º 4
0
    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)
Ejemplo n.º 5
0
 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)
Ejemplo n.º 6
0
    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)
Ejemplo n.º 7
0
    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)
Ejemplo n.º 8
0
    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)
Ejemplo n.º 9
0
    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)
Ejemplo n.º 10
0
 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
Ejemplo n.º 11
0
    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)
Ejemplo n.º 12
0
    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
Ejemplo n.º 13
0
    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)