Exemple #1
0
def _parse_selectors_on_namespace(crd, direction, pod_selector, ns_selector,
                                  rule_block, crd_rules, namespace, matched):
    ns_name = namespace['metadata'].get('name')
    ns_labels = namespace['metadata'].get('labels')
    sg_id = crd['spec']['securityGroupId']

    if (ns_selector and ns_labels
            and driver_utils.match_selector(ns_selector, ns_labels)):
        if pod_selector:
            pods = driver_utils.get_pods(pod_selector, ns_name).get('items')
            if 'ports' in rule_block:
                for port in rule_block['ports']:
                    if type(port.get('port')) is not int:
                        matched = (_create_sg_rule_on_text_port(
                            sg_id, direction, port, pods, crd_rules, matched,
                            crd))
                    else:
                        matched = True
                        for pod in pods:
                            pod_ip = driver_utils.get_pod_ip(pod)
                            crd_rules.append(
                                _create_sg_rule(sg_id,
                                                direction,
                                                pod_ip,
                                                port=port,
                                                namespace=ns_name))
            else:
                for pod in pods:
                    pod_ip = driver_utils.get_pod_ip(pod)
                    matched = True
                    crd_rules.append(
                        _create_sg_rule(sg_id,
                                        direction,
                                        pod_ip,
                                        namespace=ns_name))
        else:
            ns_pods = driver_utils.get_pods(ns_selector)
            ns_cidr = driver_utils.get_namespace_subnet_cidr(namespace)
            if 'ports' in rule_block:
                for port in rule_block['ports']:
                    if type(port.get('port')) is not int:
                        matched = (_create_sg_rule_on_text_port(
                            sg_id, direction, port, ns_pods, crd_rules,
                            matched, crd))
                    else:
                        matched = True
                        crd_rules.append(
                            _create_sg_rule(sg_id,
                                            direction,
                                            ns_cidr,
                                            port=port,
                                            namespace=ns_name))
            else:
                matched = True
                crd_rules.append(
                    _create_sg_rule(sg_id,
                                    direction,
                                    ns_cidr,
                                    namespace=ns_name))
    return matched, crd_rules
Exemple #2
0
def _create_sg_rules_with_container_ports(matched_pods, container_ports,
                                          allow_all, namespace, matched,
                                          crd_rules, sg_id, direction, port,
                                          rule_selected_pod):
    """Create security group rules based on container ports

    If it's an allow from/to everywhere rule or a rule with a
    NamespaceSelector, updates a sg rule that might already exist
    and match the named port or creates a new one with the
    remote_ip_prefixes field containing the matched pod info.
    Otherwise, creates rules for each container port without
    a remote_ip_prefixes field.

    param matched_pods: List of dicts where the key is a container
                        port and value is the pods that have the port
    param container_ports: List of tuples with pods and port values
    param allow_all: True is it's an allow from/to everywhere rule,
                     False otherwise.
    param namespace: Namespace name
    param matched: If a sg rule was created for the NP rule
    param crd_rules: List of sg rules to update when patching the CRD
    param sg_id: ID of the security group
    param direction: String representing rule direction, ingress or egress
    param port: Dict containing port and protocol
    param rule_selected_pod: K8s Pod object selected by the rules selectors

    return: True if a sg rule was created, False otherwise.
    """
    for pod, container_port in container_ports:
        pod_namespace = pod['metadata']['namespace']
        pod_ip = driver_utils.get_pod_ip(pod)
        pod_info = {pod_ip: pod_namespace}
        matched = True
        if allow_all or namespace:
            crd_rule = _get_crd_rule(crd_rules, container_port)
            if crd_rule:
                crd_rule['remote_ip_prefixes'].update(pod_info)
            else:
                if container_port in matched_pods:
                    matched_pods[container_port].update(pod_info)
                else:
                    matched_pods[container_port] = pod_info
        else:
            pod_ip = driver_utils.get_pod_ip(rule_selected_pod)
            sg_rule = driver_utils.create_security_group_rule_body(
                sg_id,
                direction,
                container_port,
                protocol=port.get('protocol'),
                cidr=pod_ip,
                pods=pod_info)
            sgr_id = driver_utils.create_security_group_rule(sg_rule)
            sg_rule['security_group_rule']['id'] = sgr_id
            if sg_rule not in crd_rules:
                crd_rules.append(sg_rule)
    return matched
    def delete_sg_rules(self, pod):
        LOG.debug("Deleting sg rule for pod: %s", pod['metadata']['name'])
        pod_ip = driver_utils.get_pod_ip(pod)
        if not pod_ip:
            LOG.debug("Skipping SG rule deletion as pod %s has no IP assigned",
                      pod['metadata']['name'])
            return None
        crd_pod_selectors = []
        knp_crds = driver_utils.get_kuryrnetpolicy_crds()
        for crd in knp_crds.get('items'):
            crd_selector = crd['spec'].get('podSelector')
            ingress_rule_list = crd['spec'].get('ingressSgRules')
            egress_rule_list = crd['spec'].get('egressSgRules')

            i_matched, i_rules = _parse_rules_on_delete_pod(
                ingress_rule_list, "ingress", pod_ip)
            e_matched, e_rules = _parse_rules_on_delete_pod(
                egress_rule_list, "egress", pod_ip)

            if i_matched or e_matched:
                driver_utils.patch_kuryrnetworkpolicy_crd(
                    crd, i_rules, e_rules, crd_selector)
            if i_matched:
                crd_pod_selectors.append(crd_selector)
        return crd_pod_selectors
 def _pods_in_ip_block(self, pods, resource):
     for pod in pods:
         pod_ip = driver_utils.get_pod_ip(pod)
         if (ipaddress.ip_address(pod_ip)
                 in ipaddress.ip_network(resource.get('cidr'))):
             return True
     return False
def _create_sg_rules(crd, pod, pod_selector, rule_block, direction, matched):
    pod_labels = pod['metadata'].get('labels')
    pod_ip = driver_utils.get_pod_ip(pod)
    if not pod_ip:
        LOG.debug(
            "Skipping SG rule creation for pod %s due to "
            "no IP assigned", pod['metadata']['name'])
        return None

    # NOTE (maysams) No need to differentiate between podSelector
    # with empty value or with '{}', as they have same result in here.
    if pod_selector:
        if driver_utils.match_selector(pod_selector, pod_labels):
            if 'ports' in rule_block:
                for port in rule_block['ports']:
                    if type(port.get('port')) is not int:
                        matched = _create_sg_rule_on_text_port(
                            direction, port, [pod], matched, crd)
                    else:
                        matched = True
            else:
                matched = True
    else:
        # NOTE (maysams) When a policy with namespaceSelector and text port
        # is applied the port on the pods needs to be retrieved.
        if 'ports' in rule_block:
            for port in rule_block['ports']:
                if type(port.get('port')) is not int:
                    matched = _create_sg_rule_on_text_port(
                        direction, port, [pod], matched, crd)
    return matched
    def delete_sg_rules(self, pod):
        LOG.debug("Deleting SG rules for pod: %s", pod['metadata']['name'])
        pod_ip = driver_utils.get_pod_ip(pod)
        crd_pod_selectors = []
        if not pod_ip:
            LOG.debug("Skipping SG rule deletion as pod %s has no IP assigned",
                      pod['metadata']['name'])
            return crd_pod_selectors
        knp_crds = driver_utils.get_kuryrnetworkpolicy_crds()
        for crd in knp_crds:
            crd_selector = crd['spec'].get('podSelector')
            ingress_rule_list = crd['spec'].get('ingressSgRules')
            egress_rule_list = crd['spec'].get('egressSgRules')

            i_matched = _parse_rules_on_delete_pod(ingress_rule_list,
                                                   "ingress", pod_ip)
            e_matched = _parse_rules_on_delete_pod(egress_rule_list, "egress",
                                                   pod_ip)

            if i_matched or e_matched:
                try:
                    driver_utils.bump_networkpolicy(crd)
                except exceptions.K8sResourceNotFound:
                    # The NP got deleted, ignore it.
                    continue
            if i_matched:
                crd_pod_selectors.append(crd_selector)
        return crd_pod_selectors
