diff --git a/hyperglass/render/__init__.py b/hyperglass/render/__init__.py
index a3f19d8..9aa2b41 100644
--- a/hyperglass/render/__init__.py
+++ b/hyperglass/render/__init__.py
@@ -6,7 +6,7 @@ from pathlib import Path
# Module Imports
import sass
-import toml
+import yaml
import jinja2
import logzero
from logzero import logger
@@ -24,67 +24,88 @@ file_loader = jinja2.FileSystemLoader(str(working_directory))
env = jinja2.Environment(loader=file_loader)
default_details = {
- "footer": (
- "---\n"
- "By using {{ branding.site_name }}, you agree to be bound by the following "
- "terms of use: All queries executed on this page are logged for analysis and "
- "troubleshooting. Users are prohibited from automating queries, or attempting "
- "to process queries in bulk. This service is provided on a best effort basis, "
- "and {{ general.org_name }} makes no availability or performance warranties "
- "or guarantees whatsoever."
- ),
- "bgp_aspath": (
- "title: Supported AS Path Patterns\n"
- "---\n"
- "{{ branding.site_name }} accepts the following `AS_PATH` regular expression "
- "patterns:\n"
- "| Expression | Match |\n"
- "| :------------------- | :-------------------------------------------- |\n"
- "| `_65000$` | Originated by 65000 |\n"
- "| `^65000_` | Received from 65000 |\n"
- "| `_65000_` | Via 65000 |\n"
- "| `_65000_65001_` | Via 65000 and 65001 |\n"
- "| `_65000(_.+_)65001$` | Anything from 65001 that passed through 65000 |\n"
- ),
- "bgp_community": (
- "title: BGP Communities\n"
- "---\n"
- "{{ branding.site_name }} makes use of the following BGP communities:\n"
- "| Community | Description |\n"
- "| :-------- | :---------- |\n"
- "| `65000:1` | Example 1 |\n"
- "| `65000:2` | Example 2 |\n"
- "| `65000:3` | Example 3 |\n"
- ),
+ "footer": [
+ "---",
+ "template: footer",
+ "---",
+ "By using {{ branding.site_name }}, you agree to be bound by the following ",
+ "terms of use: All queries executed on this page are logged for analysis and ",
+ "troubleshooting. Users are prohibited from automating queries, or attempting ",
+ "to process queries in bulk. This service is provided on a best effort basis, ",
+ "and {{ general.org_name }} makes no availability or performance warranties ",
+ "or guarantees whatsoever.",
+ ],
+ "bgp_aspath": [
+ "---",
+ "template: bgp_aspath",
+ "title: Supported AS Path Patterns",
+ "---",
+ "{{ branding.site_name }} accepts the following `AS_PATH` regular expression ",
+ "patterns:",
+ "| Expression | Match |",
+ "| :------------------- | :-------------------------------------------- |",
+ "| `_65000$` | Originated by 65000 |",
+ "| `^65000_` | Received from 65000 |",
+ "| `_65000_` | Via 65000 |",
+ "| `_65000_65001_` | Via 65000 and 65001 |",
+ "| `_65000(_.+_)65001$` | Anything from 65001 that passed through 65000 |",
+ ],
+ "bgp_community": [
+ "---",
+ "template: bgp_community",
+ "title: BGP Communities",
+ "---",
+ "{{ branding.site_name }} makes use of the following BGP communities:",
+ "| Community | Description |",
+ "| :-------- | :---------- |",
+ "| `65000:1` | Example 1 |",
+ "| `65000:2` | Example 2 |",
+ "| `65000:3` | Example 3 |",
+ ],
}
default_info = {
- "bgp_route": """
----
-Performs BGP table lookup based on IPv4/IPv6 prefix.
-""",
- "bgp_community": (
- 'link: {{ general.org_name }} '
- "BGP Communities\n"
- "---\n"
- "Performs BGP table lookup based on "
- "[Extended](https://tools.ietf.org/html/rfc4360) "
- "or [Large](https://tools.ietf.org/html/rfc8195) community value."
- '
{{ info["bgp_community"]["link"] }}'
- ),
- "bgp_aspath": (
- 'link: Supported BGP AS Path Expressions\n'
- "---\n"
- "Performs BGP table lookup based on `AS_PATH` regular expression."
- '
{{ info["bgp_aspath"]["link"] }}'
- ),
- "ping": ("---\n", "Sends 5 ICMP echo requests to the target."),
- "traceroute": (
- "---\n"
- "Performs UDP Based traceroute to the target.
For information about how to"
- "interpret traceroute results, [click here]"
- "(https://hyperglass.readthedocs.io/en/latest/assets/traceroute_nanog.pdf)."
- ),
+ "bgp_route": [
+ "---",
+ "template: bgp_route",
+ "---",
+ "Performs BGP table lookup based on IPv4/IPv6 prefix.",
+ ],
+ "bgp_community": [
+ "---",
+ "template: bgp_community",
+ (
+ 'link: {{ general.org_name }} '
+ "BGP Communities"
+ ),
+ "---",
+ "Performs BGP table lookup based on ",
+ "[Extended](https://tools.ietf.org/html/rfc4360) ",
+ "or [Large](https://tools.ietf.org/html/rfc8195) community value.",
+ '
{{ info["link"] }}',
+ ],
+ "bgp_aspath": [
+ "---",
+ "template: bgp_aspath",
+ 'link: Supported BGP AS Path Expressions',
+ "---",
+ "Performs BGP table lookup based on `AS_PATH` regular expression.",
+ '
{{ info["link"] }}',
+ ],
+ "ping": [
+ "---",
+ "template: ping",
+ "---",
+ "Sends 5 ICMP echo requests to the target.",
+ ],
+ "traceroute": [
+ "---",
+ "template: traceroute",
+ "---",
+ "Performs UDP Based traceroute to the target.
For information about how to",
+ "interpret traceroute results, [click here]",
+ "(https://hyperglass.readthedocs.io/en/latest/assets/traceroute_nanog.pdf).",
+ ],
}
@@ -108,26 +129,32 @@ def info(file_name):
if file.exists():
with file.open(mode="r") as file_raw:
file_read = file_raw.read()
- frontmatter, content = file_read.split("---")
- frontmatter_dict[file_name] = toml.loads(frontmatter)
- md_template_fm = jinja2.Environment(loader=jinja2.BaseLoader).from_string(
- frontmatter
- )
- md_template_content = jinja2.Environment(loader=jinja2.BaseLoader).from_string(
- content
- )
+ _, frontmatter, content = file_read.split("---")
else:
- _, frontmatter, content = default_info[file_name].split("+++")
- md_template_fm = jinja2.Environment(loader=jinja2.BaseLoader).from_string(
- frontmatter
- )
- md_template_content = jinja2.Environment(loader=jinja2.BaseLoader).from_string(
- content
- )
- frontmatter_rendered = md_template_fm.render(params)
- frontmatter_dict[file_name] = toml.loads(frontmatter_rendered)
- content_rendered = md_template_content.render(params, info=frontmatter_dict)
- frontmatter_dict[file_name]["content"] = markdown.convert(content_rendered)
+ fm_end = default_info[file_name][1:].index("---")
+ frontmatter = "\n".join(default_info[file_name][1:][:fm_end])
+ content = "".join(default_info[file_name][1:][fm_end + 1 :])
+ frontmatter_rendered = (
+ jinja2.Environment(loader=jinja2.BaseLoader)
+ .from_string(frontmatter)
+ .render(params)
+ )
+ if frontmatter_rendered:
+ frontmatter_loaded = yaml.safe_load(frontmatter_rendered)
+ if not frontmatter_rendered:
+ frontmatter_loaded = {"frontmatter": None}
+ content_rendered = (
+ jinja2.Environment(loader=jinja2.BaseLoader)
+ .from_string(content)
+ .render(params, info=frontmatter_loaded)
+ )
+ logger.error(frontmatter)
+ logger.error(frontmatter_loaded)
+ frontmatter_dict = dict(
+ content=markdown.convert(content_rendered), **frontmatter_loaded
+ )
+ if not frontmatter_dict:
+ raise HyperglassError(f"Error reading YAML frontmatter for {file_name}")
return frontmatter_dict
@@ -137,6 +164,7 @@ def details(file_name):
renders TOML frontmatter variables, returns dictionary of variables
and HTML content.
"""
+ frontmatter_dict = None
html_classes = {"table": "table"}
markdown = Markdown(
extras={
@@ -147,30 +175,33 @@ def details(file_name):
}
)
file = working_directory.joinpath(f"templates/info/details/{file_name}.md")
- frontmatter_dict = {}
if file.exists():
with file.open(mode="r") as file_raw:
file_read = file_raw.read()
- frontmatter, content = file_read.split("---")
- md_template_fm = jinja2.Environment(loader=jinja2.BaseLoader).from_string(
- frontmatter
- )
- md_template_content = jinja2.Environment(loader=jinja2.BaseLoader).from_string(
- content
- )
+ _, frontmatter, content = file_read.split("---")
else:
- _, frontmatter, content = default_details[file_name].split("+++")
- frontmatter_dict[file_name] = toml.loads(frontmatter)
- md_template_fm = jinja2.Environment(loader=jinja2.BaseLoader).from_string(
- frontmatter
- )
- md_template_content = jinja2.Environment(loader=jinja2.BaseLoader).from_string(
- content
- )
- frontmatter_rendered = md_template_fm.render(params)
- frontmatter_dict[file_name] = toml.loads(frontmatter_rendered)
- content_rendered = md_template_content.render(params, details=frontmatter_dict)
- frontmatter_dict[file_name]["content"] = markdown.convert(content_rendered)
+ fm_end = default_details[file_name][1:].index("---")
+ frontmatter = "\n".join(default_details[file_name][1:][:fm_end])
+ content = "".join(default_details[file_name][1:][fm_end + 1 :])
+ frontmatter_rendered = (
+ jinja2.Environment(loader=jinja2.BaseLoader)
+ .from_string(frontmatter)
+ .render(params)
+ )
+ if frontmatter_rendered:
+ frontmatter_loaded = yaml.safe_load(frontmatter_rendered)
+ if not frontmatter_rendered:
+ frontmatter_loaded = {"frontmatter": None}
+ content_rendered = (
+ jinja2.Environment(loader=jinja2.BaseLoader)
+ .from_string(content)
+ .render(params, details=frontmatter_loaded)
+ )
+ frontmatter_dict = dict(
+ content=markdown.convert(content_rendered), **frontmatter_loaded
+ )
+ if not frontmatter_dict:
+ raise HyperglassError(f"Error reading YAML frontmatter for {file_name}")
return frontmatter_dict
@@ -180,12 +211,12 @@ def html(template_name):
details_dict = {}
for details_name in details_name_list:
details_data = details(details_name)
- details_dict.update(details_data)
+ details_dict.update({details_name: details_data})
info_list = ["bgp_route", "bgp_aspath", "bgp_community", "ping", "traceroute"]
info_dict = {}
for info_name in info_list:
info_data = info(info_name)
- info_dict.update(info_data)
+ info_dict.update({info_name: info_data})
try:
template_file = f"templates/{template_name}.html.j2"
template = env.get_template(template_file)