Ejemplo n.º 1
0
    def _init_dfs(self, namespaces):
        """Initialize the dataframes used"""

        self._if_df = interfaces.IfObj(context=self.ctxt).get(
            namespace=namespaces,
            state="up",
            columns=[
                'namespace', 'hostname', 'ifname', 'ipAddressList',
                'ip6AddressList', 'state', 'type', 'master', 'macaddr'
            ])

        if self._if_df.empty:
            raise EmptyDataframeError(f"No interface found for {namespaces}")
        self._if_df['vrf'] = self._if_df.apply(
            lambda x: x['master']
            if x['type'] not in ['bridge', 'bond_slave'] else 'default',
            axis=1)
        self._if_df['vrf'] = np.where(self._if_df['vrf'] == '', 'default',
                                      self._if_df['vrf'])
        self._if_df = self._if_df.explode('ipAddressList') \
                                 .explode('ip6AddressList') \
                                 .fillna({'ipAddressList': '0.0.0.0/0',
                                          'ip6AddressList': '::0/0'})
        self._if_df['plen'] = self._if_df.ipAddressList.str.split('/').str[1]
        self._if_df['ipAddress'] = self._if_df.ipAddressList.str.split(
            '/').str[0]
        self._if_df = self._if_df.drop(
            columns=['ipAddressList', 'ip6AddressList'])

        self.nses = self._if_df['namespace'].unique()
Ejemplo n.º 2
0
    def _init_dfs(self, namespaces):
        """Initialize the dataframes used"""

        self._if_df = interfaces.IfObj(context=self.ctxt).get(namespace=namespaces)

        if self._if_df.empty:
            raise EmptyDataframeError(f"No interface found for {namespaces}")
        self.nses = self._if_df['namespace'].unique()
Ejemplo n.º 3
0
    def _init_dfs(self, namespace, source, dest):
        """Initialize the dataframes used in this path hunt"""

        self._if_df = interfaces.IfObj(context=self.ctxt) \
                                .get(namespace=namespace)
        if self._if_df.empty:
            raise EmptyDataframeError(f"No interface found for {namespace}")

        self._lldp_df = lldp.LldpObj(context=self.ctxt).get(
            namespace=namespace, columns=self.columns)
        if self._lldp_df.empty:
            raise NoLLdpError(f"No LLDP information found for {namespace}")

        self._rdf = routes.RoutesObj(context=self.ctxt) \
                          .lpm(namespace=namespace, address=dest)
        if self._rdf.empty:
            raise EmptyDataframeError("No Routes information found for {}".
                                      format(dest))

        # We ignore the lack of ARPND for now
        self._arpnd_df = arpnd.ArpndObj(
            context=self.ctxt).get(namespace=namespace)

        self._macsobj = macs.MacsObj(context=self.ctxt, namespace=namespace)

        if ':' in source:
            self._src_df = self._if_df[self._if_df.ip6AddressList.astype(str)
                                       .str.contains(source + "/")]
        else:
            self._src_df = self._if_df[self._if_df.ipAddressList.astype(str)
                                       .str.contains(source + "/")]

        if self._src_df.empty:
            raise AttributeError(f"Invalid src {source}")

        if ':' in dest:
            self._dest_df = self._if_df[self._if_df.ip6AddressList.astype(str)
                                        .str.contains(dest + "/")]
        else:
            self._dest_df = self._if_df[self._if_df.ipAddressList.astype(str)
                                        .str.contains(dest + "/")]

        if self._dest_df.empty:
            raise AttributeError(f"Invalid dest {dest}")

        self.dest_device = self._dest_df["hostname"].unique()[0]
        self.src_device = self._src_df["hostname"].unique()[0]

        # Start with the source host and find its route to the destination
        if self._rdf[self._rdf["hostname"] == self.src_device].empty:
            raise EmptyDataframeError(f"No routes found for {self.src_device}")
