Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 19 additions & 18 deletions controller/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -218,24 +218,22 @@ def validate_guardrails_v03(breeder_config):
)

# Validate reconnaissance fields
required_recon_fields = ['service', 'query']
required_recon_fields = ['service']
missing_fields = [f for f in required_recon_fields if f not in recon]

if missing_fields:
raise ValueError(
f"Guardrail {idx} ({guardrail['name']}): 'reconnaissance' missing required fields: {', '.join(missing_fields)}"
)

# Validate service type
valid_services = ['prometheus'] # Extend as needed
valid_services = ['prometheus', 'http']
if recon['service'] not in valid_services:
raise ValueError(
f"Guardrail {idx} ({guardrail['name']}): service '{recon['service']}' not supported. "
f"Valid services: {', '.join(valid_services)}"
)

# Validate query is string
if not isinstance(recon['query'], str) or recon['query'].strip() == "":
if 'query' in recon and (not isinstance(recon['query'], str) or recon['query'].strip() == ""):
raise ValueError(
f"Guardrail {idx} ({guardrail['name']}): 'query' must be a non-empty string"
)
Expand All @@ -254,7 +252,7 @@ def validate_guardrails_v03(breeder_config):
)

if 'interval' in recon:
if not isinstance(recon['interval'], int) or recon['interval'] < 1:
if not isinstance(recon['interval'], (int, float)) or recon['interval'] < 0:
raise ValueError(
f"Guardrail {idx} ({guardrail['name']}): 'interval' must be an integer >= 1"
)
Expand Down Expand Up @@ -459,18 +457,19 @@ def validate_minimal(breeder_config, strict_mode=True):
"Example: effectuation: {targetRefs: ['my-server', '550e8400-...']}"
)

# Support multiple settings categories (sysctl, sysfs, cpufreq, ethtool)
# Strain-specific validation: settings and recon constraints are strain-dependent.
# For unknown/non-linux_performance strains, skip domain validation and rely on preflight.
breeder_type = breeder_config.get('breeder', {}).get('type', '')
supported_categories = ['sysctl', 'sysfs', 'cpufreq', 'ethtool']
settings = breeder_config.get('settings', {})

# Check if at least one supported category exists
has_any_category = any(category in settings for category in supported_categories)

if not has_any_category:
errors.append(
f"Missing settings configuration. "
f"At least one category required: {', '.join(supported_categories)}"
)
if breeder_type == 'linux_performance':
has_any_category = any(category in settings for category in supported_categories)
if not has_any_category:
errors.append(
f"Missing settings configuration. "
f"At least one category required: {', '.join(supported_categories)}"
)

# Validate constraints structure for all present categories
for category in supported_categories:
Expand Down Expand Up @@ -589,7 +588,9 @@ def validate_minimal(breeder_config, strict_mode=True):
continue

# Check required fields
required_recon_fields = ['service', 'query']
required_recon_fields = ['service']
if breeder_type == 'linux_performance':
required_recon_fields.append('query')
missing_fields = [f for f in required_recon_fields if f not in recon]

if missing_fields:
Expand All @@ -601,7 +602,7 @@ def validate_minimal(breeder_config, strict_mode=True):

# Validate service type
if 'service' in recon:
valid_services = ['prometheus'] # Extend as needed
valid_services = ['prometheus', 'http']
if recon['service'] not in valid_services:
obj_name = objective.get('name', f'#{idx}')
errors.append(
Expand Down Expand Up @@ -633,7 +634,7 @@ def validate_minimal(breeder_config, strict_mode=True):
)

if 'interval' in recon:
if not isinstance(recon['interval'], int) or recon['interval'] < 1:
if not isinstance(recon['interval'], (int, float)) or recon['interval'] < 0:
obj_name = objective.get('name', f'#{idx}')
errors.append(
f"Objective {idx} ({obj_name}): 'interval' must be an integer >= 1"
Expand Down
Loading