Исправлены ошибки, выявленные на тесте инфраструктуры

This commit is contained in:
mi
2026-07-15 13:18:30 +03:00
parent 6d1cb3d6d9
commit caf6bf0516
8 changed files with 137 additions and 19 deletions
+22 -9
View File
@@ -93,6 +93,15 @@ def sanitize(value: Any) -> str:
return text[:1000]
def virtual_hosted_bucket_url(endpoint: str, bucket: str, key: str = "") -> str:
"""Собирает vHosted URL бакета для CORS preflight (Selectel не поддерживает CORS на path-style)."""
parsed = urlsplit(endpoint.rstrip("/"))
if parsed.scheme not in {"http", "https"} or not parsed.netloc:
raise ConfigError("SELECTEL_S3_ENDPOINT_URL должен быть абсолютным https URL")
path = f"/{key.lstrip('/')}" if key else "/"
return urlunsplit((parsed.scheme, f"{bucket}.{parsed.netloc}", path, "", ""))
def require(values: dict[str, str], name: str) -> str:
value = values.get(name, "").strip()
if not value:
@@ -288,6 +297,7 @@ class InfraTest:
connect_timeout=self.settings.timeout_seconds,
read_timeout=self.settings.timeout_seconds,
retries={"max_attempts": 2},
s3={"addressing_style": "virtual"},
),
}
if self.settings.s3_region:
@@ -742,14 +752,12 @@ class InfraTest:
return "GET quarantine разрешён; запись, удаление и другие бакеты запрещены"
def _check_cors(self, key: str) -> str:
url = self.api_s3.generate_presigned_url(
"put_object",
Params={
"Bucket": self.settings.buckets["quarantine"],
"Key": key,
"ContentType": "application/octet-stream",
},
ExpiresIn=300,
# Selectel обрабатывает CORS только на vHosted URL; path-style presigned URL
# возвращает 405 даже при корректной конфигурации бакета.
url = virtual_hosted_bucket_url(
self.settings.s3_endpoint,
self.settings.buckets["quarantine"],
key,
)
response = requests.options(
url,
@@ -771,7 +779,12 @@ class InfraTest:
allow_methods = response.headers.get("Access-Control-Allow-Methods", "")
if "PUT" not in allow_methods.upper():
raise AssertionError("CORS не разрешает PUT")
return "CORS разрешает presigned PUT только с PUBLIC_WEB_URL"
allow_headers = response.headers.get("Access-Control-Allow-Headers", "")
if "content-type" not in allow_headers.lower():
raise AssertionError(
f"CORS не разрешает content-type: {allow_headers!r}"
)
return "CORS разрешает PUT с PUBLIC_WEB_URL через vHosted URL"
def _cleanup(self) -> None:
failures: list[str] = []