evaluateControl evaluates a control, e.g., OPS-13. Therefore, the method needs to wait till all sub-controls (e.g., OPS-13.1) are evaluated.
(ctx context.Context, auditScope *orchestrator.AuditScope, catalog *orchestrator.Catalog, control *orchestrator.Control, manual []*evaluation.EvaluationResult)
| 586 | // evaluateControl evaluates a control, e.g., OPS-13. Therefore, the method needs to wait till all sub-controls (e.g., |
| 587 | // OPS-13.1) are evaluated. |
| 588 | func (svc *Service) evaluateControl(ctx context.Context, auditScope *orchestrator.AuditScope, catalog *orchestrator.Catalog, control *orchestrator.Control, manual []*evaluation.EvaluationResult) (err error) { |
| 589 | var ( |
| 590 | status = evaluation.EvaluationStatus_EVALUATION_STATUS_PENDING |
| 591 | result *evaluation.EvaluationResult |
| 592 | results []*evaluation.EvaluationResult |
| 593 | relevant []*orchestrator.Control |
| 594 | ignored []string |
| 595 | g *errgroup.Group |
| 596 | ) |
| 597 | |
| 598 | // Gather a list of sub control IDs that we have manual results for and thus we are ignoring |
| 599 | ignored = make([]string, 0, len(manual)) |
| 600 | for _, result := range manual { |
| 601 | ignored = append(ignored, result.ControlId) |
| 602 | } |
| 603 | |
| 604 | // Filter relevant controls |
| 605 | for _, sub := range control.Controls { |
| 606 | // If we ignore the control, we can skip it |
| 607 | if slices.Contains(ignored, sub.Id) { |
| 608 | continue |
| 609 | } |
| 610 | |
| 611 | if sub.IsRelevantFor(auditScope, catalog) { |
| 612 | relevant = append(relevant, sub) |
| 613 | } |
| 614 | } |
| 615 | |
| 616 | log.Infof("Starting control evaluation for Certification Target '%s', Catalog ID '%s' and Control '%s'. Waiting for the evaluation of %d sub-control(s)", |
| 617 | auditScope.CertificationTargetId, |
| 618 | auditScope.CatalogId, |
| 619 | control.Id, |
| 620 | len(relevant), |
| 621 | ) |
| 622 | |
| 623 | // Prepare the results slice |
| 624 | results = make([]*evaluation.EvaluationResult, len(relevant)+len(manual)) |
| 625 | |
| 626 | g, ctx = errgroup.WithContext(ctx) |
| 627 | for i, sub := range relevant { |
| 628 | i, sub := i, sub // https://golang.org/doc/faq#closures_and_goroutines needed until Go 1.22 (loopvar) |
| 629 | g.Go(func() error { |
| 630 | result, err := svc.evaluateSubcontrol(ctx, auditScope, sub) |
| 631 | if err != nil { |
| 632 | return err |
| 633 | } |
| 634 | |
| 635 | results[i] = result |
| 636 | return nil |
| 637 | }) |
| 638 | } |
| 639 | |
| 640 | // Wait until all sub-controls are evaluated |
| 641 | err = g.Wait() |
| 642 | if err != nil { |
| 643 | log.Error(err) |
| 644 | return |
| 645 | } |