Compare commits

..

No commits in common. "main" and "v0.1.5" have entirely different histories.
main ... v0.1.5

7 changed files with 61 additions and 53 deletions

View file

@ -1 +0,0 @@
.venv

View file

@ -1,17 +0,0 @@
# GenieACS COmmander
[GenieACS](https://github.com/genieacs/genieacs) is an open source TR-069
management tool for remote control (provisioning, configuration, etc)
of various devices. This includes notably end user routers, aka. *boxes*.
> GenieACS is a high performance Auto Configuration Server (ACS) for remote management
> of TR-069 enabled devices. It utilizes a declarative and fault tolerant
> configuration engine for automating complex provisioning scenarios at scale.
> It's battle-tested to handle hundreds of thousands and potentially millions
> of concurrent devices.
This tool provides:
* command line utility
* list devices
* ... *more to come* ...

View file

@ -6,9 +6,8 @@ readme = "README.md"
requires-python = ">=3.13" requires-python = ">=3.13"
dependencies = [ dependencies = [
"httpx>=0.28.1", "httpx>=0.28.1",
"netaddr>=1.3.0",
"pydantic-settings[yaml]>=2.9.1", "pydantic-settings[yaml]>=2.9.1",
"typer-slim>=0.15.4", "typer>=0.15.3",
] ]
[dependency-groups] [dependency-groups]

View file

@ -1,16 +1,16 @@
from typing import Type, Tuple from typing import Any, Type, Tuple
from pathlib import Path from pathlib import Path
from pydantic import BaseModel from pydantic import BaseModel
from pydantic_settings import ( from pydantic_settings import (
BaseSettings, BaseSettings,
# SecretsSettingsSource, SecretsSettingsSource,
SettingsConfigDict, SettingsConfigDict,
PydanticBaseSettingsSource, PydanticBaseSettingsSource,
YamlConfigSettingsSource, YamlConfigSettingsSource,
) )
config_files = [Path(Path.cwd().root) / "etc" / "gacsco" / "congig.yaml"] config_files = [Path(Path.cwd().root) / "etc" / "acsc" / "congig.yaml"]
class Connection(BaseModel): class Connection(BaseModel):

View file

@ -3,6 +3,7 @@ from typing_extensions import Annotated
from json import dumps from json import dumps
import typer import typer
from rich import print as pprint
from gacsco.server import Server from gacsco.server import Server
from gacsco.utils import AsyncTyper, GacscoError from gacsco.utils import AsyncTyper, GacscoError
@ -18,11 +19,11 @@ async def main(name: Annotated[str | None, typer.Option(help="Your name")] = Non
... ...
# await server.login() # await server.login()
except GacscoError as err: except GacscoError as err:
typer.echo(err) pprint(err)
sys.exit(1) sys.exit(1)
if name is not None: if name is not None:
typer.echo(f"Hello {name} from genieacs-commander!") pprint(f"Hello {name} from genieacs-commander!")
@app.command(help="List devices") @app.command(help="List devices")
@ -31,7 +32,7 @@ async def list():
resp = await server.list_devices() resp = await server.list_devices()
print(dumps(resp)) print(dumps(resp))
except GacscoError as err: except GacscoError as err:
typer.echo(err) pprint(err)
@app.command(help="Reset the device") @app.command(help="Reset the device")
@ -39,15 +40,12 @@ def reset(): ...
@app.command(help="Get info on the device") @app.command(help="Get info on the device")
async def info( async def info(device_id: Annotated[str, typer.Argument()]):
device_id: Annotated[str, typer.Argument(help="device_id or WAN MAC address")],
):
"""Get device info, from its device_id or WAN interface MAC address"""
try: try:
resp = await server.get_device_info(device_id) resp = await server.get_device_info(device_id)
print(dumps(resp)) print(dumps(resp))
except GacscoError as err: except GacscoError as err:
typer.echo(err) pprint(err)
app() app()

View file

@ -1,9 +1,11 @@
from dataclasses import dataclass
from json import dumps from json import dumps
from urllib.parse import quote
import httpx import httpx
from netaddr import EUI, AddrFormatError
from gacsco.config import conf from gacsco.config import conf
from gacsco.utils import GacscoError
class LoginError(Exception): class LoginError(Exception):
@ -39,15 +41,8 @@ class Server:
return resp.json() return resp.json()
async def get_device_info(self, device_id: str): async def get_device_info(self, device_id: str):
try:
EUI(device_id)
except AddrFormatError:
query = {"_id": device_id}
else:
query = {
"InternetGatewayDevice.WANDevice.1.WANConnectionDevice.1.WANIPConnection.1.MACAddress": device_id
}
async with httpx.AsyncClient(cookies=self.cookies) as client: async with httpx.AsyncClient(cookies=self.cookies) as client:
query = {"_id": device_id}
resp = await client.get( resp = await client.get(
f"{self.url}/devices/?", f"{self.url}/devices/?",
params={"query": dumps(query)}, params={"query": dumps(query)},

60
uv.lock generated
View file

@ -94,13 +94,12 @@ wheels = [
] ]
[[package]] [[package]]
name = "gacsco" name = "genieacs-commander"
source = { editable = "." } source = { editable = "." }
dependencies = [ dependencies = [
{ name = "httpx" }, { name = "httpx" },
{ name = "netaddr" },
{ name = "pydantic-settings", extra = ["yaml"] }, { name = "pydantic-settings", extra = ["yaml"] },
{ name = "typer-slim" }, { name = "typer" },
] ]
[package.dev-dependencies] [package.dev-dependencies]
@ -112,9 +111,8 @@ dev = [
[package.metadata] [package.metadata]
requires-dist = [ requires-dist = [
{ name = "httpx", specifier = ">=0.28.1" }, { name = "httpx", specifier = ">=0.28.1" },
{ name = "netaddr", specifier = ">=1.3.0" },
{ name = "pydantic-settings", extras = ["yaml"], specifier = ">=2.9.1" }, { name = "pydantic-settings", extras = ["yaml"], specifier = ">=2.9.1" },
{ name = "typer-slim", specifier = ">=0.15.4" }, { name = "typer", specifier = ">=0.15.3" },
] ]
[package.metadata.requires-dev] [package.metadata.requires-dev]
@ -227,6 +225,18 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/c0/5a/9cac0c82afec3d09ccd97c8b6502d48f165f9124db81b4bcb90b4af974ee/jedi-0.19.2-py2.py3-none-any.whl", hash = "sha256:a8ef22bde8490f57fe5c7681a3c83cb58874daf72b4784de3cce5b6ef6edb5b9", size = 1572278, upload-time = "2024-11-11T01:41:40.175Z" }, { url = "https://files.pythonhosted.org/packages/c0/5a/9cac0c82afec3d09ccd97c8b6502d48f165f9124db81b4bcb90b4af974ee/jedi-0.19.2-py2.py3-none-any.whl", hash = "sha256:a8ef22bde8490f57fe5c7681a3c83cb58874daf72b4784de3cce5b6ef6edb5b9", size = 1572278, upload-time = "2024-11-11T01:41:40.175Z" },
] ]
[[package]]
name = "markdown-it-py"
version = "3.0.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "mdurl" },
]
sdist = { url = "https://files.pythonhosted.org/packages/38/71/3b932df36c1a044d397a1f92d1cf91ee0a503d91e470cbd670aa66b07ed0/markdown-it-py-3.0.0.tar.gz", hash = "sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb", size = 74596, upload-time = "2023-06-03T06:41:14.443Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/42/d7/1ec15b46af6af88f19b8e5ffea08fa375d433c998b8a7639e76935c14f1f/markdown_it_py-3.0.0-py3-none-any.whl", hash = "sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1", size = 87528, upload-time = "2023-06-03T06:41:11.019Z" },
]
[[package]] [[package]]
name = "matplotlib-inline" name = "matplotlib-inline"
version = "0.1.7" version = "0.1.7"
@ -240,12 +250,12 @@ wheels = [
] ]
[[package]] [[package]]
name = "netaddr" name = "mdurl"
version = "1.3.0" version = "0.1.2"
source = { registry = "https://pypi.org/simple" } source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/54/90/188b2a69654f27b221fba92fda7217778208532c962509e959a9cee5229d/netaddr-1.3.0.tar.gz", hash = "sha256:5c3c3d9895b551b763779ba7db7a03487dc1f8e3b385af819af341ae9ef6e48a", size = 2260504, upload-time = "2024-05-28T21:30:37.743Z" } sdist = { url = "https://files.pythonhosted.org/packages/d6/54/cfe61301667036ec958cb99bd3efefba235e65cdeb9c84d24a8293ba1d90/mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba", size = 8729, upload-time = "2022-08-14T12:40:10.846Z" }
wheels = [ wheels = [
{ url = "https://files.pythonhosted.org/packages/12/cc/f4fe2c7ce68b92cbf5b2d379ca366e1edae38cccaad00f69f529b460c3ef/netaddr-1.3.0-py3-none-any.whl", hash = "sha256:c2c6a8ebe5554ce33b7d5b3a306b71bbb373e000bbbf2350dd5213cc56e3dbbe", size = 2262023, upload-time = "2024-05-28T21:30:34.191Z" }, { url = "https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8", size = 9979, upload-time = "2022-08-14T12:40:09.779Z" },
] ]
[[package]] [[package]]
@ -405,6 +415,28 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/fa/de/02b54f42487e3d3c6efb3f89428677074ca7bf43aae402517bc7cca949f3/PyYAML-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563", size = 156446, upload-time = "2024-08-06T20:33:04.33Z" }, { url = "https://files.pythonhosted.org/packages/fa/de/02b54f42487e3d3c6efb3f89428677074ca7bf43aae402517bc7cca949f3/PyYAML-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563", size = 156446, upload-time = "2024-08-06T20:33:04.33Z" },
] ]
[[package]]
name = "rich"
version = "14.0.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "markdown-it-py" },
{ name = "pygments" },
]
sdist = { url = "https://files.pythonhosted.org/packages/a1/53/830aa4c3066a8ab0ae9a9955976fb770fe9c6102117c8ec4ab3ea62d89e8/rich-14.0.0.tar.gz", hash = "sha256:82f1bc23a6a21ebca4ae0c45af9bdbc492ed20231dcb63f297d6d1021a9d5725", size = 224078, upload-time = "2025-03-30T14:15:14.23Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/0d/9b/63f4c7ebc259242c89b3acafdb37b41d1185c07ff0011164674e9076b491/rich-14.0.0-py3-none-any.whl", hash = "sha256:1c9491e1951aac09caffd42f448ee3d04e58923ffe14993f6e83068dc395d7e0", size = 243229, upload-time = "2025-03-30T14:15:12.283Z" },
]
[[package]]
name = "shellingham"
version = "1.5.4"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/58/15/8b3609fd3830ef7b27b655beb4b4e9c62313a4e8da8c676e142cc210d58e/shellingham-1.5.4.tar.gz", hash = "sha256:8dbca0739d487e5bd35ab3ca4b36e11c4078f3a234bfce294b0a0291363404de", size = 10310, upload-time = "2023-10-24T04:13:40.426Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/e0/f9/0595336914c5619e5f28a1fb793285925a8cd4b432c9da0a987836c7f822/shellingham-1.5.4-py2.py3-none-any.whl", hash = "sha256:7ecfff8f2fd72616f7481040475a65b2bf8af90a56c89140852d1120324e8686", size = 9755, upload-time = "2023-10-24T04:13:38.866Z" },
]
[[package]] [[package]]
name = "sniffio" name = "sniffio"
version = "1.3.1" version = "1.3.1"
@ -438,16 +470,18 @@ wheels = [
] ]
[[package]] [[package]]
name = "typer-slim" name = "typer"
version = "0.15.4" version = "0.15.3"
source = { registry = "https://pypi.org/simple" } source = { registry = "https://pypi.org/simple" }
dependencies = [ dependencies = [
{ name = "click" }, { name = "click" },
{ name = "rich" },
{ name = "shellingham" },
{ name = "typing-extensions" }, { name = "typing-extensions" },
] ]
sdist = { url = "https://files.pythonhosted.org/packages/a0/75/fb85e49851d127316f30b7f6001fa0d378c14afdac280dace89d49992518/typer_slim-0.15.4.tar.gz", hash = "sha256:1d9fe638da58f4bdeae891512c47ed83915f81e7a0ee062cf6c572ff38473128", size = 101615, upload-time = "2025-05-14T16:35:00.566Z" } sdist = { url = "https://files.pythonhosted.org/packages/98/1a/5f36851f439884bcfe8539f6a20ff7516e7b60f319bbaf69a90dc35cc2eb/typer-0.15.3.tar.gz", hash = "sha256:818873625d0569653438316567861899f7e9972f2e6e0c16dab608345ced713c", size = 101641, upload-time = "2025-04-28T21:40:59.204Z" }
wheels = [ wheels = [
{ url = "https://files.pythonhosted.org/packages/b6/7f/44304801838529b1051e00fb30e1750cacd10da31da1f3b0fa0e96ae6045/typer_slim-0.15.4-py3-none-any.whl", hash = "sha256:6d134e1b048da37ceacc1ccc3ad28a6f966c8f0833cc1513cf12a21de0da8ed8", size = 45315, upload-time = "2025-05-14T16:34:59.053Z" }, { url = "https://files.pythonhosted.org/packages/48/20/9d953de6f4367163d23ec823200eb3ecb0050a2609691e512c8b95827a9b/typer-0.15.3-py3-none-any.whl", hash = "sha256:c86a65ad77ca531f03de08d1b9cb67cd09ad02ddddf4b34745b5008f43b239bd", size = 45253, upload-time = "2025-04-28T21:40:56.269Z" },
] ]
[[package]] [[package]]