• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

kubescape / regolibrary / 5345182494

pending completion
5345182494

Pull #433

github

web-flow
Merge 755bd6bc6 into eb29b76ab
Pull Request #433: adding ks-ga #1

508 of 602 relevant lines covered (84.39%)

4428.18 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

84.29
/gitregostore/gitstoremethods.go
1
package gitregostore
2

3
import (
4
        "fmt"
5
        "strings"
6

7
        "github.com/armosec/armoapi-go/armotypes"
8
        "github.com/go-gota/gota/dataframe"
9
        "github.com/go-gota/gota/series"
10
        opapolicy "github.com/kubescape/opa-utils/reporthandling"
11
        "github.com/kubescape/opa-utils/reporthandling/attacktrack/v1alpha1"
12
        "k8s.io/utils/strings/slices"
13
)
14

15
const (
16
        TypeCompliance = "compliance"
17
        TypeSecurity   = "security"
18
)
19

20
// =============================================================
21
// =========================== Rules ===========================
22
// =============================================================
23

24
// GetOPAPolicies returns all the policies of given customer
25
func (gs *GitRegoStore) GetOPAPolicies() ([]opapolicy.PolicyRule, error) {
4✔
26
        gs.rulesLock.RLock()
4✔
27
        defer gs.rulesLock.RUnlock()
4✔
28

4✔
29
        if gs.Rules == nil {
4✔
30
                return nil, fmt.Errorf("no rules found in GitRegoStore")
×
31
        }
×
32

33
        return gs.Rules, nil
4✔
34
}
35

36
func (gs *GitRegoStore) GetOPAPoliciesNamesList() ([]string, error) {
4✔
37
        gs.rulesLock.RLock()
4✔
38
        defer gs.rulesLock.RUnlock()
4✔
39

4✔
40
        policiesNameList := make([]string, 0, len(gs.Rules))
4✔
41
        for _, rule := range gs.Rules {
1,076✔
42
                policiesNameList = append(policiesNameList, rule.Name)
1,072✔
43
        }
1,072✔
44

45
        return policiesNameList, nil
4✔
46
}
47

48
// GetOPAPolicyByName returns specific policy by the name
49
func (gs *GitRegoStore) GetOPAPolicyByName(ruleName string) (*opapolicy.PolicyRule, error) {
4✔
50
        gs.rulesLock.RLock()
4✔
51
        defer gs.rulesLock.RUnlock()
4✔
52

4✔
53
        return gs.getOPAPolicyByName(ruleName)
4✔
54
}
4✔
55

56
func (gs *GitRegoStore) getOPAPolicyByName(ruleName string) (*opapolicy.PolicyRule, error) {
3,232✔
57
        for _, ruleToPin := range gs.Rules {
437,986✔
58
                if !strings.EqualFold(ruleToPin.Name, ruleName) {
866,276✔
59
                        continue
431,522✔
60
                }
61

62
                rule := ruleToPin
3,232✔
63

3,232✔
64
                return &rule, nil
3,232✔
65
        }
66

67
        return nil, fmt.Errorf("rule '%s' not found", ruleName)
×
68
}
69

70
// =============================================================
71
// =========================== AttackTracks ====================
72
// =============================================================
73

74
func (gs *GitRegoStore) GetAttackTracks() ([]v1alpha1.AttackTrack, error) {
4✔
75
        gs.attackTracksLock.RLock()
4✔
76
        defer gs.attackTracksLock.RUnlock()
4✔
77

4✔
78
        if gs.AttackTracks == nil {
4✔
79
                return nil, fmt.Errorf("no attack tracks found in GitRegoStore")
×
80
        }
×
81

82
        return gs.AttackTracks, nil
4✔
83
}
84

85
// =============================================================
86
// =========================== Controls ========================
87
// =============================================================
88

89
// GetOPAControlByName returns specific BaseControl by the name.
90
//
91
// Deprecated: use GetOPAControlByFrameworkNameAndControlName.
92
func (gs *GitRegoStore) GetOPAControlByName(controlName string) (*opapolicy.Control, error) {
8✔
93
        gs.controlsLock.RLock()
8✔
94
        defer gs.controlsLock.RUnlock()
8✔
95

8✔
96
        for _, controlToPin := range gs.Controls {
920✔
97
                if !strings.EqualFold(controlToPin.Name, controlName) {
1,816✔
98
                        continue
904✔
99
                }
100

101
                control := controlToPin
8✔
102
                if len(control.Rules) == 0 {
16✔
103
                        err := gs.fillRulesAndRulesIDsInControl(&control)
8✔
104
                        if err != nil {
8✔
105
                                return nil, err
×
106
                        }
×
107
                }
108

109
                return &control, nil
8✔
110
        }
111

112
        return nil, fmt.Errorf("control '%s' not found", controlName)
×
113
}
114

