1
0
mirror of https://github.com/strongdm/comply synced 2025-12-06 06:14:09 +00:00

Add a model for a Control, which ou can use to document control statements, owners, governing policies, etc.

This commit is contained in:
Craine Runton
2020-09-17 10:38:11 -05:00
parent a66764470c
commit e289d6d8f4
13 changed files with 238 additions and 0 deletions

24
internal/model/control.go Normal file
View File

@@ -0,0 +1,24 @@
package model
import (
"time"
"html/template"
)
type Control struct {
Name string `yaml:"name"`
ID string `yaml:"identifier"`
Family string `yaml:"family"`
Owner string `yaml:"owner"`
GoverningPolicy []Policy `yaml:"governingPolicy"`
Revisions []Revision `yaml:"revisions"`
Targets Target `yaml:"targets"`
Published string `yaml:"published"`
FullPath string
OutputFilename string
ModifiedAt time.Time
Body string
BodyHTML template.HTML
}

View File

@@ -11,6 +11,8 @@ type Framework struct {
Criteria map[string]Criterion `yaml:",inline"`
}
type Target map[string][]string
// CriteriaSatisfied determines the unique criteria currently satisfied by all Narratives, Policies, and Procedures
func CriteriaSatisfied(data *Data) map[string][]string {
satisfied := make(map[string][]string)
@@ -38,6 +40,13 @@ func CriteriaSatisfied(data *Data) map[string][]string {
}
}
}
for _, n := range data.Controls {
for _, criteriaKeys := range n.Targets {
for _, key := range criteriaKeys {
satisfied[key] = appendSatisfaction(satisfied, key, n.OutputFilename)
}
}
}
for _, n := range data.Procedures {
for _, criteriaKeys := range n.Satisfies {
for _, key := range criteriaKeys {

View File

@@ -26,6 +26,10 @@ func ReadData() (*Data, error) {
if err != nil {
return nil, err
}
controls, err := ReadControls()
if err != nil {
return nil, err
}
procedures, err := ReadProcedures()
if err != nil {
return nil, err
@@ -39,6 +43,7 @@ func ReadData() (*Data, error) {
Tickets: tickets,
Narratives: narratives,
Policies: policies,
Controls: controls,
Procedures: procedures,
Frameworks: frameworks,
}, nil
@@ -166,6 +171,31 @@ func ReadPolicies() ([]*Document, error) {
return policies, nil
}
// ReadControls loads control documents from the filesystem
func ReadControls() ([]*Control, error) {
var controls []*Control
files, err := path.Controls()
if err != nil {
return nil, errors.Wrap(err, "unable to enumerate paths")
}
for _, f := range files {
c := &Control{}
mdmd := loadMDMD(f.FullPath)
err = yaml.Unmarshal([]byte(mdmd.yaml), &c)
if err != nil {
return nil, errors.Wrap(err, "unable to parse "+f.FullPath)
}
c.Body = mdmd.body
c.FullPath = f.FullPath
c.ModifiedAt = f.Info.ModTime()
c.OutputFilename = fmt.Sprintf("%s-%s.pdf", config.Config().FilePrefix, c.ID)
controls = append(controls, c)
}
return controls, nil
}
type metadataMarkdown struct {
yaml string
body string

View File

@@ -4,6 +4,7 @@ type Data struct {
Frameworks []*Framework
Narratives []*Document
Policies []*Document
Controls []*Control
Procedures []*Procedure
Tickets []*Ticket
Audits []*Audit

7
internal/model/policy.go Normal file
View File

@@ -0,0 +1,7 @@
package model
type Policy struct {
Name string `yaml:"policyName"`
ID string `yaml:"policyID"`
Clause string `yaml:"policyClause"`
}