feat: поддержка Go и npm экосистем

- setup-nexus.sh: создание go-proxy (proxy.golang.org) и npm-proxy (registry.npmjs.org)
- nexus_client.py: extract_go_info() и extract_npm_info() для парсинга путей
  Go:  packages/github.com/gorilla/mux/@v/v1.8.0.zip → name=github.com/gorilla/mux ver=v1.8.0
  npm: packages/lodash/-/lodash-4.17.21.tgz → name=lodash ver=4.17.21
- nexus_client.py: EXTRACTORS dict + extract_package_info() универсальный extractor
- webhooks.py: _detect_ecosystem() — определяет экосистему из asset.format
- harvester.py: использует extract_package_info() вместо extract_pypi_info()
- Всё в Docker-контейнере, на хосте ничего не ставится
- GuardDog поддерживает go и npm из коробки
This commit is contained in:
Marker689
2026-05-10 06:29:34 +03:00
parent 646a50d01a
commit 6523f55dcd
5 changed files with 134 additions and 40 deletions

View File

@@ -49,6 +49,18 @@ def _extract_asset_path(asset: dict) -> str | None:
return None
def _detect_ecosystem(source: dict) -> str:
"""Detect ecosystem from asset or component format field."""
fmt = source.get("format", "").lower()
if fmt in ("pypi", "pip", "python"):
return "pypi"
if fmt in ("go", "golang"):
return "go"
if fmt in ("npm", "node"):
return "npm"
return fmt or DEFAULT_ECOSYSTEM
@router.post("/nexus")
async def nexus_webhook(
request: Request,
@@ -96,11 +108,12 @@ async def nexus_webhook(
download_url = asset.get("downloadUrl") or _build_download_url(
repository, asset_path
)
ecosystem = _detect_ecosystem(asset)
log.info("Webhook: %s asset %s in %s", action, asset_path, repository)
log.info("Webhook: %s asset %s (%s) in %s", action, asset_path, ecosystem, repository)
background_tasks.add_task(
_scan_in_background, download_url, repository, DEFAULT_ECOSYSTEM, asset_path
_scan_in_background, download_url, repository, ecosystem, asset_path
)
return {"status": WEBHOOK_STATUS_ACCEPTED, "asset": asset_path, "action": action}
@@ -113,7 +126,8 @@ async def nexus_webhook(
"reason": WEBHOOK_IGNORE_NO_NAME_OR_VERSION,
}
background_tasks.add_task(_scan_component, repository, name, version)
ecosystem = _detect_ecosystem(component)
background_tasks.add_task(_scan_component, repository, name, version, ecosystem)
return {
"status": WEBHOOK_STATUS_ACCEPTED,
"component": f"{name}=={version}",
@@ -126,12 +140,12 @@ async def nexus_webhook(
}
async def _scan_component(repository: str, name: str, version: str):
async def _scan_component(repository: str, name: str, version: str, ecosystem: str):
from guarddog_nexus.nexus_client import nexus_get
api_path = (
f"/service/rest/v1/search"
f"?repository={repository}&name={name}&version={version}&format={DEFAULT_ECOSYSTEM}"
f"?repository={repository}&name={name}&version={version}&format={ecosystem}"
)
try:
resp = await nexus_get(api_path)
@@ -157,7 +171,7 @@ async def _scan_component(repository: str, name: str, version: str):
log.info("Scanning component asset: %s", asset_path)
async for session in get_session():
await harvest(
download_url, repository, DEFAULT_ECOSYSTEM, asset_path, session
download_url, repository, ecosystem, asset_path, session
)
break