def _rewrite_ports_for_host(self, port_list, services_for_host):
     self.logger.debug("Rewriting portList %s", port_list)
     if not services_for_host:
         # assign random port, a service with matching port will be created
         return {
             p: "%s%s" % (("-" if "-" in p else ""), str(rand_port()))
             for p in port_list
         }
     rewritten_ports = {}
     wild_card_ports = {p for p in port_list if "*" in p}
     numbered_ports = {p for p in port_list if "*" not in p}
     service_ports = [
         p for svc in services_for_host for p in svc.spec.ports
     ]
     self.logger.debug("Svc ports: %s", service_ports)
     for wildcard_port in wild_card_ports:
         prefix = "-" if "-" in wildcard_port else ""
         # choose any port for wildcard
         rewritten_ports[wildcard_port] = "%s%s" % (
             prefix,
             str(service_ports[0].port),
         )
     for port in numbered_ports:
         prefix = "-" if "-" in port else ""
         port_int = int(port.replace("-", ""))
         service_ports_for_port = [
             p for p in service_ports if p.target_port == port_int
         ]
         # TODO this was a hotfix for recipe 11, where ports 53 were allowed but not for any target,
         # resulting in test to 53 being written despite no service matching them existing.
         # That error should be handled in test generation, an exception here would be fine
         if service_ports_for_port:
             rewritten_ports[port] = "%s%s" % (
                 prefix,
                 str(service_ports_for_port[0].port),
             )
         else:
             # TODO change to exception, handle it higher up
             rewritten_ports[port] = "err"
     return rewritten_ports
示例#2
0
def test_randPort_noExceptPorts_returnsInt():
    assert isinstance(rand_port(), int)
示例#3
0
def test_randPort_allButOnePortsExcepted_returnsRemainingPort():
    generated = rand_port(except_ports=list(range(65535)))
    assert generated == 65535
示例#4
0
def test_randPort_allPortsExcept_raisesException():
    with pytest.raises(Exception):
        rand_port(except_ports=list(range(65535 + 1)))
示例#5
0
 def generate_negative_cases_for_incoming_cases(self, isolated_hosts,
                                                incoming_test_cases,
                                                other_hosts, namespaces):
     runtimes = {}
     start_time = time.time()
     namespace_labels = [
         h.namespace_labels for h in other_hosts
         if isinstance(h, GenericClusterHost)
     ]
     namespaces_per_label_strings = {
         labels_to_string(k): [
             n.metadata.name for n in namespaces
             if n.metadata.labels is not None
             and k.items() <= n.metadata.labels.items()
         ]
         for k in namespace_labels
     }
     namespace_label_resolve_time = time.time()
     runtimes["nsLabelResolve"] = namespace_label_resolve_time - start_time
     labels_per_namespace = {
         n.metadata.name: n.metadata.labels
         for n in namespaces
     }
     overlaps_per_host = {
         host: get_overlapping_hosts(host, namespaces_per_label_strings,
                                     labels_per_namespace,
                                     isolated_hosts + other_hosts)
         for host in isolated_hosts
     }
     overlap_calc_time = time.time()
     runtimes[
         "overlapCalc"] = overlap_calc_time - namespace_label_resolve_time
     cases = []
     for host in isolated_hosts:
         host_string = str(host)
         host_start_time = time.time()
         runtimes[host_string] = {}
         # Check for hosts that can target these to construct negative cases from
         logger.debug(overlaps_per_host[host])
         reaching_hosts_with_ports = [
             (t.from_host, t.port_string) for t in incoming_test_cases
             if t.to_host in overlaps_per_host[host]
         ]
         logger.debug(reaching_hosts_with_ports)
         reaching_host_find_time = time.time()
         runtimes[host_string][
             "findReachingHosts"] = reaching_host_find_time - host_start_time
         if reaching_hosts_with_ports:
             reaching_hosts, _ = zip(*reaching_hosts_with_ports)
             ports_per_host = {
                 host:
                 [p for h, p in reaching_hosts_with_ports if h == host]
                 for host in reaching_hosts
             }
             match_all_host = GenericClusterHost({}, {})
             if match_all_host in reaching_hosts:
                 # All hosts are allowed to reach (on some ports or all) => results from ALLOW all
                 if "*" in ports_per_host[match_all_host]:
                     logger.info("Not generating negative tests for host " +
                                 str(host) +
                                 " as all connections to it are allowed")
                 else:
                     case = NetworkTestCase(
                         match_all_host, host,
                         rand_port(ports_per_host[match_all_host]), False)
                     cases.append(case)
                 runtimes[host_string]["matchAllCase"] = time.time(
                 ) - reaching_host_find_time
             else:
                 inverted_hosts = set([
                     h for l in
                     [invert_host(host) for host in reaching_hosts]
                     for h in l
                 ])
                 hosts_on_inverted = {
                     h: originalHost
                     for l, originalHost in [(invert_host(host), host)
                                             for host in reaching_hosts]
                     for h in l
                 }
                 host_inversion_time = time.time()
                 runtimes[host_string][
                     "hostInversion"] = host_inversion_time - reaching_host_find_time
                 overlaps_for_inverted_hosts = {
                     h:
                     get_overlapping_hosts(h, namespaces_per_label_strings,
                                           labels_per_namespace,
                                           reaching_hosts)
                     for h in inverted_hosts
                 }
                 overlap_calc_time = time.time()
                 runtimes[host_string][
                     "overlapCalc"] = overlap_calc_time - host_inversion_time
                 logger.debug("InvertedHosts: " + str(inverted_hosts))
                 negative_test_targets = [
                     h for h in inverted_hosts
                     if len(overlaps_for_inverted_hosts[h]) <= 1
                 ]
                 logger.debug("NegativeTestTargets: " +
                              str(negative_test_targets))
                 # now remove the inverted hosts that are reachable
                 for target in negative_test_targets:
                     ports_for_inverted_hosts_original_host = ports_per_host[
                         hosts_on_inverted[target]]
                     if ports_for_inverted_hosts_original_host:
                         cases.append(
                             NetworkTestCase(
                                 target, host,
                                 ports_for_inverted_hosts_original_host[0],
                                 False))
                     else:
                         cases.append(
                             NetworkTestCase(target, host, "*", False))
                 runtimes[host_string]["casesGen"] = time.time(
                 ) - overlap_calc_time
         else:
             # No hosts are allowed to reach host -> it should be totally isolated
             # => results from default deny policy
             cases.append(NetworkTestCase(host, host, "*", False))
         runtimes["all"] = time.time() - start_time
