1
0
mirror of https://github.com/checktheroads/hyperglass synced 2024-05-11 05:55:08 +00:00

BGP Community Selection improvements

This commit is contained in:
checktheroads
2020-04-18 11:34:23 -07:00
parent 903dadd236
commit d3e1189487
8 changed files with 248 additions and 124 deletions

View File

@@ -6,11 +6,12 @@ keywords: [hyperglass, queries]
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";
<div class="table--full-width" />
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,17 +21,55 @@ Each query type may be disabled, enabled, or customized. The `display_name` para
| `enable` | Boolean | `true` | Enable or disable the BGP Route query type. |
| `display_name` | String | `'BGP Route'` | Text displayed for the BGP Route query type in the UI. |
#### Example
<!-- prettier-ignore -->
```yaml
queries:
bgp_route:
display_name: BGP Route
enable: true
```
## `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` | | | <Link to="#community-patterns">BGP Community Regular Expression Patterns</Link> |
| 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. |
| `mode` | String | `'input'` | `input` mode requires the user to type the community value in the target element. `select` mode allows the user to select a community from a preconfigured list of communities. |
| `communities` | | | [BGP Community Definitions](#community-definitions) for `select` mode. |
| `pattern` | | | [BGP Community Regular Expression Patterns](#community-patterns) for `input` mode. |
### Community Definitions
If using `select` mode, you may define a list of communities the users can choose from. Each community definition uses the following schema:
| Parameter | Type | Description | Example |
| :------------- | :----: | :--------------------- | :----------------------- |
| `community` | String | Community value | `'64496:1001'` |
| `display_name` | String | Community display name | `'64496:1001'` |
| `description` | String | Community description | `'North America Routes'` |
#### Example
```yaml
queries:
bgp_community:
enable: true
mode: select
communities:
- community: 64496:1001
display_name: 64496:1001
description: North America Routes
- community: 64496:1002
display_name: 64496:1002
description: Europe Routes
```
### 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.
If using `input` mode, 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 |
| :------------ | :----: | :--------------------------------- | :----------------------------------------------------------------------------------------------------------------------------- |
@@ -38,13 +77,45 @@ hyperglass allows you to override the default regular expression patterns used t
| `extended_as` | String | <RP pattern="community_extended"/> | Regular expression pattern for validating extended AS type BGP Community strings, e.g. `65000:1` |
| `large` | String | <RP pattern="community_large"/> | Regular expression pattern for validating [large community](http://largebgpcommunities.net/) strings, e.g. `65000:65001:65002` |
#### Example
<!-- prettier-ignore -->
```yaml
queries:
bgp_community:
enable: true
mode: input
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}$'
```
:::caution
Regular expression patterns must be enclosed in single quotes, e.g. `'^.*$'`
:::
## `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` | | | <Link to="#as-path-patterns">BGP AS Path Settings & Regular Expression Patterns</Link> |
| 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) |
#### Example
<!-- prettier-ignore -->
```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
```
### AS Path Patterns
@@ -63,6 +134,16 @@ AS Path regular expression patterns may also be customized, should you wish to m
| `enable` | Boolean | `true` | Enable or disable the Ping query type. |
| `display_name` | String | `'Ping'` | Text displayed for the Ping query type in the UI. |
#### Example
<!-- prettier-ignore -->
```yaml
queries:
ping:
display_name: Ping
enable: true
```
## `traceroute`
| Parameter | Type | Default | Description |
@@ -70,31 +151,12 @@ AS Path regular expression patterns may also be customized, should you wish to m
| `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
#### Example
<!-- prettier-ignore -->
```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
traceroute:
display_name: Traceroute
enable: true
```

View File

@@ -18,7 +18,14 @@ from hyperglass.log import log
from hyperglass.util import cpu_count
from hyperglass.constants import TRANSPORT_REST, __version__
from hyperglass.api.events import on_startup, on_shutdown
from hyperglass.api.routes import docs, query, queries, routers, import_certificate
from hyperglass.api.routes import (
docs,
query,
queries,
routers,
import_certificate,
communities,
)
from hyperglass.exceptions import HyperglassError
from hyperglass.configuration import URL_DEV, STATIC_PATH, params, devices
from hyperglass.api.error_handlers import (
@@ -31,6 +38,7 @@ from hyperglass.api.models.response import (
QueryError,
QueryResponse,
RoutersResponse,
CommunityResponse,
SupportedQueryResponse,
)
@@ -105,7 +113,7 @@ def _custom_openapi():
description=params.docs.description,
routes=app.routes,
)
openapi_schema["info"]["x-logo"] = {"url": str(params.web.logo.light)}
openapi_schema["info"]["x-logo"] = {"url": "/" + str(params.web.logo.dark)}
query_samples = []
queries_samples = []
@@ -176,6 +184,16 @@ app.add_api_route(
description=params.docs.devices.description,
tags=[params.docs.devices.title],
)
app.add_api_route(
path="/api/communities",
endpoint=communities,
methods=["GET"],
response_model=List[CommunityResponse],
summary=params.docs.communities.summary,
tags=[params.docs.communities.title],
)
app.add_api_route(
path="/api/queries",
endpoint=queries,
@@ -186,6 +204,7 @@ app.add_api_route(
description=params.docs.queries.description,
tags=[params.docs.queries.title],
)
app.add_api_route(
path="/api/query/",
endpoint=query,

View File

@@ -17,7 +17,8 @@ from hyperglass.api.models.types import SupportedQuery
from hyperglass.api.models.validators import (
validate_ip,
validate_aspath,
validate_community,
validate_community_input,
validate_community_select,
)
@@ -215,7 +216,7 @@ class Query(BaseModel):
# Use relevant function based on query_type.
validator_map = {
"bgp_aspath": validate_aspath,
"bgp_community": validate_community,
"bgp_community": validate_community_input,
"bgp_route": validate_ip,
"ping": validate_ip,
"traceroute": validate_ip,
@@ -227,6 +228,10 @@ class Query(BaseModel):
"ping": (value, values["query_type"], values["query_vrf"]),
"traceroute": (value, values["query_type"], values["query_vrf"]),
}
if params.queries.bgp_community.mode == "select":
validator_map["bgp_community"] = validate_community_select
validate_func = validator_map[query_type]
validate_args = validator_args_map[query_type]

View File

@@ -189,6 +189,14 @@ class RoutersResponse(BaseModel):
}
class CommunityResponse(BaseModel):
"""Response model for /api/communities."""
community: StrictStr
display_name: StrictStr
description: StrictStr
class SupportedQueryResponse(BaseModel):
"""Response model for /api/queries list items."""

View File

@@ -150,7 +150,7 @@ def validate_ip(value, query_type, query_vrf): # noqa: C901
return valid_ip
def validate_community(value):
def validate_community_input(value):
"""Validate input communities against configured or default regex pattern."""
# RFC4360: Extended Communities (New Format)
@@ -174,6 +174,19 @@ def validate_community(value):
return value
def validate_community_select(value):
"""Validate selected community against configured communities."""
communities = tuple(c.community for c in params.queries.bgp_community.communities)
if value not in communities:
raise InputInvalid(
params.messages.invalid_input,
target=value,
query_type=params.queries.bgp_community.display_name,
)
return value
def validate_aspath(value):
"""Validate input AS_PATH against configured or default regext pattern."""

View File

@@ -194,6 +194,14 @@ async def routers():
]
async def communities():
"""Serve list of configured communities if mode is select."""
if params.queries.bgp_community.mode != "select":
raise HTTPException(detail="BGP community mode is not select", status_code=404)
return [c.export_dict() for c in params.queries.bgp_community.communities]
async def queries():
"""Serve list of enabled query types."""
return params.queries.list

View File

@@ -77,6 +77,11 @@ class Docs(HyperglassModel):
description="List of supported query types.",
summary="Query Types",
)
communities: EndpointConfig = EndpointConfig(
title="BGP Communities",
description="List of BGP communities.",
summary="BGP Communities List",
)
class Config:
"""Pydantic model configuration."""
@@ -96,4 +101,8 @@ class Docs(HyperglassModel):
"title": "Queries API Endpoint",
"description": "`/api/devices` API documentation options.",
},
"communities": {
"title": "BGP Communities API Endpoint",
"description": "`/api/communities` API documentation options.",
},
}

View File

@@ -1,98 +1,98 @@
---
# Credentials
credentials:
- credential: &credential1
username: user1
password: secret1
- credential: &credential2
username: user2
password: secret2
- credential: &credential1
username: user1
password: secret1
- credential: &credential2
username: user2
password: secret2
# SSH Proxy/Tunnel Servers
proxies:
- proxy: &proxy1
name: server01
address: 10.11.6.204
port: 22
credential: *credential1
nos: linux_ssh
- proxy: &proxy1
name: server01
address: 10.11.6.204
port: 22
credential: *credential1
nos: linux_ssh
# Networks
networks:
- network: &net_primary
name: primary
display_name: Main Network
- network: &net_secondary
name: secondary
display_name: That Other Network
- network: &net_primary
name: primary
display_name: Main Network
- network: &net_secondary
name: secondary
display_name: That Other Network
# VRFs
vrfs:
- &vrf_default
name: default
display_name: Global
ipv4:
access_list: &vrf_default_ipv4_acl
- network: 10.0.0.0/8
action: deny
- network: 192.168.0.0/16
action: deny
- network: 172.16.0.0/12
action: deny
- network: 0.0.0.0/0
action: permit
ge: 8
le: 24
ipv6:
access_list: &vrf_default_ipv6_acl
- network: ::/0
action: permit
ge: 32
le: 64
- &vrf_customer_a
name: customer_a
display_name: Customer A
ipv4:
access_list: &vrf_customer_a_ipv4_acl
- network: 192.0.2.0/24
action: deny
- network: 10.0.0.0/8
action: permit
ipv6: null
- &vrf_default
name: default
display_name: Global
ipv4:
access_list: &vrf_default_ipv4_acl
- network: 10.0.0.0/8
action: deny
- network: 192.168.0.0/16
action: deny
- network: 172.16.0.0/12
action: deny
- network: 0.0.0.0/0
action: permit
ge: 8
le: 24
ipv6:
access_list: &vrf_default_ipv6_acl
- network: ::/0
action: permit
ge: 32
le: 64
- &vrf_customer_a
name: customer_a
display_name: Customer A
ipv4:
access_list: &vrf_customer_a_ipv4_acl
- network: 192.0.2.0/24
action: deny
- network: 10.0.0.0/8
action: permit
ipv6: null
# Routers
routers:
- name: sfo_router01
address: 10.0.0.1
network: *net_primary
credential: *credential1
display_name: San Francisco, CA
port: 22
nos: cisco_ios
vrfs:
- <<: *vrf_default
ipv4:
source_address: 192.0.2.1
access_list: *vrf_default_ipv4_acl
ipv6:
source_address: 2001:db8::1
access_list: *vrf_default_ipv6_acl
- <<: *vrf_customer_a
ipv4:
access_list: *vrf_customer_a_ipv4_acl
source_address: 192.168.1.1
proxy: null
- name: atl_router01
address: 10.0.0.2
network: *net_secondary
credential: *credential2
display_name: Atlanta, GA
port: 22
nos: juniper
vrfs:
- <<: *vrf_default
ipv4:
source_address: 192.0.2.2
ipv6:
source_address: 2001:db8::2
proxy: *proxy1
- name: sfo_router01
address: 10.0.0.1
network: *net_primary
credential: *credential1
display_name: San Francisco, CA
port: 22
nos: cisco_ios
vrfs:
- <<: *vrf_default
ipv4:
source_address: 192.0.2.1
access_list: *vrf_default_ipv4_acl
ipv6:
source_address: 2001:db8::1
access_list: *vrf_default_ipv6_acl
- <<: *vrf_customer_a
ipv4:
access_list: *vrf_customer_a_ipv4_acl
source_address: 192.168.1.1
proxy: null
- name: atl_router01
address: 10.0.0.2
network: *net_secondary
credential: *credential2
display_name: Atlanta, GA
port: 22
nos: juniper
vrfs:
- <<: *vrf_default
ipv4:
source_address: 192.0.2.2
ipv6:
source_address: 2001:db8::2
proxy: *proxy1