Skip to content

Commit 2e17ab3

Browse files
committed
Fix config import validation issues
This commit addresses two validation issues that prevented importing configuration files exported from production: 1. Export serializer converting version numbers to floats: - The _json_serializer in admin_supported_products.py was converting all Decimal types to float, including version numbers - Version numbers (match_major_version, match_minor_version) should be integers, not floats - Updated serializer to check if Decimal is a whole number and convert to int, preserving proper type semantics 2. Name validation rejecting parentheses: - Production database contains legacy products with names like "Rocky Linux 8.5 x86_64 (Legacy)" - Validation pattern only allowed: letters, numbers, spaces, dots, hyphens, and underscores - Updated NAME_PATTERN to allow parentheses for legacy product naming - Updated error message to reflect allowed characters These changes ensure that configurations exported from production can be successfully imported into development environments without manual data cleanup.
1 parent c6c9983 commit 2e17ab3

File tree

2 files changed

+7
-3
lines changed

2 files changed

+7
-3
lines changed

apollo/server/routes/admin_supported_products.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1296,6 +1296,10 @@ async def _get_mirror_config_data(mirror: SupportedProductsRhMirror) -> Dict[str
12961296
def _json_serializer(obj):
12971297
"""Custom JSON serializer for non-standard types"""
12981298
if isinstance(obj, Decimal):
1299+
# Convert Decimal to int for version numbers (which should be integers)
1300+
# Check if it's a whole number to preserve integer type
1301+
if obj % 1 == 0:
1302+
return int(obj)
12991303
return float(obj)
13001304
raise TypeError(f"Object of type {obj.__class__.__name__} is not JSON serializable")
13011305

apollo/server/validation.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,8 @@ class ValidationPatterns:
6060
# URL validation - must start with http:// or https://
6161
URL_PATTERN = re.compile(r"^https?://.+")
6262

63-
# Name patterns - alphanumeric with common special characters and spaces
64-
NAME_PATTERN = re.compile(r"^[a-zA-Z0-9._\s-]+$")
63+
# Name patterns - alphanumeric with common special characters, spaces, and parentheses
64+
NAME_PATTERN = re.compile(r"^[a-zA-Z0-9._\s()\-]+$")
6565

6666
# Architecture validation
6767
ARCH_PATTERN = re.compile(r"^(x86_64|aarch64|i386|i686|ppc64|ppc64le|s390x|riscv64|noarch)$")
@@ -107,7 +107,7 @@ def validate_name(name: str, min_length: int = 3, field_name: str = "name") -> s
107107

108108
if not ValidationPatterns.NAME_PATTERN.match(trimmed_name):
109109
raise ValidationError(
110-
f"{field_name.title()} can only contain letters, numbers, spaces, dots, hyphens, and underscores",
110+
f"{field_name.title()} can only contain letters, numbers, spaces, dots, hyphens, underscores, and parentheses",
111111
ValidationErrorType.INVALID_FORMAT,
112112
field_name,
113113
)

0 commit comments

Comments
 (0)