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()
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()
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}")
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}")
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}")