@@ -6,6 +6,30 @@ import (
66 "github.com/goccy/go-yaml"
77)
88
9+ // ControlCatalog describes a set of related controls and relevant metadata
10+ type ControlCatalog struct {
11+ // title describes the purpose of this catalog at a glance
12+ Title string `json:"title" yaml:"title"`
13+
14+ // metadata provides detailed data about this catalog
15+ Metadata Metadata `json:"metadata" yaml:"metadata"`
16+
17+ // controls is a list of unique controls defined by this catalog
18+ Controls []Control `json:"controls,omitempty" yaml:"controls,omitempty"`
19+
20+ // groups contains a list of groups that can be referenced by entries in this catalog
21+ Groups []Group `json:"groups,omitempty" yaml:"groups,omitempty"`
22+
23+ // extends references catalogs that this catalog builds upon
24+ Extends []ArtifactMapping `json:"extends,omitempty" yaml:"extends,omitempty"`
25+
26+ Imports []MultiEntryMapping `json:"imports,omitempty" yaml:"imports,omitempty"`
27+
28+ groups_cache []string
29+ controls_cache map [string ][]Control
30+ requirements_cache map [string ][]AssessmentRequirement
31+ }
32+
933// UnmarshalYAML allows decoding control catalogs from older/alternate YAML schemas.
1034// It supports mapping `families` -> `groups`.
1135func (c * ControlCatalog ) UnmarshalYAML (data []byte ) error {
@@ -44,13 +68,19 @@ func (c *ControlCatalog) UnmarshalYAML(data []byte) error {
4468}
4569
4670func (c * ControlCatalog ) GetGroupNames () (groups []string ) {
71+ if len (c .groups_cache ) > 0 {
72+ return c .groups_cache
73+ }
4774 for _ , group := range c .Groups {
4875 groups = append (groups , group .Title )
4976 }
5077 return groups
5178}
5279
5380func (c * ControlCatalog ) GetControlsForGroup (group string ) (controls []Control ) {
81+ if c .controls_cache != nil && len (c .controls_cache [group ]) > 0 {
82+ return c .controls_cache [group ]
83+ }
5484 for _ , control := range c .Controls {
5585 if control .Group == group {
5686 controls = append (controls , control )
@@ -60,6 +90,9 @@ func (c *ControlCatalog) GetControlsForGroup(group string) (controls []Control)
6090}
6191
6292func (c * ControlCatalog ) GetRequirementForApplicability (applicability string ) (reqs []AssessmentRequirement ) {
93+ if c .requirements_cache != nil && len (c .requirements_cache [applicability ]) > 0 {
94+ return c .requirements_cache [applicability ]
95+ }
6396 for _ , control := range c .Controls {
6497 for _ , assessment := range control .AssessmentRequirements {
6598 if slices .Contains (assessment .Applicability , applicability ) {
0 commit comments