Ejemplo n.º 4
0
    def _init_dfs(self, namespace, source, dest):
        """Initialize the dataframes used in this path hunt"""

        self.source = source
        self.dest = dest
        self._underlay_dfs = {}  # lpm entries for each vtep IP

        try:
            self._if_df = interfaces.IfObj(context=self.ctxt) \
                                    .get(namespace=namespace, state='up',
                                         addnl_fields=['macaddr']) \
                                    .explode('ipAddressList') \
                                    .fillna({'ipAddressList': ''}) \
                                    .explode('ip6AddressList') \
                                    .fillna({'ip6AddressList': ''}) \
                                    .reset_index(drop=True)
            if self._if_df.empty:
                raise EmptyDataframeError
        except (EmptyDataframeError, KeyError):
            raise EmptyDataframeError(
                f"No interface information found for {namespace}")

        # Need this in determining L2 peer
        mlag_df = mlag.MlagObj(context=self.ctxt).get(namespace=namespace)
        mlag_peers = defaultdict(str)
        mlag_peerlink = defaultdict(str)
        if not mlag_df.empty:
            peerlist = [x.tolist()
                        for x in mlag_df.groupby(by=['systemId'])['hostname']
                        .unique().tolist()]
            for peers in peerlist:
                mlag_peers[peers[0]] = peers[1]
                mlag_peers[peers[1]] = peers[0]
            for row in mlag_df.itertuples():
                mlag_peerlink[row.hostname] = expand_nxos_ifname(row.peerLink)
        self._mlag_peers = mlag_peers
        self._mlag_peerlink = mlag_peerlink

        try:
            # access-internal is an internal Junos route we want to
            # ignore
            self._rdf = routes.RoutesObj(context=self.ctxt) \
                              .lpm(namespace=namespace, address=dest) \
                              .query('protocol != "access-internal"') \
                              .reset_index(drop=True)
            if self._rdf.empty:
                raise EmptyDataframeError
        except (KeyError, EmptyDataframeError):
            raise EmptyDataframeError("No Routes information found for {}".
                                      format(dest))

        try:
            self._rpf_df = routes.RoutesObj(context=self.ctxt) \
                                 .lpm(namespace=namespace, address=source) \
                                 .query('protocol != "access-internal"') \
                                 .reset_index(drop=True)
            if self._rpf_df.empty:
                raise EmptyDataframeError
        except (KeyError, EmptyDataframeError):
            raise EmptyDataframeError("No Routes information found for {}".
                                      format(source))

        # We ignore the lack of ARPND for now
        self._arpnd_df = arpnd.ArpndObj(
            context=self.ctxt).get(namespace=namespace)
        if self._arpnd_df.empty:
            raise EmptyDataframeError(
                f"No ARPND information found for {dest}")

        # Enhance the ARPND table with the VRF field
        self._arpnd_df = self._arpnd_df.merge(
            self._if_df[['namespace', 'hostname', 'ifname', 'master']],
            left_on=['namespace', 'hostname', 'oif'],
            right_on=['namespace', 'hostname', 'ifname'], how='left') \
            .drop(columns=['ifname']) \
            .rename(columns={'master': 'vrf'}) \
            .replace({'vrf': {'': 'default'}}) \
            .query('state != "failed"') \
            .reset_index(drop=True)

        self._macsobj = macs.MacsObj(context=self.ctxt, namespace=namespace)

        if ':' in source:
            self._src_df = self._if_df[self._if_df.ip6AddressList.astype(str)
                                       .str.contains(source + "/")]
        else:
            self._src_df = self._if_df[self._if_df.ipAddressList.astype(str)
                                       .str.contains(source + "/")]

        if self._src_df.empty:
            # TODO: No host with this src addr. Is addr a local ARP entry?
            self._src_df = self._find_fhr_df(None, source)

        if self._src_df.empty:
            raise AttributeError(f"Invalid src {source}")

        if self._src_df.hostname.nunique() == 1 and len(self._src_df) > 1:
            # Multiple interfaces with the same IP address. Possible case
            # of Unnumbered interfaces. See if there's a loopback in there
            if 'loopback' in self._src_df.type.unique().tolist():
                self._src_df = self._src_df.query('type == "loopback"')

        if ':' in dest:
            self._dest_df = self._if_df[self._if_df.ip6AddressList.astype(str)
                                        .str.contains(dest + "/")]
        else:
            self._dest_df = self._if_df[self._if_df.ipAddressList.astype(str)
                                        .str.contains(dest + "/")]

        srcnet = self._src_df.ipAddressList.tolist()[0]
        if ip_address(dest) in ip_network(srcnet, strict=False):
            self.is_l2 = True
        else:
            self.is_l2 = False

        if self._dest_df.empty:
            # TODO: No host with this dest addr. Is addr a local ARP entry?
            self._dest_df = self._find_fhr_df(None, dest)

        if self._dest_df.empty:
            raise AttributeError(f"Invalid dest {dest}")

        if self._dest_df.hostname.nunique() == 1 and len(self._dest_df) > 1:
            # Multiple interfaces with the same IP address. Possible case
            # of Unnumbered interfaces. See if there's a loopback in there
            if 'loopback' in self._dest_df.type.unique().tolist():
                self._dest_df = self._dest_df.query('type == "loopback"')

        self.dest_device = self._dest_df["hostname"].unique()
        self.src_device = self._src_df["hostname"].unique()

        # Start with the source host and find its route to the destination
        if self._rdf[self._rdf["hostname"].isin(self.src_device)].empty:
            raise EmptyDataframeError(f"No routes found for {self.src_device}")
