Exemplo n.º 1
0
    def is_cluster_isolated(self, cluster_name):
        """."""
        # check for the presence of the firewall section
        firewall_section_name = \
            self._get_firewall_section_name_for_cluster(cluster_name)
        dfw_manager = DFWManager(self._nsxt_client)
        firewall_section = dfw_manager.get_firewall_section(
            name=firewall_section_name)

        if not firewall_section:
            return False

        rules = dfw_manager.get_all_rules_in_section(
            section_id=firewall_section['id'])

        # Check for presence of the isolation DFW rules.
        # The checks are overly rigid, because we don't want any tampering with
        # the network isolation rules created by CSE on NSX-T. If the number of
        # rules are changed in future, this piece of logic should be updated
        # accordingly.
        if len(rules) != 2:
            return False

        found_rule_names = {rules[0]['display_name'], rules[1]['display_name']}
        if self.RULE2_NAME not in found_rule_names or \
                self.RULE3_NAME not in found_rule_names:
            return False

        return True
Exemplo n.º 2
0
def _create_ncp_boundary_firewall_section(
        nsxt_client,
        anchor_id,
        firewall_section_name,
        tag_value):
    dfw_manager = DFWManager(nsxt_client)

    section = dfw_manager.get_firewall_section(name=firewall_section_name)
    if not section:
        tag = {}
        tag['scope'] = "ncp/fw_sect_marker"
        tag['tag'] = tag_value
        tags = [tag]

        nsxt_client.LOGGER.debug(
            f"Creating DFW section : {firewall_section_name}")
        section = dfw_manager.create_firewall_section(
            name=firewall_section_name,
            tags=tags,
            anchor_id=anchor_id,
            insert_policy=INSERT_POLICY.INSERT_BEFORE)
    else:
        nsxt_client.LOGGER.debug(f"DFW section : {firewall_section_name} "
                                 "already exists.")

    return section
Exemplo n.º 3
0
def setup_nsxt_constructs(nsxt_client,
                          nodes_ip_block_id,
                          pods_ip_block_id,
                          ncp_boundary_firewall_section_anchor_id):
    """Set up one time NSX-T construct which will aid in network isolation.

    :param list nodes_ip_block_id: list of strings, where each entry represents
        id of a non routable ip block from which ip of cluster nodes will be
        assigned.
    :param list pods_ip_block_id: list of strings, where each entry represents
        id of a non routable ip block from which ip of cluster pods will be
        assigned.
    :param str ncp_boundary_firewall_section_anchor_id: id of the firewal
        section which will act as anchor for the NCP fw_sector/top firewall
        section.
    """
    _create_ipset_for_node_pod_ip_blocks(nsxt_client,
                                         nodes_ip_block_id,
                                         pods_ip_block_id)

    _create_all_nodes_pods_nsgroup(nsxt_client)

    dfw_manager = DFWManager(nsxt_client)
    dfw_manager.delete_firewall_section(
        name=NCP_BOUNDARY_FIREWALL_SECTION_NAME)
    _create_ncp_boundary_firewall_section(
        nsxt_client, ncp_boundary_firewall_section_anchor_id,
        NCP_BOUNDARY_TOP_FIREWALL_SECTION_NAME, "top")
    _create_ncp_boundary_firewall_section(
        nsxt_client, ncp_boundary_firewall_section_anchor_id,
        NCP_BOUNDARY_BOTTOM_FIREWALL_SECTION_NAME, "bottom")
