diff --git a/hooks.sh b/hooks.sh index b3f1fa9..34d35d9 100755 --- a/hooks.sh +++ b/hooks.sh @@ -12,7 +12,7 @@ function isort_all () { } function validate_examples () { - python3 .tests/validate_examples.py + python3 ./validate_examples.py if [[ ! $? == 0 ]]; then exit 1 fi diff --git a/hyperglass/configuration/models/opengraph.py b/hyperglass/configuration/models/opengraph.py index 42671ac..f420d50 100644 --- a/hyperglass/configuration/models/opengraph.py +++ b/hyperglass/configuration/models/opengraph.py @@ -35,7 +35,7 @@ class OpenGraph(HyperglassModel): supported_extensions = (".jpg", ".jpeg", ".png") if ( values["image"] is not None - and values["image"].suffix not in supported_extensions + and Path(values["image"]).suffix not in supported_extensions ): raise ValueError( "OpenGraph image must be one of {e}".format( diff --git a/hyperglass/configuration/models/web.py b/hyperglass/configuration/models/web.py index cdfb05a..5bdf820 100644 --- a/hyperglass/configuration/models/web.py +++ b/hyperglass/configuration/models/web.py @@ -204,6 +204,7 @@ class DnsOverHttps(HyperglassLevel3): """Validation model for DNS over HTTPS resolution.""" name: constr(regex="|".join(DNS_OVER_HTTPS.keys())) = "cloudflare" + url: StrictStr = "" @root_validator def validate_dns(cls, values): diff --git a/hyperglass/examples/commands.yaml b/hyperglass/examples/commands.yaml index 3087873..d3e37ea 100644 --- a/hyperglass/examples/commands.yaml +++ b/hyperglass/examples/commands.yaml @@ -123,4 +123,4 @@ # bgp_community: show route protocol bgp table {vrf} community {target} # bgp_route: show route protocol bgp table {vrf} {target} detail # ping: ping inet6 routing-instance {vrf} {target} count 5 source {source} -# traceroute: traceroute inet6 routing-instance {vrf} {target} wait 1 source {source} \ No newline at end of file +# traceroute: traceroute inet6 routing-instance {vrf} {target} wait 1 source {source} diff --git a/hyperglass/examples/hyperglass.yaml b/hyperglass/examples/hyperglass.yaml index 4500726..5e94954 100644 --- a/hyperglass/examples/hyperglass.yaml +++ b/hyperglass/examples/hyperglass.yaml @@ -6,14 +6,13 @@ # show_text: true # timeout: 120 # cors_origins: [] -# debug: false +# debug: true # developer_mode: false # docs: # base_url: https://lg.example.net -# description: '' +# description: "" # devices: -# description: List of all devices/locations with associated identifiers, display -# names, networks, & VRFs. +# description: List of all devices/locations with associated identifiers, display names, networks, & VRFs. # summary: Devices List # title: Devices # enable: true @@ -27,28 +26,28 @@ # description: Request a query response per-location. # summary: Query the Looking Glass # title: Submit Query -# title: '{site_title} API Documentation' +# title: "{site_title} API Documentation" # uri: /api/docs -# listen_address: localhost +# listen_address: 0.0.0.0 # listen_port: 8001 -# log_file: /tmp/hyperglass_20202919-172921.log +# log_file: /tmp/hyperglass_20204821-134836.log # messages: -# acl_denied: '{target} is a member of {denied_network}, which is not allowed.' -# acl_not_allowed: '{target} is not allowed.' +# acl_denied: "{target} is a member of {denied_network}, which is not allowed." +# acl_not_allowed: "{target} is not allowed." # authentication_error: Authentication error occurred. -# connection_error: 'Error connecting to {device_name}: {error}' -# feature_not_enabled: '{feature} is not enabled for {device_name}.' +# connection_error: "Error connecting to {device_name}: {error}" +# feature_not_enabled: "{feature} is not enabled for {device_name}." # general: Something went wrong. -# invalid_field: '{input} is an invalid {field}.' -# invalid_input: '{target} is not a valid {query_type} target.' -# no_input: '{field} must be specified.' +# invalid_field: "{input} is an invalid {field}." +# invalid_input: "{target} is not a valid {query_type} target." +# no_input: "{field} must be specified." # no_output: No output. # no_response: No response. # request_timeout: Request timed out. # vrf_not_associated: VRF {vrf_name} is not associated with {device_name}. # vrf_not_found: VRF {vrf_name} is not defined. # org_name: Beloved Hyperglass User -# primary_asn: '65001' +# primary_asn: "65001" # queries: # bgp_aspath: # display_name: BGP AS Path @@ -76,27 +75,27 @@ # request_timeout: 30 # site_description: Beloved Hyperglass User Network Looking Glass # site_keywords: -# - hyperglass -# - looking glass -# - lg -# - peer -# - peering -# - ipv4 -# - ipv6 -# - transit -# - community -# - communities -# - bgp -# - routing -# - network -# - isp +# - hyperglass +# - looking glass +# - lg +# - peer +# - peering +# - ipv4 +# - ipv6 +# - transit +# - community +# - communities +# - bgp +# - routing +# - network +# - isp # site_title: hyperglass # web: # credit: # enable: true # dns_provider: -# name: cloudflare -# url: https://cloudflare-dns.com/dns-query +# name: google +# url: https://dns.google/resolve # external_link: # enable: true # title: PeeringDB @@ -131,24 +130,24 @@ # title_mode: logo_only # theme: # colors: -# black: '#262626' -# blue: '#314cb6' -# cyan: '#118ab2' -# danger: '#d84b4b' -# error: '#ff6b35' -# gray: '#c1c7cc' -# green: '#35b246' -# orange: '#ff6b35' -# pink: '#f2607d' -# primary: '#118ab2' -# purple: '#8d30b5' -# red: '#d84b4b' -# secondary: '#314cb6' -# success: '#35b246' -# teal: '#35b299' -# warning: '#edae49' -# white: '#f7f7f7' -# yellow: '#edae49' +# black: "#262626" +# blue: "#314cb6" +# cyan: "#118ab2" +# danger: "#d84b4b" +# error: "#ff6b35" +# gray: "#c1c7cc" +# green: "#35b246" +# orange: "#ff6b35" +# pink: "#f2607d" +# primary: "#118ab2" +# purple: "#8d30b5" +# red: "#d84b4b" +# secondary: "#314cb6" +# success: "#35b246" +# teal: "#35b299" +# warning: "#edae49" +# white: "#f7f7f7" +# yellow: "#edae49" # fonts: # body: Nunito # mono: Fira Code diff --git a/.tests/validate_examples.py b/validate_examples.py similarity index 61% rename from .tests/validate_examples.py rename to validate_examples.py index 0b6da7f..58b095c 100644 --- a/.tests/validate_examples.py +++ b/validate_examples.py @@ -1,5 +1,6 @@ """Validate example files.""" # Standard Library +import re import sys from pathlib import Path @@ -7,6 +8,7 @@ from pathlib import Path import yaml # Project +from hyperglass.util import set_app_path from hyperglass.configuration.models.params import Params from hyperglass.configuration.models.routers import Routers from hyperglass.configuration.models.commands import Commands @@ -18,6 +20,36 @@ COMMANDS = EXAMPLES / "commands.yaml" MAIN = EXAMPLES / "hyperglass.yaml" +def _uncomment_files(): + """Uncomment out files.""" + for file in (MAIN, COMMANDS): + output = [] + with file.open("r") as f: + for line in f.readlines(): + if re.match(r"^(#\s+[a-z0-9]+)|(#\s+\-\s.*$)", line): + output.append(re.sub(r"^(#\s)", "", line)) + else: + output.append(line) + with file.open("w") as f: + f.write("".join(output)) + return True + + +def _comment_optional_files(): + """Comment out files.""" + for file in (MAIN, COMMANDS): + output = [] + with file.open("r") as f: + for line in f.readlines(): + if not re.match(r"^(#\s+[A-Za-z0-9])|(^\-{3})", line): + output.append("# " + line) + else: + output.append(line) + with file.open("w") as f: + f.write("".join(output)) + return True + + def _validate_devices(): with DEVICES.open() as raw: devices_dict = yaml.safe_load(raw.read()) or {} @@ -44,12 +76,14 @@ def _validate_main(): try: Params(**main_dict) except Exception as e: + raise raise ValueError(str(e)) return True def validate_all(): """Validate all example configs against configuration models.""" + _uncomment_files() for validator in (_validate_main, _validate_commands, _validate_devices): try: validator() @@ -59,6 +93,7 @@ def validate_all(): if __name__ == "__main__": + set_app_path() try: all_passed = validate_all() message = "All tests passed" @@ -66,5 +101,7 @@ if __name__ == "__main__": except RuntimeError as e: message = str(e) status = 1 + if status == 0: + _comment_optional_files() print(message) sys.exit(status)