def _parse_rules(direction, crd, namespace):
    policy = crd['spec']['networkpolicy_spec']
    sg_id = crd['spec']['securityGroupId']

    ns_labels = namespace['metadata'].get('labels')
    ns_name = namespace['metadata'].get('name')
    ns_cidr = utils.get_namespace_subnet_cidr(namespace)

    rule_direction = 'from'
    crd_rules = crd['spec'].get('ingressSgRules')
    if direction == 'egress':
        rule_direction = 'to'
        crd_rules = crd['spec'].get('egressSgRules')

    matched = False
    rule_list = policy.get(direction, [])
    for rule_block in rule_list:
        for rule in rule_block.get(rule_direction, []):
            pod_selector = rule.get('podSelector')
            ns_selector = rule.get('namespaceSelector')
            if (ns_selector and ns_labels
                    and utils.match_selector(ns_selector, ns_labels)):
                if pod_selector:
                    pods = utils.get_pods(pod_selector, ns_name)
                    for pod in pods.get('items'):
                        pod_ip = utils.get_pod_ip(pod)
                        if 'ports' in rule_block:
                            for port in rule_block['ports']:
                                matched = True
                                crd_rules.append(
                                    _create_sg_rule(sg_id,
                                                    direction,
                                                    pod_ip,
                                                    port=port,
                                                    namespace=ns_name))
                        else:
                            matched = True
                            crd_rules.append(
                                _create_sg_rule(sg_id,
                                                direction,
                                                pod_ip,
                                                namespace=ns_name))
                else:
                    if 'ports' in rule_block:
                        for port in rule_block['ports']:
                            matched = True
                            crd_rules.append(
                                _create_sg_rule(sg_id,
                                                direction,
                                                ns_cidr,
                                                port=port,
                                                namespace=ns_name))
                    else:
                        matched = True
                        crd_rules.append(
                            _create_sg_rule(sg_id,
                                            direction,
                                            ns_cidr,
                                            namespace=ns_name))
    return matched, crd_rules
def _create_sg_rules(crd,
                     pod,
                     pod_selector,
                     rule_block,
                     crd_rules,
                     direction,
                     matched,
                     namespace=None):
    pod_labels = pod['metadata'].get('labels')

    # NOTE (maysams) No need to differentiate between podSelector
    # with empty value or with '{}', as they have same result in here.
    if (pod_selector
            and driver_utils.match_selector(pod_selector, pod_labels)):
        matched = True
        pod_ip = driver_utils.get_pod_ip(pod)
        sg_id = crd['spec']['securityGroupId']
        if 'ports' in rule_block:
            for port in rule_block['ports']:
                sg_rule = _create_sg_rule(sg_id,
                                          direction,
                                          cidr=pod_ip,
                                          port=port,
                                          namespace=namespace)
                crd_rules.append(sg_rule)
        else:
            sg_rule = _create_sg_rule(sg_id,
                                      direction,
                                      cidr=pod_ip,
                                      namespace=namespace)
            crd_rules.append(sg_rule)
    return matched
Exemple #9
0
def _create_sg_rules(crd,
                     pod,
                     pod_selector,
                     rule_block,
                     crd_rules,
                     direction,
                     matched,
                     namespace=None,
                     allow_all=False):
    pod_labels = pod['metadata'].get('labels')
    pod_ip = driver_utils.get_pod_ip(pod)
    if not pod_ip:
        LOG.debug(
            "Skipping SG rule creation for pod %s due to "
            "no IP assigned", pod['metadata']['name'])
        return None

    # NOTE (maysams) No need to differentiate between podSelector
    # with empty value or with '{}', as they have same result in here.
    if pod_selector:
        if driver_utils.match_selector(pod_selector, pod_labels):
            sg_id = crd['spec']['securityGroupId']
            if 'ports' in rule_block:
                for port in rule_block['ports']:
                    if type(port.get('port')) is not int:
                        matched = _create_sg_rule_on_text_port(
                            sg_id, direction, port, [pod], crd_rules, matched,
                            crd)
                    else:
                        matched = True
                        sg_rule = _create_sg_rule(sg_id,
                                                  direction,
                                                  cidr=pod_ip,
                                                  port=port,
                                                  namespace=namespace)
                        crd_rules.append(sg_rule)
            else:
                matched = True
                sg_rule = _create_sg_rule(sg_id,
                                          direction,
                                          cidr=pod_ip,
                                          namespace=namespace)
                crd_rules.append(sg_rule)
    else:
        # NOTE (maysams) When a policy with namespaceSelector and text port
        # is applied the port on the pods needs to be retrieved.
        sg_id = crd['spec']['securityGroupId']
        if 'ports' in rule_block:
            for port in rule_block['ports']:
                if type(port.get('port')) is not int:
                    matched = (_create_sg_rule_on_text_port(
                        sg_id,
                        direction,
                        port, [pod],
                        crd_rules,
                        matched,
                        crd,
                        allow_all=allow_all,
                        namespace=namespace))
    return matched
def _parse_selectors_on_namespace(crd, direction, pod_selector, ns_selector,
                                  rule_block, namespace, matched):
    ns_name = namespace['metadata'].get('name')
    ns_labels = namespace['metadata'].get('labels')

    if (ns_selector and ns_labels
            and driver_utils.match_selector(ns_selector, ns_labels)):
        if pod_selector:
            pods = driver_utils.get_pods(pod_selector, ns_name).get('items')
            if 'ports' in rule_block:
                for port in rule_block['ports']:
                    if type(port.get('port')) is not int:
                        matched = (_create_sg_rule_on_text_port(
                            direction, port, pods, matched, crd))
                    else:
                        for pod in pods:
                            pod_ip = driver_utils.get_pod_ip(pod)
                            if not pod_ip:
                                pod_name = pod['metadata']['name']
                                LOG.debug(
                                    "Skipping SG rule creation for pod "
                                    "%s due to no IP assigned", pod_name)
                                continue
                            matched = True
            else:
                for pod in pods:
                    pod_ip = driver_utils.get_pod_ip(pod)
                    if not pod_ip:
                        pod_name = pod['metadata']['name']
                        LOG.debug(
                            "Skipping SG rule creation for pod %s due"
                            " to no IP assigned", pod_name)
                        continue
                    matched = True
        else:
            ns_pods = driver_utils.get_pods(ns_selector)['items']
            if 'ports' in rule_block:
                for port in rule_block['ports']:
                    if type(port.get('port')) is not int:
                        matched = (_create_sg_rule_on_text_port(
                            direction, port, ns_pods, matched, crd))
                    else:
                        matched = True
            else:
                matched = True
    return matched
def _create_sg_rules_with_container_ports(container_ports, matched):
    """Checks if security group rules based on container ports will be updated

    param container_ports: List of tuples with pods and port values
    param matched: If a sg rule was created for the NP rule

    return: True if a sg rule needs to be created, False otherwise.
    """
    for pod, container_port in container_ports:
        pod_ip = driver_utils.get_pod_ip(pod)
        if not pod_ip:
            LOG.debug(
                "Skipping SG rule creation for pod %s due to "
                "no IP assigned", pod['metadata']['name'])
            continue
        return matched
    return False
    def delete_sg_rules(self, pod):
        LOG.debug("Deleting sg rule for pod: %s", pod['metadata']['name'])
        pod_ip = driver_utils.get_pod_ip(pod)
        crd_pod_selectors = []
        knp_crds = driver_utils.get_kuryrnetpolicy_crds()
        for crd in knp_crds.get('items'):
            crd_selector = crd['spec'].get('podSelector')
            ingress_rule_list = crd['spec'].get('ingressSgRules')
            egress_rule_list = crd['spec'].get('egressSgRules')
            i_rules = []
            e_rules = []

            matched = False
            for i_rule in ingress_rule_list:
                LOG.debug("Parsing ingress rule: %r", i_rule)
                remote_ip_prefix = i_rule['security_group_rule'].get(
                    'remote_ip_prefix')
                if remote_ip_prefix and remote_ip_prefix == pod_ip:
                    matched = True
                    driver_utils.delete_security_group_rule(
                        i_rule['security_group_rule']['id'])
                else:
                    i_rules.append(i_rule)

            for e_rule in egress_rule_list:
                LOG.debug("Parsing egress rule: %r", e_rule)
                remote_ip_prefix = e_rule['security_group_rule'].get(
                    'remote_ip_prefix')
                if remote_ip_prefix and remote_ip_prefix == pod_ip:
                    matched = True
                    driver_utils.delete_security_group_rule(
                        e_rule['security_group_rule']['id'])
                else:
                    e_rules.append(e_rule)

            if matched:
                driver_utils.patch_kuryr_crd(crd, i_rules, e_rules,
                                             crd_selector)
                crd_pod_selectors.append(crd_selector)
        return crd_pod_selectors
def _parse_selectors_on_namespace(crd, direction, pod_selector, ns_selector,
                                  rule_block, crd_rules, namespace, matched):
    ns_name = namespace['metadata'].get('name')
    ns_labels = namespace['metadata'].get('labels')
    sg_id = crd['spec']['securityGroupId']

    if (ns_selector and ns_labels
            and driver_utils.match_selector(ns_selector, ns_labels)):
        if pod_selector:
            pods = driver_utils.get_pods(pod_selector, ns_name).get('items')
            if 'ports' in rule_block:
                for port in rule_block['ports']:
                    if type(port.get('port')) is not int:
                        matched = (_create_sg_rule_on_text_port(
                            sg_id, direction, port, pods, crd_rules, matched,
                            crd))
                    else:
                        matched = True
                        for pod in pods:
                            pod_ip = driver_utils.get_pod_ip(pod)
                            if not pod_ip:
                                pod_name = pod['metadata']['name']
                                LOG.debug(
                                    "Skipping SG rule creation for pod "
                                    "%s due to no IP assigned", pod_name)
                                continue
                            sg_rule = _create_sg_rule(sg_id,
                                                      direction,
                                                      pod_ip,
                                                      port=port,
                                                      namespace=ns_name)
                            if sg_rule not in crd_rules:
                                crd_rules.append(sg_rule)
            else:
                for pod in pods:
                    pod_ip = driver_utils.get_pod_ip(pod)
                    if not pod_ip:
                        pod_name = pod['metadata']['name']
                        LOG.debug(
                            "Skipping SG rule creation for pod %s due"
                            " to no IP assigned", pod_name)
                        continue
                    matched = True
                    sg_rule = _create_sg_rule(sg_id,
                                              direction,
                                              pod_ip,
                                              namespace=ns_name)
                    if sg_rule not in crd_rules:
                        crd_rules.append(sg_rule)
        else:
            ns_pods = driver_utils.get_pods(ns_selector)['items']
            ns_cidr = driver_utils.get_namespace_subnet_cidr(namespace)
            if 'ports' in rule_block:
                for port in rule_block['ports']:
                    if type(port.get('port')) is not int:
                        matched = (_create_sg_rule_on_text_port(
                            sg_id, direction, port, ns_pods, crd_rules,
                            matched, crd))
                    else:
                        matched = True
                        sg_rule = _create_sg_rule(sg_id,
                                                  direction,
                                                  ns_cidr,
                                                  port=port,
                                                  namespace=ns_name)
                        if sg_rule not in crd_rules:
                            crd_rules.append(sg_rule)
            else:
                matched = True
                sg_rule = _create_sg_rule(sg_id,
                                          direction,
                                          ns_cidr,
                                          namespace=ns_name)
                if sg_rule not in crd_rules:
                    crd_rules.append(sg_rule)
    return matched, crd_rules