def validate_ip_blocks(ips_list_1, ips_list_2):
     ip_block_1 = IpBlock()
     ip_block_2 = IpBlock()
     for ip in ips_list_1:
         ip_block_1 |= ip
     for ip in ips_list_2:
         ip_block_2 |= ip
     return ip_block_1.contained_in(ip_block_2)
Esempio n. 2
0
 def test_eq(self):
     default_namespace = K8sNamespace('default')
     pod_a = Pod('A', default_namespace)
     ip1 = IpBlock("1.2.3.0/24")
     ip2 = IpBlock("1.2.3.0/32")
     ip3 = ip1 - ip2
     set1 = PeerSet({pod_a, ip1})
     set2 = PeerSet({pod_a, ip2, ip3})
     self.assertTrue(set1 == set2)
Esempio n. 3
0
 def test_subtract(self):
     self.assertTrue(True)
     default_namespace = K8sNamespace('default')
     pod_a = Pod('A', default_namespace)
     ip1 = IpBlock("1.2.3.0/24")
     ip2 = IpBlock("1.2.3.0/32")
     ip3 = ip1 - ip2
     set1 = PeerSet({pod_a, ip1})
     set2 = PeerSet({pod_a, ip2})
     set3 = PeerSet({ip3})
     self.assertTrue(set1-set2 == set3)
    def _get_rule_peers(self, entity_rule):
        """
        Parse the peer-specifying parts of the source/destination parts of a rule
        :param dict entity_rule: The object to parse
        :return: The peers that are specified by nets/notNets/selector/notSelector/namespaceSelector
        :rtype: PeerSet
        """
        nets = entity_rule.get('nets')
        if nets:
            rule_ips = IpBlock(nets[0])
            for cidr in nets[1:]:
                rule_ips |= IpBlock(cidr)
        else:
            rule_ips = IpBlock.get_all_ips_block()

        not_nets = entity_rule.get('notNets', [])
        for cidr in not_nets:
            rule_ips -= IpBlock(cidr)

        ns_selector = self._get_value_as_str(entity_rule, 'namespaceSelector')
        pod_selector = self._get_value_as_str(entity_rule, 'selector')
        not_pod_selector = self._get_value_as_str(entity_rule, 'notSelector')
        if ns_selector:
            rule_peers = self._parse_label_selector(ns_selector,
                                                    entity_rule,
                                                    namespace_selector=True)
        elif pod_selector:
            rule_peers = self.peer_container.get_namespace_pods(self.namespace)
        elif nets or not_nets:
            rule_peers = PeerSet()
            rule_peers.add(rule_ips)
        else:
            rule_peers = self.peer_container.get_all_peers_group(True)

        ns_to_use = self.namespace if not ns_selector else None
        if pod_selector is not None:
            selected_pods = self._parse_label_selector(pod_selector,
                                                       entity_rule, ns_to_use)
            if pod_selector.strip() != 'all()' and selected_pods == rule_peers:
                self.warning(
                    'selector has no effect - better delete or use "all()"',
                    entity_rule)
            rule_peers &= selected_pods
        if not_pod_selector:
            rule_peers -= self._parse_label_selector(not_pod_selector,
                                                     entity_rule, ns_to_use)

        if (nets or not_nets) and (ns_selector or pod_selector):
            rule_peers = PeerSet()
            self.warning(
                'Mixing ip-based selection with label-based selection is likely a mistake',
                entity_rule)

        return rule_peers
Esempio n. 5
0
 def test_or(self):
     default_namespace = K8sNamespace('default')
     pod_a = Pod('A', default_namespace)
     pod_b = Pod('B', default_namespace)
     ip1 = IpBlock("1.2.3.0/24")
     ip2 = IpBlock("1.2.3.0/32")
     ip3 = ip1 - ip2
     set1 = PeerSet({pod_a, pod_b, ip1})
     set2 = PeerSet({pod_a, ip2})
     set3 = PeerSet({pod_b, ip3})
     self.assertTrue(set2 | set3 == set1)
     set2 |= set3
     self.assertTrue(set2 == set1)
Esempio n. 6
0
 def test_and(self):
     default_namespace = K8sNamespace('default')
     pod_a = Pod('A', default_namespace)
     pod_b = Pod('B', default_namespace)
     ip1 = IpBlock("1.2.3.0/24")
     ip2 = IpBlock("1.2.3.0/32")
     pod_set_1 = {pod_a, pod_b, ip2}
     pod_set_2 = {pod_a, ip1}
     a = PeerSet(pod_set_1)
     b = PeerSet(pod_set_2)
     res1 = a & b
     self.assertTrue(res1 == PeerSet({pod_a, ip2}))
     a &= b
     self.assertTrue(a == res1)
 def parse_ip_block(ips_list, not_ips_list):
     """
     parse ipBlocks elements (within a source component of  a rule)
     :param list[str] ips_list: list of ip-block addresses (either ip address or ip-block cidr)
     :param list[str] not_ips_list: negative list of ip-block addresses (either ip address or ip-block cidr)
     :return: A PeerSet containing the relevant IpBlocks
     :rtype: Peer.PeerSet
     """
     ips_list = ['0.0.0.0/0', '::/0'] if ips_list is None else ips_list  # If not set, any IP is allowed
     not_ips_list = [] if not_ips_list is None else not_ips_list
     res_ip_block = IpBlock()
     for cidr in ips_list:
         res_ip_block |= IpBlock(cidr)
     for cidr in not_ips_list:
         res_ip_block -= IpBlock(cidr)
     return res_ip_block.split()
 def _add_networkset_from_yaml(self, networkset_object):
     """
     Add a Calico NetworkSet to the container based on the given resource instance
     :param dict networkset_object: The networkSet object to add
     :return: None
     """
     kind = networkset_object.get('kind')
     is_global = kind == 'GlobalNetworkSet'
     metadata = networkset_object.get('metadata', {})
     spec = networkset_object.get('spec', {})
     name = metadata.get('name', '')
     if name == '':
         print('NetworkSet must have a name', file=stderr)
         return
     if is_global:
         namespace = None
     else:
         namespace_name = metadata.get('namespace', 'default')
         namespace = self.get_namespace(namespace_name)
     ipb = IpBlock(name=name, namespace=namespace, is_global=is_global)
     labels = metadata.get('labels', {})
     if not labels:
         print(f'NetworkSet {name} should have labels', file=stderr)
     for key, val in labels.items():
         ipb.set_label(key, val)
     cidrs = spec.get('nets', {})
     for cidr in cidrs:
         ipb.add_cidr(cidr)
     self._add_peer(ipb)
