refactor(util): move is_ipv4_literal out of pipelock.py into util.py
test / run tests/run_tests.py (pull_request) Successful in 25s
test / run tests/run_tests.py (pull_request) Successful in 25s
The classifier is a pure dotted-quad regex check — nothing pipelock-specific about it. Pipelock now imports it from util. test_pipelock_classify.py retargets at the new location. Two manifest-accessor functions in pipelock.py (pipelock_bottle_allowlist, pipelock_bottle_ssh_hostnames) look generic but are 1-line wrappers used only internally; they stay for now.
This commit is contained in:
@@ -13,13 +13,13 @@ Image pin: ghcr.io/luckypipewrench/pipelock@sha256:<digest> for tag 2.3.0.
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
import re
|
||||
import subprocess
|
||||
from dataclasses import dataclass
|
||||
from pathlib import Path
|
||||
|
||||
from .log import die, info, warn
|
||||
from .manifest import Manifest
|
||||
from .util import is_ipv4_literal
|
||||
|
||||
# Pipelock image, pinned by digest. The digest is the multi-arch image
|
||||
# index for ghcr.io/luckypipewrench/pipelock:2.3.0.
|
||||
@@ -67,18 +67,6 @@ def pipelock_bottle_ssh_hostnames(manifest: Manifest, bottle_name: str) -> list[
|
||||
return [e.Hostname for e in manifest.bottles[bottle_name].ssh if e.Hostname]
|
||||
|
||||
|
||||
_IPV4_RE = re.compile(r"^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$")
|
||||
|
||||
|
||||
def is_ipv4_literal(s: str) -> bool:
|
||||
"""Pipelock's SSRF check fires on resolved IP, so an IP-literal
|
||||
Hostname goes to ssrf.ip_allowlist while a hostname goes to
|
||||
trusted_domains."""
|
||||
if not s:
|
||||
return False
|
||||
return bool(_IPV4_RE.match(s))
|
||||
|
||||
|
||||
def pipelock_bottle_ssh_trusted_domains(manifest: Manifest, bottle_name: str) -> list[str]:
|
||||
return [h for h in pipelock_bottle_ssh_hostnames(manifest, bottle_name) if not is_ipv4_literal(h)]
|
||||
|
||||
|
||||
Reference in New Issue
Block a user