Example #1
0
def config_pre_save(sender, **kwargs):
    if "instance" in kwargs:
        cur_inst = kwargs["instance"]
        cur_inst.description = cur_inst.description or ""
        check_empty_string(cur_inst, "name")
        # priority
        check_integer(cur_inst, "priority", min_val=-9999, max_val=9999)
Example #2
0
def package_search_pre_save(sender, **kwargs):
    if "instance" in kwargs:
        cur_inst = kwargs["instance"]
        check_empty_string(cur_inst, "search_string")
        if not cur_inst.deleted:
            num_ss = package_search.objects.exclude(Q(pk=cur_inst.pk)).filter(
                Q(search_string=cur_inst.search_string)
                & Q(deleted=False)).count()
            if num_ss:
                raise ValidationError("search_string already used")
Example #3
0
def config_blob_pre_save(sender, **kwargs):
    if "instance" in kwargs:
        cur_inst = kwargs["instance"]
        check_empty_string(cur_inst, "name")
        all_var_names = list(cur_inst.config.config_str_set.all().values_list("name", flat=True)) + \
            list(cur_inst.config.config_int_set.all().values_list("name", flat=True)) + \
            list(cur_inst.config.config_bool_set.all().values_list("name", flat=True)) + \
            list(cur_inst.config.config_blob_set.exclude(Q(pk=cur_inst.pk)).values_list("name", flat=True))
        if cur_inst.name in all_var_names:
            raise ValidationError("name '{}' already used".format(cur_inst.name))
Example #4
0
def config_bool_pre_save(sender, **kwargs):
    if "instance" in kwargs:
        cur_inst = kwargs["instance"]
        check_empty_string(cur_inst, "name")
        all_var_names = list(cur_inst.config.config_str_set.all().values_list("name", flat=True)) + \
            list(cur_inst.config.config_int_set.all().values_list("name", flat=True)) + \
            list(cur_inst.config.config_bool_set.exclude(Q(pk=cur_inst.pk)).values_list("name", flat=True)) + \
            list(cur_inst.config.config_blob_set.all().values_list("name", flat=True))
        if cur_inst.name in all_var_names:
            raise ValidationError("name '{}' already used".format(cur_inst.name))
        try:
            if type(cur_inst.value) == bool:
                pass
            else:
                if type(cur_inst.value) in [int, long]:
                    cur_inst.value = True if cur_inst.value else False
                else:
                    cur_inst.value = True if (cur_inst.value or "").lower() in ["1", "true", "yes"] else False
        except ValueError:
            raise ValidationError("value cannot be interpret as bool")
Example #5
0
def netdevice_pre_save(sender, **kwargs):
    if "instance" in kwargs:
        cur_inst = kwargs["instance"]
        if cur_inst.devname:
            cur_inst.devname = cur_inst.devname[:63]
        check_empty_string(cur_inst, "devname")
        check_integer(cur_inst, "mtu", min_val=0, max_val=65536)
        all_nd_names = netdevice.objects.exclude(
            Q(pk=cur_inst.pk)
        ).filter(
            Q(device=cur_inst.device_id)
        ).values_list(
            "devname",
            flat=True
        )
        if cur_inst.devname in all_nd_names:
            raise ValidationError("devname '{}' already used".format(cur_inst.devname))
        # change network_device_type
        _cur_nw_type = cur_inst.network_device_type_id
        if cur_inst.force_network_device_type_match:
            nd_type = cur_inst.find_matching_network_device_type()
            if nd_type is not None:
                cur_inst.network_device_type = nd_type
            else:
                _cs = config_store.ConfigStore(GEN_CS_NAME, quiet=True)
                if _cs["create.network.device.types"]:
                    cur_inst.network_device_type = network_device_type.create_new_type(cur_inst)
                else:
                    raise NoMatchingNetworkDeviceTypeFoundError(
                        "nothing found for '{}' ({})".format(
                            unicode(cur_inst),
                            cur_inst.pk or "new nd"
                        )
                    )
        else:
            if not cur_inst.network_device_type_id:
                # take the first one which is not used for matching
                cur_inst.network_device_type = network_device_type.objects.filter(Q(for_matching=False))[0]
        _nw_type_changed = _cur_nw_type != cur_inst.network_device_type_id
        # fix None as vlan_id
        check_integer(cur_inst, "vlan_id", none_to_zero=True, min_val=0)
        # penalty
        check_integer(cur_inst, "penalty", min_val=1)
        # mac address matching (if needed)
        if cur_inst.force_network_device_type_match:
            # check mac address
            if cur_inst.macaddr:
                cur_inst.macaddr = cur_inst.macaddr.replace("-", ":").lower()
            if cur_inst.fake_macaddr:
                cur_inst.fake_macaddr = cur_inst.fake_macaddr.replace("-", ":").lower()
            dummy_mac, mac_re_str = (
                ":".join(
                    [
                        "00"
                    ] * cur_inst.network_device_type.mac_bytes
                ),
                "^{}$".format(
                    ":".join(
                        [
                            "[0-9a-f]{2}"
                        ] * cur_inst.network_device_type.mac_bytes
                    )
                ),
            )
            mac_re = re.compile(mac_re_str)
            # set empty if not set
            try:
                try:
                    if not cur_inst.macaddr.strip() or int(cur_inst.macaddr.replace(":", ""), 16) == 0:
                        cur_inst.macaddr = dummy_mac
                except:
                    raise ValidationError("MACaddress '{}' has illegal format".format(cur_inst.macaddr))
                # set empty if not set
                try:
                    if not cur_inst.fake_macaddr.strip() or int(cur_inst.fake_macaddr.replace(":", ""), 16) == 0:
                        cur_inst.fake_macaddr = dummy_mac
                except:
                    raise ValidationError("fake MACaddress '{}' has illegal format".format(cur_inst.fake_macaddr))
                if not mac_re.match(cur_inst.macaddr):
                    raise ValidationError("MACaddress '{}' has illegal format for RE '{}'".format(cur_inst.macaddr, mac_re_str))
                if not mac_re.match(cur_inst.fake_macaddr):
                    raise ValidationError("fake MACaddress '{}' has illegal format".format(cur_inst.fake_macaddr))
            except ValidationError:
                if _nw_type_changed:
                    raise ValidationError("NetworkDeviceType has changed and so the MAC-format has changed to '{}'".format(dummy_mac))
                else:
                    raise
        if cur_inst.master_device_id:
            if not cur_inst.vlan_id:
                raise ValidationError("VLAN id cannot be zero")
            if cur_inst.master_device_id == cur_inst.pk:
                raise ValidationError("cannot be my own VLAN master")
            if cur_inst.master_device.master_device_id:
                raise ValidationError("cannot chain VLAN devices")

        if cur_inst.netdevice_speed_id is None:
            # set a default
            cur_inst.netdevice_speed = netdevice_speed.objects.get(Q(speed_bps=1000000000) & Q(full_duplex=True) & Q(check_via_ethtool=False))
Example #6
0
def device_pre_save(sender, **kwargs):
    if "instance" in kwargs:
        cur_inst = kwargs["instance"]
        check_empty_string(cur_inst, "name")
        if cur_inst.name.count("."):
            short_name, dom_name = cur_inst.name.split(".", 1)
            try:
                cur_dnt = domain_tree_node.objects.get(Q(full_name=dom_name))
            except domain_tree_node.DoesNotExist:
                _cs = config_store.ConfigStore(GEN_CS_NAME, quiet=True)
                # create new domain
                if _cs["auto.create.new.domains"]:
                    cur_inst.domain_tree_node = domain_name_tree().add_domain(
                        dom_name)
                    cur_inst.name = short_name
                else:
                    raise ValidationError(
                        "domain '{}' not defined".format(dom_name))
            else:
                cur_inst.domain_tree_node = cur_dnt
                cur_inst.name = short_name
        else:
            if not cur_inst.domain_tree_node_id:
                cur_inst.domain_tree_node = _get_top_level_dtn()
            if not cur_inst.pk:
                top_level_dn = _get_top_level_dtn()
                if top_level_dn is not None:
                    if cur_inst.domain_tree_node_id == top_level_dn.pk:
                        if cur_inst.device_group.device_id:
                            # set domain_node to domain_node of meta_device
                            cur_inst.domain_tree_node = cur_inst.device_group.device.domain_tree_node
                        else:
                            # no meta device (i am the new meta device, ignore)
                            pass
        if not valid_domain_re.match(cur_inst.name):
            # check if we can simple fix it
            if not valid_domain_re.match(cur_inst.name.replace(" ", "_")):
                raise ValidationError("illegal characters in name '{}'".format(
                    cur_inst.name))
            else:
                cur_inst.name = cur_inst.name.replace(" ", "_")
        if not cur_inst.uuid:
            cur_inst.uuid = str(uuid.uuid4())
        if not cur_inst.device_class:
            cur_inst.device_class = DeviceClass.objects.get(
                Q(default_system_class=True))
        # check for already existing device
        try:
            _cur_dev = device.objects.exclude(Q(pk=cur_inst.idx)).get(
                Q(name=cur_inst.name)
                & Q(domain_tree_node=cur_inst.domain_tree_node))
        except device.DoesNotExist:
            pass
        else:
            raise ValidationError(
                "device with name '{}' already exists".format(
                    _cur_dev.full_name))

        # check for uniqueness of UUID
        try:
            present_dev = device.objects.get(Q(uuid=cur_inst.uuid))
        except device.DoesNotExist:
            pass
        else:
            if present_dev.pk != cur_inst.pk:
                raise ValidationError(
                    "UUID clash (same value '{}' for {} and {})".format(
                        cur_inst.uuid,
                        unicode(cur_inst),
                        unicode(present_dev),
                    ))
        # check for device group
        if cur_inst.device_group.cluster_device_group and not cur_inst.is_meta_device:
            raise ValidationError("no devices allowed in cluster_device_group")
Example #7
0
def category_pre_save(sender, **kwargs):
    if "instance" in kwargs:
        cur_inst = kwargs["instance"]
        cur_inst.name = cur_inst.name.strip()
        check_float(cur_inst, "latitude")
        check_float(cur_inst, "longitude")
        if cur_inst.name and cur_inst.name.count("/"):
            parts = [
                entry for entry in cur_inst.name.split("/") if entry.strip()
            ]
            cur_parent = cur_inst.parent
            for cur_part in parts[:-1]:
                try:
                    _parent = category.objects.get(
                        Q(name=cur_part) & Q(parent=cur_parent))
                except category.DoesNotExist:
                    try:
                        _parent = category(
                            name=cur_part,
                            parent=cur_parent,
                            useable=False,
                            comment="autocreated intermediate",
                        )
                        _parent.save()
                    except:
                        raise ValidationError(
                            "cannot create parent: {}".format(
                                process_tools.get_except_info()))
                cur_parent = _parent
            cur_inst.parent = cur_parent
            cur_inst.name = parts[-1]
        if cur_inst.parent_id:
            if cur_inst.pk:
                # check for valid parent
                all_parents = {
                    _v[0]: _v[1]
                    for _v in category.objects.all().values_list(
                        "idx", "parent")
                }
                cur_p_id = cur_inst.parent_id
                while cur_p_id:
                    if cur_p_id == cur_inst.pk:
                        raise ValidationError("parent node is child of node")
                    cur_p_id = all_parents[cur_p_id]
            cur_inst.depth = cur_inst.parent.depth + 1
        if cur_inst.depth and not valid_category_re.match(cur_inst.name):
            raise ValidationError("illegal characters in name '{}'".format(
                cur_inst.name))
        if cur_inst.depth:
            if cur_inst.depth == 1:
                if cur_inst.name not in TREE_SUBTYPES:
                    raise ValidationError(
                        "illegal top-level category name '{}'".format(
                            cur_inst.name))
            check_empty_string(cur_inst, "name")
            parent_node = cur_inst.parent
            new_full_name = "{}/{}".format(
                parent_node.full_name,
                cur_inst.name,
            )
            cur_inst.depth = parent_node.depth + 1
            if new_full_name != cur_inst.full_name:
                cur_inst.full_name = new_full_name
                cur_inst.full_name_changed = True
            # get top level cat
            top_level_cat = cur_inst.full_name.split("/")[1]
            if cur_inst.asset and top_level_cat != TOP_DEVICE_CATEGORY:
                raise ValidationError(
                    "Asset flag only allowed for devicecategory '{}'".format(
                        cur_inst.full_name))
            # check for used named
            used_names = category.objects.exclude(Q(pk=cur_inst.pk)).filter(
                Q(depth=cur_inst.depth)
                & Q(parent=cur_inst.parent)).values_list("name", flat=True)
            if cur_inst.name in used_names:
                raise ValidationError(
                    "category name '{}' already used here".format(
                        cur_inst.name))
        else:
            check_non_empty_string(cur_inst, "name")
Example #8
0
def domain_tree_node_pre_save(sender, **kwargs):
    if "instance" in kwargs:
        device = apps.get_model("backbone", "device")
        net_ip = apps.get_model("backbone", "net_ip")
        cur_inst = kwargs["instance"]
        cur_inst.name = cur_inst.name.strip()
        if cur_inst.name and cur_inst.name.count("."):
            parts = list(reversed(cur_inst.name.split(".")))
            cur_parent = cur_inst.parent
            for cur_part in parts[:-1]:
                try:
                    _parent = domain_tree_node.objects.get(
                        Q(name=cur_part) & Q(parent=cur_parent))
                except domain_tree_node.DoesNotExist:
                    try:
                        _parent = domain_tree_node(
                            name=cur_part,
                            parent=cur_parent,
                            create_short_names=cur_inst.create_short_names,
                            always_create_ip=cur_inst.always_create_ip,
                            write_nameserver_config=cur_inst.
                            write_nameserver_config,
                            comment="autocreated intermediate",
                            node_postfix="",
                        )
                        _parent.save()
                    except:
                        raise ValidationError(
                            "cannot create parent: {}".format(
                                process_tools.get_except_info()))
                cur_parent = _parent
            cur_inst.parent = cur_parent
            cur_inst.name = parts[-1]
        if cur_inst.parent_id:
            if cur_inst.pk:
                # check for valid parent
                all_parents = {
                    _v[0]: _v[1]
                    for _v in domain_tree_node.objects.all().values_list(
                        "idx", "parent")
                }
                cur_p_id = cur_inst.parent_id
                while cur_p_id:
                    if cur_p_id == cur_inst.pk:
                        raise ValidationError("parent node is child of node")
                    cur_p_id = all_parents[cur_p_id]
            cur_inst.depth = cur_inst.parent.depth + 1
        if cur_inst.depth and not valid_domain_re.match(cur_inst.name):
            raise ValidationError("illegal characters in name '{}'".format(
                cur_inst.name))
        if cur_inst.intermediate:
            if net_ip.objects.filter(Q(domain_tree_node=cur_inst)).count(
            ) + device.objects.filter(Q(domain_tree_node=cur_inst)).count():
                cur_inst.intermediate = False
                # raise ValidationError("cannot set used domain_tree_node as intermediate")
        cur_inst.node_postfix = cur_inst.node_postfix.strip()
        if not cur_inst.node_postfix and valid_domain_re.match(
                cur_inst.node_postfix):
            raise ValidationError(
                "illegal characters in node postfix '{}'".format(
                    cur_inst.node_postfix))
        if cur_inst.depth:
            check_empty_string(cur_inst, "name")
            parent_node = cur_inst.parent
            new_full_name = "{}{}".format(
                cur_inst.name,
                ".{}".format(parent_node.full_name)
                if parent_node.full_name else "",
            )
            cur_inst.depth = parent_node.depth + 1
            if new_full_name != cur_inst.full_name:
                cur_inst.full_name = new_full_name
                cur_inst.full_name_changed = True
            used_names = domain_tree_node.objects.exclude(
                Q(pk=cur_inst.pk)).filter(
                    Q(depth=cur_inst.depth)
                    & Q(parent=cur_inst.parent)).values_list("name", flat=True)
            if cur_inst.name in used_names:
                raise ValidationError("DTN-name '{}' already used here".format(
                    cur_inst.name))
        else:
            check_non_empty_string(cur_inst, "name")
            check_non_empty_string(cur_inst, "node_postfix")
Example #9
0
def device_variable_pre_save(sender, **kwargs):
    if "instance" in kwargs:
        cur_inst = kwargs["instance"]
        if cur_inst.device_id:
            if not cur_inst.device_variable_scope_id:
                cur_inst.device_variable_scope = device_variable_scope.objects.get(
                    Q(default_scope=True))
            _dvs = cur_inst.device_variable_scope
            if _dvs.forced_flags:
                # set flags
                for _f_name, _f_value in json.loads(
                        _dvs.forced_flags).iteritems():
                    setattr(cur_inst, _f_name, _f_value)
            # check values
            if cur_inst.var_type == "?":
                # guess type
                _val = cur_inst.val_str
                cur_inst.val_str = ""
                if len(_val.strip()) and _val.strip().isdigit():
                    cur_inst.var_type = "i"
                    cur_inst.val_int = int(_val.strip())
                else:
                    cur_inst.var_type = "s"
                    cur_inst.val_str = _val
            if cur_inst.var_type == "s":
                check_empty_string(cur_inst, "val_str")
            if cur_inst.var_type == "i":
                check_integer(cur_inst, "val_int")
            check_empty_string(cur_inst, "var_type")
            if _dvs.dvs_allowed_name_set.all().count():
                _allowed = _dvs.dvs_allowed_name_set.all()
                if cur_inst.name not in [entry.name for entry in _allowed]:
                    raise ValidationError(
                        "Name '{}' not allowed in scope '{}'".format(
                            cur_inst.name,
                            _dvs.name,
                        ))
                _allowed_struct = [
                    entry for entry in _allowed if entry.name == cur_inst.name
                ][0]
                cur_inst.dvs_allowed_name = _allowed_struct
                if _allowed_struct.unique:
                    _found = device_variable.objects.exclude(
                        Q(pk=cur_inst.idx)).filter(
                            Q(name=cur_inst.name)
                            & Q(device_variable_scope=_dvs)).count()
                    print "Fg", _found
                if _allowed_struct.forced_type:
                    if cur_inst.var_type != _allowed_struct.forced_type:
                        raise ValidationError("Type is not allowed")
            check_empty_string(cur_inst, "name")
            all_var_names = device_variable.objects.exclude(
                Q(pk=cur_inst.pk)).filter(
                    Q(device=cur_inst.device)).values_list("name", flat=True)
            if cur_inst.name in all_var_names:
                raise ValidationError(
                    "name '{}' already used for device '{}'".format(
                        cur_inst.name, unicode(cur_inst.device)))
            cur_inst._clear()
            if not cur_inst.uuid:
                cur_inst.uuid = str(uuid.uuid4())