forked from opencontrol/compliance-masonry
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathworkspace.go
128 lines (116 loc) · 3.76 KB
/
workspace.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
package lib
import (
"errors"
"io/ioutil"
"os"
"path/filepath"
"sync"
"github.com/codegangsta/cli"
"github.com/opencontrol/compliance-masonry/lib/common"
"github.com/opencontrol/compliance-masonry/lib/result"
)
// localWorkspace struct combines components, standards, and a certification data
// For more information on the opencontrol schema visit: https://github.com/opencontrol/schemas
type localWorkspace struct {
components *componentsMap
standards *standardsMap
justifications *result.Justifications
certification common.Certification
}
// getKey extracts a component key from the filepath
func getKey(filePath string) string {
_, key := filepath.Split(filePath)
return key
}
// NewWorkspace initializes an empty OpenControl struct
func NewWorkspace() common.Workspace {
return &localWorkspace{
justifications: result.NewJustifications(),
components: newComponents(),
standards: newStandards(),
}
}
// LoadData creates a new instance of OpenControl struct and loads
// the components, standards, and certification data.
func LoadData(openControlDir string, certificationPath string) (common.Workspace, []error) {
var wg sync.WaitGroup
ws := NewWorkspace()
wg.Add(3)
var componentsErrs, standardsErrs []error
var certificationErr error
go func(wg *sync.WaitGroup) {
defer wg.Done()
componentsErrs = ws.LoadComponents(filepath.Join(openControlDir, "components"))
}(&wg)
go func(wg *sync.WaitGroup) {
defer wg.Done()
standardsErrs = ws.LoadStandards(filepath.Join(openControlDir, "standards"))
}(&wg)
go func(wg *sync.WaitGroup) {
defer wg.Done()
certificationErr = ws.LoadCertification(certificationPath)
}(&wg)
wg.Wait()
var errs []error
if certificationErr != nil {
errs = append(errs, certificationErr)
}
errs = append(errs, componentsErrs...)
errs = append(errs, standardsErrs...)
return ws, errs
}
// LoadComponents loads multiple components by searching for components in a
// given directory
func (ws *localWorkspace) LoadComponents(directory string) []error {
var wg sync.WaitGroup
componentsDir, err := ioutil.ReadDir(directory)
if err != nil {
return []error{errors.New("Error: Unable to read the directory " + directory)}
}
errChannel := make(chan error, len(componentsDir))
wg.Add(len(componentsDir))
for _, componentDir := range componentsDir {
go func(componentDir os.FileInfo, wg *sync.WaitGroup) {
if componentDir.IsDir() {
componentDir := filepath.Join(directory, componentDir.Name())
errChannel <- ws.LoadComponent(componentDir)
}
wg.Done()
}(componentDir, &wg)
}
wg.Wait()
close(errChannel)
return convertErrChannelToErrorSlice(errChannel)
}
// LoadStandards loads multiple standards by searching for components in a
// given directory
func (ws *localWorkspace) LoadStandards(standardsDir string) []error {
var wg sync.WaitGroup
standardsFiles, err := ioutil.ReadDir(standardsDir)
if err != nil {
return []error{errors.New("Error: Unable to read the directory " + standardsDir)}
}
errChannel := make(chan error, len(standardsFiles))
wg.Add(len(standardsFiles))
for _, standardFile := range standardsFiles {
go func(standardFile os.FileInfo, wg *sync.WaitGroup) {
errChannel <- ws.LoadStandard(filepath.Join(standardsDir, standardFile.Name()))
wg.Done()
}(standardFile, &wg)
}
wg.Wait()
close(errChannel)
return convertErrChannelToErrorSlice(errChannel)
}
func convertErrChannelToErrorSlice(errs <-chan error) []error {
errMessages := cli.NewMultiError()
for err := range errs {
if err != nil && len(err.Error()) > 0 {
errMessages.Errors = append(errMessages.Errors, err)
}
}
return errMessages.Errors
}
func (ws *localWorkspace) GetAllVerificationsWith(standardKey string, controlKey string) common.Verifications {
return ws.justifications.Get(standardKey, controlKey)
}