Skip to content

Commit a4868ee

Browse files
authored
Add include option to CLI and config file (#289)
* Add include option to CLI and config file
1 parent 3185069 commit a4868ee

File tree

4 files changed

+42
-17
lines changed

4 files changed

+42
-17
lines changed

.poutine.sample.yml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,3 +47,10 @@ skipExamples:
4747
# skip findings by OSV ID
4848
- osv_id:
4949
- GHSA-mcph-m25j-8j63
50+
51+
52+
# includes only this set of rules
53+
allowedRules:
54+
- "pr_runs_on_self_hosted"
55+
- "unpinnable_action"
56+
- "github_action_from_unverified_creator_used"

cmd/root.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ var token string
3838
var cfgFile string
3939
var config *models.Config = models.DefaultConfig()
4040
var skipRules []string
41+
var allowedRules []string
4142

4243
var legacyFlags = []string{"-token", "-format", "-verbose", "-scm", "-scm-base-uri", "-threads"}
4344

@@ -115,6 +116,7 @@ func init() {
115116
rootCmd.PersistentFlags().VarP(&ScmBaseURL, "scm-base-url", "b", "Base URI of the self-hosted SCM instance (optional)")
116117
rootCmd.PersistentFlags().BoolVarP(&config.Quiet, "quiet", "q", false, "Disable progress output")
117118
rootCmd.PersistentFlags().StringSliceVar(&skipRules, "skip", []string{}, "Adds rules to the configured skip list for the current run (optional)")
119+
rootCmd.PersistentFlags().StringSliceVar(&allowedRules, "allowed-rules", []string{}, "Overwrite the configured allowedRules list for the current run (optional)")
118120

119121
viper.BindPFlag("quiet", rootCmd.PersistentFlags().Lookup("quiet"))
120122
}
@@ -192,6 +194,9 @@ func newOpa(ctx context.Context) (*opa.Opa, error) {
192194
if len(skipRules) > 0 {
193195
config.Skip = append(config.Skip, models.ConfigSkip{Rule: skipRules})
194196
}
197+
if len(allowedRules) > 0 {
198+
config.AllowedRules = allowedRules
199+
}
195200
opaClient, err := opa.NewOpa(ctx, config)
196201
if err != nil {
197202
log.Error().Err(err).Msg("Failed to create OPA client")

models/config.go

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,12 @@ type ConfigInclude struct {
2323
}
2424

2525
type Config struct {
26-
Skip []ConfigSkip `json:"skip"`
27-
Include []ConfigInclude `json:"include"`
28-
IgnoreForks bool `json:"ignore_forks"`
29-
Quiet bool `json:"quiet,omitempty"`
30-
RulesConfig map[string]map[string]interface{} `json:"rules_config"`
26+
Skip []ConfigSkip `json:"skip"`
27+
AllowedRules []string `json:"allowed_rules"`
28+
Include []ConfigInclude `json:"include"`
29+
IgnoreForks bool `json:"ignore_forks"`
30+
Quiet bool `json:"quiet,omitempty"`
31+
RulesConfig map[string]map[string]interface{} `json:"rules_config"`
3132
}
3233

3334
func DefaultConfig() *Config {

opa/opa.go

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,7 @@ func NewOpa(ctx context.Context, config *models.Config) (*Opa, error) {
4343
}),
4444
}
4545

46-
err := newOpa.WithConfig(ctx, config)
47-
if err != nil {
46+
if err := newOpa.WithConfig(ctx, config); err != nil {
4847
return nil, fmt.Errorf("failed to set opa with config: %w", err)
4948
}
5049

@@ -55,8 +54,7 @@ func NewOpa(ctx context.Context, config *models.Config) (*Opa, error) {
5554
}
5655
}
5756

58-
err = newOpa.Compile(ctx, subset)
59-
if err != nil {
57+
if err := newOpa.Compile(ctx, subset, config.AllowedRules); err != nil {
6058
return nil, fmt.Errorf("failed to initialize opa compiler: %w", err)
6159
}
6260

@@ -87,20 +85,31 @@ func (o *Opa) WithConfig(ctx context.Context, config *models.Config) error {
8785
)
8886
}
8987

90-
func (o *Opa) Compile(ctx context.Context, skip []string) error {
88+
func skipRule(path string, skip []string, allowed []string) bool {
89+
if !strings.Contains(filepath.ToSlash(path), "/rules/") {
90+
return false
91+
}
92+
filename := strings.TrimSuffix(filepath.Base(path), filepath.Ext(path))
93+
if len(allowed) > 0 {
94+
if !slices.Contains(allowed, filename) {
95+
return true
96+
}
97+
}
98+
if slices.Contains(skip, filename) {
99+
return true
100+
}
101+
return false
102+
}
103+
104+
func (o *Opa) Compile(ctx context.Context, skip []string, allowed []string) error {
91105
modules := make(map[string]string)
92106
err := fs.WalkDir(regoFs, "rego", func(path string, d fs.DirEntry, err error) error {
93107
if d.IsDir() {
94108
return err
95109
}
96110

97-
if len(skip) != 0 {
98-
if filepath.Dir(path) == filepath.Join("rego", "rules") {
99-
filename := strings.TrimSuffix(filepath.Base(path), filepath.Ext(path))
100-
if slices.Contains(skip, filename) {
101-
return nil
102-
}
103-
}
111+
if skipRule(path, skip, allowed) {
112+
return nil
104113
}
105114

106115
content, err := regoFs.ReadFile(path)
@@ -124,6 +133,9 @@ func (o *Opa) Compile(ctx context.Context, skip []string) error {
124133
}
125134

126135
for name, mod := range result.Modules {
136+
if skipRule(name, skip, allowed) {
137+
continue
138+
}
127139
modules["include/"+name] = string(mod.Raw)
128140
}
129141

0 commit comments

Comments
 (0)