in geneve/solver/type_ip.py [0:0]
def __init__(self, field, constraints, field_constraints, schema):
super().__init__(field, constraints, field_constraints, schema)
self.include_nets = set()
self.exclude_nets = set()
self.exclude_addrs = set()
for k, v, *_ in constraints + field_constraints:
if k == "==":
v = str(v)
try:
v = ipaddress.ip_address(v)
except ValueError:
pass
else:
if self.is_array:
self.value.extend(v if isinstance(v, list) else [v])
elif self.value is None or self.value == v:
self.value = v
else:
raise ConflictError(f"is already {self.value}, cannot set to {v}", field, k)
continue
try:
self.include_nets.add(ipaddress.ip_network(v))
except ValueError:
raise ValueError(f"Not an IP address or network: {v}")
elif k == "!=":
v = str(v)
try:
self.exclude_addrs.add(ipaddress.ip_address(v))
continue
except ValueError:
pass
try:
self.exclude_nets.add(ipaddress.ip_network(v))
except ValueError:
raise ValueError(f"Not an IP address or network: {v}")
elif k == "in":
values = [v] if isinstance(v, str) else v
for v in values:
try:
self.include_nets.add(ipaddress.ip_network(str(v)))
except ValueError:
raise ValueError(f"Not an IP network: {str(v)}")
elif k == "not in":
values = [v] if isinstance(v, str) else v
for v in values:
try:
self.exclude_nets.add(ipaddress.ip_network(str(v)))
except ValueError:
raise ValueError(f"Not an IP network: {str(v)}")
if self.include_nets & self.exclude_nets:
intersecting_nets = ", ".join(str(net) for net in sorted(self.include_nets & self.exclude_nets))
raise ConflictError(f"net(s) both included and excluded: {intersecting_nets}", field)
if (
self.value is not None
and self.exclude_addrs
and set(self.value if isinstance(self.value, list) else [self.value]) & self.exclude_addrs
):
if len(self.exclude_addrs) == 1:
raise ConflictError(f"cannot be {self.exclude_addrs.pop()}", field)
else:
self.exclude_addrs = ", ".join(str(v) for v in sorted(self.exclude_addrs))
raise ConflictError(f"cannot be any of ({self.exclude_addrs})", field)
if self.value is not None and self.exclude_nets and match_nets(self.value, self.exclude_nets):
if len(self.exclude_nets) == 1:
raise ConflictError(f"cannot be in net {self.exclude_nets.pop()}", field)
else:
self.exclude_nets = ", ".join(str(v) for v in sorted(self.exclude_nets))
raise ConflictError(f"cannot be in any of nets ({self.exclude_nets})", field)
self.ip_versions = sorted(ip.version for ip in self.include_nets | self.exclude_nets | self.exclude_addrs) or [4]
self.include_nets = sorted(self.include_nets, key=lambda x: (x.version, x))