115
// GetOPAControlByID returns specific BaseControl by the ID
116
func (gs *GitRegoStore) GetOPAControlByID(controlID string) (*opapolicy.Control, error) {
1,713✔
117
        gs.controlsLock.RLock()
1,713✔
118
        defer gs.controlsLock.RUnlock()
1,713✔
119

1,713✔
120
        return gs.getOPAControlByID(controlID)
1,713✔
121
}
1,713✔
122

123
func (gs *GitRegoStore) getOPAControlByID(controlID string) (*opapolicy.Control, error) {
1,713✔
124
        for _, controlToPin := range gs.Controls {
196,651✔
125
                if !strings.EqualFold(controlToPin.ControlID, controlID) {
388,163✔
126
                        continue
193,225✔
127
                }
128

129
                control := controlToPin
1,713✔
130
                if len(control.Rules) == 0 {
3,426✔
131
                        if err := gs.fillRulesAndRulesIDsInControl(&control); err != nil {
1,713✔
132
                                return nil, err
×
133
                        }
×
134
                }
135

136
                return &control, nil
1,713✔
137
        }
138

139
        return nil, fmt.Errorf("control '%s' not found", controlID)
×
140
}
141

142
// GetOPAControlByFrameworkNameAndControlName - get framework name and control name and return the relevant control object
143
func (gs *GitRegoStore) GetOPAControlByFrameworkNameAndControlName(frameworkName string, controlName string) (*opapolicy.Control, error) {
4✔
144
        gs.frameworksLock.RLock()
4✔
145
        defer gs.frameworksLock.RUnlock()
4✔
146
        gs.controlsLock.RLock()
4✔
147
        defer gs.controlsLock.RUnlock()
4✔
148

4✔
149
        fw, err := gs.getOPAFrameworkByName(frameworkName) // locks framework
4✔
150
        if err != nil {
4✔
151
                return nil, err
×
152
        }
×
153

154
        for _, controlToPin := range fw.Controls {
28✔
155
                if !strings.EqualFold(controlToPin.Name, controlName) {
44✔
156
                        continue
20✔
157
                }
158

159
                control := controlToPin
4✔
160

4✔
161
                if len(control.Rules) == 0 {
4✔
162
                        if err := gs.fillRulesAndRulesIDsInControl(&control); err != nil {
×
163
                                return nil, err
×
164
                        }
×
165
                }
166

167
                return &control, nil
4✔
168
        }
169

170
        return nil, fmt.Errorf("control  name '%s' not found in framework '%s'", controlName, fw.Name)
×
171

172
}
173

174
// GetOPAControl returns specific control by the name or ID
175
func (gs *GitRegoStore) GetOPAControl(c string) (*opapolicy.Control, error) {
8✔
176
        if isControlID(c) {
12✔
177
                return gs.GetOPAControlByID(c)
4✔
178
        } else {
8✔
179
                return gs.GetOPAControlByName(c)
4✔
180
        }
4✔
181
}
182

183
// GetOPAControls returns all the controls of given customer
184
func (gs *GitRegoStore) GetOPAControls() ([]opapolicy.Control, error) {
4✔
185
        gs.controlsLock.RLock()
4✔
186
        defer gs.controlsLock.RUnlock()
4✔
187

4✔
188
        if gs.Controls == nil {
4✔
189
                return nil, fmt.Errorf("no controls found in GitRegoStore")
×
190
        }
×
191

192
        controlsList := make([]opapolicy.Control, 0, len(gs.Controls))
4✔
193
        for _, controlToPin := range gs.Controls {
916✔
194
                control := controlToPin
912✔
195

912✔
196
                if err := gs.fillRulesAndRulesIDsInControl(&control); err != nil {
912✔
197
                        return nil, err
×
198
                }
×
199

200
                controlsList = append(controlsList, control)
912✔
201
        }
202

203
        return controlsList, nil
4✔
204
}
205

206
func (gs *GitRegoStore) GetOPAControlsNamesList() ([]string, error) {
4✔
207
        gs.controlsLock.RLock()
4✔
208
        defer gs.controlsLock.RUnlock()
4✔
209

4✔
210
        controlsNameList := make([]string, 0, len(gs.Controls))
4✔
211
        for _, control := range gs.Controls {
916✔
212
                controlsNameList = append(controlsNameList, control.Name)
912✔
213
        }
912✔
214

215
        return controlsNameList, nil
4✔
216
}
217