Ejemplo n.º 5
0
    def _init_dfs(self, namespace, source, dest):
        """Initialize the dataframes used in this path hunt"""

        self.source = source
        self.dest = dest
        self._underlay_dfs = {}  # lpm entries for each vtep IP

        try:
            self._if_df = interfaces.IfObj(context=self.ctxt) \
                                    .get(namespace=namespace,
                                         addnl_fields=['macaddr']) \
                                    .explode('ipAddressList') \
                                    .fillna({'ipAddressList': ''}) \
                                    .explode('ip6AddressList') \
                                    .fillna({'ip6AddressList': ''})
            if self._if_df.empty:
                raise EmptyDataframeError
        except (EmptyDataframeError, KeyError):
            raise EmptyDataframeError(
                f"No interface information found for {namespace}")

        try:
            self._rdf = routes.RoutesObj(context=self.ctxt) \
                              .lpm(namespace=namespace, address=dest)
            if self._rdf.empty:
                raise EmptyDataframeError
        except (KeyError, EmptyDataframeError):
            raise EmptyDataframeError(
                "No Routes information found for {}".format(dest))

        # We ignore the lack of ARPND for now
        self._arpnd_df = arpnd.ArpndObj(context=self.ctxt).get(
            namespace=namespace)
        if self._arpnd_df.empty:
            raise EmptyDataframeError(f"No ARPND information found for {dest}")

        # Enhance the ARPND table with the VRF field
        self._arpnd_df = self._arpnd_df.merge(
            self._if_df[['namespace', 'hostname', 'ifname', 'master']],
            left_on=['namespace', 'hostname', 'oif'],
            right_on=['namespace', 'hostname', 'ifname'], how='left') \
            .drop(columns=['ifname']) \
            .rename(columns={'master': 'vrf'}) \
            .replace({'vrf': {'': 'default'}})

        self._macsobj = macs.MacsObj(context=self.ctxt, namespace=namespace)

        if ':' in source:
            self._src_df = self._if_df[self._if_df.ip6AddressList.astype(
                str).str.contains(source + "/")]
        else:
            self._src_df = self._if_df[self._if_df.ipAddressList.astype(
                str).str.contains(source + "/")]

        if self._src_df.empty:
            # TODO: No host with this src addr. Is addr a local ARP entry?
            self._src_df = self._find_fhr_df(source)

        if self._src_df.empty:
            raise AttributeError(f"Invalid src {source}")

        if ':' in dest:
            self._dest_df = self._if_df[self._if_df.ip6AddressList.astype(
                str).str.contains(dest + "/")]
        else:
            self._dest_df = self._if_df[self._if_df.ipAddressList.astype(
                str).str.contains(dest + "/")]

        srcnet = self._src_df.ipAddressList.tolist()[0]
        if ip_address(dest) in ip_network(srcnet, strict=False):
            self.is_l2 = True
        else:
            self.is_l2 = False

        if self._dest_df.empty:
            # TODO: No host with this dest addr. Is addr a local ARP entry?
            self._dest_df = self._find_fhr_df(dest)

        if self._dest_df.empty:
            raise AttributeError(f"Invalid dest {dest}")

        self.dest_device = self._dest_df["hostname"].unique()
        self.src_device = self._src_df["hostname"].unique()

        # Start with the source host and find its route to the destination
        if self._rdf[self._rdf["hostname"].isin(self.src_device)].empty:
            raise EmptyDataframeError(f"No routes found for {self.src_device}")