hyperglass icon indicating copy to clipboard operation
hyperglass copied to clipboard

Avatar Error

Open SwimGeek opened this issue 1 year ago • 2 comments

Deployment Type

Docker

Version

2.0.4

Steps to Reproduce

define 'avatar' in devices.yaml

Expected Behavior

Create a logo for a router.

Observed Behavior

Error in: /opt/hyperglass/hyperglass/models/config/devices.py, line 201 device=values["name"]

Configuration

No response

Devices

---
devices:
  - name: r1
    group: Cape Town
    avatar: /etc/hyperglass/router.png

Logs

error: hyperglass_1  |   File "/opt/hyperglass/hyperglass/models/config/devices.py", line 201, in validate_avatar
hyperglass_1  |     device=values["name"]

SwimGeek avatar Jan 01 '25 12:01 SwimGeek

@thatmattlove I seem to be having possibly a similar issue trying to get avatars working. Using the following device config (just some testing values):

devices:
  - name: UKSE1 (London)
    address: 127.0.0.1
    avatar: /etc/hyperglass/flags/gb.png
    credential:
      username: test
      password: test
    platform: frr
    attrs:
      source4: 127.0.0.1
      source6: 2001:db8::1
    directives:
      - builtins: false
      - frr-bgp-route

I end up with the following traceback when restarting hyperglass

