Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: prevent planning and applying directories outside PR scope using --restrict-file-list #2440

Merged
merged 15 commits into from
Dec 9, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions cmd/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ const (
SlackTokenFlag = "slack-token"
SSLCertFileFlag = "ssl-cert-file"
SSLKeyFileFlag = "ssl-key-file"
StrictPlanFileList = "strict-plan-file-list"
TFDownloadURLFlag = "tf-download-url"
VarFileAllowlistFlag = "var-file-allowlist"
VCSStatusName = "vcs-status-name"
Expand Down Expand Up @@ -435,6 +436,10 @@ var boolFlags = map[string]boolFlag{
description: "Switches on or off the Basic Authentication on the HTTP Middleware interface",
defaultValue: DefaultWebBasicAuth,
},
StrictPlanFileList: {
description: "Block plan requests from projects outside the files modified in the pull request.",
defaultValue: false,
},
}
var intFlags = map[string]intFlag{
ParallelPoolSize: {
Expand Down
1 change: 1 addition & 0 deletions cmd/server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ var testFlags = map[string]interface{}{
SlackTokenFlag: "slack-token",
SSLCertFileFlag: "cert-file",
SSLKeyFileFlag: "key-file",
StrictPlanFileList: false,
TFDownloadURLFlag: "https://my-hostname.com",
TFEHostnameFlag: "my-hostname",
TFELocalExecutionModeFlag: true,
Expand Down
6 changes: 6 additions & 0 deletions runatlantis.io/docs/server-configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -603,6 +603,12 @@ Values are chosen in this order:
```
File containing x509 private key matching `--ssl-cert-file`.

* ### `--strict-plan-file-list`
```bash
atlantis server --strict-plan-file-list
```
nitrocode marked this conversation as resolved.
Show resolved Hide resolved
`--strict-plan-file-list` will block plan requests from projects outside the files modified in the pull request.

Fabianoshz marked this conversation as resolved.
Show resolved Hide resolved
* ### `--stats-namespace`
```bash
atlantis server --stats-namespace="myatlantis"
Expand Down
1 change: 1 addition & 0 deletions server/controllers/events/events_controller_e2e_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -933,6 +933,7 @@ func setupE2E(t *testing.T, repoDir string) (events_controllers.VCSEventsControl
false,
false,
"**/*.tf,**/*.tfvars,**/*.tfvars.json,**/terragrunt.hcl,**/.terraform.lock.hcl",
false,
statsScope,
logger,
)
Expand Down
27 changes: 27 additions & 0 deletions server/events/project_command_builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package events
import (
"fmt"
"os"
"path/filepath"
"sort"

"github.com/runatlantis/atlantis/server/core/config/valid"
Expand Down Expand Up @@ -45,6 +46,7 @@ func NewInstrumentedProjectCommandBuilder(
skipCloneNoChanges bool,
EnableRegExpCmd bool,
AutoplanFileList string,
StrictPlanFileList bool,
scope tally.Scope,
logger logging.SimpleLogging,
) *InstrumentedProjectCommandBuilder {
Expand All @@ -62,6 +64,7 @@ func NewInstrumentedProjectCommandBuilder(
skipCloneNoChanges,
EnableRegExpCmd,
AutoplanFileList,
StrictPlanFileList,
scope,
logger,
),
Expand All @@ -82,6 +85,7 @@ func NewProjectCommandBuilder(
skipCloneNoChanges bool,
EnableRegExpCmd bool,
AutoplanFileList string,
StrictPlanFileList bool,
scope tally.Scope,
logger logging.SimpleLogging,
) *DefaultProjectCommandBuilder {
Expand All @@ -96,6 +100,7 @@ func NewProjectCommandBuilder(
SkipCloneNoChanges: skipCloneNoChanges,
EnableRegExpCmd: EnableRegExpCmd,
AutoplanFileList: AutoplanFileList,
StrictPlanFileList: StrictPlanFileList,
ProjectCommandContextBuilder: NewProjectCommandContextBuilder(
policyChecksSupported,
commentBuilder,
Expand Down Expand Up @@ -159,6 +164,7 @@ type DefaultProjectCommandBuilder struct {
EnableRegExpCmd bool
AutoplanFileList string
EnableDiffMarkdownFormat bool
StrictPlanFileList bool
}

// See ProjectCommandBuilder.BuildAutoplanCommands.
Expand Down Expand Up @@ -345,6 +351,27 @@ func (p *DefaultProjectCommandBuilder) buildProjectPlanCommand(ctx *command.Cont
workspace = cmd.Workspace
}

if p.StrictPlanFileList {
Fabianoshz marked this conversation as resolved.
Show resolved Hide resolved
modifiedFiles, err := p.VCSClient.GetModifiedFiles(ctx.Pull.BaseRepo, ctx.Pull)
nitrocode marked this conversation as resolved.
Show resolved Hide resolved
if err != nil {
return nil, err
}

if cmd.RepoRelDir != "" {
foundDir := false

for _, f := range modifiedFiles {
if filepath.Dir(f) == cmd.RepoRelDir {
foundDir = true
}
}

if !foundDir {
return nil, fmt.Errorf("the dir \"%s\" is not in the plan list of this pull request", cmd.RepoRelDir)
}
}
}

var pcc []command.ProjectContext
ctx.Log.Debug("building plan command")
unlockFn, err := p.WorkingDirLocker.TryLock(ctx.Pull.BaseRepo.FullName, ctx.Pull.Num, workspace, DefaultRepoRelDir)
Expand Down
3 changes: 3 additions & 0 deletions server/events/project_command_builder_internal_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -626,6 +626,7 @@ projects:
false,
false,
"**/*.tf,**/*.tfvars,**/*.tfvars.json,**/terragrunt.hcl,**/.terraform.lock.hcl",
false,
statsScope,
logger,
)
Expand Down Expand Up @@ -828,6 +829,7 @@ projects:
false,
true,
"**/*.tf,**/*.tfvars,**/*.tfvars.json,**/terragrunt.hcl,**/.terraform.lock.hcl",
false,
statsScope,
logger,
)
Expand Down Expand Up @@ -1058,6 +1060,7 @@ workflows:
false,
false,
"**/*.tf,**/*.tfvars,**/*.tfvars.json,**/terragrunt.hcl,**/.terraform.lock.hcl",
false,
statsScope,
logger,
)
Expand Down
10 changes: 10 additions & 0 deletions server/events/project_command_builder_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@ projects:
false,
false,
"**/*.tf,**/*.tfvars,**/*.tfvars.json,**/terragrunt.hcl,**/.terraform.lock.hcl",
false,
scope,
logger,
)
Expand Down Expand Up @@ -427,6 +428,7 @@ projects:
false,
true,
"**/*.tf,**/*.tfvars,**/*.tfvars.json,**/terragrunt.hcl,**/.terraform.lock.hcl",
false,
scope,
logger,
)
Expand Down Expand Up @@ -582,6 +584,7 @@ projects:
false,
false,
"**/*.tf,**/*.tfvars,**/*.tfvars.json,**/terragrunt.hcl,**/.terraform.lock.hcl",
false,
scope,
logger,
)
Expand Down Expand Up @@ -673,6 +676,7 @@ func TestDefaultProjectCommandBuilder_BuildMultiApply(t *testing.T) {
false,
false,
"**/*.tf,**/*.tfvars,**/*.tfvars.json,**/terragrunt.hcl,**/.terraform.lock.hcl",
false,
scope,
logger,
)
Expand Down Expand Up @@ -758,6 +762,7 @@ projects:
false,
false,
"**/*.tf,**/*.tfvars,**/*.tfvars.json,**/terragrunt.hcl,**/.terraform.lock.hcl",
false,
scope,
logger,
)
Expand Down Expand Up @@ -837,6 +842,7 @@ func TestDefaultProjectCommandBuilder_EscapeArgs(t *testing.T) {
false,
false,
"**/*.tf,**/*.tfvars,**/*.tfvars.json,**/terragrunt.hcl,**/.terraform.lock.hcl",
false,
scope,
logger,
)
Expand Down Expand Up @@ -1020,6 +1026,7 @@ projects:
false,
false,
"**/*.tf,**/*.tfvars,**/*.tfvars.json,**/terragrunt.hcl,**/.terraform.lock.hcl",
false,
scope,
logger,
)
Expand Down Expand Up @@ -1087,6 +1094,7 @@ projects:
true,
false,
"**/*.tf,**/*.tfvars,**/*.tfvars.json,**/terragrunt.hcl,**/.terraform.lock.hcl",
false,
scope,
logger,
)
Expand Down Expand Up @@ -1145,6 +1153,7 @@ func TestDefaultProjectCommandBuilder_WithPolicyCheckEnabled_BuildAutoplanComman
false,
false,
"**/*.tf,**/*.tfvars,**/*.tfvars.json,**/terragrunt.hcl,**/.terraform.lock.hcl",
false,
scope,
logger,
)
Expand Down Expand Up @@ -1227,6 +1236,7 @@ func TestDefaultProjectCommandBuilder_BuildVersionCommand(t *testing.T) {
false,
false,
"**/*.tf,**/*.tfvars,**/*.tfvars.json,**/terragrunt.hcl,**/.terraform.lock.hcl",
false,
scope,
logger,
)
Expand Down
1 change: 1 addition & 0 deletions server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -507,6 +507,7 @@ func NewServer(userConfig UserConfig, config Config) (*Server, error) {
userConfig.SkipCloneNoChanges,
userConfig.EnableRegExpCmd,
userConfig.AutoplanFileList,
userConfig.StrictPlanFileList,
statsScope,
logger,
)
Expand Down
1 change: 1 addition & 0 deletions server/user_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ type UserConfig struct {
SlackToken string `mapstructure:"slack-token"`
SSLCertFile string `mapstructure:"ssl-cert-file"`
SSLKeyFile string `mapstructure:"ssl-key-file"`
StrictPlanFileList bool `mapstructure:"strict-plan-file-list"`
TFDownloadURL string `mapstructure:"tf-download-url"`
TFEHostname string `mapstructure:"tfe-hostname"`
TFELocalExecutionMode bool `mapstructure:"tfe-local-execution-mode"`
Expand Down