func()

in sg/internal/engine/rego_query.go [171:232]


func (engine *RegoEngine) queryRule(
	ctx context.Context,
	policyPackage policy.Package,
	policyRule policy.Rule,
	loadedConfiguration loadedConfiguration,
	queryResult *result.QueryResults,
) error {
	resolveRuleDocLink := resolveRuleDocLinkFn(policyPackage)

	// execute exception query
	exceptionQuery := fmt.Sprintf("data.%s.exception[_][_] == %q", PackageMain, policyRule.Name)
	exceptions, err := engine.executeOneQuery(ctx, loadedConfiguration.Configuration, exceptionQuery)
	if err != nil {
		return fmt.Errorf("failed to execute exception query (%q): %w", exceptionQuery, err)
	}
	exceptions = utils.Filter(exceptions, func(x result.Result) bool { return x.Passed() })

	// execute query
	// NOTE: even if the exception query returns true, we still execute the query
	query := fmt.Sprintf("data.%s.%s", PackageMain, policyRule.Query())
	results, err := engine.executeOneQuery(ctx, loadedConfiguration.Configuration, query)
	if err != nil {
		return fmt.Errorf("failed to execute query (%q): %w", query, err)
	}

	// excluded by at least one exception
	if len(exceptions) > 0 {
		for idx := range exceptions {
			exceptions[idx].Rule = policyRule
			docLink, err := resolveRuleDocLink(policyRule)
			if err != nil {
				return fmt.Errorf("resolve rule doc link failed: %w", err)
			}
			exceptions[idx].RuleDocLink = docLink
		}
		queryResult.Exceptions = append(queryResult.Exceptions, exceptions...)
		return nil
	}

	for _, result := range results {
		if result.Passed() {
			queryResult.Successes += 1
			continue
		}

		result.Rule = policyRule
		ruleDocLink, err := resolveRuleDocLink(policyRule)
		if err != nil {
			return fmt.Errorf("resolve rule doc link failed: %w", err)
		}
		result.RuleDocLink = ruleDocLink

		switch {
		case policyRule.IsKind(policy.QueryKindWarn):
			queryResult.Warnings = append(queryResult.Warnings, result)
		case policyRule.IsKind(policy.QueryKindViolation, policy.QueryKindDeny):
			queryResult.Failures = append(queryResult.Failures, result)
		}
	}

	return nil
}