218
func (gs *GitRegoStore) GetOPAControlsIDsList() ([]string, error) {
4✔
219
        gs.controlsLock.RLock()
4✔
220
        defer gs.controlsLock.RUnlock()
4✔
221

4✔
222
        controlsIDList := make([]string, 0, len(gs.Controls))
4✔
223
        for _, control := range gs.Controls {
916✔
224
                controlsIDList = append(controlsIDList, control.ControlID)
912✔
225
        }
912✔
226

227
        return controlsIDList, nil
4✔
228
}
229

230
// GetOpaFrameworkListByControlName returns a list of framework names this control is in
231
func (gs *GitRegoStore) GetOpaFrameworkListByControlName(controlName string) []string {
4✔
232
        gs.frameworkRelationsLock.RLock()
4✔
233
        defer gs.frameworkRelationsLock.RUnlock()
4✔
234

4✔
235
        fil := gs.FrameworkControlRelations.Filter(
4✔
236
                dataframe.F{Colname: "ControlName", Comparator: series.Eq, Comparando: controlName},
4✔
237
        )
4✔
238
        rows := fil.Nrow()
4✔
239
        frameworksNameList := make([]string, 0, rows)
4✔
240

4✔
241
        for row := 0; row < rows; row++ {
16✔
242
                fwName := fil.Elem(row, 0)
12✔
243
                frameworksNameList = append(frameworksNameList, fwName.String())
12✔
244
        }
12✔
245

246
        return frameworksNameList
4✔
247
}
248

249
// GetOpaFrameworkListByControlID returns a list of framework names this control is in
250
func (gs *GitRegoStore) GetOpaFrameworkListByControlID(controlID string) []string {
4✔
251
        gs.frameworkRelationsLock.RLock()
4✔
252
        defer gs.frameworkRelationsLock.RUnlock()
4✔
253

4✔
254
        fil := gs.FrameworkControlRelations.Filter(
4✔
255
                dataframe.F{Colname: "ControlID", Comparator: series.Eq, Comparando: controlID},
4✔
256
        )
4✔
257
        rows := fil.Nrow()
4✔
258
        frameworksNameList := make([]string, 0, rows)
4✔
259

4✔
260
        for row := 0; row < rows; row++ {
16✔
261
                fwName := fil.Elem(row, 0)
12✔
262
                frameworksNameList = append(frameworksNameList, fwName.String())
12✔
263
        }
12✔
264

265
        return frameworksNameList
4✔
266
}
267

268
// ===============================================================
269
// =========================== Frameworks ========================
270
// ===============================================================
271

272
// GetOPAFrameworksByType returns all frameworks of given type
273
func (gs *GitRegoStore) getOPAFrameworksByType(frameworkType string) ([]opapolicy.Framework, error) {
14✔
274
        gs.frameworksLock.RLock()
14✔
275
        defer gs.frameworksLock.RUnlock()
14✔
276

14✔
277
        if gs.Frameworks == nil {
14✔
278
                return nil, fmt.Errorf("no frameworks found in GitRegoStore")
×
279
        }
×
280
        frameworksList := make([]opapolicy.Framework, 0, len(gs.Frameworks))
14✔
281
        for _, frameworkToPin := range gs.Frameworks {
104✔
282
                framework := frameworkToPin
90✔
283
                if slices.Contains(framework.TypeTags, frameworkType) {
163✔
284
                        frameworksList = append(frameworksList, framework)
73✔
285
                }
73✔
286
        }
287
        return frameworksList, nil
14✔
288
}
289

290
// ====================== compliance frameworks ======================
291

292
// GetOPAFrameworks returns all compliance frameworks
293
func (gs *GitRegoStore) GetOPAFrameworks() ([]opapolicy.Framework, error) {
5✔
294
        complianceFrameworks, err := gs.getOPAFrameworksByType(TypeCompliance)
5✔
295
        if err != nil {
5✔
296
                return nil, fmt.Errorf("failed to get compliance frameworks: %w", err)
×
297
        }
×
298

299
        frameworksList := make([]opapolicy.Framework, 0, len(complianceFrameworks))
5✔
300
        for _, frameworkToPin := range complianceFrameworks {
39✔
301
                fw := frameworkToPin
34✔
302
                if err := gs.fillControlsAndControlIDsInFramework(&fw); err != nil {
34✔
303
                        return nil, err
×
304
                }
×
305
                frameworksList = append(frameworksList, fw)
34✔
306
        }
307

308
        return frameworksList, nil
5✔
309
}
310