示例#6
0
 def generate_negative_cases_for_incoming_cases(
     self, isolated_hosts, incoming_test_cases, other_hosts, namespaces
 ):
     """
     Generates negative test cases based on desired positive test cases
     """
     runtimes = {}
     start_time = time.time()
     # list of all namespace labels set on other hosts
     namespace_labels = [
         h.namespace_labels for h in other_hosts if isinstance(h, GenericClusterHost)
     ]
     namespaces_per_label_strings = get_namespace_label_strings(
         namespace_labels, namespaces
     )
     namespace_label_resolve_time = time.time()
     runtimes["nsLabelResolve"] = namespace_label_resolve_time - start_time
     labels_per_namespace = {n.metadata.name: n.metadata.labels for n in namespaces}
     overlaps_per_host = {
         host: self.get_overlapping_hosts(
             host,
             namespaces_per_label_strings,
             labels_per_namespace,
             isolated_hosts + other_hosts,
         )
         for host in isolated_hosts
     }
     overlap_calc_time = time.time()
     runtimes["overlapCalc"] = overlap_calc_time - namespace_label_resolve_time
     cases = []
     for host in isolated_hosts:
         host_string = str(host)
         host_start_time = time.time()
         runtimes[host_string] = {}
         # Check for hosts that can target these to construct negative cases from
         self.logger.debug(overlaps_per_host[host])
         allowed_hosts_with_ports = [
             (test_case.from_host, test_case.port_string)
             for test_case in incoming_test_cases
             if test_case.to_host in overlaps_per_host[host]
         ]
         self.logger.debug("allowed_hosts_with_ports=%s", allowed_hosts_with_ports)
         reaching_host_find_time = time.time()
         runtimes[host_string]["findReachingHosts"] = (
             reaching_host_find_time - host_start_time
         )
         if allowed_hosts_with_ports:
             allowed_hosts, _ = zip(*allowed_hosts_with_ports)
             ports_per_host = {
                 host: [
                     port
                     for _host, port in allowed_hosts_with_ports
                     if _host == host
                 ]
                 for host in allowed_hosts
             }
             match_all_host = GenericClusterHost({}, {})
             if match_all_host in allowed_hosts:
                 # All hosts are allowed to reach (on some ports or all) => results from ALLOW all
                 if "*" in ports_per_host[match_all_host]:
                     self.logger.info(
                         "Not generating negative tests for host %s"
                         "as all connections to it are allowed",
                         host,
                     )
                 else:
                     cases.append(
                         NetworkTestCase(
                             match_all_host,
                             host,
                             rand_port(ports_per_host[match_all_host]),
                             False,
                         )
                     )
                 runtimes[host_string]["matchAllCase"] = (
                     time.time() - reaching_host_find_time
                 )
             else:
                 inverted_hosts = set(
                     [
                         h
                         for l in [invert_host(host) for host in allowed_hosts]
                         for h in l
                     ]
                 )
                 hosts_on_inverted = {
                     h: originalHost
                     for l, originalHost in [
                         (invert_host(host), host) for host in allowed_hosts
                     ]
                     for h in l
                 }
                 host_inversion_time = time.time()
                 runtimes[host_string]["hostInversion"] = (
                     host_inversion_time - reaching_host_find_time
                 )
                 overlaps_for_inverted_hosts = {
                     h: self.get_overlapping_hosts(
                         h,
                         namespaces_per_label_strings,
                         labels_per_namespace,
                         allowed_hosts,
                     )
                     for h in inverted_hosts
                 }
                 overlap_calc_time = time.time()
                 runtimes[host_string]["overlapCalc"] = (
                     overlap_calc_time - host_inversion_time
                 )
                 self.logger.debug("InvertedHosts: %s", inverted_hosts)
                 negative_test_targets = [
                     h
                     for h in inverted_hosts
                     if len(overlaps_for_inverted_hosts[h]) <= 1
                 ]
                 self.logger.debug("NegativeTestTargets: %s", negative_test_targets)
                 # now remove the inverted hosts that are reachable
                 for target in negative_test_targets:
                     ports_for_inverted_hosts_original_host = ports_per_host[
                         hosts_on_inverted[target]
                     ]
                     if ports_for_inverted_hosts_original_host:
                         cases.append(
                             NetworkTestCase(
                                 target,
                                 host,
                                 ports_for_inverted_hosts_original_host[0],
                                 False,
                             )
                         )
                     else:
                         cases.append(NetworkTestCase(target, host, "*", False))
                 runtimes[host_string]["casesGen"] = time.time() - overlap_calc_time
         else:
             # No hosts are allowed to reach host -> it should be totally isolated
             # => results from default deny policy
             cases.append(NetworkTestCase(host, host, "*", False))
         runtimes["all"] = time.time() - start_time
     return cases, runtimes