|
16 | 16 | package policydevel |
17 | 17 |
|
18 | 18 | import ( |
19 | | - "bytes" |
20 | 19 | "context" |
21 | 20 | "embed" |
22 | 21 | "errors" |
@@ -123,8 +122,7 @@ func Lookup(absPath, config string, format bool) (*PolicyToLint, error) { |
123 | 122 | return policy, nil |
124 | 123 | } |
125 | 124 |
|
126 | | -// Loads referenced rego files from all YAML files in the policy |
127 | | -// Loads referenced rego files from all YAML files in the policy |
| 125 | +// Loads referenced rego files from YAML files in the policy |
128 | 126 | func (p *PolicyToLint) loadReferencedRegoFiles(baseDir string) error { |
129 | 127 | seen := make(map[string]struct{}) |
130 | 128 | for _, yamlFile := range p.YAMLFiles { |
@@ -184,77 +182,12 @@ func (p *PolicyToLint) processFile(filePath string) error { |
184 | 182 | } |
185 | 183 |
|
186 | 184 | func (p *PolicyToLint) Validate() { |
187 | | - // Validate all YAML files (including their embedded policies) |
188 | | - for _, yamlFile := range p.YAMLFiles { |
189 | | - p.validateYAMLFile(yamlFile) |
190 | | - } |
191 | | - |
192 | 185 | // Validate standalone rego files |
193 | 186 | for _, regoFile := range p.RegoFiles { |
194 | 187 | p.validateRegoFile(regoFile) |
195 | 188 | } |
196 | 189 | } |
197 | 190 |
|
198 | | -func (p *PolicyToLint) validateYAMLFile(file *File) { |
199 | | - var policy v1.Policy |
200 | | - if err := unmarshal.FromRaw(file.Content, unmarshal.RawFormatYAML, &policy, true); err != nil { |
201 | | - p.AddError(file.Path, "failed to parse/validate policy", 0) |
202 | | - return |
203 | | - } |
204 | | - |
205 | | - p.processEmbeddedPolicies(&policy, file) |
206 | | - |
207 | | - // Update policy file with formatted content |
208 | | - if p.Format { |
209 | | - var root yaml.Node |
210 | | - if err := yaml.Unmarshal(file.Content, &root); err != nil { |
211 | | - p.AddError(file.Path, "failed to parse YAML", 0) |
212 | | - return |
213 | | - } |
214 | | - |
215 | | - if err := p.updateEmbeddedRegoInYAML(file, &root); err != nil { |
216 | | - p.AddError(file.Path, fmt.Sprintf("failed to update embedded Rego: %v", err), 0) |
217 | | - return |
218 | | - } |
219 | | - |
220 | | - var buf bytes.Buffer |
221 | | - enc := yaml.NewEncoder(&buf) |
222 | | - enc.SetIndent(2) |
223 | | - defer enc.Close() |
224 | | - |
225 | | - if err := enc.Encode(&root); err != nil { |
226 | | - p.AddError(file.Path, err.Error(), 0) |
227 | | - return |
228 | | - } |
229 | | - |
230 | | - outYAML := buf.Bytes() |
231 | | - if err := os.WriteFile(file.Path, outYAML, 0600); err != nil { |
232 | | - p.AddError(file.Path, err.Error(), 0) |
233 | | - } else { |
234 | | - if err := os.WriteFile(file.Path, outYAML, 0600); err != nil { |
235 | | - p.AddError(file.Path, fmt.Sprintf("failed to save updated file: %v", err), 0) |
236 | | - } else { |
237 | | - file.Content = outYAML |
238 | | - } |
239 | | - } |
240 | | - } |
241 | | -} |
242 | | - |
243 | | -func (p *PolicyToLint) processEmbeddedPolicies(pa *v1.Policy, file *File) { |
244 | | - for idx, spec := range pa.Spec.Policies { |
245 | | - if regoSrc := spec.GetEmbedded(); regoSrc != "" { |
246 | | - formatted := p.validateAndFormatRego( |
247 | | - regoSrc, |
248 | | - fmt.Sprintf("%s:(embedded #%d)", file.Path, idx+1), |
249 | | - ) |
250 | | - |
251 | | - if p.Format && formatted != regoSrc { |
252 | | - spec.Source = &v1.PolicySpecV2_Embedded{Embedded: formatted} |
253 | | - } |
254 | | - } |
255 | | - } |
256 | | -} |
257 | | - |
258 | 191 | func (p *PolicyToLint) validateRegoFile(file *File) { |
259 | 192 | original := string(file.Content) |
260 | 193 | formatted := p.validateAndFormatRego(original, file.Path) |
@@ -435,64 +368,6 @@ func (p *PolicyToLint) loadDefaultConfig() (*config.Config, error) { |
435 | 368 | return &cfg, nil |
436 | 369 | } |
437 | 370 |
|
438 | | -// Updates the embedded rego policies in a YAML file |
439 | | -// Manual update required due to yaml.marshal limitations |
440 | | -func (p *PolicyToLint) updateEmbeddedRegoInYAML(file *File, rootNode *yaml.Node) error { |
441 | | - if rootNode.Kind != yaml.DocumentNode || len(rootNode.Content) == 0 { |
442 | | - return fmt.Errorf("unexpected YAML root structure") |
443 | | - } |
444 | | - |
445 | | - doc := rootNode.Content[0] |
446 | | - if doc.Kind != yaml.MappingNode { |
447 | | - return fmt.Errorf("expected mapping node at document root") |
448 | | - } |
449 | | - |
450 | | - // Locate spec policy node |
451 | | - var specNode *yaml.Node |
452 | | - for i := 0; i < len(doc.Content)-1; i += 2 { |
453 | | - if doc.Content[i].Value == "spec" && doc.Content[i+1].Kind == yaml.MappingNode { |
454 | | - specNode = doc.Content[i+1] |
455 | | - break |
456 | | - } |
457 | | - } |
458 | | - if specNode == nil { |
459 | | - return fmt.Errorf("spec node not found") |
460 | | - } |
461 | | - |
462 | | - // Locate policies node within spec |
463 | | - var policiesNode *yaml.Node |
464 | | - for i := 0; i < len(specNode.Content)-1; i += 2 { |
465 | | - if specNode.Content[i].Value == "policies" && specNode.Content[i+1].Kind == yaml.SequenceNode { |
466 | | - policiesNode = specNode.Content[i+1] |
467 | | - break |
468 | | - } |
469 | | - } |
470 | | - if policiesNode == nil { |
471 | | - return fmt.Errorf("spec.policies node not found") |
472 | | - } |
473 | | - |
474 | | - // Iterate over and update each rego policy |
475 | | - for _, policy := range policiesNode.Content { |
476 | | - if policy.Kind != yaml.MappingNode { |
477 | | - continue |
478 | | - } |
479 | | - |
480 | | - for i := 0; i < len(policy.Content)-1; i += 2 { |
481 | | - key := policy.Content[i] |
482 | | - val := policy.Content[i+1] |
483 | | - |
484 | | - if key.Value == "embedded" && val.Kind == yaml.ScalarNode { |
485 | | - formatted := p.validateAndFormatRego(val.Value, file.Path) |
486 | | - if formatted != val.Value { |
487 | | - val.Value = formatted |
488 | | - } |
489 | | - } |
490 | | - } |
491 | | - } |
492 | | - |
493 | | - return nil |
494 | | -} |
495 | | - |
496 | 371 | // Creates a mapping from line numbers to Rego rule names |
497 | 372 | func (p *PolicyToLint) buildRegoRuleMap(regoSrc string) map[int]string { |
498 | 373 | ruleMap := make(map[int]string) |
|
0 commit comments