From 99f79b16b5864ad859050ab01d87cb9692394cf0 Mon Sep 17 00:00:00 2001 From: checktheroads Date: Sat, 11 Apr 2020 17:44:32 -0700 Subject: [PATCH] docs updates --- docs/docs/commands.mdx | 110 ++ docs/docs/devices.mdx | 41 +- docs/docusaurus.config.js | 56 +- docs/sidebars.js | 17 +- docs/src/css/custom.css | 4 + docs/src/theme/CodeBlock/index.js | 21 +- docs/src/theme/Navbar/index.js | 30 +- docs/yarn.lock | 2138 +++++++++++++++++------------ 8 files changed, 1443 insertions(+), 974 deletions(-) create mode 100644 docs/docs/commands.mdx diff --git a/docs/docs/commands.mdx b/docs/docs/commands.mdx new file mode 100644 index 0000000..1516055 --- /dev/null +++ b/docs/docs/commands.mdx @@ -0,0 +1,110 @@ +--- +id: commands +title: Commands +sidebar_label: Commands +keywords: + [ + hyperglass, + commands, + customize, + cisco, + ios, + ios-xe, + ios-xr, + juniper, + junos, + arista, + eos, + huawei, + vrp, + ] +description: Custom Commands +--- + +hyperglass comes with built in support for the following platforms: + +- Cisco IOS & IOS-XE +- Cisco IOS-XR +- Juniper JunOS +- Arista EOS +- Huawei VRP + +Default commands for each of these network operating systems are built into hyperglass. However, you may override any of them or even add commands for another Network Operating System (NOS), as long as it's [supported](platforms.mdx). To define custom commands, add a `commands.yaml` file to your installation directory (`/etc/hyperglass`, +`~/hyperglass`). As an example, you could override the default Juniper `bgp_route` command for the default routing table like this: + +```yaml +juniper: + ipv4_default: + bgp_route: "show route protocol bgp {target} terse" +``` + +Only the command you specify will be overridden. + +## Command Types + +Each command definition carries the following structure: + +```yaml +command_name: + ipv4_default: ... + bgp_route: ... + bgp_aspath: ... + bgp_community: ... + ping: ... + traceroute: ... + ipv6_default: + bgp_route: ... + bgp_aspath: ... + bgp_community: ... + ping: ... + traceroute: ... + ipv4_vpn: + bgp_route: ... + bgp_aspath: ... + bgp_community: ... + ping: ... + traceroute: ... + ipv6_vpn: + bgp_route: ... + bgp_aspath: ... + bgp_community: ... + ping: ... + traceroute: ... +``` + +`ipv4_default` and `ipv6_default` reference the commands used in the default routing table/VRF, while `ipv4_vpn` and `ipv6_vpn` reference the commands used in **any** configured VRF. Every command will have the following keywords replaced: + +| Keyword | Description | +| :--------- | :------------------------------------------------------------ | +| `{target}` | Query Target (IP address, community, AS Path). | +| `{vrf}` | If it's a VRF query, the [name of the VRF](devices.mdx#vrfs). | + +## Defining Custom Commands + +You can also define your own arbitrary command groups, and reference them in your `devices.yaml` file. For example, if you wanted define a set of commands for a specific device to use, you could do it like this: + +```yaml +# commands.yaml +--- +special_commands: + ipv4_default: + bgp_route: "show ip route {target}" + ipv4_vpn: + bgp_route: "show ip route {target} vrf {vrf}" +``` + +The above example defines the command set. + +:::important +You must define _all_ commands, even if they're disabled in your [configuration](queries.mdx). +::: + +Then, in the device's definition in `devices.yaml`, reference the command set: + +```yaml {5} +# devices.yaml +--- +routers: + - name: specialrouter01 + commands: special_commands +``` diff --git a/docs/docs/devices.mdx b/docs/docs/devices.mdx index a2dacba..390eb53 100644 --- a/docs/docs/devices.mdx +++ b/docs/docs/devices.mdx @@ -80,20 +80,27 @@ The VRFs section is a list of available VRFs for a given device. Each VRF may be May be set to `null` to disable IPv4 for this VRF, on the parent device. -| Parameter | Type | Description | -| :-------------------- | :----: | :-------------------------------------------------------------------- | -| `source_address` | String | Device's source IPv4 address for directed queries (ping, traceroute). | -| `access_list` | | IPv4 Access List Configuration | +| Parameter | Type | Description | +| :-------------------- | :-----: | :-------------------------------------------------------------------- | +| `source_address` | String | Device's source IPv4 address for directed queries (ping, traceroute). | +| `force_cidr` | Boolean | `true` | Convert IP host queries to actual advertised containing prefix length | +| `access_list` | | IPv4 Access List Configuration | #### `ipv6` May be set to `null` to disable IPv6 for this VRF, on the parent device. -| Parameter | Type | Default | Description | -| :-------------------- | :-----: | :------ | :------------------------------------------------------------------------------------------------------------------------------ | -| `source_address` | String | | Device's source IPv6 address for directed queries (ping, traceroute). | -| `force_cidr` | Boolean | `true` | Convert host queries to the highest allowed prefix-length (defined in the le field) | -| `access_list` | | | IPv6 Access List Configuration | +| Parameter | Type | Default | Description | +| :-------------------- | :-----: | :------ | :-------------------------------------------------------------------- | +| `source_address` | String | | Device's source IPv6 address for directed queries (ping, traceroute). | +| `force_cidr` | Boolean | `true` | Convert IP host queries to actual advertised containing prefix length | +| `access_list` | | | [IPv6 Access List Configuration](#access_list) | + +:::note +The `force_cidr` option will ensure that a **BGP Route** query for an IP host (/32 IPv4, /128 IPv6) is converted to its containing prefix. For example, a query for `1.1.1.1` would be converted to a query for `1.1.1.0/24`. This is because not all platforms support a BGP lookup for a host (this is primary a problem with IPv6, but the option applies to both address families). + +When `force_cidr`is set to `true`, hyperglass will perform a lookup via the [RIPEStat](https://stat.ripe.net/docs/data_api#network-info) Data API to get the advertised prefix for an IP host. +::: #### `access_list` @@ -135,7 +142,21 @@ info: community: "65000" ``` -### Full Example +## Telnet + +Telnet support is provided via the underlying device connection handling framework, [Netmiko](https://github.com/ktbyers/netmiko). To connect to a device via serial, add the suffix `_telnet` to the device's `nos` value and set the `port` value to `23`. + +For example: + +```yaml {3-4} +routers: + - name: router01 + nos: cisco_ios_telnet + port: 23 + ... +``` + +## Full Example Below is a full example with nearly every available knob turned: diff --git a/docs/docusaurus.config.js b/docs/docusaurus.config.js index 5f7014c..63234a6 100755 --- a/docs/docusaurus.config.js +++ b/docs/docusaurus.config.js @@ -14,11 +14,11 @@ module.exports = { googleAnalytics: { trackingID: googleTrackingId || " ", anonymizeIP: false }, gtag: { trackingID: googleTrackingId || " ", - anonymizeIP: false + anonymizeIP: false, }, algolia: { apiKey: algoliaKey, - indexName: "hyperglass" + indexName: "hyperglass", }, navbar: { links: [ @@ -27,9 +27,9 @@ module.exports = { { href: "https://demo.hyperglass.io", label: "Demo", - position: "left" - } - ] + position: "left", + }, + ], }, footer: { style: "dark", @@ -39,46 +39,46 @@ module.exports = { items: [ { label: "Introduction", - to: "docs/introduction" + to: "docs/introduction", }, { label: "Getting Started", - to: "docs/getting-started" + to: "docs/getting-started", }, { label: "Configuration", - to: "docs/configuration" - } - ] + to: "docs/configuration", + }, + ], }, { title: "Community", items: [ { label: "Gitter", - href: "https://gitter.im/hyperglass" + href: "https://gitter.im/hyperglass", }, { label: "Keybase", - href: "https://keybase.io/team/hyperglass" - } - ] + href: "https://keybase.io/team/hyperglass", + }, + ], }, { title: "Social", items: [ { label: "GitHub", - href: githubURL + href: githubURL, }, { label: "Twitter", - href: "https://twitter.com/checktheroads" - } - ] - } - ] - } + href: "https://twitter.com/checktheroads", + }, + ], + }, + ], + }, }, presets: [ [ @@ -86,17 +86,17 @@ module.exports = { { docs: { sidebarPath: require.resolve("./sidebars.js"), - editUrl: githubURL + "/edit/master/docs/" + editUrl: githubURL + "/edit/master/docs/", }, theme: { - customCss: require.resolve("./src/css/custom.css") - } - } - ] + customCss: require.resolve("./src/css/custom.css"), + }, + }, + ], ], plugins: [ "@docusaurus/plugin-google-analytics", "@docusaurus/plugin-google-gtag", - "@docusaurus/plugin-sitemap" - ] + "@docusaurus/plugin-sitemap", + ], }; diff --git a/docs/sidebars.js b/docs/sidebars.js index 96fda87..29e99bf 100755 --- a/docs/sidebars.js +++ b/docs/sidebars.js @@ -3,15 +3,24 @@ module.exports = { { type: "category", label: "Installation", - items: ["introduction", "getting-started", "setup"] + items: ["introduction", "getting-started", "setup"], }, { type: "category", label: "Configuration", - items: ["configuration", "devices", "ui", "cache", "api", "messages", "queries"] + items: [ + "configuration", + "devices", + "commands", + "ui", + "cache", + "api", + "messages", + "queries", + ], }, { type: "category", label: "Linux Agent", items: ["agent/installation"] }, { type: "doc", id: "platforms" }, - { type: "doc", id: "license" } - ] + { type: "doc", id: "license" }, + ], }; diff --git a/docs/src/css/custom.css b/docs/src/css/custom.css index 036594c..05cedd6 100755 --- a/docs/src/css/custom.css +++ b/docs/src/css/custom.css @@ -143,3 +143,7 @@ h6 code { border-color: var(--ifm-navbar-search-input-background-color); border-style: solid; } + +.admonition-content table tr:nth-child(2n) { + background-color: unset; +} diff --git a/docs/src/theme/CodeBlock/index.js b/docs/src/theme/CodeBlock/index.js index 33c74a9..8782be8 100755 --- a/docs/src/theme/CodeBlock/index.js +++ b/docs/src/theme/CodeBlock/index.js @@ -20,20 +20,19 @@ const highlightLinesRangeRegex = /{([\d,-]+)}/; export default ({ children, className: languageClassName, metastring }) => { (typeof global !== "undefined" ? global : window).Prism = Prism; require("prismjs/components/prism-shell-session"); - require("prismjs/components/prism-yaml"); const { siteConfig: { - themeConfig: { prism = {} } - } + themeConfig: { prism = {} }, + }, } = useDocusaurusContext(); - const [showCopied, setShowCopied] = useState(false); + // const [showCopied, setShowCopied] = useState(false); const target = useRef(null); const button = useRef(null); let highlightLines = []; if (metastring && highlightLinesRangeRegex.test(metastring)) { const highlightLinesRange = metastring.match(highlightLinesRangeRegex)[1]; - highlightLines = rangeParser.parse(highlightLinesRange).filter(n => n > 0); + highlightLines = rangeParser.parse(highlightLinesRange).filter((n) => n > 0); } useEffect(() => { @@ -41,7 +40,7 @@ export default ({ children, className: languageClassName, metastring }) => { if (button.current) { clipboard = new Clipboard(button.current, { - target: () => target.current + target: () => target.current, }); } @@ -58,12 +57,12 @@ export default ({ children, className: languageClassName, metastring }) => { language = prism.defaultLanguage; } - const handleCopyCode = () => { - window.getSelection().empty(); - setShowCopied(true); + // const handleCopyCode = () => { + // window.getSelection().empty(); + // setShowCopied(true); - setTimeout(() => setShowCopied(false), 2000); - }; + // setTimeout(() => setShowCopied(false), 2000); + // }; return ( @@ -48,6 +48,8 @@ function NavLink({ to, href, label, position, ...props }) { ); } +const logoColor = { true: "#ff5e5b", false: "#000" }; + function Navbar() { const context = useDocusaurusContext(); const { siteConfig = {} } = context; @@ -73,7 +75,7 @@ function Navbar() { setSidebarShown(false); }, [setSidebarShown]); - const onToggleChange = checked => { + const onToggleChange = (checked) => { checked ? setDarkTheme() : setLightTheme(); }; @@ -82,12 +84,12 @@ function Navbar() { const logoLinkProps = isExternalLogoLink ? { rel: "noopener noreferrer", - target: "_blank" + target: "_blank", } : null; const logoSrc = logo.srcDark && isDarkTheme ? logo.srcDark : logo.src; - const logoColor = isDarkTheme ? "#ff5e5b" : "#000"; + // const logoColor = isDarkTheme ? "#ff5e5b" : "#000"; return (