Exemplo n.º 4
0
    def _create_firewall_rules_for_cluster(self, section_id, nodes_nsgroup_id,
                                           pods_nsgroup_id,
                                           nodes_pods_nsgroup_id,
                                           all_nodes_pods_nsgroup_id):
        """Create DFW Rules to isolate a cluster network.

        One rule to limit communication from pods to nodes.
        One rule to allow other form of communication between nodes and pods.
        One rule to isolate the nodes and pods of this cluster from other
            clusters.

        :param str section_id: id of the DFW Section where these rules will be
            added.
        :param str nodes_nsgroup_id:
        :param str pods_nsgroup_id:
        :param str nodes_pods_nsgroup_id:
        :param str all_nodes_pods_nsgroup_id:
        """
        dfw_manager = DFWManager(self._nsxt_client)
        # self._nsxt_client.LOGGER.debug(
        # f"Creating DFW rule : {self.RULE1_NAME}")
        # rule1 = dfw_manager.create_dfw_rule(
        #    section_id=section_id,
        #    rule_name=self.RULE1_NAME,
        #    source_nsgroup_id=pods_nsgroup_id,
        #    dest_nsgroup_id=nodes_nsgroup_id,
        #    action=FIREWALL_ACTION.DROP)

        self._nsxt_client.LOGGER.debug(
            f"Creating DFW rule : {self.RULE2_NAME}")
        rule2 = dfw_manager.create_dfw_rule(
            section_id=section_id,
            rule_name=self.RULE2_NAME,
            source_nsgroup_id=nodes_pods_nsgroup_id,
            dest_nsgroup_id=nodes_pods_nsgroup_id,
            action=FIREWALL_ACTION.ALLOW,
            # anchor_rule_id=rule1['id'],
            # insert_policy=INSERT_POLICY.INSERT_AFTER
        )

        self._nsxt_client.LOGGER.debug(
            f"Creating DFW rule : {self.RULE3_NAME}")
        dfw_manager.create_dfw_rule(section_id=section_id,
                                    rule_name=self.RULE3_NAME,
                                    source_nsgroup_id=nodes_pods_nsgroup_id,
                                    dest_nsgroup_id=all_nodes_pods_nsgroup_id,
                                    action=FIREWALL_ACTION.DROP,
                                    anchor_rule_id=rule2['id'],
                                    insert_policy=INSERT_POLICY.INSERT_AFTER)
Exemplo n.º 5
0
    def remove_cluster_isolation(self, cluster_name):
        """Revert isolation of a PKS cluster's network.

        :param str cluster_name: name of the cluster whose network isolation
            needs to be reverted.
        """
        firewall_section_name = \
            self._get_firewall_section_name_for_cluster(cluster_name)

        nodes_nsgroup_name = self._get_nodes_nsgroup_name(cluster_name)
        pods_nsgroup_name = self._get_pods_nsgroup_name(cluster_name)
        nodes_pods_nsgroup_name = \
            self._get_nodes_pods_nsgroup_name(cluster_name)

        dfw_manager = DFWManager(self._nsxt_client)
        nsgroup_manager = NSGroupManager(self._nsxt_client)

        dfw_manager.delete_firewall_section(firewall_section_name,
                                            cascade=True)
        nsgroup_manager.delete_nsgroup(nodes_pods_nsgroup_name, force=True)
        nsgroup_manager.delete_nsgroup(nodes_nsgroup_name, force=True)
        nsgroup_manager.delete_nsgroup(pods_nsgroup_name, force=True)
Exemplo n.º 6
0
    def _create_firewall_section_for_cluster(self, cluster_name,
                                             applied_to_nsgroup_id):
        """Create DFW Section for the cluster.

        If DFW Section already exists, delete it and re-create it. Since this
        section is based on cluster name, it possible that a previously
        deployed cluster on deletion failed to cleanup properly. We shouldn't
        re-use such a section rather create it afresh with new rules pointing
        to the correct NSGroups.

        :param str cluster_name: name of the cluster whose network is being
            isolated.
        :param str applied_to_nsgroup_id: id of the NSGroup on which the rules
            in this DFW Section will apply to.
        """
        section_name = self._get_firewall_section_name_for_cluster(
            cluster_name)
        dfw_manager = DFWManager(self._nsxt_client)
        section = dfw_manager.get_firewall_section(section_name)
        if section:
            self._nsxt_client.LOGGER.debug(f"DFW section : {section_name} "
                                           "already exists.")
            dfw_manager.delete_firewall_section(section_name, cascade=True)
            self._nsxt_client.LOGGER.debug("Deleted DFW section : "
                                           f"{section_name} ")

        target = {}
        target['target_type'] = "NSGroup"
        target['target_id'] = applied_to_nsgroup_id

        anchor_section = dfw_manager.get_firewall_section(
            NCP_BOUNDARY_BOTTOM_FIREWALL_SECTION_NAME)

        self._nsxt_client.LOGGER.debug("Creating DFW section : "
                                       f"{section_name}")
        section = dfw_manager.create_firewall_section(
            name=section_name,
            applied_tos=[target],
            anchor_id=anchor_section['id'],
            insert_policy=INSERT_POLICY.INSERT_AFTER)

        return section
