fix: P1.4 — validateSpec() fail-fast on unknown operation kind in generator

This commit is contained in:
“Naeel”
2026-06-30 17:34:31 +04:00
parent ce28906d32
commit 0f2036f061
2 changed files with 39 additions and 2 deletions
+2
View File
@@ -49,3 +49,5 @@ __pycache__/
*.dump *.dump
*.dmp *.dmp
docs/70_api/api_analysis/*.txt docs/70_api/api_analysis/*.txt
universal_rebuild/gen_v2
universal_rebuild/docs_template_gen_v2
@@ -213,6 +213,11 @@ func loadSpecs(dir string) ([]GenResource, []GenSubresource, []GenAction, error)
return err return err
} }
// P1.4: fail-fast на неизвестных kind'ах и отсутствующих обязательных полях.
if err := validateSpec(path, &spec); err != nil {
return fmt.Errorf("%s: %w", path, err)
}
createParams := []Param{} createParams := []Param{}
modifyParams := []Param{} modifyParams := []Param{}
supportsSuspendDestroy := false supportsSuspendDestroy := false
@@ -2039,8 +2044,38 @@ func (r *{{ToCamel (printf "%s_%s" .ServiceName .ActionName)}}Resource) Configur
} }
` `
// TODO: Support import by resource_name (non-UUID) by resolving instanceUid via API. // knownKinds — допустимые значения Kind операций.
// TODO: Handle non-unique names (error or require service_id/resource_realm filter). var knownKinds = map[string]bool{
"instance": true,
"subresource": true,
"action": true,
}
// validateSpec проверяет YAML-спек на обязательные поля и неизвестные kinds.
// P1.4: fail-fast — паника при неизвестном kind вместо тихого игнорирования.
func validateSpec(path string, spec *ServiceSpec) error {
if spec.Name == "" {
return fmt.Errorf("missing required field: name")
}
if spec.ServiceID <= 0 {
return fmt.Errorf("missing required field: service_id")
}
for i, op := range spec.Operations {
if op.Kind == "" {
return fmt.Errorf("operation[%d] %q: missing required field: kind", i, op.Name)
}
if !knownKinds[op.Kind] {
return fmt.Errorf("operation[%d] %q: unknown kind %q (valid: instance, subresource, action)", i, op.Name, op.Kind)
}
if op.Action == "" {
return fmt.Errorf("operation[%d] %q (kind=%s): missing required field: action", i, op.Name, op.Kind)
}
if op.Kind == "subresource" && op.Subresource == "" {
return fmt.Errorf("operation[%d] %q (kind=subresource): missing required field: subresource", i, op.Name)
}
}
return nil
}
func buildSubresourceForceNewCodes(sr *GenSubresource, createOnly map[string]struct{}) map[string]struct{} { func buildSubresourceForceNewCodes(sr *GenSubresource, createOnly map[string]struct{}) map[string]struct{} {
forceNew := map[string]struct{}{} forceNew := map[string]struct{}{}