diff --git a/hyperglass/command/construct.py b/hyperglass/command/construct.py index 75b8f41..6993516 100644 --- a/hyperglass/command/construct.py +++ b/hyperglass/command/construct.py @@ -4,6 +4,7 @@ command for Netmiko library or API call parameters for supported hyperglass API modules. """ # Standard Library Imports +import re import ipaddress import json import operator @@ -15,6 +16,7 @@ from logzero import logger as log from hyperglass.configuration import vrfs from hyperglass.configuration import commands from hyperglass.configuration import logzero_config # noqa: F401 +from hyperglass.constants import target_format_space class Construct: @@ -30,14 +32,12 @@ class Construct: self.query_target = self.query_data["query_target"] self.query_vrf = self.query_data["query_vrf"] - @staticmethod - def get_src(device, afi): - """ - Returns source IP based on IP version of query destination. - """ - src_afi = f"src_addr_{afi}" - src = getattr(device, src_afi) - return src.exploded + def format_target(self, target): + """Formats query target based on NOS requirement""" + if self.device.nos in target_format_space: + _target = re.sub(r"\/", r" ", target) + log.debug(f"Formatted target: {_target}") + return _target @staticmethod def device_commands(nos, afi, query_type): @@ -87,7 +87,7 @@ class Construct: ) ) elif self.transport == "scrape": - cmd_type = self.get_cmd_type(afi, self.query_vrf) + cmd_type = self.get_cmd_type(afi.afi_name, self.query_vrf) cmd = self.device_commands(self.device.commands, cmd_type, "ping") query.append( cmd.format( @@ -130,7 +130,7 @@ class Construct: ) ) elif self.transport == "scrape": - cmd_type = self.get_cmd_type(afi, self.query_vrf) + cmd_type = self.get_cmd_type(afi.afi_name, self.query_vrf) cmd = self.device_commands(self.device.commands, cmd_type, "traceroute") query.append( cmd.format( @@ -170,11 +170,11 @@ class Construct: ) ) elif self.transport == "scrape": - cmd_type = self.get_cmd_type(afi, self.query_vrf) + cmd_type = self.get_cmd_type(afi.afi_name, self.query_vrf) cmd = self.device_commands(self.device.commands, cmd_type, "bgp_route") query.append( cmd.format( - target=self.query_target, + target=self.format_target(self.query_target), source=afi.source_address, vrf=afi.vrf_name, afi=afi.afi_name, @@ -223,7 +223,7 @@ class Construct: ) ) elif self.transport == "scrape": - cmd_type = self.get_cmd_type(afi, self.query_vrf) + cmd_type = self.get_cmd_type(afi.afi_name, self.query_vrf) cmd = self.device_commands( self.device.commands, cmd_type, "bgp_community" ) @@ -277,7 +277,7 @@ class Construct: ) ) elif self.transport == "scrape": - cmd_type = self.get_cmd_type(afi, self.query_vrf) + cmd_type = self.get_cmd_type(afi.afi_name, self.query_vrf) cmd = self.device_commands(self.device.commands, cmd_type, "bgp_aspath") query.append( cmd.format( diff --git a/hyperglass/configuration/models/commands.py b/hyperglass/configuration/models/commands.py index a76b757..36e700c 100644 --- a/hyperglass/configuration/models/commands.py +++ b/hyperglass/configuration/models/commands.py @@ -75,9 +75,9 @@ class Commands(BaseSettings): class IPv4Vrf(BaseSettings): """Default commands for dual afi commands""" - bgp_community: str = "show bgp {afi} unicast vrf {vrf} community {target}" - bgp_aspath: str = 'show bgp {afi} unicast vrf {vrf} quote-regexp "{target}"' - bgp_route: str = "show bgp {afi} unicast vrf {vrf} {target}" + bgp_community: str = "show bgp vpnv4 unicast vrf {vrf} community {target}" + bgp_aspath: str = 'show bgp vpnv4 unicast vrf {vrf} quote-regexp "{target}"' + bgp_route: str = "show bgp vpnv4 unicast vrf {vrf} {target}" ping: str = "ping vrf {vrf} {target} repeat 5 source {source}" traceroute: str = ( "traceroute vrf {vrf} {target} timeout 1 probe 2 source {source}" @@ -86,9 +86,9 @@ class Commands(BaseSettings): class IPv6Vrf(BaseSettings): """Default commands for dual afi commands""" - bgp_community: str = "show bgp {afi} unicast vrf {vrf} community {target}" - bgp_aspath: str = 'show bgp {afi} unicast vrf {vrf} quote-regexp "{target}"' - bgp_route: str = "show bgp {afi} unicast vrf {vrf} {target}" + bgp_community: str = "show bgp vpnv6 unicast vrf {vrf} community {target}" + bgp_aspath: str = 'show bgp vpnv6 unicast vrf {vrf} quote-regexp "{target}"' + bgp_route: str = "show bgp vpnv6 unicast vrf {vrf} {target}" ping: str = "ping vrf {vrf} {target} repeat 5 source {source}" traceroute: str = ( "traceroute vrf {vrf} {target} timeout 1 probe 2 source {source}" @@ -97,18 +97,18 @@ class Commands(BaseSettings): class IPv4Default(BaseSettings): """Default commands for ipv4 commands""" - bgp_community: str = "show bgp {afi} unicast community {target}" - bgp_aspath: str = 'show bgp {afi} unicast quote-regexp "{target}"' - bgp_route: str = "show bgp {afi} unicast {target} | exclude pathid:|Epoch" + bgp_community: str = "show bgp ipv4 unicast community {target}" + bgp_aspath: str = 'show bgp ipv4 unicast quote-regexp "{target}"' + bgp_route: str = "show bgp ipv4 unicast {target} | exclude pathid:|Epoch" ping: str = "ping {target} repeat 5 source {source}" traceroute: str = "traceroute {target} timeout 1 probe 2 source {source}" class IPv6Default(BaseSettings): """Default commands for ipv6 commands""" - bgp_community: str = "show bgp {afi} unicast community {target}" - bgp_aspath: str = 'show bgp {afi} unicast quote-regexp "{target}"' - bgp_route: str = "show bgp {afi} unicast {target} | exclude pathid:|Epoch" + bgp_community: str = "show bgp ipv6 unicast community {target}" + bgp_aspath: str = 'show bgp ipv6 unicast quote-regexp "{target}"' + bgp_route: str = "show bgp ipv6 unicast {target} | exclude pathid:|Epoch" ping: str = ("ping {afi} {target} repeat 5 source {source}") traceroute: str = ( "traceroute ipv6 {target} timeout 1 probe 2 source {source}" @@ -189,9 +189,76 @@ class Commands(BaseSettings): ipv4: IPv4 = IPv4() ipv6: IPv6 = IPv6() + class Huawei(BaseSettings): + """Class model for default huawei commands""" + + class IPv4Vrf(BaseSettings): + """Default commands for dual afi commands""" + + bgp_community: str = ( + "display bgp vpnv4 vpn-instance {vrf} routing-table " + "regular-expression {target}" + ) + bgp_aspath: str = ( + "display bgp vpnv4 vpn-instance {vrf} routing-table " + "regular-expression {target}" + ) + bgp_route: str = ( + "display bgp vpnv4 vpn-instance {vrf} routing-table {target}" + ) + ping: str = "ping -vpn-instance {vrf} -c 5 -a {source} {target}" + traceroute: str = ( + "tracert -q 2 -f 1 -vpn-instance {vrf} -a {source} {target}" + ) + + class IPv6Vrf(BaseSettings): + """Default commands for dual afi commands""" + + bgp_community: str = ( + "display bgp vpnv6 vpn-instance {vrf} routing-table " + "regular-expression {target}" + ) + bgp_aspath: str = ( + "display bgp vpnv6 vpn-instance {vrf} routing-table " + "regular-expression {target}" + ) + bgp_route: str = ( + "display bgp vpnv6 vpn-instance {vrf} routing-table {target}" + ) + ping: str = "ping vpnv6 vpn-instance {vrf} -c 5 -a {source} {target}" + traceroute: str = ( + "tracert -q 2 -f 1 vpn-instance {vrf} -a {source} {target}" + ) + + class IPv4Default(BaseSettings): + """Default commands for ipv4 commands""" + + bgp_community: str = "display bgp routing-table regular-expression {target}" + bgp_aspath: str = "display bgp routing-table regular-expression {target}" + bgp_route: str = "display bgp routing-table {target}" + ping: str = "ping -c 5 -a {source} {target}" + traceroute: str = "tracert -q 2 -f 1 -a {source} {target}" + + class IPv6Default(BaseSettings): + """Default commands for ipv6 commands""" + + bgp_community: str = "display bgp ipv6 routing-table community {target}" + bgp_aspath: str = ( + "display bgp ipv6 routing-table regular-expression {target}" + ) + bgp_route: str = "display bgp ipv6 routing-table {target}" + ping: str = "ping ipv6 -c 5 -a {source} {target}" + traceroute: str = "tracert ipv6 -q 2 -f 1 -a {source} {target}" + + ipv4_default: IPv4Default = IPv4Default() + ipv6_default: IPv6Default = IPv6Default() + ipv4_vrf: IPv4Vrf = IPv4Vrf() + ipv6_vrf: IPv6Vrf = IPv6Vrf() + cisco_ios: Command = CiscoIOS() cisco_xr: Command = CiscoXR() juniper: Command = Juniper() + huawei: Command = Huawei() class Config: """Pydantic Config""" diff --git a/hyperglass/constants.py b/hyperglass/constants.py index c630b10..b28682e 100644 --- a/hyperglass/constants.py +++ b/hyperglass/constants.py @@ -4,14 +4,7 @@ Global Constants for hyperglass protocol_map = {80: "http", 8080: "http", 443: "https", 8443: "https"} -afi_nos_map = { - "default": { - "ipv4_global": "ipv4", - "ipv6_global": "ipv6", - "ipv4_vpn": "vpnv4", - "ipv6_vpn": "vpnv6", - } -} +target_format_space = ("huawei", "huawei_vrpv8") class Supported: