mirror of
https://github.com/tiennm99/coolify.git
synced 2026-04-17 17:21:04 +00:00
feat: add YAML validation for cloud-init scripts
Add ValidCloudInitYaml validation rule to ensure cloud-init scripts are properly formatted before saving. The validator supports: - Cloud-config YAML (with or without #cloud-config header) - Bash scripts (starting with #!) - Empty/null values (optional field) Uses Symfony YAML parser to validate YAML syntax and provides detailed error messages when validation fails. Added comprehensive unit tests covering: - Valid cloud-config with/without header - Valid bash scripts - Invalid YAML syntax detection - Complex multi-section cloud-config Applied validation to: - ByHetzner component (server creation) - CloudInitScriptForm component (script management) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
55
app/Rules/ValidCloudInitYaml.php
Normal file
55
app/Rules/ValidCloudInitYaml.php
Normal file
@@ -0,0 +1,55 @@
|
||||
<?php
|
||||
|
||||
namespace App\Rules;
|
||||
|
||||
use Closure;
|
||||
use Illuminate\Contracts\Validation\ValidationRule;
|
||||
use Symfony\Component\Yaml\Exception\ParseException;
|
||||
use Symfony\Component\Yaml\Yaml;
|
||||
|
||||
class ValidCloudInitYaml implements ValidationRule
|
||||
{
|
||||
/**
|
||||
* Run the validation rule.
|
||||
*
|
||||
* Validates that the cloud-init script is either:
|
||||
* - Valid YAML format (for cloud-config)
|
||||
* - Valid bash script (starting with #!)
|
||||
* - Empty/null (optional field)
|
||||
*/
|
||||
public function validate(string $attribute, mixed $value, Closure $fail): void
|
||||
{
|
||||
if (empty($value)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$script = trim($value);
|
||||
|
||||
// If it's a bash script (starts with shebang), skip YAML validation
|
||||
if (str_starts_with($script, '#!')) {
|
||||
return;
|
||||
}
|
||||
|
||||
// If it's a cloud-config file (starts with #cloud-config), validate YAML
|
||||
if (str_starts_with($script, '#cloud-config')) {
|
||||
// Remove the #cloud-config header and validate the rest as YAML
|
||||
$yamlContent = preg_replace('/^#cloud-config\s*/m', '', $script, 1);
|
||||
|
||||
try {
|
||||
Yaml::parse($yamlContent);
|
||||
} catch (ParseException $e) {
|
||||
$fail('The :attribute must be valid YAML format. Error: '.$e->getMessage());
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// If it doesn't start with #! or #cloud-config, try to parse as YAML
|
||||
// (some users might omit the #cloud-config header)
|
||||
try {
|
||||
Yaml::parse($script);
|
||||
} catch (ParseException $e) {
|
||||
$fail('The :attribute must be either a valid bash script (starting with #!) or valid cloud-config YAML. YAML parse error: '.$e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user