311
// GetOPAFrameworksNamesList returns all compliance frameworks names
312
func (gs *GitRegoStore) GetOPAFrameworksNamesList() ([]string, error) {
5✔
313
        complianceFrameworks, err := gs.getOPAFrameworksByType(TypeCompliance)
5✔
314
        if err != nil {
5✔
315
                return nil, fmt.Errorf("failed to get compliance frameworks: %w", err)
×
316
        }
×
317
        frameworksNameList := make([]string, 0, len(complianceFrameworks))
5✔
318
        for _, framework := range complianceFrameworks {
39✔
319
                frameworksNameList = append(frameworksNameList, framework.Name)
34✔
320
        }
34✔
321

322
        return frameworksNameList, nil
5✔
323
}
324

325
// ====================== security frameworks ======================
326

327
// GetOPAFrameworks returns all security frameworks
328
func (gs *GitRegoStore) GetOPASecurityFrameworks() ([]opapolicy.Framework, error) {
1✔
329
        securityFrameworks, err := gs.getOPAFrameworksByType(TypeSecurity)
1✔
330
        if err != nil {
1✔
331
                return nil, fmt.Errorf("failed to get security frameworks: %w", err)
×
332
        }
×
333
        frameworksList := make([]opapolicy.Framework, 0, len(securityFrameworks))
1✔
334
        for _, frameworkToPin := range securityFrameworks {
2✔
335
                fw := frameworkToPin
1✔
336
                if err := gs.fillControlsAndControlIDsInFramework(&fw); err != nil {
1✔
337
                        return nil, err
×
338
                }
×
339
                frameworksList = append(frameworksList, fw)
1✔
340
        }
341
        return frameworksList, nil
1✔
342
}
343

344
// GetOPAFrameworksNamesList returns all security frameworks names
345
func (gs *GitRegoStore) GetOPASecurityFrameworksNamesList() ([]string, error) {
1✔
346
        securityFrameworks, err := gs.getOPAFrameworksByType(TypeSecurity)
1✔
347
        if err != nil {
1✔
348
                return nil, fmt.Errorf("failed to get security frameworks: %w", err)
×
349
        }
×
350
        frameworksNameList := make([]string, 0, len(securityFrameworks))
1✔
351
        for _, framework := range securityFrameworks {
2✔
352
                frameworksNameList = append(frameworksNameList, framework.Name)
1✔
353
        }
1✔
354
        return frameworksNameList, nil
1✔
355
}
356

357
// GetOPAFrameworkTypeTags returns all type tags of given framework
358
func (gs *GitRegoStore) GetOPAFrameworkTypeTags(frameworkName string) ([]string, error) {
2✔
359
        framework, err := gs.getOPAFrameworkByName(frameworkName)
2✔
360
        if err != nil {
2✔
361
                return nil, err
×
362
        }
×
363
        return framework.TypeTags, nil
2✔
364
}
365

366
// GetOPAFrameworkByName returns specific framework by the name
367
func (gs *GitRegoStore) GetOPAFrameworkByName(frameworkName string) (*opapolicy.Framework, error) {
5✔
368
        gs.frameworksLock.RLock()
5✔
369
        defer gs.frameworksLock.RUnlock()
5✔
370

5✔
371
        return gs.getOPAFrameworkByName(frameworkName)
5✔
372
}
5✔
373

374
func (gs *GitRegoStore) getOPAFrameworkByName(frameworkName string) (*opapolicy.Framework, error) {
11✔
375

11✔
376
        for _, frameworkToPin := range gs.Frameworks {
47✔
377
                if !strings.EqualFold(frameworkToPin.Name, frameworkName) {
61✔
378
                        continue
25✔
379
                }
380

381
                fw := frameworkToPin
11✔
382

11✔
383
                if err := gs.fillControlsAndControlIDsInFramework(&fw); err != nil {
11✔
384
                        return nil, err
×
385
                }
×
386

387
                return &fw, nil
11✔
388
        }
389

390
        return nil, fmt.Errorf("framework '%s' not found", frameworkName)
×
391
}
392

393
// ===============================================================
394

395
func (gs *GitRegoStore) GetDefaultConfigInputs() (armotypes.CustomerConfig, error) {
4✔
396
        gs.DefaultConfigInputsLock.RLock()
4✔
397
        defer gs.DefaultConfigInputsLock.RUnlock()
4✔
398

4✔
399
        return gs.DefaultConfigInputs, nil
4✔
400
}
4✔
401

402
func (gs *GitRegoStore) GetSystemPostureExceptionPolicies() ([]armotypes.PostureExceptionPolicy, error) {
4✔
403
        gs.systemPostureExceptionPoliciesLock.RLock()
4✔
404
        defer gs.systemPostureExceptionPoliciesLock.RUnlock()
4✔
405

4✔
406
        return gs.SystemPostureExceptionPolicies, nil
4✔
407
}
4✔
408

