Skip to content

Commit 04436d0

Browse files
Merge branch 'thatmattlove:main' into main
2 parents d1e42f5 + fd34bda commit 04436d0

File tree

5 files changed

+29
-16
lines changed

5 files changed

+29
-16
lines changed

CHANGELOG.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,13 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
77
## [Unreleased]
88

99
### Fixed
10-
- [#280](https://github.com/thatmattlove/hyperglass/issues/280): Fix: `condition: None` caused error in directive
10+
- [#280](https://github.com/thatmattlove/hyperglass/issues/280): Fix: `condition: None` caused error in directive @Jimmy01240397
1111
- [#306](https://github.com/thatmattlove/hyperglass/issues/306): Fix: allow integer values in ext_community_list_raw field for Arista BGP - @cooperwinser
12+
- [#311](https://github.com/thatmattlove/hyperglass/issues/311): Fix: device and directive errors.
13+
- [#315](https://github.com/thatmattlove/hyperglass/issues/315): Impossibile to use command "BGP Route" with Huawei NetEngine 8000
14+
- [#315](https://github.com/thatmattlove/hyperglass/issues/187): Error in bgp_router query on Huawei
1215
- [#325](https://github.com/thatmattlove/hyperglass/pull/325): Fix code block padding in the documentation - @jagardaniel
13-
- [#327](https://github.com/thatmattlove/hyperglass/pull/327): Fix huawei bgp route and plugin validation/transform order - @JelsonRodrigues
16+
- [#332](https://github.com/thatmattlove/hyperglass/pull/332): Fix custom proxy port support in SSH proxy tunnels @jessiebryan
1417

1518
### Updated
1619

docs/pages/configuration/directives.mdx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,7 @@ your-directive:
166166
- condition: null
167167
command: show ip route {target}
168168
field:
169+
description: IP of target
169170
validation: '[0-9a-f\.\:]+'
170171
```
171172

@@ -178,6 +179,7 @@ your-directive:
178179
- condition: null
179180
command: show ip bgp community {target}
180181
field:
182+
description: BGP community to show
181183
options:
182184
- value: "65001:1"
183185
description: Provider A Routes

hyperglass/execution/drivers/ssh.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,9 @@ def opener():
4848
proxy.credential.password.get_secret_value()
4949
)
5050
try:
51-
return open_tunnel(proxy._target, proxy.port, **tunnel_kwargs)
51+
return open_tunnel(
52+
ssh_address_or_host=proxy._target, ssh_port=proxy.port, **tunnel_kwargs
53+
)
5254

5355
except BaseSSHTunnelForwarderError as scrape_proxy_error:
5456
log.bind(device=self.device.name, proxy=proxy.name).error(

hyperglass/models/api/query.py

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@
77
from datetime import datetime
88

99
# Third Party
10-
from pydantic import Field, BaseModel, ConfigDict, field_validator
10+
from pydantic import BaseModel, ConfigDict, field_validator, StringConstraints
11+
from typing_extensions import Annotated
1112

1213
# Project
1314
from hyperglass.log import log
@@ -21,6 +22,11 @@
2122
from ..config.devices import Device
2223

2324

25+
QueryLocation = Annotated[str, StringConstraints(strict=True, min_length=1, strip_whitespace=True)]
26+
QueryTarget = Annotated[str, StringConstraints(min_length=1, strip_whitespace=True)]
27+
QueryType = Annotated[str, StringConstraints(strict=True, min_length=1, strip_whitespace=True)]
28+
29+
2430
class SimpleQuery(BaseModel):
2531
"""A simple representation of a post-validated query."""
2632

@@ -39,12 +45,12 @@ class Query(BaseModel):
3945
model_config = ConfigDict(extra="allow", alias_generator=snake_to_camel, populate_by_name=True)
4046

4147
# Device `name` field
42-
query_location: str = Field(strict=True, min_length=1, strip_whitespace=True)
48+
query_location: QueryLocation
4349

44-
query_target: t.Union[t.List[str], str] = Field(min_length=1, strip_whitespace=True)
50+
query_target: t.Union[t.List[QueryTarget], QueryTarget]
4551

4652
# Directive `id` field
47-
query_type: str = Field(strict=True, min_length=1, strip_whitespace=True)
53+
query_type: QueryType
4854
_kwargs: t.Dict[str, t.Any]
4955

5056
def __init__(self, **data) -> None:

hyperglass/models/config/devices.py

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -170,22 +170,22 @@ def _validate_directive_attrs(self) -> None:
170170

171171
@field_validator("address")
172172
def validate_address(
173-
cls, value: t.Union[IPv4Address, IPv6Address, str], values: t.Dict[str, t.Any]
173+
cls, value: t.Union[IPv4Address, IPv6Address, str], info: ValidationInfo
174174
) -> t.Union[IPv4Address, IPv6Address, str]:
175175
"""Ensure a hostname is resolvable."""
176176

177177
if not isinstance(value, (IPv4Address, IPv6Address)):
178178
if not any(resolve_hostname(value)):
179179
raise ConfigError(
180180
"Device '{d}' has an address of '{a}', which is not resolvable.",
181-
d=values["name"],
181+
d=info.data["name"],
182182
a=value,
183183
)
184184
return value
185185

186186
@field_validator("avatar")
187187
def validate_avatar(
188-
cls, value: t.Union[FilePath, None], values: t.Dict[str, t.Any]
188+
cls, value: t.Union[FilePath, None], info: ValidationInfo
189189
) -> t.Union[FilePath, None]:
190190
"""Migrate avatar to static directory."""
191191
if value is not None:
@@ -198,7 +198,7 @@ def validate_avatar(
198198
target = Settings.static_path / "images" / value.name
199199
copied = shutil.copy2(value, target)
200200
log.bind(
201-
device=values["name"],
201+
device=info.data["name"],
202202
source=str(value),
203203
destination=str(target),
204204
).debug("Copied device avatar")
@@ -210,24 +210,24 @@ def validate_avatar(
210210
return value
211211

212212
@field_validator("platform", mode="before")
213-
def validate_platform(cls: "Device", value: t.Any, values: t.Dict[str, t.Any]) -> str:
213+
def validate_platform(cls: "Device", value: t.Any, info: ValidationInfo) -> str:
214214
"""Validate & rewrite device platform, set default `directives`."""
215215

216216
if value == "http":
217-
if values.get("http") is None:
217+
if info.data.get("http") is None:
218218
raise ConfigError(
219219
"Device '{device}' has platform 'http' configured, but no http parameters are defined.",
220-
device=values["name"],
220+
device=info.data["name"],
221221
)
222222

223223
if value is None:
224-
if values.get("http") is not None:
224+
if info.data.get("http") is not None:
225225
value = "http"
226226
else:
227227
# Ensure device platform is defined.
228228
raise ConfigError(
229229
"Device '{device}' is missing a 'platform' (Network Operating System) property",
230-
device=values["name"],
230+
device=info.data["name"],
231231
)
232232

233233
if value in SCRAPE_HELPERS.keys():

0 commit comments

Comments
 (0)