Esempio n. 9
0
 def get_all_peers_group(self, add_external_ips=False, include_globals=True):
     """
     Return all peers known in the system
     :param bool add_external_ips: Whether to also add the full range of ips
     :param bool include_globals: Whether to include global peers
     :return PeerSet: The required set of peers
     """
     res = PeerSet()
     for peer in self.peer_set:
         if include_globals or not peer.is_global_peer():
             res.add(peer)
     if add_external_ips:
         res.add(IpBlock.get_all_ips_block())
     return res
 def _make_deny_rules(self, allowed_conns):
     """
     Make deny rules from the given connections
     :param TcpLikeProperties allowed_conns: the given allowed connections
     :return: the list of deny IngressPolicyRules
     """
     all_peers_and_ip_blocks = self.peer_container.peer_set.copy()
     all_peers_and_ip_blocks.add(
         IpBlock.get_all_ips_block())  # add IpBlock of all IPs
     all_conns = self._make_tcp_like_properties(PortSet(True),
                                                all_peers_and_ip_blocks)
     denied_conns = all_conns - allowed_conns
     res = self._make_rules_from_conns(denied_conns)
     # Add deny rule for all protocols but TCP , relevant for all peers and ip blocks
     non_tcp_conns = ConnectionSet.get_non_tcp_connections()
     res.append(IngressPolicyRule(all_peers_and_ip_blocks, non_tcp_conns))
     return res
Esempio n. 11
0
 def test_get_peer_set(self):
     ip1 = IpBlock("1.2.3.0/24")
     ip1_set = PeerSet({ip1})
     self.assertTrue(ip1_set == ip1.get_peer_set())
     self.assertTrue(PeerSet() == (ip1-ip1).get_peer_set())
    def _make_tcp_like_properties(self,
                                  dest_ports,
                                  peers,
                                  paths_dfa=None,
                                  hosts_dfa=None):
        """
        get TcpLikeProperties with TCP allowed connections, corresponding to input properties cube.
        TcpLikeProperties should not contain named ports: substitute them with corresponding port numbers, per peer
        :param PortSet dest_ports: ports set for dest_ports dimension (possibly containing named ports)
        :param PeerSet peers: the set of (target) peers
        :param MinDFA paths_dfa: MinDFA obj for paths dimension
        :param MinDFA hosts_dfa: MinDFA obj for hosts dimension
        :return: TcpLikeProperties with TCP allowed connections, corresponding to input properties cube
        """
        assert peers
        base_peer_set = self.peer_container.peer_set.copy()
        base_peer_set.add(IpBlock.get_all_ips_block())
        if not dest_ports.named_ports:
            peers_interval = base_peer_set.get_peer_interval_of(peers)
            return TcpLikeProperties(source_ports=PortSet(True),
                                     dest_ports=dest_ports,
                                     methods=MethodSet(True),
                                     paths=paths_dfa,
                                     hosts=hosts_dfa,
                                     peers=peers_interval,
                                     base_peer_set=base_peer_set)
        assert not dest_ports.port_set
        assert len(dest_ports.named_ports) == 1
        port = list(dest_ports.named_ports)[0]
        tcp_properties = None
        for peer in peers:
            named_ports = peer.get_named_ports()
            real_port = named_ports.get(port)
            if not real_port:
                self.warning(
                    f'Missing named port {port} in the pod {peer}. Ignoring the pod'
                )
                continue
            if real_port[1] != 'TCP':
                self.warning(
                    f'Illegal protocol {real_port[1]} in the named port {port} ingress target pod {peer}.'
                    f'Ignoring the pod')
                continue
            peer_in_set = PeerSet()
            peer_in_set.add(peer)
            ports = PortSet()
            ports.add_port(real_port[0])
            props = TcpLikeProperties(
                source_ports=PortSet(True),
                dest_ports=ports,
                methods=MethodSet(True),
                paths=paths_dfa,
                hosts=hosts_dfa,
                peers=base_peer_set.get_peer_interval_of(peer_in_set),
                base_peer_set=base_peer_set)
            if tcp_properties:
                tcp_properties |= props
            else:
                tcp_properties = props

        return tcp_properties