Jun 03 21:27:18 lg1 python3[39548]: [DEBUG] 20250603 21:27:18 |66 | load_dsl <E2><86><92> Loaded configuration {'path': PosixPath('/etc/hyperglass/config.yaml')}
Jun 03 21:27:18 lg1 python3[39548]: [DEBUG] 20250603 21:27:18 |66 | load_dsl <E2><86><92> Loaded configuration {'path': PosixPath('/etc/hyperglass/directives.yaml')}
Jun 03 21:27:18 lg1 python3[39548]: [DEBUG] 20250603 21:27:18 |66 | load_dsl <E2><86><92> Loaded configuration {'path': PosixPath('/etc/hyperglass/directives.yaml')}
Jun 03 21:27:18 lg1 python3[39548]: [DEBUG] 20250603 21:27:18 |66 | load_dsl <E2><86><92> Loaded configuration {'path': PosixPath('/etc/hyperglass/devices.yaml')}
Jun 03 21:27:18 lg1 python3[39548]: [CRITICAL] 20250603 21:27:18 |176 | run <E2><86><92> 'pydantic_core._pydantic_core.ValidationInfo' object is not subscriptable {}
Jun 03 21:27:18 lg1 python3[39548]: [DEBUG] 20250603 21:27:18 |181 | run <E2><86><92> Cleared hyperglass state {}
Jun 03 21:27:18 lg1 python3[39548]: Error in sys.excepthook:
Jun 03 21:27:18 lg1 python3[39548]: Traceback (most recent call last):
Jun 03 21:27:18 lg1 python3[39548]:   File "/opt/hyperglass/venv/lib/python3.12/site-packages/typer/main.py", line 72, in except_hook
Jun 03 21:27:18 lg1 python3[39548]:     rich_tb = Traceback.from_exception(
Jun 03 21:27:18 lg1 python3[39548]:               ^^^^^^^^^^^^^^^^^^^^^^^^^
Jun 03 21:27:18 lg1 python3[39548]:   File "/opt/hyperglass/venv/lib/python3.12/site-packages/rich/traceback.py", line 343, in from_exception
Jun 03 21:27:18 lg1 python3[39548]:     rich_traceback = cls.extract(
Jun 03 21:27:18 lg1 python3[39548]:                      ^^^^^^^^^^^^
Jun 03 21:27:18 lg1 python3[39548]:   File "/opt/hyperglass/venv/lib/python3.12/site-packages/rich/traceback.py", line 489, in extract
Jun 03 21:27:18 lg1 python3[39548]:     key: pretty.traverse(
Jun 03 21:27:18 lg1 python3[39548]:          ^^^^^^^^^^^^^^^^
Jun 03 21:27:18 lg1 python3[39548]:   File "/opt/hyperglass/venv/lib/python3.12/site-packages/rich/pretty.py", line 874, in traverse
Jun 03 21:27:18 lg1 python3[39548]:     node = _traverse(_object, root=True)
Jun 03 21:27:18 lg1 python3[39548]:            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Jun 03 21:27:18 lg1 python3[39548]:   File "/opt/hyperglass/venv/lib/python3.12/site-packages/rich/pretty.py", line 667, in _traverse
Jun 03 21:27:18 lg1 python3[39548]:     args = list(iter_rich_args(rich_repr_result))
Jun 03 21:27:18 lg1 python3[39548]:            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Jun 03 21:27:18 lg1 python3[39548]:   File "/opt/hyperglass/venv/lib/python3.12/site-packages/rich/pretty.py", line 634, in iter_rich_args
Jun 03 21:27:18 lg1 python3[39548]:     for arg in rich_args:
Jun 03 21:27:18 lg1 python3[39548]:   File "/opt/hyperglass/venv/lib/python3.12/site-packages/pydantic/_internal/_repr.py", line 80, in __rich_repr__
Jun 03 21:27:18 lg1 python3[39548]:     for name, field_repr in self.__repr_args__():
Jun 03 21:27:18 lg1 python3[39548]:   File "/opt/hyperglass/venv/lib/python3.12/site-packages/pydantic/root_model.py", line 157, in __repr_args__
Jun 03 21:27:18 lg1 python3[39548]:     yield 'root', self.root
Jun 03 21:27:18 lg1 python3[39548]:                   ^^^^^^^^^
Jun 03 21:27:18 lg1 python3[39548]:   File "/opt/hyperglass/venv/lib/python3.12/site-packages/pydantic/main.py", line 991, in __getattr__
Jun 03 21:27:18 lg1 python3[39548]:     raise AttributeError(f'{type(self).__name__!r} object has no attribute {item!r}')
Jun 03 21:27:18 lg1 python3[39548]: AttributeError: 'Devices' object has no attribute 'root'
Jun 03 21:27:18 lg1 python3[39548]: Original exception was:
Jun 03 21:27:18 lg1 python3[39548]: Traceback (most recent call last):
Jun 03 21:27:18 lg1 python3[39548]:   File "<frozen runpy>", line 198, in _run_module_as_main
Jun 03 21:27:18 lg1 python3[39548]:   File "<frozen runpy>", line 88, in _run_code
Jun 03 21:27:18 lg1 python3[39548]:   File "/opt/hyperglass/hyperglass/console.py", line 8, in <module>
Jun 03 21:27:18 lg1 python3[39548]:     run()
Jun 03 21:27:18 lg1 python3[39548]:   File "/opt/hyperglass/hyperglass/cli/main.py", line 29, in run
Jun 03 21:27:18 lg1 python3[39548]:     return typer.run(cli())
Jun 03 21:27:18 lg1 python3[39548]:                      ^^^^^
Jun 03 21:27:18 lg1 python3[39548]:   File "/opt/hyperglass/venv/lib/python3.12/site-packages/typer/main.py", line 328, in __call__
Jun 03 21:27:18 lg1 python3[39548]:     raise e
Jun 03 21:27:18 lg1 python3[39548]:   File "/opt/hyperglass/venv/lib/python3.12/site-packages/typer/main.py", line 311, in __call__
Jun 03 21:27:18 lg1 python3[39548]:     return get_command(self)(*args, **kwargs)
Jun 03 21:27:18 lg1 python3[39548]:            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Jun 03 21:27:18 lg1 python3[39548]:   File "/opt/hyperglass/venv/lib/python3.12/site-packages/click/core.py", line 1442, in __call__
Jun 03 21:27:18 lg1 python3[39548]:     return self.main(*args, **kwargs)
Jun 03 21:27:18 lg1 python3[39548]:            ^^^^^^^^^^^^^^^^^^^^^^^^^^
Jun 03 21:27:18 lg1 python3[39548]:   File "/opt/hyperglass/venv/lib/python3.12/site-packages/typer/core.py", line 783, in main
Jun 03 21:27:18 lg1 python3[39548]:     return _main(
Jun 03 21:27:18 lg1 python3[39548]:            ^^^^^^
Jun 03 21:27:18 lg1 python3[39548]:   File "/opt/hyperglass/venv/lib/python3.12/site-packages/typer/core.py", line 225, in _main
Jun 03 21:27:18 lg1 python3[39548]:     rv = self.invoke(ctx)
Jun 03 21:27:18 lg1 python3[39548]:          ^^^^^^^^^^^^^^^^
Jun 03 21:27:18 lg1 python3[39548]:   File "/opt/hyperglass/venv/lib/python3.12/site-packages/click/core.py", line 1830, in invoke
Jun 03 21:27:18 lg1 python3[39548]:     return _process_result(sub_ctx.command.invoke(sub_ctx))
Jun 03 21:27:18 lg1 python3[39548]:                            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Jun 03 21:27:18 lg1 python3[39548]:   File "/opt/hyperglass/venv/lib/python3.12/site-packages/click/core.py", line 1226, in invoke
Jun 03 21:27:18 lg1 python3[39548]:     return ctx.invoke(self.callback, **ctx.params)
Jun 03 21:27:18 lg1 python3[39548]:            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Jun 03 21:27:18 lg1 python3[39548]:   File "/opt/hyperglass/venv/lib/python3.12/site-packages/click/core.py", line 794, in invoke
Jun 03 21:27:18 lg1 python3[39548]:     return callback(*args, **kwargs)
Jun 03 21:27:18 lg1 python3[39548]:            ^^^^^^^^^^^^^^^^^^^^^^^^^
Jun 03 21:27:18 lg1 python3[39548]:   File "/opt/hyperglass/venv/lib/python3.12/site-packages/typer/main.py", line 683, in wrapper
Jun 03 21:27:18 lg1 python3[39548]:     return callback(**use_params)  # type: ignore
Jun 03 21:27:18 lg1 python3[39548]:            ^^^^^^^^^^^^^^^^^^^^^^
Jun 03 21:27:18 lg1 python3[39548]:   File "/opt/hyperglass/hyperglass/cli/main.py", line 61, in _start
Jun 03 21:27:18 lg1 python3[39548]:     run(workers)
Jun 03 21:27:18 lg1 python3[39548]:   File "/opt/hyperglass/hyperglass/main.py", line 183, in run
Jun 03 21:27:18 lg1 python3[39548]:     raise error
Jun 03 21:27:18 lg1 python3[39548]:   File "/opt/hyperglass/hyperglass/main.py", line 140, in run
Jun 03 21:27:18 lg1 python3[39548]:     init_user_config()
Jun 03 21:27:18 lg1 python3[39548]:   File "/opt/hyperglass/hyperglass/configuration/__init__.py", line 41, in init_user_config
Jun 03 21:27:18 lg1 python3[39548]:     _devices = devices or init_devices()
Jun 03 21:27:18 lg1 python3[39548]:                           ^^^^^^^^^^^^^^
Jun 03 21:27:18 lg1 python3[39548]:   File "/opt/hyperglass/hyperglass/configuration/validate.py", line 105, in init_devices
Jun 03 21:27:18 lg1 python3[39548]:     devices = Devices(*items)
Jun 03 21:27:18 lg1 python3[39548]:               ^^^^^^^^^^^^^^^
Jun 03 21:27:18 lg1 python3[39548]:   File "/opt/hyperglass/hyperglass/models/config/devices.py", line 315, in __init__
Jun 03 21:27:18 lg1 python3[39548]:     super().__init__(*with_id)
Jun 03 21:27:18 lg1 python3[39548]:   File "/opt/hyperglass/hyperglass/models/main.py", line 203, in __init__
Jun 03 21:27:18 lg1 python3[39548]:     valid = self._valid_items(*items)
Jun 03 21:27:18 lg1 python3[39548]:             ^^^^^^^^^^^^^^^^^^^^^^^^^
Jun 03 21:27:18 lg1 python3[39548]:   File "/opt/hyperglass/hyperglass/models/main.py", line 305, in _valid_items
Jun 03 21:27:18 lg1 python3[39548]:     items[index] = self.model(**item)
Jun 03 21:27:18 lg1 python3[39548]:                    ^^^^^^^^^^^^^^^^^^
Jun 03 21:27:18 lg1 python3[39548]:   File "/opt/hyperglass/hyperglass/models/config/devices.py", line 78, in __init__
Jun 03 21:27:18 lg1 python3[39548]:     super().__init__(**kw)
Jun 03 21:27:18 lg1 python3[39548]:   File "/opt/hyperglass/venv/lib/python3.12/site-packages/pydantic/main.py", line 253, in __init__
Jun 03 21:27:18 lg1 python3[39548]:     validated_self = self.__pydantic_validator__.validate_python(data, self_instance=self)
Jun 03 21:27:18 lg1 python3[39548]:                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Jun 03 21:27:18 lg1 python3[39548]:   File "/opt/hyperglass/hyperglass/models/config/devices.py", line 201, in validate_avatar
Jun 03 21:27:18 lg1 python3[39548]:     device=values["name"],
Jun 03 21:27:18 lg1 python3[39548]:            ~~~~~~^^^^^^^^
Jun 03 21:27:18 lg1 python3[39548]: TypeError: 'pydantic_core._pydantic_core.ValidationInfo' object is not subscriptable

gb.png gets copied successfully to static/images

Computroniks avatar Jun 03 '25 21:06 Computroniks

I can also reproduce this issue for the address field when it is set to a hostname that is unresolvable. The issue stems from the attempt to use https://docs.pydantic.dev/latest/concepts/validators/#validation-info like a dictionary when writing to the logs.

https://github.com/thatmattlove/hyperglass/blob/15491f904b1522b639b3dc2a4b051e37b4c87bb7/hyperglass/models/config/devices.py#L171-L184

The troublesome line is 181. I am not particularly familiar with pydantic but the use of values looks like it might be a left over from v1? (current pydantic version is v2).

I will try fix this then open a PR

Computroniks avatar Jun 04 '25 12:06 Computroniks