409
// ====================== helpers ======================
410

411
func (gs *GitRegoStore) fillRulesAndRulesIDsInControl(control *opapolicy.Control) error {
2,633✔
412
        gs.controlEscalatedLock.Lock() // this locks all concurrent attempts to fill any control
2,633✔
413
        defer gs.controlEscalatedLock.Unlock()
2,633✔
414

2,633✔
415
        gs.rulesLock.RLock()
2,633✔
416
        defer gs.rulesLock.RUnlock()
2,633✔
417

2,633✔
418
        gs.controlRelationsLock.RLock()
2,633✔
419
        defer gs.controlRelationsLock.RUnlock()
2,633✔
420

2,633✔
421
        fil := gs.ControlRuleRelations.Filter(
2,633✔
422
                dataframe.F{Colname: "ControlID", Comparator: series.Eq, Comparando: control.ControlID},
2,633✔
423
        )
2,633✔
424

2,633✔
425
        rows := fil.Nrow()
2,633✔
426
        rulesList := make([]opapolicy.PolicyRule, 0, rows)
2,633✔
427
        rulesIDList := make([]string, 0, rows)
2,633✔
428

2,633✔
429
        for row := 0; row < rows; row++ {
5,861✔
430
                ruleName := fil.Elem(row, 1)
3,228✔
431
                rule, err := gs.getOPAPolicyByName(ruleName.String()) // requires R-Lock on Rules
3,228✔
432
                if err != nil {
3,228✔
433
                        return err
×
434
                }
×
435
                // add rule to control.rules
436
                rulesList = append(rulesList, *rule)
3,228✔
437
                // add ruleId ro control.ruleIds
3,228✔
438
                rulesIDList = append(rulesIDList, rule.GUID)
3,228✔
439
        }
440

441
        control.Rules = rulesList
2,633✔
442
        control.RulesIDs = &rulesIDList
2,633✔
443

2,633✔
444
        return nil
2,633✔
445
}
446

447
func (gs *GitRegoStore) fillControlsAndControlIDsInFramework(fw *opapolicy.Framework) error {
46✔
448
        gs.frameworkEscalatedLock.Lock()
46✔
449
        defer gs.frameworkEscalatedLock.Unlock()
46✔
450

46✔
451
        gs.rulesLock.RLock()
46✔
452
        defer gs.rulesLock.RUnlock()
46✔
453

46✔
454
        gs.frameworkRelationsLock.RLock()
46✔
455
        defer gs.frameworkRelationsLock.RUnlock()
46✔
456

46✔
457
        fil := gs.FrameworkControlRelations.Filter(
46✔
458
                dataframe.F{Colname: "frameworkName", Comparator: series.Eq, Comparando: fw.Name},
46✔
459
        )
46✔
460

46✔
461
        rows := fil.Nrow()
46✔
462
        controlsList := make([]opapolicy.Control, 0, rows)
46✔
463
        controlsIDList := make([]string, 0, rows)
46✔
464

46✔
465
        // if there are no controls in framework, need to populate them all from base controls.
46✔
466
        if len(fw.Controls) == 0 {
51✔
467
                for row := 0; row < rows; row++ {
5✔
468
                        controlID := fil.Elem(row, 1)
×
469
                        control, err := gs.getOPAControlByID(controlID.String())
×
470
                        if err != nil {
×
471
                                return err
×
472
                        }
×
473

474
                        // add control to controlsList
475
                        controlsList = append(controlsList, *control)
×
476
                        // add controlID to controlsIDList
×
477
                        controlsIDList = append(controlsIDList, control.ControlID)
×
478

479
                }
480

481
                fw.Controls = controlsList
5✔
482
                fw.ControlsIDs = &controlsIDList
5✔
483

5✔
484
                return nil
5✔
485
        }
486

487
        // if there are controls, need to populate only the rules.
488
        for i := range fw.Controls {
2,058✔
489
                if len(fw.Controls[i].Rules) == 0 {
3,722✔
490
                        tmpControl, err := gs.GetOPAControlByID(fw.Controls[i].ControlID)
1,705✔
491
                        if err != nil {
1,705✔
492
                                return err
×
493
                        }
×
494

495
                        fw.Controls[i].Rules = tmpControl.Rules
1,705✔
496
                        fw.Controls[i].RulesIDs = tmpControl.RulesIDs
1,705✔
497
                }
498
        }
499

500
        return nil
41✔
501
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc