def peer_information_pre_save(sender, **kwargs): if "instance" in kwargs: cur_inst = kwargs["instance"] try: _cur_peer = peer_information.objects.get( ( Q(s_netdevice=cur_inst.s_netdevice_id) & Q(d_netdevice=cur_inst.d_netdevice_id) ) | ( Q(s_netdevice=cur_inst.d_netdevice_id) & Q(d_netdevice=cur_inst.s_netdevice_id) ) ) except peer_information.DoesNotExist: pass else: if _cur_peer.pk != cur_inst.pk: raise ValidationError( u"peer already exists [{} on {} --- {} on {}]".format( cur_inst.s_netdevice.devname, unicode(cur_inst.s_netdevice.device), cur_inst.d_netdevice.devname, unicode(cur_inst.d_netdevice.device), ) ) check_integer(cur_inst, "penalty", min_val=1)
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)
def config_script_pre_save(sender, **kwargs): if "instance" in kwargs: cur_inst = kwargs["instance"] if not cur_inst.name: raise ValidationError("name is empty") if not cur_inst.value: raise ValidationError("value is empty") if cur_inst.name in cur_inst.config.config_script_set.exclude(Q(pk=cur_inst.pk)).values_list("name", flat=True): raise ValidationError("name '{}' already used".format(cur_inst.name)) check_integer(cur_inst, "priority") cur_inst.error_text = cur_inst.error_text or ""
def config_int_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.exclude(Q(pk=cur_inst.pk)).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.all().values_list("name", flat=True)) if cur_inst.name in all_var_names: raise ValidationError("name '{}' already used".format(cur_inst.name)) check_integer(cur_inst, "value")
def partition_pre_save(sender, **kwargs): if "instance" in kwargs: cur_inst = kwargs["instance"] p_num = cur_inst.pnum if isinstance(p_num, basestring): if not p_num.strip(): p_num = "0" try: p_num = int(p_num) except: raise ValidationError( "partition number '{}' not parseable".format(p_num)) if p_num == 0: if partition.objects.filter( Q(partition_disc=cur_inst.partition_disc)).count() > 1: raise ValidationError( "for pnum==0 only one partition is allowed") elif p_num < 1 or p_num > 32: raise ValidationError( "partition number {:d} out of bounds [1, 32]".format(p_num)) all_part_nums = partition.objects.exclude(Q(pk=cur_inst.pk)).filter( Q(partition_disc=cur_inst.partition_disc)).values_list("pnum", flat=True) if p_num in all_part_nums: raise ValidationError("partition number already used") cur_inst.pnum = p_num # size check_integer(cur_inst, "size", min_val=0) check_integer(cur_inst, "warn_threshold", none_to_zero=True, min_val=0, max_val=100) check_integer(cur_inst, "crit_threshold", none_to_zero=True, min_val=0, max_val=100) # mountpoint if cur_inst.partition_fs.need_mountpoint(): if cur_inst.mountpoint.strip( ) and not cur_inst.mountpoint.startswith("/"): raise ValidationError("mountpoint must start with '/'") # fs_freq check_integer(cur_inst, "fs_freq", min_val=0, max_val=1) # fs_passno check_integer(cur_inst, "fs_passno", min_val=0, max_val=2) if cur_inst.partition_fs_id: if cur_inst.partition_fs.name == "swap": cur_inst.mountpoint = "swap" cur_inst.partition_hex = cur_inst.partition_fs.hexid
def cd_connection_pre_save(sender, **kwargs): if "instance" in kwargs: cur_inst = kwargs["instance"] for par_idx in xrange(1, 5): check_integer(cur_inst, "parameter_i{:d}".format(par_idx), min_val=0, max_val=256) try: cd_connection.objects.get( Q(parent=cur_inst.parent_id) & Q(child=cur_inst.child_id)) except cd_connection.DoesNotExist: pass except cd_connection.MultipleObjectsReturned: raise ValidationError("connections already exist") else: if cur_inst.pk is None: raise ValidationError("connection already exists")
def network_device_type_pre_save(sender, **kwargs): if "instance" in kwargs: cur_inst = kwargs["instance"] if not(cur_inst.identifier.strip()): raise ValidationError("identifer must not be empty") if not re.match("^[a-zA-Z0-9\-]+$", cur_inst.identifier): raise ValidationError("identifier '{}' contains illegal characters".format(cur_inst.identifier)) if not cur_inst.name_re.startswith("^"): cur_inst.name_re = "^{}".format(cur_inst.name_re) if not cur_inst.name_re.endswith("$"): cur_inst.name_re = "{}$".format(cur_inst.name_re) try: _cur_re = re.compile(cur_inst.name_re) except: raise ValidationError( "invalid re '{}': {}".format( cur_inst.name_re, process_tools.get_except_info() ) ) check_integer(cur_inst, "mac_bytes", min_val=6, max_val=24)
def lvm_lv_pre_save(sender, **kwargs): if "instance" in kwargs: cur_inst = kwargs["instance"] check_integer(cur_inst, "warn_threshold", none_to_zero=True, min_val=0, max_val=100) check_integer(cur_inst, "crit_threshold", none_to_zero=True, min_val=0, max_val=100) # fs_freq check_integer(cur_inst, "fs_freq", min_val=0, max_val=1) # fs_passno check_integer(cur_inst, "fs_passno", min_val=0, max_val=2)
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))
def network_pre_save(sender, **kwargs): if "instance" in kwargs: cur_inst = kwargs["instance"] # what was the changed attribute change_attr = getattr(cur_inst, "change_attribute", None) check_integer(cur_inst, "penalty", min_val=-100, max_val=100) nw_type = cur_inst.network_type.identifier if cur_inst.rel_master_network.all().count() and nw_type != "p": raise ValidationError("slave networks exists, cannot change type") if nw_type != "s" and cur_inst.master_network_id: raise ValidationError("only slave networks can have a master") if nw_type == "s": if not cur_inst.master_network_id: raise ValidationError("slave network needs a master network") else: # print cur_inst.pk, cur_inst.master_network_id if cur_inst.master_network.network_type.identifier != "p": raise ValidationError("master network must be a production network") # validate IP ip_dict = { key: None for key in ["network", "netmask", "broadcast", "gateway"] } for key in ip_dict.keys(): try: ip_dict[key] = ipvx_tools.ipv4(getattr(cur_inst, key)) except: raise ValidationError("{} is not an IPv4 address".format(key)) if not change_attr: change_attr = "network" if change_attr in ["network", "netmask"]: ip_dict["broadcast"] = ~ip_dict["netmask"] | (ip_dict["network"] & ip_dict["netmask"]) elif change_attr == "broadcast": ip_dict["netmask"] = ~(ip_dict["broadcast"] & ~ip_dict["network"]) elif change_attr == "gateway": # do nothing pass # check netmask _mask = 0 any_match = False for _idx in xrange(32, -1, -1): if _mask == ip_dict["netmask"].value(): any_match = True break _mask = _mask + 2 ** (_idx - 1) if not any_match: raise ValidationError("netmask is not valid") ip_dict["network"] = ip_dict["network"] & ip_dict["netmask"] # always correct gateway ip_dict["gateway"] = (ip_dict["gateway"] & ~ip_dict["netmask"]) | ip_dict["network"] if cur_inst._pre_enforce_unique_ips != cur_inst.enforce_unique_ips and cur_inst.enforce_unique_ips: ip_dict = {} for _ip in cur_inst.net_ip_set.all(): ip_dict.setdefault(_ip.ip, []).append(_ip) ip_dict = { key: value for key, value in ip_dict.iteritems() if len(value) > 1 } if ip_dict: raise ValidationError( "not all IPs are unique: {}".format( ", ".join( [ "{}: used {}".format( _key, logging_tools.get_plural("time", len(_value)), ) for _key, _value in ip_dict.iteritems() ] ) ) ) # check range _ignore_range = {None, "", "0.0.0.0"} if cur_inst.start_range not in _ignore_range and cur_inst.end_range not in _ignore_range: # validate range try: ip_dict["start_range"] = ipvx_tools.ipv4(cur_inst.start_range) ip_dict["end_range"] = ipvx_tools.ipv4(cur_inst.end_range) except: raise ValidationError( "start / end range {} / {} not valid".format( cur_inst.start_range, cur_inst.end_range, ) ) else: if ip_dict["end_range"] < ip_dict["start_range"]: raise ValidationError( "range end {} is below range start {}".format( str(ip_dict["end_range"]), str(ip_dict["start_range"]), ) ) if ip_dict["start_range"] <= ip_dict["network"]: raise ValidationError( "range start {} is less or equal to network {}".format( str(ip_dict["end_range"]), str(ip_dict["network"]), ) ) _highest = ip_dict["network"] | (ip_dict["broadcast"] & ~ip_dict["netmask"]) if ip_dict["end_range"] >= _highest: raise ValidationError( "range end {} is above or equal to highest IP {}".format( str(ip_dict["end_range"]), str(_highest), ) ) # set values for key, value in ip_dict.iteritems(): setattr(cur_inst, key, unicode(value))
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())