diff --git a/docs/docs/introduction.mdx b/docs/docs/introduction.mdx index 4d807e9..1477347 100644 --- a/docs/docs/introduction.mdx +++ b/docs/docs/introduction.mdx @@ -7,7 +7,7 @@ description: Welcome to hyperglass import Link from "@docusaurus/Link"; import useBaseUrl from "@docusaurus/useBaseUrl"; import classnames from "classnames"; -import styles from "../src/pages/styles.module.css"; +import styles from "./styles.module.css"; # What is hyperglass? diff --git a/docs/docs/queries.mdx b/docs/docs/queries.mdx index 6f69bfd..1660dbe 100644 --- a/docs/docs/queries.mdx +++ b/docs/docs/queries.mdx @@ -8,8 +8,10 @@ description: hyperglass query types import Link from "@docusaurus/Link"; import Code from "../src/components/JSXCode"; +import MiniNote from "../src/components/MiniNote"; +import RP from "../src/components/RegexPattern"; -Each query type may be disabled, enabled, or customized. +Each query type may be disabled, enabled, or customized. The `display_name` parameter defines how the query type will be displayed in the UI's Query Type select element. ## `bgp_route` @@ -20,19 +22,39 @@ Each query type may be disabled, enabled, or customized. ## `bgp_community` -| Parameter | Type | Default | Description | -| :------------- | :-----: | :---------------- | :--------------------------------------------------------- | -| `enable` | Boolean | `true` | Enable or disable the BGP Community query type. | -| `display_name` | String | `'BGP Community'` | Text displayed for the BGP Community query type in the UI. | -| `pattern` | | | | +| Parameter | Type | Default | Description | +| :------------- | :-----: | :---------------- | :------------------------------------------------------------------------------ | +| `enable` | Boolean | `true` | Enable or disable the BGP Community query type. | +| `display_name` | String | `'BGP Community'` | Text displayed for the BGP Community query type in the UI. | +| `pattern` | | | BGP Community Regular Expression Patterns | + +### Community Patterns + +hyperglass allows you to override the default regular expression patterns used to validate UI and API queries. hyperglass supports [Decimal (well known)](https://tools.ietf.org/html/rfc1997) communities, [Extended AS](https://tools.ietf.org/html/rfc4360) communities, and [Large](https://tools.ietf.org/html/rfc8092) communities. + +| Parameter | Type | Default | Description | +| :------------ | :----: | :--------------------------------- | :----------------------------------------------------------------------------------------------------------------------------- | +| `decimal` | String | | Regular expression pattern for validating decimal type BGP Community strings. | +| `extended_as` | String | | Regular expression pattern for validating extended AS type BGP Community strings, e.g. `65000:1` | +| `large` | String | | Regular expression pattern for validating [large community](http://largebgpcommunities.net/) strings, e.g. `65000:65001:65002` | ## `bgp_aspath` -| Parameter | Type | Default | Description | -| :------------- | :-----: | :-------------- | :------------------------------------------------------- | -| `enable` | Boolean | `true` | Enable or disable the BGP AS Path query type. | -| `display_name` | String | `'BGP AS Path'` | Text displayed for the BGP AS Path query type in the UI. | -| `pattern` | | | | +| Parameter | Type | Default | Description | +| :------------- | :-----: | :-------------- | :------------------------------------------------------------------------------------- | +| `enable` | Boolean | `true` | Enable or disable the BGP AS Path query type. | +| `display_name` | String | `'BGP AS Path'` | Text displayed for the BGP AS Path query type in the UI. | +| `pattern` | | | BGP AS Path Settings & Regular Expression Patterns | + +### AS Path Patterns + +AS Path regular expression patterns may also be customized, should you wish to more granularly control what your network considers a valid AS Path pattern. hyperglass makes two "modes" available for validation - [**`asplain`** and **`asdot`**](https://tools.ietf.org/html/rfc5396). + +| Parameter | Type | Default | Description | +| :-------- | :----: | :----------------------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `mode` | String | `'asplain'` | Set ASN display mode. This field is dependent on how your network devices are configured. Must be asplain or asdot | +| `asplain` | String | | Regular expression pattern for validating **asplain** type BGP AS Path queries. | +| `asdot` | String | | Regular expression pattern for validating **asdot** type BGP AS Path queries. | ## `ping` @@ -47,3 +69,32 @@ Each query type may be disabled, enabled, or customized. | :------------- | :-----: | :------------- | :------------------------------------------------------ | | `enable` | Boolean | `true` | Enable or disable the Traceroute query type. | | `display_name` | String | `'Traceroute'` | Text displayed for the Traceroute query type in the UI. | + +## Example + +```yaml +queries: + bgp_aspath: + display_name: BGP AS Path + enable: true + pattern: + asdot: '^(\^|^\_)((\d+\.\d+)\_|(\d+\.\d+)\$|(\d+\.\d+)\(\_\.\+\_\))+$' + asplain: '^(\^|^\_)(\d+\_|\d+\$|\d+\(\_\.\+\_\))+$' + mode: asplain + bgp_community: + display_name: BGP Community + enable: true + pattern: + decimal: "^[0-9]{1,10}$" + extended_as: '^([0-9]{0,5})\:([0-9]{1,5})$' + large: '^([0-9]{1,10})\:([0-9]{1,10})\:[0-9]{1,10}$' + bgp_route: + display_name: BGP Route + enable: true + ping: + display_name: Ping + enable: true + traceroute: + display_name: Traceroute + enable: true +``` diff --git a/docs/docs/styles.module.css b/docs/docs/styles.module.css new file mode 100644 index 0000000..4a3bb7f --- /dev/null +++ b/docs/docs/styles.module.css @@ -0,0 +1,3 @@ +.getStarted[class][class]:not(.button--active):not(:hover) { + color: var(--ifm-color-secondary); +} diff --git a/docs/docusaurus.config.js b/docs/docusaurus.config.js index 029aa5f..d5bb084 100755 --- a/docs/docusaurus.config.js +++ b/docs/docusaurus.config.js @@ -22,11 +22,6 @@ module.exports = { href: "https://demo.hyperglass.io", label: "Demo", position: "left" - }, - { - href: githubURL, - label: "GitHub", - position: "right" } ] }, diff --git a/docs/src/components/Logo.js b/docs/src/components/Logo.js new file mode 100644 index 0000000..8a510a3 --- /dev/null +++ b/docs/src/components/Logo.js @@ -0,0 +1,52 @@ +import React from "react"; + +export default ({ color = "inherit", size = 32, className }) => ( + + + + + + + +); diff --git a/docs/src/components/RegexPattern.js b/docs/src/components/RegexPattern.js new file mode 100644 index 0000000..e0c7b1b --- /dev/null +++ b/docs/src/components/RegexPattern.js @@ -0,0 +1,15 @@ +import React from "react"; +import Code from "./JSXCode"; + +const patternMap = { + aspath_asdot: String.raw`^(\^|^\_)((\d+\.\d+)\_|(\d+\.\d+)\$|(\d+\.\d+)\(\_\.\+\_\))+$`, + aspath_asplain: String.raw`^(\^|^\_)(\d+\_|\d+\$|\d+\(\_\.\+\_\))+$`, + community_decimal: String.raw`^[0-9]{1,10}$`, + community_extended: String.raw`^([0-9]{0,5})\:([0-9]{1,5})$`, + community_large: String.raw`^([0-9]{1,10})\:([0-9]{1,10})\:[0-9]{1,10}$` +}; + +export default ({ pattern }) => { + const thisPattern = patternMap[pattern]; + return '{thisPattern}'; +}; diff --git a/docs/src/css/custom.css b/docs/src/css/custom.css index 7231375..f9037c3 100755 --- a/docs/src/css/custom.css +++ b/docs/src/css/custom.css @@ -7,13 +7,20 @@ /* You can override the default Infima variables here. */ :root { --ifm-font-size-sm: 12px; - --ifm-color-secondary: #314cb6; + /* --ifm-color-secondary: #314cb6; --ifm-color-secondary-dark: #2c44a4; --ifm-color-secondary-darker: #2a419b; --ifm-color-secondary-darkest: #22357f; --ifm-color-secondary-light: #3654c8; --ifm-color-secondary-lighter: #3e5bcb; - --ifm-color-secondary-lightest: #5a72d3; + --ifm-color-secondary-lightest: #5a72d3; */ + --ifm-color-secondary: #69a2b0; + --ifm-color-secondary-dark: #5796a6; + --ifm-color-secondary-darker: #528e9c; + --ifm-color-secondary-darkest: #447581; + --ifm-color-secondary-light: #7badba; + --ifm-color-secondary-lighter: #85b3bf; + --ifm-color-secondary-lightest: #a0c4cd; --ifm-color-primary: #ff5e5b; --ifm-color-primary-dark: #ff3c38; --ifm-color-primary-darker: #ff2b27; @@ -24,6 +31,39 @@ --ifm-code-font-size: 95%; } +:root { + --ifm-code-background: rgba(0, 0, 0, 0.04); + --ifm-code-color: var(--ifm-color-secondary-darker); + --ifm-footer-color: var(--ifm-secondary-lightest); + --ifm-footer-link-color: var(--ifm-secondary-lightest); + --ifm-footer-title-color: var(--ifm-color-emphasis-800); + --ifm-footer-background-color: var(--ifm-color-emphasis-100); +} + +html[data-theme="dark"] .footer.footer--dark { + --ifm-footer-color: var(--ifm-color-emphasis-300); +} + +.footer.footer--dark { + --ifm-footer-color: var(--ifm-color-emphasis-600); + --ifm-footer-link-color: var(--ifm-footer-color); + --ifm-footer-title-color: var(--ifm-color-emphasis-800); + --ifm-footer-background-color: var(--ifm-color-emphasis-100); +} + +.footer.footer--dark .footer__items { + font-size: 0.8rem; +} + +html[data-theme="dark"] { + --ifm-code-background: rgba(255, 255, 255, 0.08); + --ifm-code-color: var(--ifm-color-secondary-lightest); + /* #ace8cd + #b6a7e2 + #dc7381 + */ +} + .docusaurus-highlight-code-line { background-color: rgb(72, 77, 91); display: block; @@ -31,6 +71,19 @@ padding: 0 var(--ifm-pre-padding); } +table { + margin-top: var(--ifm-spacing-vertical); +} + table td:nth-child(1) { white-space: nowrap; } + +h1 code, +h2 code, +h3 code, +h4 code, +h5 code, +h6 code { + color: var(--ifm-color-primary); +} diff --git a/docs/src/pages/index.js b/docs/src/pages/index.js index 4cc7df8..8d090e1 100755 --- a/docs/src/pages/index.js +++ b/docs/src/pages/index.js @@ -66,8 +66,8 @@ function Home() {
diff --git a/docs/src/pages/styles.module.css b/docs/src/pages/styles.module.css index 4732b3d..4d6f613 100755 --- a/docs/src/pages/styles.module.css +++ b/docs/src/pages/styles.module.css @@ -34,6 +34,13 @@ width: 200px; } -.getStarted[class]:hover { - color: var(--ifm-color-content-secondary); +.getStarted[class][class]:not(.button--active):not(:hover) { + color: white; + border-color: white; +} + +.getStarted[class]:hover { + background-color: var(--ifm-color-secondary); + color: white; + border-color: none; } diff --git a/docs/src/theme/Navbar/index.js b/docs/src/theme/Navbar/index.js new file mode 100644 index 0000000..5b6aa8e --- /dev/null +++ b/docs/src/theme/Navbar/index.js @@ -0,0 +1,217 @@ +/** + * Copyright (c) 2017-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +import React, { useCallback, useState } from "react"; +import Link from "@docusaurus/Link"; +import { useLocation } from "react-router-dom"; +import useDocusaurusContext from "@docusaurus/useDocusaurusContext"; +import useBaseUrl from "@docusaurus/useBaseUrl"; + +import SearchBar from "@theme/SearchBar"; +import Toggle from "@theme/Toggle"; + +import classnames from "classnames"; + +import useTheme from "@theme/hooks/useTheme"; +import useHideableNavbar from "@theme/hooks/useHideableNavbar"; + +import Logo from "../../components/Logo"; +import styles from "./styles.module.css"; + +function NavLink({ to, href, label, position, ...props }) { + const toUrl = useBaseUrl(to); + return ( + + {label} + + ); +} + +function Navbar() { + const context = useDocusaurusContext(); + const { siteConfig = {} } = context; + const { baseUrl, themeConfig = {} } = siteConfig; + const { navbar = {}, disableDarkMode = false } = themeConfig; + const { title, logo = {}, links = [], hideOnScroll = false } = navbar; + const [sidebarShown, setSidebarShown] = useState(false); + const [isSearchBarExpanded, setIsSearchBarExpanded] = useState(false); + const [theme, setTheme] = useTheme(); + const { pathname } = useLocation(); + + const { navbarRef, isNavbarVisible } = useHideableNavbar(hideOnScroll); + + const showSidebar = useCallback(() => { + document.body.style.overflow = "hidden"; + setSidebarShown(true); + }, [setSidebarShown]); + const hideSidebar = useCallback(() => { + document.body.style.overflow = "visible"; + setSidebarShown(false); + }, [setSidebarShown]); + + const onToggleChange = useCallback(e => setTheme(e.target.checked ? "dark" : ""), [setTheme]); + + const logoUrl = useBaseUrl(logo.src); + const logoDark = useBaseUrl(logo.dark); + return ( + + ); +} + +export default Navbar; diff --git a/docs/src/theme/Navbar/styles.module.css b/docs/src/theme/Navbar/styles.module.css new file mode 100644 index 0000000..3ce1e64 --- /dev/null +++ b/docs/src/theme/Navbar/styles.module.css @@ -0,0 +1,71 @@ +@media screen and (max-width: 997px) { + .displayOnlyInLargeViewport { + display: none !important; + } +} + +@media (max-width: 360px) { + .hideLogoText { + display: none; + } +} + +.navbarHideable { + transition: top 0.2s ease-in-out; +} + +.navbarHidden { + top: calc(var(--ifm-navbar-height) * -1) !important; +} +.navbarItems { + justify-content: space-between; +} + +.navLink[class] { + position: relative; +} + +.navLink[class]:hover { + color: var(--ifm-color-white); +} + +html[data-theme="dark"] .navLink[class]:hover { + color: var(--ifm-color-secondary); +} + +.navLink[class]:global(.navbar__link--active) { + color: inherit; + font-weight: bold; +} +.navLink[class]:global(.navbar__link--active)::after { + position: absolute; + left: 0; + width: 100%; + height: 1px; + background: var(--ifm-color-content); + content: ""; + transition: width 0.5s, opacity 0.5s, transform 0.5s; + transform: translateY(-6px); +} + +.toggle { + margin-right: 20px; +} + +.navbarMain { + background-color: var(--ifm-color-primary); + box-shadow: none; +} + +.logo { + margin: 4px; + fill: var(--ifm-color-content); +} + +html[data-theme="dark"] .navbarOther { + background-color: var(--ifm-background-color); +} + +.navbarOther { + background-color: var(--ifm-color-white); +}