diff --git a/hyperglass/command/construct.py b/hyperglass/command/construct.py index bdb800a..ff912d4 100644 --- a/hyperglass/command/construct.py +++ b/hyperglass/command/construct.py @@ -11,6 +11,7 @@ from hyperglass import configuration code = configuration.codes() +g = configuration.general() def frr(cmd, ipprefix, device): @@ -39,7 +40,7 @@ def frr(cmd, ipprefix, device): msg = f"{ipprefix} matched large community." return (msg, code.success, d_address, query) else: - msg = f"{ipprefix} is an invalid BGP Community Format." + msg = g.msg_error_invaliddual.format(i=ipprefix, qt="BGP Community") logger.error(f"{msg}, {code.danger}, {d_name}, {query}") return (msg, code.danger, d_address, query) # BGP AS_PATH Query @@ -49,7 +50,7 @@ def frr(cmd, ipprefix, device): msg = f"{ipprefix} matched AS_PATH regex." return (msg, code.success, d_address, query) else: - msg = f"{ipprefix} is an invalid AS_PATH regex." + msg = g.msg_error_invaliddual.format(i=ipprefix, qt="AS Path") logger.error(f"{msg}, {code.danger}, {d_name}, {cmd}, {ipprefix}") return (msg, code.danger, d_address, query) # BGP Route Query @@ -67,7 +68,7 @@ def frr(cmd, ipprefix, device): return (msg, code.success, d_address, query) # Exception from netaddr library will return a user-facing error except: - msg = f"{ipprefix} is an invalid IP Address." + msg = g.msg_error_invalidip.format(i=ipprefix) logger.error(f"{msg}, {code.danger}, {d_name}, {query}") return (msg, code.danger, d_address, query) # Ping/Traceroute @@ -93,10 +94,10 @@ def frr(cmd, ipprefix, device): "target": ipprefix, } ) - msg = f"{ipprefix} is a valid IPv6 Adddress." + msg = f"{ipprefix} is a valid IPv6 Adddress." return (msg, code.success, d_address, query) except: - msg = f"{ipprefix} is an invalid IP Address." + msg = g.msg_error_invalidip.format(i=ipprefix) logger.error(f"{msg}, {code.danger}, {d_name}, {query}") return (msg, code.danger, d_name, query) else: @@ -137,7 +138,7 @@ def ssh(cmd, ipprefix, device): msg = f"{ipprefix} matched large community." return (msg, code.success, d_address, d_type, command) else: - msg = f"{ipprefix} is an invalid BGP Community Format." + msg = g.msg_error_invaliddual.format(i=ipprefix, qt="BGP Community") logger.error(f"{msg}, {code.danger}, {d_name}, {cmd}, {ipprefix}") return (msg, code.danger, d_name, cmd, ipprefix) # BGP AS_PATH Query @@ -148,7 +149,7 @@ def ssh(cmd, ipprefix, device): msg = f"{ipprefix} matched AS_PATH regex." return (msg, code.success, d_address, d_type, command) else: - msg = f"{ipprefix} is an invalid AS_PATH regex." + msg = g.msg_error_invaliddual.format(i=ipprefix, qt="AS Path") logger.error(f"{msg}, {code.danger}, {d_name}, {cmd}, {ipprefix}") return (msg, code.danger, d_name, cmd, ipprefix) # BGP Route Query @@ -168,7 +169,7 @@ def ssh(cmd, ipprefix, device): return (msg, code.success, d_address, d_type, command) # Exception from netaddr library will return a user-facing error except: - msg = f"{ipprefix} is an invalid IP Address." + msg = g.msg_error_invalidip.format(i=ipprefix) logger.error(f"{msg}, {code.danger}, {d_name}, {cmd}, {ipprefix}") return (msg, code.danger, d_name, cmd, ipprefix) # Ping/Traceroute @@ -185,7 +186,7 @@ def ssh(cmd, ipprefix, device): msg = f"{ipprefix} is a valid IPv6 Adddress." return (msg, code.success, d_address, d_type, command) except: - msg = f"{ipprefix} is an invalid IP Address." + msg = g.msg_error_invalidip.format(i=ipprefix) logger.error(f"{msg}, {code.danger}, {d_name}, {cmd}, {ipprefix}") return (msg, code.danger, d_name, cmd, ipprefix) else: diff --git a/hyperglass/command/execute.py b/hyperglass/command/execute.py index dfd06af..eddbfc8 100644 --- a/hyperglass/command/execute.py +++ b/hyperglass/command/execute.py @@ -166,39 +166,33 @@ def execute(lg_data): global code code = configuration.codes() + # Initialize general configuration parameters class, create global variable for reuse. + global general + general = configuration.general() + # Validate prefix input with netaddr library if lg_cmd in ["bgp_route", "ping", "traceroute"]: - # Initialize prefix regex check class - ipc = ipcheck().test(lg_ipprefix) + msg = general.msg_error_invalidip.format(i=lg_ipprefix) try: + # Initialize prefix regex check class + ipc = ipcheck().test(lg_ipprefix) if IPNetwork(lg_ipprefix).ip.is_reserved(): - msg = f"{lg_ipprefix} is not a valid IP address." return (msg, code.danger, lg_data) elif IPNetwork(lg_ipprefix).ip.is_netmask(): - msg = f"{lg_ipprefix} is not a valid IP address." return (msg, code.danger, lg_data) elif IPNetwork(lg_ipprefix).ip.is_hostmask(): - msg = f"{lg_ipprefix} is not a valid IP address." return (msg, code.danger, lg_data) elif IPNetwork(lg_ipprefix).ip.is_loopback(): - msg = f"{lg_ipprefix} is not a valid IP address." return (msg, code.danger, lg_data) elif IPNetwork(lg_ipprefix).ip.is_unicast(): pass else: - msg = f"{lg_ipprefix} is not a valid unicast IP address." return (msg, code.danger, lg_data) except: - msg = f"{lg_ipprefix} is not a valid IP Address." return (msg, code.danger, lg_data) if lg_cmd == "Query Type": - msg = "You must select a query type." - return (msg, code.warning, lg_data) - - # Initialize general configuration parameters class, create global variable for reuse. - global general - general = configuration.general() + return (general.msg_error_querytype, code.warning, lg_data) global d d = configuration.device(lg_router) @@ -209,15 +203,14 @@ def execute(lg_data): # Check blacklist list for prefixes/IPs and return an error upon a match if lg_cmd in ["bgp_route", "ping", "traceroute"]: blacklist = IPSet(configuration.blacklist()) + msg = general.msg_error_notallowed.format(i=lg_ipprefix) if IPNetwork(lg_ipprefix).ip in blacklist: - msg = f"{lg_ipprefix} is not allowed." return (msg, code.warning, lg_data) if lg_cmd == "bgp_route" and IPNetwork(lg_ipprefix).version == 6: if requires_ipv6_cidr == True and ipc["type"] == "host": - msg = f"{d.display_name} requires IPv6 BGP lookups to be in CIDR notation." + msg = general.msg_error_ipv6cidr.format(d=d.display_name) return (msg, code.warning, lg_data) if lg_cmd in ["ping", "traceroute"] and ipc["type"] == "cidr": - msg = f"{lg_cmd} does not allow networks masks." return (msg, code.warning, lg_data) # If enable_max_prefix feature enabled, require BGP Route queries be smaller than prefix size limit @@ -226,13 +219,17 @@ def execute(lg_data): IPNetwork(lg_ipprefix).version == 4 and IPNetwork(lg_ipprefix).prefixlen > general.max_prefix_length_ipv4 ): - msg = f"Prefix length must be smaller than /{general.max_prefix_length_ipv4}. {IPNetwork(lg_ipprefix)} is too specific." + msg = general.msg_max_prefix.format( + m=general.max_prefix_length_ipv4, i=IPNetwork(lg_ipprefix) + ) return (msg, code.warning, lg_data) if ( IPNetwork(lg_ipprefix).version == 6 and IPNetwork(lg_ipprefix).prefixlen > general.max_prefix_length_ipv6 ): - msg = f"Prefix length must be smaller than /{general.max_prefix_length_ipv4}. {IPNetwork(lg_ipprefix)} is too specific." + msg = general.msg_max_prefix.format( + m=general.max_prefix_length_ipv6, i=IPNetwork(lg_ipprefix) + ) return (msg, code.warning, lg_data) if d.type == "frr": diff --git a/hyperglass/configuration/__init__.py b/hyperglass/configuration/__init__.py index 64cd320..d4afeb2 100644 --- a/hyperglass/configuration/__init__.py +++ b/hyperglass/configuration/__init__.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python3 - # Module Imports import os import math @@ -143,10 +141,26 @@ class general: self.org_name = g.get("org_name", "The Company") self.debug = g.get("debug", False) self.google_analytics = g.get("google_analytics", "") - self.message_error = g.get("message_error", "{input} is invalid.") - self.message_blacklist = g.get("message_blacklist", "{input} is not allowed.") - self.message_general_error = g.get( - "message_general_error", "Error connecting to device." + self.msg_error_querytype = g.get( + "msg_error_querytype", "You must select a query type." + ) + self.msg_error_notallowed = g.get( + "msg_error_notallowed", "{i} is not allowed." + ) + self.msg_error_ipv6cidr = g.get( + "msg_error_ipv6cidr", + "{d} requires IPv6 BGP lookups to be in CIDR notation.", + ) + self.msg_error_invalidip = g.get( + "msg_error_invalidip", "{i} is not a valid IP address." + ) + self.msg_error_invaliddual = g.get( + "msg_error_invaliddual", "{i} is an invalid {qt}." + ) + self.msg_error_general = g.get("msg_error_general", "A general error occurred.") + self.msg_max_prefix = g.get( + "msg_max_prefix", + "Prefix length must be smaller than /{m}. {i} is too specific.", ) self.rate_limit_query = g.get("rate_limit_query", "5") self.message_rate_limit_query = g.get( @@ -192,13 +206,8 @@ class branding: "logo_path", os.path.join(hyperglass_root, "static/images/hyperglass-dark.png"), ) - self.favicon16_path = b.get( - "favicon16_path", "static/images/favicon/favicon-16x16.png" - ) - self.favicon32_path = b.get( - "favicon32_path", "static/images/favicon/favicon-32x32.png" - ) self.logo_width = b.get("logo_width", "384") + self.favicon_dir = b.get("favicon_path", "static/images/favicon/") self.placeholder_prefix = b.get( "placeholder_prefix", "IP, Prefix, Community, or AS_PATH" ) diff --git a/hyperglass/configuration/configuration.toml.example b/hyperglass/configuration/configuration.toml.example index 95a21a0..c55ec1a 100644 --- a/hyperglass/configuration/configuration.toml.example +++ b/hyperglass/configuration/configuration.toml.example @@ -1,58 +1,23 @@ # General site-wide parameters [[general]] -primary_asn = "" -org_name = "" -debug = false -google_analytics = "" -message_error = "" -message_blacklist = "" -message_rate_limit_query = "" -enable_bgp_route = true -enable_bgp_community = true -enable_bgp_aspath = true -enable_ping = true -enable_traceroute = true -rate_limit_query = "" -rate_limit_site = "" -cache_timeout = 120 -cache_directory = "" +# primary_asn = "" +# org_name = "" +# google_analytics = "" +# enable_bgp_route = "" +# enable_bgp_community = "" +# enable_bgp_aspath = "" +# enable_ping = "" +# enable_traceroute = "" +# enable_max_prefix = "" +# max_prefix_length_ipv4 = "" +# max_prefix_length_ipv6 = "" # Branding/Site Customization Parameters [[branding]] -site_title = "" -title_mode = "" -title = "" -subtitle = "" -enable_footer = true -enable_credit = true -color_bg = "" -color_danger = "" -color_btn_submit = "" -color_tag_loctitle = "" -color_tag_cmdtitle = "" -color_tag_cmd = "" -color_tag_loc = "" -color_progressbar = "" -logo_path = "" -logo_width = "" -favicon16_path = "" -favicon32_path = "" -placeholder_prefix = "" -show_peeringdb = true -text_results = "" -text_location = "" -text_cache = "" -text_limiter_title = "" -text_limiter_subtitle = "" -text_500_title = "" -text_500_subtitle = "" -text_500_button = "" -text_help_bgp_route = "" -text_help_bgp_community = "" -text_help_bgp_aspath = "" -text_help_ping = "" -text_help_traceroute = "" -primary_font_url = "" -primary_font_name = "" -mono_font_url = "" -mono_font_name = "" +# site_title = "" +# title = "" +# subtitle = "" +# title_mode = "" +# logo_path = "" +# logo_width = "" +# favicon_dir = "" diff --git a/hyperglass/render/__init__.py b/hyperglass/render/__init__.py index 6d5a7bf..a199a65 100644 --- a/hyperglass/render/__init__.py +++ b/hyperglass/render/__init__.py @@ -68,8 +68,7 @@ class html: footer_content=md.convert(footer_jinja), logo_path=branding.logo_path, logo_width=branding.logo_width, - favicon16_path=branding.favicon16_path, - favicon32_path=branding.favicon32_path, + favicon_dir=branding.favicon_dir, placeholder_prefix=branding.placeholder_prefix, show_peeringdb=branding.show_peeringdb, text_results=branding.text_results, diff --git a/hyperglass/render/templates/base.html b/hyperglass/render/templates/base.html index 22f197b..64bde26 100644 --- a/hyperglass/render/templates/base.html +++ b/hyperglass/render/templates/base.html @@ -6,14 +6,14 @@ - - - - - - + + + + + + - +