def _validate_pks_config_data_integrity(
        pks_config,
        msg_update_callback=NullPrinter(),
        logger_debug=NULL_LOGGER,
        logger_wire=NULL_LOGGER
):
    all_pks_servers = \
        [entry['name'] for entry in pks_config[PKS_SERVERS_SECTION_KEY]]
    all_pks_accounts = \
        [entry['name'] for entry in pks_config[PKS_ACCOUNTS_SECTION_KEY]]

    # Create a cache with pks_account to Credentials mapping
    pks_account_info_table = {}
    for pks_account in pks_config[PKS_ACCOUNTS_SECTION_KEY]:
        pks_account_name = pks_account['pks_api_server']
        credentials = Credentials(
            pks_account['username'],
            pks_account['secret']
        )

        pks_account_info_table[pks_account_name] = credentials

    # Check for duplicate pks api server names
    duplicate_pks_server_names = get_duplicate_items_in_list(all_pks_servers)
    if len(duplicate_pks_server_names) != 0:
        raise ValueError(
            f"Duplicate PKS api server(s) : {duplicate_pks_server_names} found"
            f" in Section : {PKS_SERVERS_SECTION_KEY}"
        )

    # Check for duplicate pks account names
    duplicate_pks_account_names = get_duplicate_items_in_list(all_pks_accounts)
    if len(duplicate_pks_account_names) != 0:
        raise ValueError(
            f"Duplicate PKS account(s) : {duplicate_pks_account_names} found"
            f" in Section : {PKS_ACCOUNTS_SECTION_KEY}"
        )

    # Check validity of all PKS api servers referenced in PKS accounts section
    for pks_account in pks_config[PKS_ACCOUNTS_SECTION_KEY]:
        pks_server_name = pks_account.get('pks_api_server')
        if pks_server_name not in all_pks_servers:
            raise ValueError(
                f"Unknown PKS api server : {pks_server_name} referenced by "
                f"PKS account : {pks_account.get('name')} in Section : "
                f"{PKS_ACCOUNTS_SECTION_KEY}"
            )

    # Check validity of all PKS accounts referenced in Orgs section
    if PKS_ORGS_SECTION_KEY in pks_config.keys():
        for org in pks_config[PKS_ORGS_SECTION_KEY]:
            referenced_accounts = org.get('pks_accounts')
            if not referenced_accounts:
                continue
            for account in referenced_accounts:
                if account not in all_pks_accounts:
                    raise ValueError(
                        f"Unknown PKS account : {account} "
                        f"referenced by Org : {org.get('name')} "
                        f"in Section : {PKS_ORGS_SECTION_KEY}"
                    )

    # Check validity of all PKS api servers referenced in PVDC section
    for pvdc in pks_config[PKS_PVDCS_SECTION_KEY]:
        pks_server_name = pvdc.get('pks_api_server')
        if pks_server_name not in all_pks_servers:
            raise ValueError(
                f"Unknown PKS api server : {pks_server_name} "
                f"referenced by PVDC : {pvdc.get('name')} in "
                f"Section : {PKS_PVDCS_SECTION_KEY}"
            )

    # Check validity of all PKS api servers referenced in the pks_api_servers
    # section
    for pks_server in pks_config[PKS_SERVERS_SECTION_KEY]:
        pks_account = pks_account_info_table.get(pks_server.get('name'))
        pks_configuration = Configuration()
        pks_configuration.proxy = f"http://{pks_server['proxy']}:80" \
            if pks_server.get('proxy') else None
        pks_configuration.host = \
            f"https://{pks_server['host']}:{pks_server['port']}/" \
            f"{VERSION_V1}"
        pks_configuration.access_token = None
        pks_configuration.username = pks_account.username
        pks_configuration.verify_ssl = pks_server['verify']
        pks_configuration.secret = pks_account.secret
        pks_configuration.uaac_uri = \
            f"https://{pks_server['host']}:{pks_server['uaac_port']}"

        uaa_client = UaaClient(
            pks_configuration.uaac_uri,
            pks_configuration.username,
            pks_configuration.secret,
            proxy_uri=pks_configuration.proxy
        )
        token = uaa_client.getToken()

        if not token:
            raise ValueError(
                "Unable to connect to PKS server : "
                f"{pks_server.get('name')} ({pks_server.get('host')})"
            )

        pks_configuration.token = token
        client = ApiClient(configuration=pks_configuration)

        if client:
            msg_update_callback.general(
                "Connected to PKS server ("
                f"{pks_server.get('name')} : {pks_server.get('host')})"
            )

    # Check validity of all PKS api servers referenced in NSX-T section
    for nsxt_server in pks_config[PKS_NSXT_SERVERS_SECTION_KEY]:
        pks_server_name = nsxt_server.get('pks_api_server')
        if pks_server_name not in all_pks_servers:
            raise ValueError(
                f"Unknown PKS api server : {pks_server_name} referenced by "
                f"NSX-T server : {nsxt_server.get('name')} in Section : "
                f"{PKS_NSXT_SERVERS_SECTION_KEY}"
            )

        # Create a NSX-T client and verify connection
        # server
        nsxt_client = NSXTClient(
            host=nsxt_server.get('host'),
            username=nsxt_server.get('username'),
            password=nsxt_server.get('password'),
            logger_debug=logger_debug,
            logger_wire=logger_wire,
            http_proxy=nsxt_server.get('proxy'),
            https_proxy=nsxt_server.get('proxy'),
            verify_ssl=nsxt_server.get('verify')
        )
        if not nsxt_client.test_connectivity():
            raise ValueError(
                "Unable to connect to NSX-T server : "
                f"{nsxt_server.get('name')} ({nsxt_server.get('host')})"
            )

        msg_update_callback.general(
            f"Connected to NSX-T server ({nsxt_server.get('host')})"
        )

        ipset_manager = IPSetManager(nsxt_client)
        if nsxt_server.get('nodes_ip_block_ids'):
            block_not_found = False
            ip_block_id = ''
            try:
                for ip_block_id in nsxt_server.get('nodes_ip_block_ids'):
                    if not ipset_manager.get_ip_block_by_id(ip_block_id):
                        block_not_found = True
            except HTTPError:
                block_not_found = True
            if block_not_found:
                raise ValueError(
                    f"Unknown Node IP Block : {ip_block_id} referenced by "
                    f"NSX-T server : {nsxt_server.get('name')}.")
        if nsxt_server.get('pods_ip_block_ids'):
            block_not_found = False
            ip_block_id = ''
            try:
                for ip_block_id in nsxt_server.get('pods_ip_block_ids'):
                    if not ipset_manager.get_ip_block_by_id(ip_block_id):
                        block_not_found = True
            except HTTPError:
                block_not_found = True
            if block_not_found:
                raise ValueError(
                    f"Unknown Pod IP Block : {ip_block_id} referenced by "
                    f"NSX-T server : {nsxt_server.get('name')}.")

        dfw_manager = DFWManager(nsxt_client)
        fw_section_id = \
            nsxt_server.get('distributed_firewall_section_anchor_id')
        section = dfw_manager.get_firewall_section(id=fw_section_id)
        if not section:
            raise ValueError(
                f"Unknown Firewall section : {fw_section_id} referenced by "
                f"NSX-T server : {nsxt_server.get('name')}.")