feat: add NetBox plugin store
This commit is contained in:
@@ -0,0 +1,57 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import re
|
||||
from urllib.parse import urlsplit
|
||||
|
||||
from packaging.utils import canonicalize_name
|
||||
|
||||
|
||||
SLUG_RE = re.compile(r"^[a-z0-9](?:[a-z0-9-]{0,62}[a-z0-9])?$")
|
||||
DISTRIBUTION_RE = re.compile(r"^[A-Za-z0-9](?:[A-Za-z0-9._-]{0,126}[A-Za-z0-9])?$")
|
||||
IMPORT_RE = re.compile(r"^[A-Za-z_][A-Za-z0-9_]{0,127}$")
|
||||
SHA256_RE = re.compile(r"^[a-fA-F0-9]{64}$")
|
||||
|
||||
SELF_IMPORT_NAME = "netbox_plugin_store"
|
||||
SELF_DISTRIBUTION_NAME = canonicalize_name("netbox-plugin-store")
|
||||
|
||||
|
||||
class ValidationError(ValueError):
|
||||
pass
|
||||
|
||||
|
||||
def validate_slug(value: str) -> str:
|
||||
if not isinstance(value, str) or not SLUG_RE.fullmatch(value):
|
||||
raise ValidationError("Invalid plugin slug.")
|
||||
return value
|
||||
|
||||
|
||||
def validate_distribution_name(value: str) -> str:
|
||||
if not isinstance(value, str) or not DISTRIBUTION_RE.fullmatch(value):
|
||||
raise ValidationError("Invalid Python distribution name.")
|
||||
return value
|
||||
|
||||
|
||||
def validate_import_name(value: str) -> str:
|
||||
if not isinstance(value, str) or not IMPORT_RE.fullmatch(value):
|
||||
raise ValidationError("Invalid Python import name.")
|
||||
return value
|
||||
|
||||
|
||||
def validate_sha256(value: str) -> str:
|
||||
if not isinstance(value, str) or not SHA256_RE.fullmatch(value):
|
||||
raise ValidationError("Invalid SHA-256 digest.")
|
||||
return value.lower()
|
||||
|
||||
|
||||
def ensure_not_self(package_name: str, import_name: str) -> None:
|
||||
if canonicalize_name(package_name) == SELF_DISTRIBUTION_NAME or import_name == SELF_IMPORT_NAME:
|
||||
raise ValidationError("The Plugin Store cannot manage its own lifecycle.")
|
||||
|
||||
|
||||
def validate_public_url(value: str) -> str:
|
||||
parsed = urlsplit(value)
|
||||
if parsed.scheme not in {"https", "http"} or not parsed.hostname:
|
||||
raise ValidationError("URL must be an absolute HTTP(S) URL.")
|
||||
if parsed.username is not None or parsed.password is not None:
|
||||
raise ValidationError("URLs containing credentials are not accepted.")
|
||||
return value
|
||||
Reference in New Issue
Block a user