From 7ac8106f8a113da3640401db3736fe747ea27482 Mon Sep 17 00:00:00 2001 From: Nish Krishnan Date: Tue, 6 Apr 2021 12:02:25 -0700 Subject: [PATCH 01/13] Add structured logger (#54) (#1467) This is two changes: Replacing all usages of SimpleLogger with it's interface SimpleLogging which makes it easier to swap out loggers going forward Nukes SimpleLogger in favor of StructuredLogger which allows us to better analyze logs in our log management system we choose. --- cmd/server.go | 2 +- cmd/server_test.go | 69 ++-- go.mod | 25 +- go.sum | 145 +++++++-- main.go | 10 +- server/events/apply_command_runner_test.go | 3 +- server/events/command_context.go | 2 +- server/events/command_runner.go | 12 +- server/events/command_runner_test.go | 24 +- server/events/delete_lock_command.go | 2 +- server/events/delete_lock_command_test.go | 14 +- server/events/git_cred_writer.go | 2 +- server/events/git_cred_writer_test.go | 2 +- server/events/github_app_working_dir.go | 2 +- server/events/github_app_working_dir_test.go | 11 +- .../matchers/ptr_to_logging_simplelogger.go | 12 +- server/events/mock_workingdir_test.go | 12 +- .../matchers/ptr_to_logging_simplelogger.go | 12 +- server/events/mocks/mock_project_lock.go | 12 +- server/events/mocks/mock_webhooks_sender.go | 12 +- server/events/mocks/mock_working_dir.go | 12 +- server/events/models/models.go | 2 +- .../pre_workflow_hooks_command_runner_test.go | 2 +- .../project_command_builder_internal_test.go | 31 +- server/events/project_command_builder_test.go | 44 ++- server/events/project_command_runner.go | 2 +- server/events/project_command_runner_test.go | 6 +- server/events/project_finder.go | 8 +- server/events/project_finder_test.go | 4 +- server/events/project_locker.go | 4 +- server/events/project_locker_test.go | 6 +- server/events/pull_updater.go | 2 +- .../events/runtime/apply_step_runner_test.go | 23 +- server/events/runtime/env_step_runner_test.go | 2 +- server/events/runtime/executor.go | 2 +- .../events/runtime/init_step_runner_test.go | 15 +- .../matchers/ptr_to_logging_simplelogger.go | 12 +- .../mocks/mock_versionedexecutorworkflow.go | 12 +- .../events/runtime/plan_step_runner_test.go | 30 +- .../events/runtime/policy/conftest_client.go | 4 +- .../runtime/policy/conftest_client_test.go | 4 +- .../runtime/policy_check_step_runner_test.go | 2 +- .../runtime/pre_workflow_hook_runner_test.go | 2 +- server/events/runtime/run_step_runner_test.go | 2 +- server/events/runtime/runtime.go | 6 +- .../events/runtime/show_step_runner_test.go | 2 +- .../matchers/ptr_to_logging_simplelogger.go | 12 +- .../terraform/mocks/mock_terraform_client.go | 24 +- server/events/terraform/terraform_client.go | 16 +- .../terraform_client_internal_test.go | 17 +- .../events/terraform/terraform_client_test.go | 42 ++- server/events/vcs/github_client.go | 4 +- .../events/vcs/github_client_internal_test.go | 5 +- server/events/vcs/github_client_test.go | 26 +- server/events/vcs/github_credentials_test.go | 7 +- server/events/vcs/gitlab_client.go | 2 +- server/events/vcs/gitlab_client_test.go | 4 +- .../matchers/ptr_to_logging_simplelogger.go | 18 +- server/events/webhooks/mocks/mock_sender.go | 12 +- server/events/webhooks/slack.go | 2 +- server/events/webhooks/slack_test.go | 4 +- server/events/webhooks/webhooks.go | 4 +- server/events/webhooks/webhooks_test.go | 4 +- server/events/working_dir.go | 8 +- server/events/working_dir_test.go | 23 +- server/events/yaml/valid/global_cfg_test.go | 4 +- server/events_controller.go | 2 +- server/events_controller_e2e_test.go | 11 +- server/events_controller_test.go | 13 +- server/github_app_controller.go | 2 +- server/locks_controller.go | 2 +- server/locks_controller_test.go | 34 +- server/logging/logging_test.go | 20 +- .../mocks/matchers/logging_loglevel.go | 15 +- .../mocks/matchers/logging_simplelogging.go | 33 ++ .../matchers/ptr_to_logging_simplelogger.go | 12 +- server/logging/mocks/mock_simple_logging.go | 160 +++++++--- server/logging/simple_logger.go | 294 +++++++++--------- server/middleware.go | 4 +- server/server.go | 11 +- server/server_test.go | 2 + server/status_controller.go | 2 +- server/status_controller_test.go | 6 +- 83 files changed, 888 insertions(+), 599 deletions(-) create mode 100644 server/logging/mocks/matchers/logging_simplelogging.go diff --git a/cmd/server.go b/cmd/server.go index 0220e2247f..23a91abd60 100644 --- a/cmd/server.go +++ b/cmd/server.go @@ -406,7 +406,7 @@ type ServerCmd struct { // Useful for testing to keep the logs clean. SilenceOutput bool AtlantisVersion string - Logger *logging.SimpleLogger + Logger logging.SimpleLogging } // ServerCreator creates servers. diff --git a/cmd/server_test.go b/cmd/server_test.go index c98c5c0bd5..f80b325131 100644 --- a/cmd/server_test.go +++ b/cmd/server_test.go @@ -24,6 +24,7 @@ import ( homedir "github.com/mitchellh/go-homedir" "github.com/runatlantis/atlantis/server" + "github.com/runatlantis/atlantis/server/logging" . "github.com/runatlantis/atlantis/testing" "github.com/spf13/cobra" "github.com/spf13/viper" @@ -111,7 +112,7 @@ func TestExecute_Defaults(t *testing.T) { GHUserFlag: "user", GHTokenFlag: "token", RepoAllowlistFlag: "*", - }) + }, t) err := c.Execute() Ok(t, err) @@ -155,7 +156,7 @@ func TestExecute_Defaults(t *testing.T) { func TestExecute_Flags(t *testing.T) { t.Log("Should use all flags that are set.") - c := setup(testFlags) + c := setup(testFlags, t) err := c.Execute() Ok(t, err) for flag, exp := range testFlags { @@ -173,7 +174,7 @@ func TestExecute_ConfigFile(t *testing.T) { defer os.Remove(tmpFile) // nolint: errcheck c := setup(map[string]interface{}{ ConfigFlag: tmpFile, - }) + }, t) err := c.Execute() Ok(t, err) for flag, exp := range testFlags { @@ -188,7 +189,7 @@ func TestExecute_EnvironmentVariables(t *testing.T) { os.Setenv(envKey, fmt.Sprintf("%v", value)) // nolint: errcheck defer func(key string) { os.Unsetenv(key) }(envKey) } - c := setup(nil) + c := setup(nil, t) err := c.Execute() Ok(t, err) for flag, exp := range testFlags { @@ -200,7 +201,7 @@ func TestExecute_NoConfigFlag(t *testing.T) { t.Log("If there is no config flag specified Execute should return nil.") c := setupWithDefaults(map[string]interface{}{ ConfigFlag: "", - }) + }, t) err := c.Execute() Ok(t, err) } @@ -209,7 +210,7 @@ func TestExecute_ConfigFileExtension(t *testing.T) { t.Log("If the config file doesn't have an extension then error.") c := setupWithDefaults(map[string]interface{}{ ConfigFlag: "does-not-exist", - }) + }, t) err := c.Execute() Equals(t, "invalid config: reading does-not-exist: Unsupported Config Type \"\"", err.Error()) } @@ -218,7 +219,7 @@ func TestExecute_ConfigFileMissing(t *testing.T) { t.Log("If the config file doesn't exist then error.") c := setupWithDefaults(map[string]interface{}{ ConfigFlag: "does-not-exist.yaml", - }) + }, t) err := c.Execute() Equals(t, "invalid config: reading does-not-exist.yaml: open does-not-exist.yaml: no such file or directory", err.Error()) } @@ -229,7 +230,7 @@ func TestExecute_ConfigFileExists(t *testing.T) { defer os.Remove(tmpFile) // nolint: errcheck c := setupWithDefaults(map[string]interface{}{ ConfigFlag: tmpFile, - }) + }, t) err := c.Execute() Ok(t, err) } @@ -240,7 +241,7 @@ func TestExecute_InvalidConfig(t *testing.T) { defer os.Remove(tmpFile) // nolint: errcheck c := setupWithDefaults(map[string]interface{}{ ConfigFlag: tmpFile, - }) + }, t) err := c.Execute() Assert(t, strings.Contains(err.Error(), "unmarshal errors"), "should be an unmarshal error") } @@ -251,7 +252,7 @@ func TestExecute_RepoAllowlistScheme(t *testing.T) { GHUserFlag: "user", GHTokenFlag: "token", RepoAllowlistFlag: "http://github.com/*", - }) + }, t) err := c.Execute() Assert(t, err != nil, "should be an error") Equals(t, "--repo-allowlist cannot contain ://, should be hostnames only", err.Error()) @@ -280,7 +281,7 @@ func TestExecute_ValidateLogLevel(t *testing.T) { } for _, testCase := range cases { t.Log("Should validate log level when " + testCase.description) - c := setupWithDefaults(testCase.flags) + c := setupWithDefaults(testCase.flags, t) err := c.Execute() if testCase.expectError { Assert(t, err != nil, "should be an error") @@ -293,7 +294,7 @@ func TestExecute_ValidateLogLevel(t *testing.T) { func TestExecute_ValidateCheckoutStrategy(t *testing.T) { c := setupWithDefaults(map[string]interface{}{ CheckoutStrategyFlag: "invalid", - }) + }, t) err := c.Execute() ErrEquals(t, "invalid checkout strategy: not one of branch or merge", err) } @@ -335,7 +336,7 @@ func TestExecute_ValidateSSLConfig(t *testing.T) { } for _, testCase := range cases { t.Log("Should validate ssl config when " + testCase.description) - c := setupWithDefaults(testCase.flags) + c := setupWithDefaults(testCase.flags, t) err := c.Execute() if testCase.expectError { Assert(t, err != nil, "should be an error") @@ -511,7 +512,7 @@ func TestExecute_ValidateVCSConfig(t *testing.T) { t.Log("Should validate vcs config when " + testCase.description) testCase.flags[RepoAllowlistFlag] = "*" - c := setup(testCase.flags) + c := setup(testCase.flags, t) err := c.Execute() if testCase.expectError { Assert(t, err != nil, "should be an error") @@ -529,7 +530,7 @@ func TestExecute_ExpandHomeInDataDir(t *testing.T) { GHTokenFlag: "token", RepoAllowlistFlag: "*", DataDirFlag: "~/this/is/a/path", - }) + }, t) err := c.Execute() Ok(t, err) @@ -542,7 +543,7 @@ func TestExecute_RelativeDataDir(t *testing.T) { t.Log("Should convert relative dir to absolute.") c := setupWithDefaults(map[string]interface{}{ DataDirFlag: "../", - }) + }, t) // Figure out what ../ should be as an absolute path. expectedAbsolutePath, err := filepath.Abs("../") @@ -559,7 +560,7 @@ func TestExecute_GithubUser(t *testing.T) { GHUserFlag: "@user", GHTokenFlag: "token", RepoAllowlistFlag: "*", - }) + }, t) err := c.Execute() Ok(t, err) @@ -572,7 +573,7 @@ func TestExecute_GithubApp(t *testing.T) { GHAppKeyFileFlag: "key.pem", GHAppIDFlag: "1", RepoAllowlistFlag: "*", - }) + }, t) err := c.Execute() Ok(t, err) @@ -585,7 +586,7 @@ func TestExecute_GitlabUser(t *testing.T) { GitlabUserFlag: "@user", GitlabTokenFlag: "token", RepoAllowlistFlag: "*", - }) + }, t) err := c.Execute() Ok(t, err) @@ -598,7 +599,7 @@ func TestExecute_BitbucketUser(t *testing.T) { BitbucketUserFlag: "@user", BitbucketTokenFlag: "token", RepoAllowlistFlag: "*", - }) + }, t) err := c.Execute() Ok(t, err) @@ -611,7 +612,7 @@ func TestExecute_ADUser(t *testing.T) { ADUserFlag: "@user", ADTokenFlag: "token", RepoAllowlistFlag: "*", - }) + }, t) err := c.Execute() Ok(t, err) @@ -625,7 +626,7 @@ func TestExecute_BitbucketCloudWithWebhookSecret(t *testing.T) { BitbucketTokenFlag: "token", RepoAllowlistFlag: "*", BitbucketWebhookSecretFlag: "my secret", - }) + }, t) err := c.Execute() ErrEquals(t, "--bitbucket-webhook-secret cannot be specified for Bitbucket Cloud because it is not supported by Bitbucket", err) } @@ -637,7 +638,7 @@ func TestExecute_BitbucketServerBaseURLScheme(t *testing.T) { BitbucketTokenFlag: "token", RepoAllowlistFlag: "*", BitbucketBaseURLFlag: "mydomain.com", - }) + }, t) ErrEquals(t, "--bitbucket-base-url must have http:// or https://, got \"mydomain.com\"", c.Execute()) c = setup(map[string]interface{}{ @@ -645,7 +646,7 @@ func TestExecute_BitbucketServerBaseURLScheme(t *testing.T) { BitbucketTokenFlag: "token", RepoAllowlistFlag: "*", BitbucketBaseURLFlag: "://mydomain.com", - }) + }, t) ErrEquals(t, "error parsing --bitbucket-webhook-secret flag value \"://mydomain.com\": parse \"://mydomain.com\": missing protocol scheme", c.Execute()) } @@ -656,7 +657,7 @@ func TestExecute_BitbucketServerBaseURLPort(t *testing.T) { BitbucketTokenFlag: "token", RepoAllowlistFlag: "*", BitbucketBaseURLFlag: "http://mydomain.com:7990", - }) + }, t) Ok(t, c.Execute()) Equals(t, "http://mydomain.com:7990", passedConfig.BitbucketBaseURL) } @@ -669,7 +670,7 @@ func TestExecute_RepoCfgFlags(t *testing.T) { RepoAllowlistFlag: "github.com", RepoConfigFlag: "repos.yaml", RepoConfigJSONFlag: "{}", - }) + }, t) err := c.Execute() ErrEquals(t, "cannot use --repo-config and --repo-config-json at the same time", err) } @@ -681,7 +682,7 @@ func TestExecute_TFEHostnameOnly(t *testing.T) { GHTokenFlag: "token", RepoAllowlistFlag: "github.com", TFEHostnameFlag: "not-app.terraform.io", - }) + }, t) err := c.Execute() ErrEquals(t, "if setting --tfe-hostname, must set --tfe-token", err) } @@ -693,7 +694,7 @@ func TestExecute_BothAllowAndWhitelist(t *testing.T) { GHTokenFlag: "token", RepoAllowlistFlag: "github.com", RepoWhitelistFlag: "github.com", - }) + }, t) err := c.Execute() ErrEquals(t, "both --repo-allowlist and --repo-whitelist cannot be set–use --repo-allowlist", err) } @@ -703,7 +704,7 @@ func TestExecute_AllowAndWhitelist(t *testing.T) { c := setup(map[string]interface{}{ GHUserFlag: "user", GHTokenFlag: "token", - }) + }, t) err := c.Execute() ErrEquals(t, "--repo-allowlist must be set for security purposes", err) } @@ -716,7 +717,7 @@ func TestExecute_BothSilenceAllowAndWhitelistErrors(t *testing.T) { RepoAllowlistFlag: "*", SilenceWhitelistErrorsFlag: true, SilenceAllowlistErrorsFlag: true, - }) + }, t) err := c.Execute() ErrEquals(t, "both --silence-allowlist-errors and --silence-whitelist-errors cannot be set–use --silence-allowlist-errors", err) } @@ -729,14 +730,14 @@ func TestExecute_RepoWhitelistDeprecation(t *testing.T) { GHTokenFlag: "token", RepoWhitelistFlag: "*", SilenceWhitelistErrorsFlag: true, - }) + }, t) err := c.Execute() Ok(t, err) Equals(t, true, passedConfig.SilenceAllowlistErrors) Equals(t, "*", passedConfig.RepoAllowlist) } -func setup(flags map[string]interface{}) *cobra.Command { +func setup(flags map[string]interface{}, t *testing.T) *cobra.Command { vipr := viper.New() for k, v := range flags { vipr.Set(k, v) @@ -745,11 +746,12 @@ func setup(flags map[string]interface{}) *cobra.Command { ServerCreator: &ServerCreatorMock{}, Viper: vipr, SilenceOutput: true, + Logger: logging.NewNoopLogger(t), } return c.Init() } -func setupWithDefaults(flags map[string]interface{}) *cobra.Command { +func setupWithDefaults(flags map[string]interface{}, t *testing.T) *cobra.Command { vipr := viper.New() flags[GHUserFlag] = "user" flags[GHTokenFlag] = "token" @@ -762,6 +764,7 @@ func setupWithDefaults(flags map[string]interface{}) *cobra.Command { ServerCreator: &ServerCreatorMock{}, Viper: vipr, SilenceOutput: true, + Logger: logging.NewNoopLogger(t), } return c.Init() } diff --git a/go.mod b/go.mod index 68fd6edee9..22af4dd0ba 100644 --- a/go.mod +++ b/go.mod @@ -2,59 +2,70 @@ module github.com/runatlantis/atlantis go 1.16 +replace google.golang.org/grpc => google.golang.org/grpc v1.29.1 + require ( github.com/Laisky/graphql v1.0.5 github.com/Masterminds/sprig/v3 v3.2.2 github.com/agext/levenshtein v1.2.3 // indirect github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a // indirect - github.com/aws/aws-sdk-go v1.17.14 // indirect + github.com/aws/aws-sdk-go v1.31.15 // indirect github.com/bradleyfalzon/ghinstallation v1.1.1 github.com/briandowns/spinner v0.0.0-20170614154858-48dbb65d7bd5 - github.com/davecgh/go-spew v1.1.1 + github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc github.com/dgrijalva/jwt-go v3.2.0+incompatible github.com/docker/docker v0.0.0-20180620051407-e2593239d949 github.com/elazarl/go-bindata-assetfs v1.0.1 github.com/flynn-archive/go-shlex v0.0.0-20150515145356-3f9db97f8568 + github.com/fsnotify/fsnotify v1.4.10-0.20200417215612-7f4cf4dd2b52 // indirect github.com/go-ozzo/ozzo-validation v0.0.0-20170913164239-85dcd8368eba github.com/go-playground/locales v0.12.1 // indirect github.com/go-playground/universal-translator v0.16.0 // indirect github.com/go-test/deep v1.0.7 github.com/google/go-cmp v0.5.2 // indirect github.com/google/go-github/v31 v31.0.0 + github.com/google/uuid v1.1.2-0.20200519141726-cb32006e483f // indirect github.com/gorilla/mux v1.8.0 github.com/hashicorp/go-getter v1.5.2 github.com/hashicorp/go-version v1.2.1 github.com/hashicorp/hcl/v2 v2.6.0 // indirect github.com/hashicorp/terraform-config-inspect v0.0.0-20200806211835-c481b8bfa41e github.com/inconshreveable/mousetrap v1.0.0 // indirect + github.com/jmespath/go-jmespath v0.3.1-0.20200310193758-2437e8417af5 // indirect + github.com/kelseyhightower/envconfig v1.4.1-0.20200624135755-c974cae29cf5 // indirect github.com/leodido/go-urn v1.2.0 // indirect github.com/lusis/slack-test v0.0.0-20190426140909-c40012f20018 // indirect + github.com/lyft/gostats v0.4.5 github.com/mcdafydd/go-azuredevops v0.12.0 github.com/microcosm-cc/bluemonday v1.0.5 github.com/mitchellh/colorstring v0.0.0-20150917214807-8631ce90f286 github.com/mitchellh/go-homedir v1.1.0 github.com/mohae/deepcopy v0.0.0-20170603005431-491d3605edfb github.com/nlopes/slack v0.4.0 - github.com/onsi/ginkgo v1.9.0 // indirect - github.com/onsi/gomega v1.4.3 // indirect github.com/petergtz/pegomock v2.9.0+incompatible github.com/pkg/errors v0.9.1 github.com/remeh/sizedwaitgroup v1.0.0 github.com/shurcooL/githubv4 v0.0.0-20191127044304-8f68eb5628d0 github.com/shurcooL/graphql v0.0.0-20181231061246-d48a9a75455f // indirect + github.com/sirupsen/logrus v1.6.1-0.20200528085638-6699a89a232f // indirect github.com/spf13/cobra v0.0.0-20170905172051-b78744579491 github.com/spf13/pflag v1.0.5 github.com/spf13/viper v1.7.1 + github.com/stretchr/testify v1.6.1 github.com/urfave/cli v1.22.5 github.com/urfave/negroni v0.3.0 github.com/xanzy/go-gitlab v0.47.0 github.com/zclconf/go-cty v1.5.1 // indirect go.etcd.io/bbolt v1.3.5 - golang.org/x/crypto v0.0.0-20200414173820-0848c9571904 - golang.org/x/net v0.0.0-20191126235420-ef20fe5d7933 // indirect + go.opencensus.io v0.22.3 // indirect + go.uber.org/zap v1.15.0 + golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 golang.org/x/oauth2 v0.0.0-20191122200657-5d9234df094c // indirect - golang.org/x/text v0.3.3 // indirect + golang.org/x/tools v0.0.0-20201023174141-c8cfbd0f21e6 // indirect google.golang.org/appengine v1.6.5 // indirect + google.golang.org/genproto v0.0.0-20200701001935-0939c5918c31 // indirect + google.golang.org/grpc v1.30.0 // indirect + google.golang.org/protobuf v1.25.1-0.20200622203222-a9513ebdb860 // indirect gopkg.in/go-playground/assert.v1 v1.2.1 // indirect gopkg.in/go-playground/validator.v9 v9.31.0 gopkg.in/yaml.v2 v2.4.0 diff --git a/go.sum b/go.sum index 4008e09c1b..a497d0b689 100644 --- a/go.sum +++ b/go.sum @@ -1,4 +1,3 @@ -cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= @@ -45,8 +44,8 @@ github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a h1:idn718Q4B6AGu/h5Sxe66HYVdqdGu2l9Iebqhi/AEoA= github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= github.com/aws/aws-sdk-go v1.15.78/go.mod h1:E3/ieXAlvM0XWO57iftYVDLLvQ824smPP3ATZkfNZeM= -github.com/aws/aws-sdk-go v1.17.14 h1:IjqZDIQoLyZ48A93BxVrZOaIGgZPRi4nXt6WQUMJplY= -github.com/aws/aws-sdk-go v1.17.14/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= +github.com/aws/aws-sdk-go v1.31.15 h1:1Ahi6nvJLg5cjO5i3U7BWh91/zOw//tqOTLpLnIeyss= +github.com/aws/aws-sdk-go v1.31.15/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZveU8YkpAk0= github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk= github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= @@ -59,11 +58,12 @@ github.com/bradleyfalzon/ghinstallation v1.1.1 h1:pmBXkxgM1WeF8QYvDLT5kuQiHMcmf+ github.com/bradleyfalzon/ghinstallation v1.1.1/go.mod h1:vyCmHTciHx/uuyN82Zc3rXN3X2KTK8nUTCrTMwAhcug= github.com/briandowns/spinner v0.0.0-20170614154858-48dbb65d7bd5 h1:osZyZB7J4kE1tKLeaUjV6+uZVBfS835T0I/RxmwWw1w= github.com/briandowns/spinner v0.0.0-20170614154858-48dbb65d7bd5/go.mod h1:hw/JEQBIE+c/BLI4aKM8UU8v+ZqrD3h7HC27kKt8JQU= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cheggaaa/pb v1.0.27/go.mod h1:pQciLPpbU0oxA0h+VJYYLxO+XeDQb5pZijXscXHm81s= github.com/chris-ramon/douceur v0.2.0 h1:IDMEdxlEUUBYBKE4z/mJnFyVXox+MjuEVDJNN27glkU= github.com/chris-ramon/douceur v0.2.0/go.mod h1:wDW5xjJdeoMm1mRt4sD4c/LbF/mWdEpRXQKjTR8nIBE= -github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= @@ -74,6 +74,8 @@ github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:ma github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= @@ -81,12 +83,17 @@ github.com/docker/docker v0.0.0-20180620051407-e2593239d949 h1:La/qO5ApRpiO4c0wG github.com/docker/docker v0.0.0-20180620051407-e2593239d949/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/elazarl/go-bindata-assetfs v1.0.1 h1:m0kkaHRKEu7tUIUFVwhGGGYClXvyl4RE03qmvRTNfbw= github.com/elazarl/go-bindata-assetfs v1.0.1/go.mod h1:v+YaWX3bdea5J/mo8dSETolEo7R71Vk1u8bnjau5yw4= +github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/flynn-archive/go-shlex v0.0.0-20150515145356-3f9db97f8568 h1:BMXYYRWTLOJKlh+lOBt6nUQgXAfB7oVIQt5cNreqSLI= github.com/flynn-archive/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:rZfgFAXFS/z/lEd6LJmf9HVZ1LkgYiHx5pHhV5DR16M= github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/fsnotify/fsnotify v1.4.10-0.20200417215612-7f4cf4dd2b52 h1:0NmERxogGTU8hgzOhRKNoKivtBZkDW29GeuJtK9e0sc= +github.com/fsnotify/fsnotify v1.4.10-0.20200417215612-7f4cf4dd2b52/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= @@ -98,28 +105,41 @@ github.com/go-playground/locales v0.12.1 h1:2FITxuFt/xuCNP1Acdhv62OzaCiviiE4kotf github.com/go-playground/locales v0.12.1/go.mod h1:IUMDtCfWo/w/mtMfIE/IG2K+Ey3ygWanZIBtBW0W2TM= github.com/go-playground/universal-translator v0.16.0 h1:X++omBR/4cE2MNg91AoC3rmGrCjJ8eAeUP/K/EKx4DM= github.com/go-playground/universal-translator v0.16.0/go.mod h1:1AnU7NaIRDWWzGEKwgtJRd2xk99HeFyHw3yid4rvQIY= +github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-test/deep v1.0.3/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= github.com/go-test/deep v1.0.7 h1:/VSMRlnY/JSyqxQUzQLKVMAskpY/NZKFA5j2P+0pP2M= github.com/go-test/deep v1.0.7/go.mod h1:QV8Hv/iy04NyLBxAdO9njL0iVPN1S4d/A3NVv1V36o8= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= -github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6 h1:ZgQEtGgCBiWRM39fZuwSd1LwSqqSW0hOdXCYYDX0R3I= +github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= github.com/golang/protobuf v1.1.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1 h1:ZFgWrT+bLgsYPirOnRfKLYJLvssAegOj/hgyMFdJZe0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.2 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-github/v29 v29.0.2 h1:opYN6Wc7DOz7Ku3Oh4l7prmkOMwEcQxpFtxdU8N8Pts= @@ -133,8 +153,9 @@ github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXi github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= -github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.1.2-0.20200519141726-cb32006e483f h1:qa1wFcvZzVLbFVPdsdTsWL6k5IP6BEmFmd9SeahRQ5s= +github.com/google/uuid v1.1.2-0.20200519141726-cb32006e483f/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5 h1:sjZBwGj9Jlw33ImPtvFviGYvseOtDM7hkSKB7+Tv3SM= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= @@ -177,7 +198,6 @@ github.com/hashicorp/go-version v1.2.1 h1:zEfKbn2+PDgroKdiOzqiE8rsmLqU2uwi5PB5pB github.com/hashicorp/go-version v1.2.1/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/hcl v0.0.0-20170504190234-a4b07c25de5f/go.mod h1:oZtUIOe8dh44I2q6ScRibXws4Ajl+d+nod3AaR9vL5w= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= @@ -200,8 +220,9 @@ github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= -github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af h1:pmfjZENx5imkbgOkpRUYLnmbU7UEFbjtDA2hxJ1ichM= -github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= +github.com/jmespath/go-jmespath v0.3.0/go.mod h1:9QtRXoHjLGCJ5IBSaohpXITPlowMeeYCZ7fLUTSywik= +github.com/jmespath/go-jmespath v0.3.1-0.20200310193758-2437e8417af5 h1:1G6l+WClVmbflmgW0Wsr6a50KeKCQcYKv/vUjtQUHuw= +github.com/jmespath/go-jmespath v0.3.1-0.20200310193758-2437e8417af5/go.mod h1:9QtRXoHjLGCJ5IBSaohpXITPlowMeeYCZ7fLUTSywik= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024 h1:rBMNdlhTLzJjJSDIjNEXX1Pz3Hmwmz91v+zycvx9PJc= @@ -209,11 +230,13 @@ github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1 github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/kelseyhightower/envconfig v1.4.0/go.mod h1:cccZRl6mQpaq41TPp5QxidR+Sa3axMbJDNb//FQX6Gg= +github.com/kelseyhightower/envconfig v1.4.1-0.20200624135755-c974cae29cf5 h1:TW7YQVw105jR4B+n/tAlkKNbYFSdWRK1RyLL5YYruso= +github.com/kelseyhightower/envconfig v1.4.1-0.20200624135755-c974cae29cf5/go.mod h1:cccZRl6mQpaq41TPp5QxidR+Sa3axMbJDNb//FQX6Gg= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.11.2 h1:MiK62aErc3gIiVEtyzKfeOHgW7atJb5g/KNX5m3c2nQ= github.com/klauspost/compress v1.11.2/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= -github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= @@ -228,6 +251,8 @@ github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y= github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= github.com/lusis/slack-test v0.0.0-20190426140909-c40012f20018 h1:MNApn+Z+fIT4NPZopPfCc1obT6aY3SVM6DOctz1A9ZU= github.com/lusis/slack-test v0.0.0-20190426140909-c40012f20018/go.mod h1:sFlOUpQL1YcjhFVXhg1CG8ZASEs/Mf1oVb6H75JL/zg= +github.com/lyft/gostats v0.4.5 h1:2KYdjsz+RfxeJAWqOpYUlyXgFgYd0SxPFUSFm9PdXM4= +github.com/lyft/gostats v0.4.5/go.mod h1:7ECvCenOq0N9BE6Tn+dtwFoS6xAwbvsx4tVSETO/hmc= github.com/magiconair/properties v1.8.1 h1:ZC2Vc7/ZFkGmsVC9KvOjumD+G5lXy2RtTKyzRKO2BQ4= github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/mattn/go-colorable v0.0.9 h1:UVL0vNpWh04HeJXV0KLcaT7r06gOH2l4OW6ddYRUIY4= @@ -269,12 +294,16 @@ github.com/mohae/deepcopy v0.0.0-20170603005431-491d3605edfb/go.mod h1:TaXosZuwd github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/nlopes/slack v0.4.0 h1:OVnHm7lv5gGT5gkcHsZAyw++oHVFihbjWbL3UceUpiA= github.com/nlopes/slack v0.4.0/go.mod h1:jVI4BBK3lSktibKahxBF74txcK2vyvkza1z/+rRnVAM= +github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78= +github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.9.0 h1:SZjF721BByVj8QH636/8S2DnX4n0Re3SteMmw3N+tzc= -github.com/onsi/ginkgo v1.9.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/gomega v1.4.3 h1:RE1xgDvH7imwFD45h+u2SgIfERHlS2yNG4DObb5BSKU= -github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= +github.com/onsi/ginkgo v1.14.0 h1:2mOpI4JVVPBN+WQRa0WKH2eXR+Ey+uK4n7Zj0aYpIQA= +github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= +github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= +github.com/onsi/gomega v1.10.1 h1:o0+MgICZLuZ7xjH7Vx6zS/zcu93/BEp1VwkIW1mEXCE= +github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc= @@ -292,6 +321,7 @@ github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXP github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= @@ -315,8 +345,10 @@ github.com/shurcooL/graphql v0.0.0-20181231061246-d48a9a75455f h1:tygelZueB1EtXk github.com/shurcooL/graphql v0.0.0-20181231061246-d48a9a75455f/go.mod h1:AuYgA5Kyo4c7HfUmvRGs/6rGlMMV/6B1bVnB9JxJEEg= github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= -github.com/sirupsen/logrus v1.2.0 h1:juTguoYk5qI21pwyTXY3B3Y5cOTH3ZUyZCg1v/mihuo= +github.com/sirupsen/logrus v1.0.6/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +github.com/sirupsen/logrus v1.6.1-0.20200528085638-6699a89a232f h1:qqqIhBDFUBrbMezIyJkKWIpf+E5CdObleGMjW1s19Hg= +github.com/sirupsen/logrus v1.6.1-0.20200528085638-6699a89a232f/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s= @@ -343,8 +375,9 @@ github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= @@ -358,6 +391,7 @@ github.com/vmihailenco/msgpack v3.3.3+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6Ac github.com/xanzy/go-gitlab v0.47.0 h1:nC35CNaGr9skHkJq1HMYZ58R7gZsy7SO37SkA2RIHbM= github.com/xanzy/go-gitlab v0.47.0/go.mod h1:sPLojNBn68fMUWSxIJtdVVIP8uSBYqesTfDUseX11Ug= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/zclconf/go-cty v1.1.0/go.mod h1:xnAOWiHeOqg2nWS62VtQ7pbOu17FtxJNW8RLEih+O3s= github.com/zclconf/go-cty v1.2.0/go.mod h1:hOPWgoHbaTUnI5k4D2ld+GRpFJSCe6bCM7m1q/N4PQ8= github.com/zclconf/go-cty v1.5.1 h1:oALUZX+aJeEBUe2a1+uD2+UTaYfEjnKFDEMRydkGvWE= @@ -366,20 +400,32 @@ go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/bbolt v1.3.5 h1:XAzx9gjCb0Rxj7EoqcClPD1d5ZBxZJk0jbuoPHenBt0= go.etcd.io/bbolt v1.3.5/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= -go.opencensus.io v0.22.0 h1:C9hSCOW830chIVkdja34wa6Ky+IzWllkUinR+BtRZd4= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= +go.opencensus.io v0.22.3 h1:8sGtKOrtQqkN1bp2AtX+misvLIlOmsEsNd+9NIcPEm8= +go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/atomic v1.6.0 h1:Ezj3JGmsOnG1MoRWQkPBsKLe9DwWD9QeXzTRzzldNVk= +go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= +go.uber.org/multierr v1.5.0 h1:KCa4XfM8CWFCpxXRGok+Q0SS/0XBhMDbHHGABQLvD2A= +go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= +go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee h1:0mgffUl7nfd+FpvXMVz4IDEaUSmT1ysygQC7qYo7sG4= +go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= +go.uber.org/zap v1.15.0 h1:ZZCA22JRF2gQE5FoNmhmrf7jeJJ2uhqDUNRYKm8dvmM= +go.uber.org/zap v1.15.0/go.mod h1:Mb2vm2krFEG5DV0W9qcHBYFtp/Wku1cvYaqPsS/WYfc= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200204104054-c9f3fb736b72/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200403201458-baeed622b8d8/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200414173820-0848c9571904 h1:bXoxMPcSLOq08zI3/c5dEBT6lE4eh+jOh886GHrn6V8= golang.org/x/crypto v0.0.0-20200414173820-0848c9571904/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -388,7 +434,6 @@ golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136 h1:A1gGSx58LAGVHUUsOf7IiR0u8 golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= -golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= @@ -400,9 +445,10 @@ golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= +golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180811021610-c39426892332/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181108082009-03003ca0c849/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -417,8 +463,10 @@ golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20191126235420-ef20fe5d7933 h1:e6HwijUxhDe+hPNjZQQn9bA5PW3vNmnN64U2ZW759Lk= -golang.org/x/net v0.0.0-20191126235420-ef20fe5d7933/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20201021035429-f5854403a974 h1:IX6qOQeG5uLjB/hjjwjedwfjND0hgjPMMyO1RoIXQNI= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181106182150-f42d05182288/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -430,10 +478,10 @@ golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190423024810-112230192c58 h1:8gQV6CLnAEikrhgkHFbMAEhagSSnXWGV915qUMm9mrU= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9 h1:SQFwaSi55rU7vdNs9Yr0Z324VNlrF+0wMqRXT4St8ck= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -447,8 +495,15 @@ golang.org/x/sys v0.0.0-20190502175342-a43fa875dd82/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5 h1:LfCXLvNmTYH9kEmVgqbnsWfruoXZIrh4YBgqVHtDvw0= +golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f h1:+Nyd8tzPX9R7BWHguqsrbFdRx3WQ/1ib8I44HXV5yTA= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= @@ -460,7 +515,6 @@ golang.org/x/time v0.0.0-20191024005414-555d28b269f0 h1:/5xXl8Y5W96D+TtHSlonuFqG golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= @@ -468,17 +522,24 @@ golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3 golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc h1:NCy3Ohtk6Iny5V/reW2Ktypo4zIpWBdRJ1uFMjBxdg8= +golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20201023174141-c8cfbd0f21e6 h1:rbvTkL9AkFts1cgI78+gG6Yu1pwaqX6hjSJAatB78E4= +golang.org/x/tools v0.0.0-20201023174141-c8cfbd0f21e6/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= @@ -500,12 +561,24 @@ google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRn google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= -google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a h1:Ob5/580gVHBJZgXnff1cZDbG+xLtMVE5mDRTe+nIsX4= google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= -google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= -google.golang.org/grpc v1.21.1 h1:j6XxA85m/6txkUCHvzlV5f+HBNl/1r5cZ2A/3IEFOO8= -google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/genproto v0.0.0-20200701001935-0939c5918c31 h1:Of4QP8bfRqzDROen6+s2j/p0jCPgzvQRd9nHiactfn4= +google.golang.org/genproto v0.0.0-20200701001935-0939c5918c31/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/grpc v1.29.1 h1:EC2SB8S04d2r73uptxphDSUG+kTKVgjRPF+N3xpxRB4= +google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= +google.golang.org/protobuf v1.25.1-0.20200622203222-a9513ebdb860 h1:tL2Vm8k2K9M9JSKg64klrDP2WV6W4cW7THc8GfJyBsQ= +google.golang.org/protobuf v1.25.1-0.20200622203222-a9513ebdb860/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= @@ -514,6 +587,7 @@ gopkg.in/cheggaaa/pb.v1 v1.0.27/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qS gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2/go.mod h1:Xk6kEKp8OKb+X14hQBKWaSkCsqBpgog8nAV2xsGOxlo= gopkg.in/go-playground/assert.v1 v1.2.1 h1:xoYuJVE7KT85PYWrN730RguIQO0ePzVRfFMXadIrXTM= gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE= gopkg.in/go-playground/validator.v9 v9.31.0 h1:bmXmP2RSNtFES+bn4uYuHT7iJFJv7Vj+an+ZQdDaD1M= @@ -530,11 +604,14 @@ gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.1-2019.2.3 h1:3JgtbtFHMiCmsznwGVTUWbgGov+pVqnlf1dEJTNAXeM= honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= diff --git a/main.go b/main.go index dc4307941a..43841b5498 100644 --- a/main.go +++ b/main.go @@ -15,6 +15,8 @@ package main import ( + "fmt" + "github.com/runatlantis/atlantis/cmd" "github.com/runatlantis/atlantis/server/logging" "github.com/spf13/viper" @@ -25,13 +27,19 @@ const atlantisVersion = "0.17.0-beta" func main() { v := viper.New() + logger, err := logging.NewStructuredLogger() + + if err != nil { + panic(fmt.Sprintf("unable to initialize logger. %s", err.Error())) + } + // We're creating commands manually here rather than using init() functions // (as recommended by cobra) because it makes testing easier. server := &cmd.ServerCmd{ ServerCreator: &cmd.DefaultServerCreator{}, Viper: v, AtlantisVersion: atlantisVersion, - Logger: logging.NewSimpleLogger("cmd", false, logging.Info), + Logger: logger, } version := &cmd.VersionCmd{AtlantisVersion: atlantisVersion} testdrive := &cmd.TestdriveCmd{} diff --git a/server/events/apply_command_runner_test.go b/server/events/apply_command_runner_test.go index 9a17e76589..49b171c2ee 100644 --- a/server/events/apply_command_runner_test.go +++ b/server/events/apply_command_runner_test.go @@ -10,6 +10,7 @@ import ( "github.com/runatlantis/atlantis/server/events/locking" "github.com/runatlantis/atlantis/server/events/models" "github.com/runatlantis/atlantis/server/events/models/fixtures" + "github.com/runatlantis/atlantis/server/logging" ) func TestApplyCommandRunner_IsLocked(t *testing.T) { @@ -54,7 +55,7 @@ func TestApplyCommandRunner_IsLocked(t *testing.T) { ctx := &events.CommandContext{ User: fixtures.User, - Log: noopLogger, + Log: logging.NewNoopLogger(t), Pull: modelPull, HeadRepo: fixtures.GithubRepo, Trigger: events.Comment, diff --git a/server/events/command_context.go b/server/events/command_context.go index 16c4abf67c..de48295dd0 100644 --- a/server/events/command_context.go +++ b/server/events/command_context.go @@ -39,7 +39,7 @@ type CommandContext struct { Pull models.PullRequest // User is the user that triggered this command. User models.User - Log *logging.SimpleLogger + Log logging.SimpleLogging // PullMergeable is true if Pull is able to be merged. This is available in // the CommandContext because we want to collect this information before we // set our own build statuses which can affect mergeability if users have diff --git a/server/events/command_runner.go b/server/events/command_runner.go index 5d78eebe3f..a851b85cbf 100644 --- a/server/events/command_runner.go +++ b/server/events/command_runner.go @@ -15,6 +15,7 @@ package events import ( "fmt" + "strconv" "github.com/google/go-github/v31/github" "github.com/mcdafydd/go-azuredevops/azuredevops" @@ -238,9 +239,12 @@ func (c *DefaultCommandRunner) getAzureDevopsData(baseRepo models.Repo, pullNum return pull, headRepo, nil } -func (c *DefaultCommandRunner) buildLogger(repoFullName string, pullNum int) *logging.SimpleLogger { - src := fmt.Sprintf("%s#%d", repoFullName, pullNum) - return c.Logger.NewLogger(src, true, c.Logger.GetLevel()) +func (c *DefaultCommandRunner) buildLogger(repoFullName string, pullNum int) logging.SimpleLogging { + + return c.Logger.WithHistory( + "repo", repoFullName, + "pull", strconv.Itoa(pullNum), + ) } func (c *DefaultCommandRunner) ensureValidRepoMetadata( @@ -249,7 +253,7 @@ func (c *DefaultCommandRunner) ensureValidRepoMetadata( maybePull *models.PullRequest, user models.User, pullNum int, - log *logging.SimpleLogger, + log logging.SimpleLogging, ) (headRepo models.Repo, pull models.PullRequest, err error) { if maybeHeadRepo != nil { headRepo = *maybeHeadRepo diff --git a/server/events/command_runner_test.go b/server/events/command_runner_test.go index 048ca25115..15d97be5ff 100644 --- a/server/events/command_runner_test.go +++ b/server/events/command_runner_test.go @@ -33,7 +33,6 @@ import ( "github.com/runatlantis/atlantis/server/events/models" "github.com/runatlantis/atlantis/server/events/models/fixtures" vcsmocks "github.com/runatlantis/atlantis/server/events/vcs/mocks" - logmocks "github.com/runatlantis/atlantis/server/logging/mocks" . "github.com/runatlantis/atlantis/testing" ) @@ -44,7 +43,6 @@ var azuredevopsGetter *mocks.MockAzureDevopsPullGetter var githubGetter *mocks.MockGithubPullGetter var gitlabGetter *mocks.MockGitlabMergeRequestGetter var ch events.DefaultCommandRunner -var pullLogger *logging.SimpleLogger var workingDir events.WorkingDir var pendingPlanFinder *mocks.MockPendingPlanFinder var drainer *events.Drainer @@ -73,8 +71,7 @@ func setup(t *testing.T) *vcsmocks.MockClient { githubGetter = mocks.NewMockGithubPullGetter() gitlabGetter = mocks.NewMockGitlabMergeRequestGetter() azuredevopsGetter = mocks.NewMockAzureDevopsPullGetter() - logger := logmocks.NewMockSimpleLogging() - pullLogger = logging.NewSimpleLogger("runatlantis/atlantis#1", true, logging.Info) + logger = logging.NewNoopLogger(t) projectCommandRunner = mocks.NewMockProjectCommandRunner() workingDir = mocks.NewMockWorkingDir() pendingPlanFinder = mocks.NewMockPendingPlanFinder() @@ -88,9 +85,6 @@ func setup(t *testing.T) *vcsmocks.MockClient { drainer = &events.Drainer{} deleteLockCommand = eventmocks.NewMockDeleteLockCommand() applyLockChecker = lockingmocks.NewMockApplyLockChecker() - When(logger.GetLevel()).ThenReturn(logging.Info) - When(logger.NewLogger("runatlantis/atlantis#1", true, logging.Info)). - ThenReturn(pullLogger) dbUpdater = &events.DBUpdater{ DB: defaultBoltDB, @@ -194,22 +188,6 @@ func TestRunCommentCommand_LogPanics(t *testing.T) { Assert(t, strings.Contains(comment, "Error: goroutine panic"), fmt.Sprintf("comment should be about a goroutine panic but was %q", comment)) } -func TestRunCommentCommand_NoGithubPullGetter(t *testing.T) { - t.Log("if DefaultCommandRunner was constructed with a nil GithubPullGetter an error should be logged") - setup(t) - ch.GithubPullGetter = nil - ch.RunCommentCommand(fixtures.GithubRepo, &fixtures.GithubRepo, nil, fixtures.User, 1, nil) - Equals(t, "[EROR] Atlantis not configured to support GitHub\n", pullLogger.History.String()) -} - -func TestRunCommentCommand_NoGitlabMergeGetter(t *testing.T) { - t.Log("if DefaultCommandRunner was constructed with a nil GitlabMergeRequestGetter an error should be logged") - setup(t) - ch.GitlabMergeRequestGetter = nil - ch.RunCommentCommand(fixtures.GitlabRepo, &fixtures.GitlabRepo, nil, fixtures.User, 1, nil) - Equals(t, "[EROR] Atlantis not configured to support GitLab\n", pullLogger.History.String()) -} - func TestRunCommentCommand_GithubPullErr(t *testing.T) { t.Log("if getting the github pull request fails an error should be logged") vcsClient := setup(t) diff --git a/server/events/delete_lock_command.go b/server/events/delete_lock_command.go index 5ed05f0bc4..ff3cfd1680 100644 --- a/server/events/delete_lock_command.go +++ b/server/events/delete_lock_command.go @@ -18,7 +18,7 @@ type DeleteLockCommand interface { // DefaultDeleteLockCommand deletes a specific lock after a request from the LocksController. type DefaultDeleteLockCommand struct { Locker locking.Locker - Logger *logging.SimpleLogger + Logger logging.SimpleLogging WorkingDir WorkingDir WorkingDirLocker WorkingDirLocker DB *db.BoltDB diff --git a/server/events/delete_lock_command_test.go b/server/events/delete_lock_command_test.go index ba2acd8c07..9c34e80032 100644 --- a/server/events/delete_lock_command_test.go +++ b/server/events/delete_lock_command_test.go @@ -20,7 +20,7 @@ func TestDeleteLock_LockerErr(t *testing.T) { When(l.Unlock("id")).ThenReturn(nil, errors.New("err")) dlc := events.DefaultDeleteLockCommand{ Locker: l, - Logger: logging.NewNoopLogger(), + Logger: logging.NewNoopLogger(t), } _, err := dlc.DeleteLock("id") ErrEquals(t, "err", err) @@ -33,7 +33,7 @@ func TestDeleteLock_None(t *testing.T) { When(l.Unlock("id")).ThenReturn(nil, nil) dlc := events.DefaultDeleteLockCommand{ Locker: l, - Logger: logging.NewNoopLogger(), + Logger: logging.NewNoopLogger(t), } lock, err := dlc.DeleteLock("id") Ok(t, err) @@ -47,7 +47,7 @@ func TestDeleteLock_OldFormat(t *testing.T) { When(l.Unlock("id")).ThenReturn(&models.ProjectLock{}, nil) dlc := events.DefaultDeleteLockCommand{ Locker: l, - Logger: logging.NewNoopLogger(), + Logger: logging.NewNoopLogger(t), } lock, err := dlc.DeleteLock("id") Ok(t, err) @@ -78,7 +78,7 @@ func TestDeleteLock_Success(t *testing.T) { Ok(t, err) dlc := events.DefaultDeleteLockCommand{ Locker: l, - Logger: logging.NewNoopLogger(), + Logger: logging.NewNoopLogger(t), DB: db, WorkingDirLocker: workingDirLocker, WorkingDir: workingDir, @@ -98,7 +98,7 @@ func TestDeleteLocksByPull_LockerErr(t *testing.T) { When(l.UnlockByPull(repoName, pullNum)).ThenReturn(nil, errors.New("err")) dlc := events.DefaultDeleteLockCommand{ Locker: l, - Logger: logging.NewNoopLogger(), + Logger: logging.NewNoopLogger(t), } err := dlc.DeleteLocksByPull(repoName, pullNum) ErrEquals(t, "err", err) @@ -113,7 +113,7 @@ func TestDeleteLocksByPull_None(t *testing.T) { When(l.UnlockByPull(repoName, pullNum)).ThenReturn([]models.ProjectLock{}, nil) dlc := events.DefaultDeleteLockCommand{ Locker: l, - Logger: logging.NewNoopLogger(), + Logger: logging.NewNoopLogger(t), } err := dlc.DeleteLocksByPull(repoName, pullNum) Ok(t, err) @@ -128,7 +128,7 @@ func TestDeleteLocksByPull_OldFormat(t *testing.T) { When(l.UnlockByPull(repoName, pullNum)).ThenReturn([]models.ProjectLock{{}}, nil) dlc := events.DefaultDeleteLockCommand{ Locker: l, - Logger: logging.NewNoopLogger(), + Logger: logging.NewNoopLogger(t), } err := dlc.DeleteLocksByPull(repoName, pullNum) Ok(t, err) diff --git a/server/events/git_cred_writer.go b/server/events/git_cred_writer.go index ab92d038c9..1eea384c2d 100644 --- a/server/events/git_cred_writer.go +++ b/server/events/git_cred_writer.go @@ -16,7 +16,7 @@ import ( // used for authenticating with git over HTTPS // It will create the file in home/.git-credentials // If ghAccessToken is true we will look for a line starting with https://x-access-token and ending with gitHostname and replace it. -func WriteGitCreds(gitUser string, gitToken string, gitHostname string, home string, logger *logging.SimpleLogger, ghAccessToken bool) error { +func WriteGitCreds(gitUser string, gitToken string, gitHostname string, home string, logger logging.SimpleLogging, ghAccessToken bool) error { const credsFilename = ".git-credentials" credsFile := filepath.Join(home, credsFilename) credsFileContentsPattern := `https://%s:%s@%s` diff --git a/server/events/git_cred_writer_test.go b/server/events/git_cred_writer_test.go index 3e881666a0..c8fc9a2cc2 100644 --- a/server/events/git_cred_writer_test.go +++ b/server/events/git_cred_writer_test.go @@ -12,7 +12,7 @@ import ( . "github.com/runatlantis/atlantis/testing" ) -var logger *logging.SimpleLogger +var logger logging.SimpleLogging // Test that we write the file as expected func TestWriteGitCreds_WriteFile(t *testing.T) { diff --git a/server/events/github_app_working_dir.go b/server/events/github_app_working_dir.go index 9e364eb413..05e2055e33 100644 --- a/server/events/github_app_working_dir.go +++ b/server/events/github_app_working_dir.go @@ -21,7 +21,7 @@ type GithubAppWorkingDir struct { } // Clone writes a fresh token for Github App authentication -func (g *GithubAppWorkingDir) Clone(log *logging.SimpleLogger, headRepo models.Repo, p models.PullRequest, workspace string) (string, bool, error) { +func (g *GithubAppWorkingDir) Clone(log logging.SimpleLogging, headRepo models.Repo, p models.PullRequest, workspace string) (string, bool, error) { log.Info("Refreshing git tokens for Github App") diff --git a/server/events/github_app_working_dir_test.go b/server/events/github_app_working_dir_test.go index 9dbcbd77bf..25dd64da7d 100644 --- a/server/events/github_app_working_dir_test.go +++ b/server/events/github_app_working_dir_test.go @@ -11,6 +11,7 @@ import ( "github.com/runatlantis/atlantis/server/events/vcs" "github.com/runatlantis/atlantis/server/events/vcs/fixtures" vcsMocks "github.com/runatlantis/atlantis/server/events/vcs/mocks" + "github.com/runatlantis/atlantis/server/logging" . "github.com/runatlantis/atlantis/testing" ) @@ -49,7 +50,9 @@ func TestClone_GithubAppNoneExisting(t *testing.T) { GithubHostname: testServer, } - cloneDir, _, err := gwd.Clone(nil, models.Repo{}, models.PullRequest{ + logger := logging.NewNoopLogger(t) + + cloneDir, _, err := gwd.Clone(logger, models.Repo{}, models.PullRequest{ BaseRepo: models.Repo{}, HeadBranch: "branch", }, "default") @@ -81,6 +84,8 @@ func TestClone_GithubAppSetsCorrectUrl(t *testing.T) { "", ) + logger := logging.NewNoopLogger(t) + headRepo := baseRepo modifiedBaseRepo := baseRepo @@ -88,11 +93,11 @@ func TestClone_GithubAppSetsCorrectUrl(t *testing.T) { modifiedBaseRepo.SanitizedCloneURL = "https://x-access-token:@github.com/runatlantis/atlantis.git" When(credentials.GetToken()).ThenReturn("token", nil) - When(workingDir.Clone(nil, modifiedBaseRepo, models.PullRequest{BaseRepo: modifiedBaseRepo}, "default")).ThenReturn( + When(workingDir.Clone(logger, modifiedBaseRepo, models.PullRequest{BaseRepo: modifiedBaseRepo}, "default")).ThenReturn( "", true, nil, ) - _, success, _ := ghAppWorkingDir.Clone(nil, headRepo, models.PullRequest{BaseRepo: baseRepo}, "default") + _, success, _ := ghAppWorkingDir.Clone(logger, headRepo, models.PullRequest{BaseRepo: baseRepo}, "default") Assert(t, success == true, "clone url mutation error") } diff --git a/server/events/matchers/ptr_to_logging_simplelogger.go b/server/events/matchers/ptr_to_logging_simplelogger.go index 04c72791bc..cf9bb5453f 100644 --- a/server/events/matchers/ptr_to_logging_simplelogger.go +++ b/server/events/matchers/ptr_to_logging_simplelogger.go @@ -2,19 +2,19 @@ package matchers import ( - "reflect" "github.com/petergtz/pegomock" logging "github.com/runatlantis/atlantis/server/logging" + "reflect" ) -func AnyPtrToLoggingSimpleLogger() *logging.SimpleLogger { - pegomock.RegisterMatcher(pegomock.NewAnyMatcher(reflect.TypeOf((*(*logging.SimpleLogger))(nil)).Elem())) - var nullValue *logging.SimpleLogger +func AnyPtrToLoggingSimpleLogger() logging.SimpleLogging { + pegomock.RegisterMatcher(pegomock.NewAnyMatcher(reflect.TypeOf((*(logging.SimpleLogging))(nil)).Elem())) + var nullValue logging.SimpleLogging return nullValue } -func EqPtrToLoggingSimpleLogger(value *logging.SimpleLogger) *logging.SimpleLogger { +func EqPtrToLoggingSimpleLogger(value logging.SimpleLogging) logging.SimpleLogging { pegomock.RegisterMatcher(&pegomock.EqMatcher{Value: value}) - var nullValue *logging.SimpleLogger + var nullValue logging.SimpleLogging return nullValue } diff --git a/server/events/mock_workingdir_test.go b/server/events/mock_workingdir_test.go index 41608a5355..163d3549b0 100644 --- a/server/events/mock_workingdir_test.go +++ b/server/events/mock_workingdir_test.go @@ -27,7 +27,7 @@ func NewMockWorkingDir(options ...pegomock.Option) *MockWorkingDir { func (mock *MockWorkingDir) SetFailHandler(fh pegomock.FailHandler) { mock.fail = fh } func (mock *MockWorkingDir) FailHandler() pegomock.FailHandler { return mock.fail } -func (mock *MockWorkingDir) Clone(log *logging.SimpleLogger, headRepo models.Repo, p models.PullRequest, workspace string) (string, bool, error) { +func (mock *MockWorkingDir) Clone(log logging.SimpleLogging, headRepo models.Repo, p models.PullRequest, workspace string) (string, bool, error) { if mock == nil { panic("mock must not be nil. Use myMock := NewMockWorkingDir().") } @@ -155,7 +155,7 @@ type VerifierMockWorkingDir struct { timeout time.Duration } -func (verifier *VerifierMockWorkingDir) Clone(log *logging.SimpleLogger, headRepo models.Repo, p models.PullRequest, workspace string) *MockWorkingDir_Clone_OngoingVerification { +func (verifier *VerifierMockWorkingDir) Clone(log logging.SimpleLogging, headRepo models.Repo, p models.PullRequest, workspace string) *MockWorkingDir_Clone_OngoingVerification { params := []pegomock.Param{log, headRepo, p, workspace} methodInvocations := pegomock.GetGenericMockFrom(verifier.mock).Verify(verifier.inOrderContext, verifier.invocationCountMatcher, "Clone", params, verifier.timeout) return &MockWorkingDir_Clone_OngoingVerification{mock: verifier.mock, methodInvocations: methodInvocations} @@ -166,17 +166,17 @@ type MockWorkingDir_Clone_OngoingVerification struct { methodInvocations []pegomock.MethodInvocation } -func (c *MockWorkingDir_Clone_OngoingVerification) GetCapturedArguments() (*logging.SimpleLogger, models.Repo, models.PullRequest, string) { +func (c *MockWorkingDir_Clone_OngoingVerification) GetCapturedArguments() (logging.SimpleLogging, models.Repo, models.PullRequest, string) { log, headRepo, p, workspace := c.GetAllCapturedArguments() return log[len(log)-1], headRepo[len(headRepo)-1], p[len(p)-1], workspace[len(workspace)-1] } -func (c *MockWorkingDir_Clone_OngoingVerification) GetAllCapturedArguments() (_param0 []*logging.SimpleLogger, _param1 []models.Repo, _param2 []models.PullRequest, _param3 []string) { +func (c *MockWorkingDir_Clone_OngoingVerification) GetAllCapturedArguments() (_param0 []logging.SimpleLogging, _param1 []models.Repo, _param2 []models.PullRequest, _param3 []string) { params := pegomock.GetGenericMockFrom(c.mock).GetInvocationParams(c.methodInvocations) if len(params) > 0 { - _param0 = make([]*logging.SimpleLogger, len(c.methodInvocations)) + _param0 = make([]logging.SimpleLogging, len(c.methodInvocations)) for u, param := range params[0] { - _param0[u] = param.(*logging.SimpleLogger) + _param0[u] = param.(logging.SimpleLogging) } _param1 = make([]models.Repo, len(c.methodInvocations)) for u, param := range params[1] { diff --git a/server/events/mocks/matchers/ptr_to_logging_simplelogger.go b/server/events/mocks/matchers/ptr_to_logging_simplelogger.go index 04c72791bc..cf9bb5453f 100644 --- a/server/events/mocks/matchers/ptr_to_logging_simplelogger.go +++ b/server/events/mocks/matchers/ptr_to_logging_simplelogger.go @@ -2,19 +2,19 @@ package matchers import ( - "reflect" "github.com/petergtz/pegomock" logging "github.com/runatlantis/atlantis/server/logging" + "reflect" ) -func AnyPtrToLoggingSimpleLogger() *logging.SimpleLogger { - pegomock.RegisterMatcher(pegomock.NewAnyMatcher(reflect.TypeOf((*(*logging.SimpleLogger))(nil)).Elem())) - var nullValue *logging.SimpleLogger +func AnyPtrToLoggingSimpleLogger() logging.SimpleLogging { + pegomock.RegisterMatcher(pegomock.NewAnyMatcher(reflect.TypeOf((*(logging.SimpleLogging))(nil)).Elem())) + var nullValue logging.SimpleLogging return nullValue } -func EqPtrToLoggingSimpleLogger(value *logging.SimpleLogger) *logging.SimpleLogger { +func EqPtrToLoggingSimpleLogger(value logging.SimpleLogging) logging.SimpleLogging { pegomock.RegisterMatcher(&pegomock.EqMatcher{Value: value}) - var nullValue *logging.SimpleLogger + var nullValue logging.SimpleLogging return nullValue } diff --git a/server/events/mocks/mock_project_lock.go b/server/events/mocks/mock_project_lock.go index 7515468aac..5674a361cb 100644 --- a/server/events/mocks/mock_project_lock.go +++ b/server/events/mocks/mock_project_lock.go @@ -27,7 +27,7 @@ func NewMockProjectLocker(options ...pegomock.Option) *MockProjectLocker { func (mock *MockProjectLocker) SetFailHandler(fh pegomock.FailHandler) { mock.fail = fh } func (mock *MockProjectLocker) FailHandler() pegomock.FailHandler { return mock.fail } -func (mock *MockProjectLocker) TryLock(log *logging.SimpleLogger, pull models.PullRequest, user models.User, workspace string, project models.Project) (*events.TryLockResponse, error) { +func (mock *MockProjectLocker) TryLock(log logging.SimpleLogging, pull models.PullRequest, user models.User, workspace string, project models.Project) (*events.TryLockResponse, error) { if mock == nil { panic("mock must not be nil. Use myMock := NewMockProjectLocker().") } @@ -83,7 +83,7 @@ type VerifierMockProjectLocker struct { timeout time.Duration } -func (verifier *VerifierMockProjectLocker) TryLock(log *logging.SimpleLogger, pull models.PullRequest, user models.User, workspace string, project models.Project) *MockProjectLocker_TryLock_OngoingVerification { +func (verifier *VerifierMockProjectLocker) TryLock(log logging.SimpleLogging, pull models.PullRequest, user models.User, workspace string, project models.Project) *MockProjectLocker_TryLock_OngoingVerification { params := []pegomock.Param{log, pull, user, workspace, project} methodInvocations := pegomock.GetGenericMockFrom(verifier.mock).Verify(verifier.inOrderContext, verifier.invocationCountMatcher, "TryLock", params, verifier.timeout) return &MockProjectLocker_TryLock_OngoingVerification{mock: verifier.mock, methodInvocations: methodInvocations} @@ -94,17 +94,17 @@ type MockProjectLocker_TryLock_OngoingVerification struct { methodInvocations []pegomock.MethodInvocation } -func (c *MockProjectLocker_TryLock_OngoingVerification) GetCapturedArguments() (*logging.SimpleLogger, models.PullRequest, models.User, string, models.Project) { +func (c *MockProjectLocker_TryLock_OngoingVerification) GetCapturedArguments() (logging.SimpleLogging, models.PullRequest, models.User, string, models.Project) { log, pull, user, workspace, project := c.GetAllCapturedArguments() return log[len(log)-1], pull[len(pull)-1], user[len(user)-1], workspace[len(workspace)-1], project[len(project)-1] } -func (c *MockProjectLocker_TryLock_OngoingVerification) GetAllCapturedArguments() (_param0 []*logging.SimpleLogger, _param1 []models.PullRequest, _param2 []models.User, _param3 []string, _param4 []models.Project) { +func (c *MockProjectLocker_TryLock_OngoingVerification) GetAllCapturedArguments() (_param0 []logging.SimpleLogging, _param1 []models.PullRequest, _param2 []models.User, _param3 []string, _param4 []models.Project) { params := pegomock.GetGenericMockFrom(c.mock).GetInvocationParams(c.methodInvocations) if len(params) > 0 { - _param0 = make([]*logging.SimpleLogger, len(c.methodInvocations)) + _param0 = make([]logging.SimpleLogging, len(c.methodInvocations)) for u, param := range params[0] { - _param0[u] = param.(*logging.SimpleLogger) + _param0[u] = param.(logging.SimpleLogging) } _param1 = make([]models.PullRequest, len(c.methodInvocations)) for u, param := range params[1] { diff --git a/server/events/mocks/mock_webhooks_sender.go b/server/events/mocks/mock_webhooks_sender.go index 2be91b0896..8f35624580 100644 --- a/server/events/mocks/mock_webhooks_sender.go +++ b/server/events/mocks/mock_webhooks_sender.go @@ -26,7 +26,7 @@ func NewMockWebhooksSender(options ...pegomock.Option) *MockWebhooksSender { func (mock *MockWebhooksSender) SetFailHandler(fh pegomock.FailHandler) { mock.fail = fh } func (mock *MockWebhooksSender) FailHandler() pegomock.FailHandler { return mock.fail } -func (mock *MockWebhooksSender) Send(log *logging.SimpleLogger, res webhooks.ApplyResult) error { +func (mock *MockWebhooksSender) Send(log logging.SimpleLogging, res webhooks.ApplyResult) error { if mock == nil { panic("mock must not be nil. Use myMock := NewMockWebhooksSender().") } @@ -78,7 +78,7 @@ type VerifierMockWebhooksSender struct { timeout time.Duration } -func (verifier *VerifierMockWebhooksSender) Send(log *logging.SimpleLogger, res webhooks.ApplyResult) *MockWebhooksSender_Send_OngoingVerification { +func (verifier *VerifierMockWebhooksSender) Send(log logging.SimpleLogging, res webhooks.ApplyResult) *MockWebhooksSender_Send_OngoingVerification { params := []pegomock.Param{log, res} methodInvocations := pegomock.GetGenericMockFrom(verifier.mock).Verify(verifier.inOrderContext, verifier.invocationCountMatcher, "Send", params, verifier.timeout) return &MockWebhooksSender_Send_OngoingVerification{mock: verifier.mock, methodInvocations: methodInvocations} @@ -89,17 +89,17 @@ type MockWebhooksSender_Send_OngoingVerification struct { methodInvocations []pegomock.MethodInvocation } -func (c *MockWebhooksSender_Send_OngoingVerification) GetCapturedArguments() (*logging.SimpleLogger, webhooks.ApplyResult) { +func (c *MockWebhooksSender_Send_OngoingVerification) GetCapturedArguments() (logging.SimpleLogging, webhooks.ApplyResult) { log, res := c.GetAllCapturedArguments() return log[len(log)-1], res[len(res)-1] } -func (c *MockWebhooksSender_Send_OngoingVerification) GetAllCapturedArguments() (_param0 []*logging.SimpleLogger, _param1 []webhooks.ApplyResult) { +func (c *MockWebhooksSender_Send_OngoingVerification) GetAllCapturedArguments() (_param0 []logging.SimpleLogging, _param1 []webhooks.ApplyResult) { params := pegomock.GetGenericMockFrom(c.mock).GetInvocationParams(c.methodInvocations) if len(params) > 0 { - _param0 = make([]*logging.SimpleLogger, len(c.methodInvocations)) + _param0 = make([]logging.SimpleLogging, len(c.methodInvocations)) for u, param := range params[0] { - _param0[u] = param.(*logging.SimpleLogger) + _param0[u] = param.(logging.SimpleLogging) } _param1 = make([]webhooks.ApplyResult, len(c.methodInvocations)) for u, param := range params[1] { diff --git a/server/events/mocks/mock_working_dir.go b/server/events/mocks/mock_working_dir.go index 4ad6467fdf..30e756d87d 100644 --- a/server/events/mocks/mock_working_dir.go +++ b/server/events/mocks/mock_working_dir.go @@ -26,7 +26,7 @@ func NewMockWorkingDir(options ...pegomock.Option) *MockWorkingDir { func (mock *MockWorkingDir) SetFailHandler(fh pegomock.FailHandler) { mock.fail = fh } func (mock *MockWorkingDir) FailHandler() pegomock.FailHandler { return mock.fail } -func (mock *MockWorkingDir) Clone(log *logging.SimpleLogger, headRepo models.Repo, p models.PullRequest, workspace string) (string, bool, error) { +func (mock *MockWorkingDir) Clone(log logging.SimpleLogging, headRepo models.Repo, p models.PullRequest, workspace string) (string, bool, error) { if mock == nil { panic("mock must not be nil. Use myMock := NewMockWorkingDir().") } @@ -154,7 +154,7 @@ type VerifierMockWorkingDir struct { timeout time.Duration } -func (verifier *VerifierMockWorkingDir) Clone(log *logging.SimpleLogger, headRepo models.Repo, p models.PullRequest, workspace string) *MockWorkingDir_Clone_OngoingVerification { +func (verifier *VerifierMockWorkingDir) Clone(log logging.SimpleLogging, headRepo models.Repo, p models.PullRequest, workspace string) *MockWorkingDir_Clone_OngoingVerification { params := []pegomock.Param{log, headRepo, p, workspace} methodInvocations := pegomock.GetGenericMockFrom(verifier.mock).Verify(verifier.inOrderContext, verifier.invocationCountMatcher, "Clone", params, verifier.timeout) return &MockWorkingDir_Clone_OngoingVerification{mock: verifier.mock, methodInvocations: methodInvocations} @@ -165,17 +165,17 @@ type MockWorkingDir_Clone_OngoingVerification struct { methodInvocations []pegomock.MethodInvocation } -func (c *MockWorkingDir_Clone_OngoingVerification) GetCapturedArguments() (*logging.SimpleLogger, models.Repo, models.PullRequest, string) { +func (c *MockWorkingDir_Clone_OngoingVerification) GetCapturedArguments() (logging.SimpleLogging, models.Repo, models.PullRequest, string) { log, headRepo, p, workspace := c.GetAllCapturedArguments() return log[len(log)-1], headRepo[len(headRepo)-1], p[len(p)-1], workspace[len(workspace)-1] } -func (c *MockWorkingDir_Clone_OngoingVerification) GetAllCapturedArguments() (_param0 []*logging.SimpleLogger, _param1 []models.Repo, _param2 []models.PullRequest, _param3 []string) { +func (c *MockWorkingDir_Clone_OngoingVerification) GetAllCapturedArguments() (_param0 []logging.SimpleLogging, _param1 []models.Repo, _param2 []models.PullRequest, _param3 []string) { params := pegomock.GetGenericMockFrom(c.mock).GetInvocationParams(c.methodInvocations) if len(params) > 0 { - _param0 = make([]*logging.SimpleLogger, len(c.methodInvocations)) + _param0 = make([]logging.SimpleLogging, len(c.methodInvocations)) for u, param := range params[0] { - _param0[u] = param.(*logging.SimpleLogger) + _param0[u] = param.(logging.SimpleLogging) } _param1 = make([]models.Repo, len(c.methodInvocations)) for u, param := range params[1] { diff --git a/server/events/models/models.go b/server/events/models/models.go index 6ce3271256..4e449a3643 100644 --- a/server/events/models/models.go +++ b/server/events/models/models.go @@ -355,7 +355,7 @@ type ProjectCommandContext struct { // be the same as BaseRepo. HeadRepo Repo // Log is a logger that's been set up for this context. - Log *logging.SimpleLogger + Log logging.SimpleLogging // PullMergeable is true if the pull request for this project is able to be merged. PullMergeable bool // Pull is the pull request we're responding to. diff --git a/server/events/pre_workflow_hooks_command_runner_test.go b/server/events/pre_workflow_hooks_command_runner_test.go index b0c3a7dc98..0b9fd48cfc 100644 --- a/server/events/pre_workflow_hooks_command_runner_test.go +++ b/server/events/pre_workflow_hooks_command_runner_test.go @@ -42,7 +42,7 @@ func newBool(b bool) *bool { func TestRunPreHooks_Clone(t *testing.T) { - log := logging.NewNoopLogger() + log := logging.NewNoopLogger(t) var newPull = fixtures.Pull newPull.BaseRepo = fixtures.GithubRepo diff --git a/server/events/project_command_builder_internal_test.go b/server/events/project_command_builder_internal_test.go index 3bb07fcc41..f721dff6b4 100644 --- a/server/events/project_command_builder_internal_test.go +++ b/server/events/project_command_builder_internal_test.go @@ -12,11 +12,14 @@ import ( vcsmocks "github.com/runatlantis/atlantis/server/events/vcs/mocks" "github.com/runatlantis/atlantis/server/events/yaml" "github.com/runatlantis/atlantis/server/events/yaml/valid" + "github.com/runatlantis/atlantis/server/logging" + logging_matchers "github.com/runatlantis/atlantis/server/logging/mocks/matchers" . "github.com/runatlantis/atlantis/testing" ) // Test different permutations of global and repo config. func TestBuildProjectCmdCtx(t *testing.T) { + logger := logging.NewNoopLogger(t) emptyPolicySets := valid.PolicySets{ Version: nil, PolicySets: []valid.PolicySet{}, @@ -62,7 +65,7 @@ workflows: AutomergeEnabled: false, AutoplanEnabled: true, HeadRepo: models.Repo{}, - Log: nil, + Log: logger, PullMergeable: true, Pull: pull, ProjectName: "", @@ -112,7 +115,7 @@ projects: AutomergeEnabled: true, AutoplanEnabled: true, HeadRepo: models.Repo{}, - Log: nil, + Log: logger, PullMergeable: true, Pull: pull, ProjectName: "", @@ -164,7 +167,7 @@ projects: AutomergeEnabled: true, AutoplanEnabled: true, HeadRepo: models.Repo{}, - Log: nil, + Log: logger, PullMergeable: true, Pull: pull, ProjectName: "", @@ -224,7 +227,7 @@ projects: AutomergeEnabled: true, AutoplanEnabled: true, HeadRepo: models.Repo{}, - Log: nil, + Log: logger, PullMergeable: true, Pull: pull, ProjectName: "", @@ -371,7 +374,7 @@ workflows: AutomergeEnabled: true, AutoplanEnabled: true, HeadRepo: models.Repo{}, - Log: nil, + Log: logger, PullMergeable: true, Pull: pull, ProjectName: "", @@ -427,7 +430,7 @@ projects: AutomergeEnabled: true, AutoplanEnabled: true, HeadRepo: models.Repo{}, - Log: nil, + Log: logger, PullMergeable: true, Pull: pull, ProjectName: "", @@ -486,7 +489,7 @@ workflows: AutomergeEnabled: true, AutoplanEnabled: true, HeadRepo: models.Repo{}, - Log: nil, + Log: logger, PullMergeable: true, Pull: pull, ProjectName: "", @@ -529,7 +532,7 @@ projects: AutomergeEnabled: false, AutoplanEnabled: true, HeadRepo: models.Repo{}, - Log: nil, + Log: logger, PullMergeable: true, Pull: pull, ProjectName: "", @@ -595,6 +598,7 @@ projects: for _, cmd := range []models.CommandName{models.PlanCommand, models.ApplyCommand} { t.Run(cmd.String(), func(t *testing.T) { ctxs, err := builder.buildProjectCommandCtx(&CommandContext{ + Log: logger, Pull: models.PullRequest{ BaseRepo: baseRepo, }, @@ -713,7 +717,7 @@ projects: AutomergeEnabled: true, AutoplanEnabled: true, HeadRepo: models.Repo{}, - Log: nil, + Log: logging.NewNoopLogger(t), PullMergeable: true, Pull: pull, ProjectName: "myproject_1", @@ -747,7 +751,7 @@ projects: defer cleanup() workingDir := NewMockWorkingDir() - When(workingDir.Clone(matchers.AnyPtrToLoggingSimpleLogger(), matchers.AnyModelsRepo(), matchers.AnyModelsPullRequest(), AnyString())).ThenReturn(tmp, false, nil) + When(workingDir.Clone(logging_matchers.AnyPtrToLoggingSimpleLogger(), matchers.AnyModelsRepo(), matchers.AnyModelsPullRequest(), AnyString())).ThenReturn(tmp, false, nil) vcsClient := vcsmocks.NewMockClient() When(vcsClient.GetModifiedFiles(matchers.AnyModelsRepo(), matchers.AnyModelsPullRequest())).ThenReturn([]string{"modules/module/main.tf"}, nil) @@ -783,6 +787,7 @@ projects: Pull: models.PullRequest{ BaseRepo: baseRepo, }, + Log: logging.NewNoopLogger(t), PullMergeable: true, }, cmd, "myproject_[1-2]", []string{"flag"}, tmp, "project1", "myworkspace", true) @@ -827,6 +832,7 @@ projects: } func TestBuildProjectCmdCtx_WithPolicCheckEnabled(t *testing.T) { + logger := logging.NewNoopLogger(t) emptyPolicySets := valid.PolicySets{ Version: nil, PolicySets: []valid.PolicySet{}, @@ -862,7 +868,7 @@ repos: AutomergeEnabled: false, AutoplanEnabled: true, HeadRepo: models.Repo{}, - Log: nil, + Log: logger, PullMergeable: true, Pull: pull, ProjectName: "", @@ -917,7 +923,7 @@ workflows: AutomergeEnabled: true, AutoplanEnabled: true, HeadRepo: models.Repo{}, - Log: nil, + Log: logger, PullMergeable: true, Pull: pull, ProjectName: "", @@ -982,6 +988,7 @@ workflows: cmd := models.PolicyCheckCommand t.Run(cmd.String(), func(t *testing.T) { ctxs, err := builder.buildProjectCommandCtx(&CommandContext{ + Log: logger, Pull: models.PullRequest{ BaseRepo: baseRepo, }, diff --git a/server/events/project_command_builder_test.go b/server/events/project_command_builder_test.go index 781e3a253e..5c59f8cd4e 100644 --- a/server/events/project_command_builder_test.go +++ b/server/events/project_command_builder_test.go @@ -117,6 +117,8 @@ projects: }, } + logger := logging.NewNoopLogger(t) + for _, c := range cases { t.Run(c.Description, func(t *testing.T) { RegisterMockTestingT(t) @@ -150,6 +152,7 @@ projects: ctxs, err := builder.BuildAutoplanCommands(&events.CommandContext{ PullMergeable: true, + Log: logger, }) Ok(t, err) Equals(t, len(c.exp), len(ctxs)) @@ -340,6 +343,8 @@ projects: }, } + logger := logging.NewNoopLogger(t) + for _, c := range cases { // NOTE: we're testing both plan and apply here. for _, cmdName := range []models.CommandName{models.PlanCommand, models.ApplyCommand} { @@ -377,9 +382,11 @@ projects: var actCtxs []models.ProjectCommandContext var err error if cmdName == models.PlanCommand { - actCtxs, err = builder.BuildPlanCommands(&events.CommandContext{}, &c.Cmd) + actCtxs, err = builder.BuildPlanCommands(&events.CommandContext{ + Log: logger, + }, &c.Cmd) } else { - actCtxs, err = builder.BuildApplyCommands(&events.CommandContext{}, &c.Cmd) + actCtxs, err = builder.BuildApplyCommands(&events.CommandContext{Log: logger}, &c.Cmd) } if c.ExpErr != "" { @@ -481,6 +488,8 @@ projects: }, }, } + + logger := logging.NewNoopLogger(t) for name, c := range cases { t.Run(name, func(t *testing.T) { RegisterMockTestingT(t) @@ -512,7 +521,9 @@ projects: ) ctxs, err := builder.BuildPlanCommands( - &events.CommandContext{}, + &events.CommandContext{ + Log: logger, + }, &events.CommentCommand{ RepoRelDir: "", Flags: nil, @@ -572,6 +583,8 @@ func TestDefaultProjectCommandBuilder_BuildMultiApply(t *testing.T) { matchers.AnyModelsPullRequest())). ThenReturn(tmpDir, nil) + logger := logging.NewNoopLogger(t) + builder := events.NewProjectCommandBuilder( false, &yaml.ParserValidator{}, @@ -587,7 +600,9 @@ func TestDefaultProjectCommandBuilder_BuildMultiApply(t *testing.T) { ) ctxs, err := builder.BuildApplyCommands( - &events.CommandContext{}, + &events.CommandContext{ + Log: logger, + }, &events.CommentCommand{ RepoRelDir: "", Flags: nil, @@ -660,7 +675,7 @@ projects: HeadRepo: models.Repo{}, Pull: models.PullRequest{}, User: models.User{}, - Log: logging.NewNoopLogger(), + Log: logging.NewNoopLogger(t), } _, err = builder.BuildPlanCommands(ctx, &events.CommentCommand{ RepoRelDir: ".", @@ -693,6 +708,8 @@ func TestDefaultProjectCommandBuilder_EscapeArgs(t *testing.T) { }, } + logger := logging.NewNoopLogger(t) + for _, c := range cases { t.Run(strings.Join(c.ExtraArgs, " "), func(t *testing.T) { RegisterMockTestingT(t) @@ -723,7 +740,9 @@ func TestDefaultProjectCommandBuilder_EscapeArgs(t *testing.T) { var actCtxs []models.ProjectCommandContext var err error - actCtxs, err = builder.BuildPlanCommands(&events.CommandContext{}, &events.CommentCommand{ + actCtxs, err = builder.BuildPlanCommands(&events.CommandContext{ + Log: logger, + }, &events.CommentCommand{ RepoRelDir: ".", Flags: c.ExtraArgs, Name: models.PlanCommand, @@ -852,6 +871,8 @@ projects: }, } + logger := logging.NewNoopLogger(t) + for name, testCase := range testCases { t.Run(name, func(t *testing.T) { RegisterMockTestingT(t) @@ -889,7 +910,9 @@ projects: ) actCtxs, err := builder.BuildPlanCommands( - &events.CommandContext{}, + &events.CommandContext{ + Log: logger, + }, &events.CommentCommand{ RepoRelDir: "", Flags: nil, @@ -925,6 +948,8 @@ projects: When(vcsClient.DownloadRepoConfigFile(matchers.AnyModelsPullRequest())).ThenReturn(true, []byte(atlantisYAML), nil) workingDir := mocks.NewMockWorkingDir() + logger := logging.NewNoopLogger(t) + builder := events.NewProjectCommandBuilder( false, &yaml.ParserValidator{}, @@ -945,7 +970,7 @@ projects: HeadRepo: models.Repo{}, Pull: models.PullRequest{}, User: models.User{}, - Log: nil, + Log: logger, PullMergeable: true, }) Ok(t, err) @@ -960,6 +985,8 @@ func TestDefaultProjectCommandBuilder_WithPolicyCheckEnabled_BuildAutoplanComman }) defer cleanup() + logger := logging.NewNoopLogger(t) + workingDir := mocks.NewMockWorkingDir() When(workingDir.Clone(matchers.AnyPtrToLoggingSimpleLogger(), matchers.AnyModelsRepo(), matchers.AnyModelsPullRequest(), AnyString())).ThenReturn(tmpDir, false, nil) vcsClient := vcsmocks.NewMockClient() @@ -982,6 +1009,7 @@ func TestDefaultProjectCommandBuilder_WithPolicyCheckEnabled_BuildAutoplanComman ctxs, err := builder.BuildAutoplanCommands(&events.CommandContext{ PullMergeable: true, + Log: logger, }) Ok(t, err) diff --git a/server/events/project_command_runner.go b/server/events/project_command_runner.go index e10c41f8c7..3d3d72a832 100644 --- a/server/events/project_command_runner.go +++ b/server/events/project_command_runner.go @@ -75,7 +75,7 @@ type EnvStepRunner interface { // WebhooksSender sends webhook. type WebhooksSender interface { // Send sends the webhook. - Send(log *logging.SimpleLogger, res webhooks.ApplyResult) error + Send(log logging.SimpleLogging, res webhooks.ApplyResult) error } //go:generate pegomock generate -m --use-experimental-model-gen --package mocks -o mocks/mock_project_command_runner.go ProjectCommandRunner diff --git a/server/events/project_command_runner_test.go b/server/events/project_command_runner_test.go index b6739d82d6..a51b091188 100644 --- a/server/events/project_command_runner_test.go +++ b/server/events/project_command_runner_test.go @@ -79,7 +79,7 @@ func TestDefaultProjectCommandRunner_Plan(t *testing.T) { "name": "value", } ctx := models.ProjectCommandContext{ - Log: logging.NewNoopLogger(), + Log: logging.NewNoopLogger(t), Steps: []valid.Step{ { StepName: "env", @@ -298,7 +298,7 @@ func TestDefaultProjectCommandRunner_Apply(t *testing.T) { )).ThenReturn(repoDir, nil) ctx := models.ProjectCommandContext{ - Log: logging.NewNoopLogger(), + Log: logging.NewNoopLogger(t), Steps: c.steps, Workspace: "default", ApplyRequirements: c.applyReqs, @@ -387,7 +387,7 @@ func TestDefaultProjectCommandRunner_RunEnvSteps(t *testing.T) { }, nil) ctx := models.ProjectCommandContext{ - Log: logging.NewNoopLogger(), + Log: logging.NewNoopLogger(t), Steps: []valid.Step{ { StepName: "run", diff --git a/server/events/project_finder.go b/server/events/project_finder.go index 3dcaf762cb..679df16f8d 100644 --- a/server/events/project_finder.go +++ b/server/events/project_finder.go @@ -34,11 +34,11 @@ type ProjectFinder interface { // DetermineProjects returns the list of projects that were modified based on // the modifiedFiles. The list will be de-duplicated. // absRepoDir is the path to the cloned repo on disk. - DetermineProjects(log *logging.SimpleLogger, modifiedFiles []string, repoFullName string, absRepoDir string) []models.Project + DetermineProjects(log logging.SimpleLogging, modifiedFiles []string, repoFullName string, absRepoDir string) []models.Project // DetermineProjectsViaConfig returns the list of projects that were modified // based on modifiedFiles and the repo's config. // absRepoDir is the path to the cloned repo on disk. - DetermineProjectsViaConfig(log *logging.SimpleLogger, modifiedFiles []string, config valid.RepoCfg, absRepoDir string) ([]valid.Project, error) + DetermineProjectsViaConfig(log logging.SimpleLogging, modifiedFiles []string, config valid.RepoCfg, absRepoDir string) ([]valid.Project, error) } // ignoredFilenameFragments contains filename fragments to ignore while looking at changes @@ -48,7 +48,7 @@ var ignoredFilenameFragments = []string{"terraform.tfstate", "terraform.tfstate. type DefaultProjectFinder struct{} // See ProjectFinder.DetermineProjects. -func (p *DefaultProjectFinder) DetermineProjects(log *logging.SimpleLogger, modifiedFiles []string, repoFullName string, absRepoDir string) []models.Project { +func (p *DefaultProjectFinder) DetermineProjects(log logging.SimpleLogging, modifiedFiles []string, repoFullName string, absRepoDir string) []models.Project { var projects []models.Project modifiedTerraformFiles := p.filterToTerraform(modifiedFiles) @@ -82,7 +82,7 @@ func (p *DefaultProjectFinder) DetermineProjects(log *logging.SimpleLogger, modi } // See ProjectFinder.DetermineProjectsViaConfig. -func (p *DefaultProjectFinder) DetermineProjectsViaConfig(log *logging.SimpleLogger, modifiedFiles []string, config valid.RepoCfg, absRepoDir string) ([]valid.Project, error) { +func (p *DefaultProjectFinder) DetermineProjectsViaConfig(log logging.SimpleLogging, modifiedFiles []string, config valid.RepoCfg, absRepoDir string) ([]valid.Project, error) { var projects []valid.Project for _, project := range config.Projects { log.Debug("checking if project at dir %q workspace %q was modified", project.Dir, project.Workspace) diff --git a/server/events/project_finder_test.go b/server/events/project_finder_test.go index d2c01bfa79..4f218371c4 100644 --- a/server/events/project_finder_test.go +++ b/server/events/project_finder_test.go @@ -25,7 +25,6 @@ import ( . "github.com/runatlantis/atlantis/testing" ) -var noopLogger = logging.NewNoopLogger() var modifiedRepo = "owner/repo" var m = events.DefaultProjectFinder{} var nestedModules1 string @@ -105,6 +104,7 @@ func setupTmpRepos(t *testing.T) { } func TestDetermineProjects(t *testing.T) { + noopLogger := logging.NewNoopLogger(t) setupTmpRepos(t) cases := []struct { @@ -459,7 +459,7 @@ func TestDefaultProjectFinder_DetermineProjectsViaConfig(t *testing.T) { for _, c := range cases { t.Run(c.description, func(t *testing.T) { pf := events.DefaultProjectFinder{} - projects, err := pf.DetermineProjectsViaConfig(logging.NewNoopLogger(), c.modified, c.config, tmpDir) + projects, err := pf.DetermineProjectsViaConfig(logging.NewNoopLogger(t), c.modified, c.config, tmpDir) Ok(t, err) Equals(t, len(c.expProjPaths), len(projects)) for i, proj := range projects { diff --git a/server/events/project_locker.go b/server/events/project_locker.go index 92aa64b0c0..bfffd0feb7 100644 --- a/server/events/project_locker.go +++ b/server/events/project_locker.go @@ -33,7 +33,7 @@ type ProjectLocker interface { // The third return value is a function that can be called to unlock the // lock. It will only be set if the lock was acquired. Any errors will set // error. - TryLock(log *logging.SimpleLogger, pull models.PullRequest, user models.User, workspace string, project models.Project) (*TryLockResponse, error) + TryLock(log logging.SimpleLogging, pull models.PullRequest, user models.User, workspace string, project models.Project) (*TryLockResponse, error) } // DefaultProjectLocker implements ProjectLocker. @@ -58,7 +58,7 @@ type TryLockResponse struct { } // TryLock implements ProjectLocker.TryLock. -func (p *DefaultProjectLocker) TryLock(log *logging.SimpleLogger, pull models.PullRequest, user models.User, workspace string, project models.Project) (*TryLockResponse, error) { +func (p *DefaultProjectLocker) TryLock(log logging.SimpleLogging, pull models.PullRequest, user models.User, workspace string, project models.Project) (*TryLockResponse, error) { lockAttempt, err := p.Locker.TryLock(project, workspace, pull, user) if err != nil { return nil, err diff --git a/server/events/project_locker_test.go b/server/events/project_locker_test.go index ba78f4718e..ce5af7c97b 100644 --- a/server/events/project_locker_test.go +++ b/server/events/project_locker_test.go @@ -53,7 +53,7 @@ func TestDefaultProjectLocker_TryLockWhenLocked(t *testing.T) { }, nil, ) - res, err := locker.TryLock(logging.NewNoopLogger(), expPull, expUser, expWorkspace, expProject) + res, err := locker.TryLock(logging.NewNoopLogger(t), expPull, expUser, expWorkspace, expProject) link, _ := mockClient.MarkdownPullLink(lockingPull) Ok(t, err) Equals(t, &events.TryLockResponse{ @@ -90,7 +90,7 @@ func TestDefaultProjectLocker_TryLockWhenLockedSamePull(t *testing.T) { }, nil, ) - res, err := locker.TryLock(logging.NewNoopLogger(), expPull, expUser, expWorkspace, expProject) + res, err := locker.TryLock(logging.NewNoopLogger(t), expPull, expUser, expWorkspace, expProject) Ok(t, err) Equals(t, true, res.LockAcquired) @@ -129,7 +129,7 @@ func TestDefaultProjectLocker_TryLockUnlocked(t *testing.T) { }, nil, ) - res, err := locker.TryLock(logging.NewNoopLogger(), expPull, expUser, expWorkspace, expProject) + res, err := locker.TryLock(logging.NewNoopLogger(t), expPull, expUser, expWorkspace, expProject) Ok(t, err) Equals(t, true, res.LockAcquired) diff --git a/server/events/pull_updater.go b/server/events/pull_updater.go index 418f91711f..bab9938771 100644 --- a/server/events/pull_updater.go +++ b/server/events/pull_updater.go @@ -25,7 +25,7 @@ func (c *PullUpdater) updatePull(ctx *CommandContext, command PullCommand, res C } } - comment := c.MarkdownRenderer.Render(res, command.CommandName(), ctx.Log.History.String(), command.IsVerbose(), ctx.Pull.BaseRepo.VCSHost.Type) + comment := c.MarkdownRenderer.Render(res, command.CommandName(), ctx.Log.GetHistory(), command.IsVerbose(), ctx.Pull.BaseRepo.VCSHost.Type) if err := c.VCSClient.CreateComment(ctx.Pull.BaseRepo, ctx.Pull.Num, comment, command.CommandName().String()); err != nil { ctx.Log.Err("unable to comment: %s", err) } diff --git a/server/events/runtime/apply_step_runner_test.go b/server/events/runtime/apply_step_runner_test.go index 386857a17a..aec19d98f8 100644 --- a/server/events/runtime/apply_step_runner_test.go +++ b/server/events/runtime/apply_step_runner_test.go @@ -20,6 +20,7 @@ import ( "github.com/runatlantis/atlantis/server/events/terraform/mocks" matchers2 "github.com/runatlantis/atlantis/server/events/terraform/mocks/matchers" "github.com/runatlantis/atlantis/server/logging" + logging_matchers "github.com/runatlantis/atlantis/server/logging/mocks/matchers" . "github.com/runatlantis/atlantis/testing" ) @@ -59,17 +60,19 @@ func TestRun_Success(t *testing.T) { o := runtime.ApplyStepRunner{ TerraformExecutor: terraform, } + logger := logging.NewNoopLogger(t) When(terraform.RunCommandWithVersion(matchers.AnyPtrToLoggingSimpleLogger(), AnyString(), AnyStringSlice(), matchers2.AnyMapOfStringToString(), matchers2.AnyPtrToGoVersionVersion(), AnyString())). ThenReturn("output", nil) output, err := o.Run(models.ProjectCommandContext{ + Log: logger, Workspace: "workspace", RepoRelDir: ".", EscapedCommentArgs: []string{"comment", "args"}, }, []string{"extra", "args"}, tmpDir, map[string]string(nil)) Ok(t, err) Equals(t, "output", output) - terraform.VerifyWasCalledOnce().RunCommandWithVersion(nil, tmpDir, []string{"apply", "-input=false", "-no-color", "extra", "args", "comment", "args", fmt.Sprintf("%q", planPath)}, map[string]string(nil), nil, "workspace") + terraform.VerifyWasCalledOnce().RunCommandWithVersion(logger, tmpDir, []string{"apply", "-input=false", "-no-color", "extra", "args", "comment", "args", fmt.Sprintf("%q", planPath)}, map[string]string(nil), nil, "workspace") _, err = os.Stat(planPath) Assert(t, os.IsNotExist(err), "planfile should be deleted") } @@ -87,10 +90,12 @@ func TestRun_AppliesCorrectProjectPlan(t *testing.T) { o := runtime.ApplyStepRunner{ TerraformExecutor: terraform, } + logger := logging.NewNoopLogger(t) When(terraform.RunCommandWithVersion(matchers.AnyPtrToLoggingSimpleLogger(), AnyString(), AnyStringSlice(), matchers2.AnyMapOfStringToString(), matchers2.AnyPtrToGoVersionVersion(), AnyString())). ThenReturn("output", nil) output, err := o.Run(models.ProjectCommandContext{ + Log: logger, Workspace: "default", RepoRelDir: ".", ProjectName: "projectname", @@ -98,7 +103,7 @@ func TestRun_AppliesCorrectProjectPlan(t *testing.T) { }, []string{"extra", "args"}, tmpDir, map[string]string(nil)) Ok(t, err) Equals(t, "output", output) - terraform.VerifyWasCalledOnce().RunCommandWithVersion(nil, tmpDir, []string{"apply", "-input=false", "-no-color", "extra", "args", "comment", "args", fmt.Sprintf("%q", planPath)}, map[string]string(nil), nil, "default") + terraform.VerifyWasCalledOnce().RunCommandWithVersion(logger, tmpDir, []string{"apply", "-input=false", "-no-color", "extra", "args", "comment", "args", fmt.Sprintf("%q", planPath)}, map[string]string(nil), nil, "default") _, err = os.Stat(planPath) Assert(t, os.IsNotExist(err), "planfile should be deleted") } @@ -115,19 +120,21 @@ func TestRun_UsesConfiguredTFVersion(t *testing.T) { o := runtime.ApplyStepRunner{ TerraformExecutor: terraform, } + logger := logging.NewNoopLogger(t) tfVersion, _ := version.NewVersion("0.11.0") - When(terraform.RunCommandWithVersion(matchers.AnyPtrToLoggingSimpleLogger(), AnyString(), AnyStringSlice(), matchers2.AnyMapOfStringToString(), matchers2.AnyPtrToGoVersionVersion(), AnyString())). + When(terraform.RunCommandWithVersion(logging_matchers.AnyLoggingSimpleLogging(), AnyString(), AnyStringSlice(), matchers2.AnyMapOfStringToString(), matchers2.AnyPtrToGoVersionVersion(), AnyString())). ThenReturn("output", nil) output, err := o.Run(models.ProjectCommandContext{ Workspace: "workspace", RepoRelDir: ".", EscapedCommentArgs: []string{"comment", "args"}, TerraformVersion: tfVersion, + Log: logger, }, []string{"extra", "args"}, tmpDir, map[string]string(nil)) Ok(t, err) Equals(t, "output", output) - terraform.VerifyWasCalledOnce().RunCommandWithVersion(nil, tmpDir, []string{"apply", "-input=false", "-no-color", "extra", "args", "comment", "args", fmt.Sprintf("%q", planPath)}, map[string]string(nil), tfVersion, "workspace") + terraform.VerifyWasCalledOnce().RunCommandWithVersion(logger, tmpDir, []string{"apply", "-input=false", "-no-color", "extra", "args", "comment", "args", fmt.Sprintf("%q", planPath)}, map[string]string(nil), tfVersion, "workspace") _, err = os.Stat(planPath) Assert(t, os.IsNotExist(err), "planfile should be deleted") } @@ -135,6 +142,7 @@ func TestRun_UsesConfiguredTFVersion(t *testing.T) { // Apply ignores the -target flag when used with a planfile so we should give // an error if it's being used with -target. func TestRun_UsingTarget(t *testing.T) { + logger := logging.NewNoopLogger(t) cases := []struct { commentFlags []string extraArgs []string @@ -197,6 +205,7 @@ func TestRun_UsingTarget(t *testing.T) { } output, err := step.Run(models.ProjectCommandContext{ + Log: logger, Workspace: "workspace", RepoRelDir: ".", EscapedCommentArgs: c.commentFlags, @@ -240,7 +249,7 @@ Plan: 0 to add, 0 to change, 1 to destroy.` } tfVersion, _ := version.NewVersion("0.11.0") ctx := models.ProjectCommandContext{ - Log: logging.NewSimpleLogger("testing", false, logging.Debug), + Log: logging.NewNoopLogger(t), Workspace: "workspace", RepoRelDir: ".", EscapedCommentArgs: []string{"comment", "args"}, @@ -302,7 +311,7 @@ Plan: 0 to add, 0 to change, 1 to destroy.` tfVersion, _ := version.NewVersion("0.11.0") output, err := o.Run(models.ProjectCommandContext{ - Log: logging.NewSimpleLogger("testing", false, logging.Debug), + Log: logging.NewNoopLogger(t), Workspace: "workspace", RepoRelDir: ".", EscapedCommentArgs: []string{"comment", "args"}, @@ -356,7 +365,7 @@ type remoteApplyMock struct { } // RunCommandAsync fakes out running terraform async. -func (r *remoteApplyMock) RunCommandAsync(log *logging.SimpleLogger, path string, args []string, envs map[string]string, v *version.Version, workspace string) (chan<- string, <-chan terraform.Line) { +func (r *remoteApplyMock) RunCommandAsync(log logging.SimpleLogging, path string, args []string, envs map[string]string, v *version.Version, workspace string) (chan<- string, <-chan terraform.Line) { r.CalledArgs = args in := make(chan string) diff --git a/server/events/runtime/env_step_runner_test.go b/server/events/runtime/env_step_runner_test.go index 62b6f255fc..1120166534 100644 --- a/server/events/runtime/env_step_runner_test.go +++ b/server/events/runtime/env_step_runner_test.go @@ -68,7 +68,7 @@ func TestEnvStepRunner_Run(t *testing.T) { User: models.User{ Username: "acme-user", }, - Log: logging.NewNoopLogger(), + Log: logging.NewNoopLogger(t), Workspace: "myworkspace", RepoRelDir: "mydir", TerraformVersion: tfVersion, diff --git a/server/events/runtime/executor.go b/server/events/runtime/executor.go index 80cf3f0961..fc06b0a099 100644 --- a/server/events/runtime/executor.go +++ b/server/events/runtime/executor.go @@ -21,5 +21,5 @@ type Executor interface { // ExecutorVersionEnsurer ensures a given version exists and outputs a path to the executable type ExecutorVersionEnsurer interface { - EnsureExecutorVersion(log *logging.SimpleLogger, v *version.Version) (string, error) + EnsureExecutorVersion(log logging.SimpleLogging, v *version.Version) (string, error) } diff --git a/server/events/runtime/init_step_runner_test.go b/server/events/runtime/init_step_runner_test.go index 01e2eafa29..47c9f39a4a 100644 --- a/server/events/runtime/init_step_runner_test.go +++ b/server/events/runtime/init_step_runner_test.go @@ -6,11 +6,13 @@ import ( version "github.com/hashicorp/go-version" . "github.com/petergtz/pegomock" "github.com/pkg/errors" - "github.com/runatlantis/atlantis/server/events/mocks/matchers" + "github.com/runatlantis/atlantis/server/events/models" "github.com/runatlantis/atlantis/server/events/runtime" "github.com/runatlantis/atlantis/server/events/terraform/mocks" matchers2 "github.com/runatlantis/atlantis/server/events/terraform/mocks/matchers" + "github.com/runatlantis/atlantis/server/logging" + logging_matchers "github.com/runatlantis/atlantis/server/logging/mocks/matchers" . "github.com/runatlantis/atlantis/testing" ) @@ -42,17 +44,20 @@ func TestRun_UsesGetOrInitForRightVersion(t *testing.T) { t.Run(c.version, func(t *testing.T) { terraform := mocks.NewMockClient() + logger := logging.NewNoopLogger(t) + tfVersion, _ := version.NewVersion(c.version) iso := runtime.InitStepRunner{ TerraformExecutor: terraform, DefaultTFVersion: tfVersion, } - When(terraform.RunCommandWithVersion(matchers.AnyPtrToLoggingSimpleLogger(), AnyString(), AnyStringSlice(), matchers2.AnyMapOfStringToString(), matchers2.AnyPtrToGoVersionVersion(), AnyString())). + When(terraform.RunCommandWithVersion(logging_matchers.AnyLoggingSimpleLogging(), AnyString(), AnyStringSlice(), matchers2.AnyMapOfStringToString(), matchers2.AnyPtrToGoVersionVersion(), AnyString())). ThenReturn("output", nil) output, err := iso.Run(models.ProjectCommandContext{ Workspace: "workspace", RepoRelDir: ".", + Log: logger, }, []string{"extra", "args"}, "/path", map[string]string(nil)) Ok(t, err) // When there is no error, should not return init output to PR. @@ -63,7 +68,7 @@ func TestRun_UsesGetOrInitForRightVersion(t *testing.T) { if c.expCmd == "get" { expArgs = []string{c.expCmd, "-no-color", "-upgrade", "extra", "args"} } - terraform.VerifyWasCalledOnce().RunCommandWithVersion(nil, "/path", expArgs, map[string]string(nil), tfVersion, "workspace") + terraform.VerifyWasCalledOnce().RunCommandWithVersion(logger, "/path", expArgs, map[string]string(nil), tfVersion, "workspace") }) } } @@ -72,7 +77,8 @@ func TestRun_ShowInitOutputOnError(t *testing.T) { // If there was an error during init then we want the output to be returned. RegisterMockTestingT(t) tfClient := mocks.NewMockClient() - When(tfClient.RunCommandWithVersion(matchers.AnyPtrToLoggingSimpleLogger(), AnyString(), AnyStringSlice(), matchers2.AnyMapOfStringToString(), matchers2.AnyPtrToGoVersionVersion(), AnyString())). + logger := logging.NewNoopLogger(t) + When(tfClient.RunCommandWithVersion(logging_matchers.AnyLoggingSimpleLogging(), AnyString(), AnyStringSlice(), matchers2.AnyMapOfStringToString(), matchers2.AnyPtrToGoVersionVersion(), AnyString())). ThenReturn("output", errors.New("error")) tfVersion, _ := version.NewVersion("0.11.0") @@ -84,6 +90,7 @@ func TestRun_ShowInitOutputOnError(t *testing.T) { output, err := iso.Run(models.ProjectCommandContext{ Workspace: "workspace", RepoRelDir: ".", + Log: logger, }, nil, "/path", map[string]string(nil)) ErrEquals(t, "error", err) Equals(t, "output", output) diff --git a/server/events/runtime/mocks/matchers/ptr_to_logging_simplelogger.go b/server/events/runtime/mocks/matchers/ptr_to_logging_simplelogger.go index 04c72791bc..cf9bb5453f 100644 --- a/server/events/runtime/mocks/matchers/ptr_to_logging_simplelogger.go +++ b/server/events/runtime/mocks/matchers/ptr_to_logging_simplelogger.go @@ -2,19 +2,19 @@ package matchers import ( - "reflect" "github.com/petergtz/pegomock" logging "github.com/runatlantis/atlantis/server/logging" + "reflect" ) -func AnyPtrToLoggingSimpleLogger() *logging.SimpleLogger { - pegomock.RegisterMatcher(pegomock.NewAnyMatcher(reflect.TypeOf((*(*logging.SimpleLogger))(nil)).Elem())) - var nullValue *logging.SimpleLogger +func AnyPtrToLoggingSimpleLogger() logging.SimpleLogging { + pegomock.RegisterMatcher(pegomock.NewAnyMatcher(reflect.TypeOf((*(logging.SimpleLogging))(nil)).Elem())) + var nullValue logging.SimpleLogging return nullValue } -func EqPtrToLoggingSimpleLogger(value *logging.SimpleLogger) *logging.SimpleLogger { +func EqPtrToLoggingSimpleLogger(value logging.SimpleLogging) logging.SimpleLogging { pegomock.RegisterMatcher(&pegomock.EqMatcher{Value: value}) - var nullValue *logging.SimpleLogger + var nullValue logging.SimpleLogging return nullValue } diff --git a/server/events/runtime/mocks/mock_versionedexecutorworkflow.go b/server/events/runtime/mocks/mock_versionedexecutorworkflow.go index f566d289ec..cfe6556d7c 100644 --- a/server/events/runtime/mocks/mock_versionedexecutorworkflow.go +++ b/server/events/runtime/mocks/mock_versionedexecutorworkflow.go @@ -27,7 +27,7 @@ func NewMockVersionedExecutorWorkflow(options ...pegomock.Option) *MockVersioned func (mock *MockVersionedExecutorWorkflow) SetFailHandler(fh pegomock.FailHandler) { mock.fail = fh } func (mock *MockVersionedExecutorWorkflow) FailHandler() pegomock.FailHandler { return mock.fail } -func (mock *MockVersionedExecutorWorkflow) EnsureExecutorVersion(log *logging.SimpleLogger, v *go_version.Version) (string, error) { +func (mock *MockVersionedExecutorWorkflow) EnsureExecutorVersion(log logging.SimpleLogging, v *go_version.Version) (string, error) { if mock == nil { panic("mock must not be nil. Use myMock := NewMockVersionedExecutorWorkflow().") } @@ -102,7 +102,7 @@ type VerifierMockVersionedExecutorWorkflow struct { timeout time.Duration } -func (verifier *VerifierMockVersionedExecutorWorkflow) EnsureExecutorVersion(log *logging.SimpleLogger, v *go_version.Version) *MockVersionedExecutorWorkflow_EnsureExecutorVersion_OngoingVerification { +func (verifier *VerifierMockVersionedExecutorWorkflow) EnsureExecutorVersion(log logging.SimpleLogging, v *go_version.Version) *MockVersionedExecutorWorkflow_EnsureExecutorVersion_OngoingVerification { params := []pegomock.Param{log, v} methodInvocations := pegomock.GetGenericMockFrom(verifier.mock).Verify(verifier.inOrderContext, verifier.invocationCountMatcher, "EnsureExecutorVersion", params, verifier.timeout) return &MockVersionedExecutorWorkflow_EnsureExecutorVersion_OngoingVerification{mock: verifier.mock, methodInvocations: methodInvocations} @@ -113,17 +113,17 @@ type MockVersionedExecutorWorkflow_EnsureExecutorVersion_OngoingVerification str methodInvocations []pegomock.MethodInvocation } -func (c *MockVersionedExecutorWorkflow_EnsureExecutorVersion_OngoingVerification) GetCapturedArguments() (*logging.SimpleLogger, *go_version.Version) { +func (c *MockVersionedExecutorWorkflow_EnsureExecutorVersion_OngoingVerification) GetCapturedArguments() (logging.SimpleLogging, *go_version.Version) { log, v := c.GetAllCapturedArguments() return log[len(log)-1], v[len(v)-1] } -func (c *MockVersionedExecutorWorkflow_EnsureExecutorVersion_OngoingVerification) GetAllCapturedArguments() (_param0 []*logging.SimpleLogger, _param1 []*go_version.Version) { +func (c *MockVersionedExecutorWorkflow_EnsureExecutorVersion_OngoingVerification) GetAllCapturedArguments() (_param0 []logging.SimpleLogging, _param1 []*go_version.Version) { params := pegomock.GetGenericMockFrom(c.mock).GetInvocationParams(c.methodInvocations) if len(params) > 0 { - _param0 = make([]*logging.SimpleLogger, len(c.methodInvocations)) + _param0 = make([]logging.SimpleLogging, len(c.methodInvocations)) for u, param := range params[0] { - _param0[u] = param.(*logging.SimpleLogger) + _param0[u] = param.(logging.SimpleLogging) } _param1 = make([]*go_version.Version, len(c.methodInvocations)) for u, param := range params[1] { diff --git a/server/events/runtime/plan_step_runner_test.go b/server/events/runtime/plan_step_runner_test.go index 740a895d03..03e8e63e1c 100644 --- a/server/events/runtime/plan_step_runner_test.go +++ b/server/events/runtime/plan_step_runner_test.go @@ -20,6 +20,7 @@ import ( "github.com/runatlantis/atlantis/server/events/terraform/mocks" matchers2 "github.com/runatlantis/atlantis/server/events/terraform/mocks/matchers" "github.com/runatlantis/atlantis/server/logging" + logging_matchers "github.com/runatlantis/atlantis/server/logging/mocks/matchers" . "github.com/runatlantis/atlantis/testing" ) @@ -29,14 +30,14 @@ func TestRun_NoWorkspaceIn08(t *testing.T) { terraform := mocks.NewMockClient() tfVersion, _ := version.NewVersion("0.8") - logger := logging.NewNoopLogger() + logger := logging.NewNoopLogger(t) workspace := "default" s := runtime.PlanStepRunner{ DefaultTFVersion: tfVersion, TerraformExecutor: terraform, } - When(terraform.RunCommandWithVersion(matchers.AnyPtrToLoggingSimpleLogger(), AnyString(), AnyStringSlice(), matchers2.AnyMapOfStringToString(), matchers2.AnyPtrToGoVersionVersion(), AnyString())). + When(terraform.RunCommandWithVersion(logging_matchers.AnyLoggingSimpleLogging(), AnyString(), AnyStringSlice(), matchers2.AnyMapOfStringToString(), matchers2.AnyPtrToGoVersionVersion(), AnyString())). ThenReturn("output", nil) output, err := s.Run(models.ProjectCommandContext{ Log: logger, @@ -111,14 +112,14 @@ func TestRun_ErrWorkspaceIn08(t *testing.T) { terraform := mocks.NewMockClient() tfVersion, _ := version.NewVersion("0.8") - logger := logging.NewNoopLogger() + logger := logging.NewNoopLogger(t) workspace := "notdefault" s := runtime.PlanStepRunner{ TerraformExecutor: terraform, DefaultTFVersion: tfVersion, } - When(terraform.RunCommandWithVersion(matchers.AnyPtrToLoggingSimpleLogger(), AnyString(), AnyStringSlice(), matchers2.AnyMapOfStringToString(), matchers2.AnyPtrToGoVersionVersion(), AnyString())). + When(terraform.RunCommandWithVersion(logging_matchers.AnyLoggingSimpleLogging(), AnyString(), AnyStringSlice(), matchers2.AnyMapOfStringToString(), matchers2.AnyPtrToGoVersionVersion(), AnyString())). ThenReturn("output", nil) _, err := s.Run(models.ProjectCommandContext{ Log: logger, @@ -159,14 +160,14 @@ func TestRun_SwitchesWorkspace(t *testing.T) { terraform := mocks.NewMockClient() tfVersion, _ := version.NewVersion(c.tfVersion) - logger := logging.NewNoopLogger() + logger := logging.NewNoopLogger(t) s := runtime.PlanStepRunner{ TerraformExecutor: terraform, DefaultTFVersion: tfVersion, } - When(terraform.RunCommandWithVersion(matchers.AnyPtrToLoggingSimpleLogger(), AnyString(), AnyStringSlice(), matchers2.AnyMapOfStringToString(), matchers2.AnyPtrToGoVersionVersion(), AnyString())). + When(terraform.RunCommandWithVersion(logging_matchers.AnyLoggingSimpleLogging(), AnyString(), AnyStringSlice(), matchers2.AnyMapOfStringToString(), matchers2.AnyPtrToGoVersionVersion(), AnyString())). ThenReturn("output", nil) output, err := s.Run(models.ProjectCommandContext{ Log: logger, @@ -255,7 +256,7 @@ func TestRun_CreatesWorkspace(t *testing.T) { t.Run(c.tfVersion, func(t *testing.T) { terraform := mocks.NewMockClient() tfVersion, _ := version.NewVersion(c.tfVersion) - logger := logging.NewNoopLogger() + logger := logging.NewNoopLogger(t) s := runtime.PlanStepRunner{ TerraformExecutor: terraform, DefaultTFVersion: tfVersion, @@ -321,7 +322,7 @@ func TestRun_NoWorkspaceSwitchIfNotNecessary(t *testing.T) { RegisterMockTestingT(t) terraform := mocks.NewMockClient() tfVersion, _ := version.NewVersion("0.10.0") - logger := logging.NewNoopLogger() + logger := logging.NewNoopLogger(t) s := runtime.PlanStepRunner{ TerraformExecutor: terraform, DefaultTFVersion: tfVersion, @@ -390,7 +391,7 @@ func TestRun_AddsEnvVarFile(t *testing.T) { // Using version >= 0.10 here so we don't expect any env commands. tfVersion, _ := version.NewVersion("0.10.0") - logger := logging.NewNoopLogger() + logger := logging.NewNoopLogger(t) s := runtime.PlanStepRunner{ TerraformExecutor: terraform, DefaultTFVersion: tfVersion, @@ -450,7 +451,7 @@ func TestRun_UsesDiffPathForProject(t *testing.T) { RegisterMockTestingT(t) terraform := mocks.NewMockClient() tfVersion, _ := version.NewVersion("0.10.0") - logger := logging.NewNoopLogger() + logger := logging.NewNoopLogger(t) s := runtime.PlanStepRunner{ TerraformExecutor: terraform, DefaultTFVersion: tfVersion, @@ -705,6 +706,8 @@ locally at this time. for name, remoteOpsErr := range cases { t.Run(name, func(t *testing.T) { + logger := logging.NewNoopLogger(t) + RegisterMockTestingT(t) terraform := mocks.NewMockClient() asyncTf := &remotePlanMock{} @@ -722,7 +725,7 @@ locally at this time. // First, terraform workspace gets run. When(terraform.RunCommandWithVersion( - nil, + logger, absProjectPath, []string{"workspace", "show"}, map[string]string(nil), @@ -755,11 +758,12 @@ locally at this time. planErr := errors.New("exit status 1: err") planOutput := "\n" + remoteOpsErr asyncTf.LinesToSend = remotePlanOutput - When(terraform.RunCommandWithVersion(nil, absProjectPath, expPlanArgs, map[string]string(nil), tfVersion, "default")). + When(terraform.RunCommandWithVersion(logger, absProjectPath, expPlanArgs, map[string]string(nil), tfVersion, "default")). ThenReturn(planOutput, planErr) // Now that mocking is set up, we're ready to run the plan. ctx := models.ProjectCommandContext{ + Log: logger, Workspace: "default", RepoRelDir: ".", User: models.User{Username: "username"}, @@ -886,7 +890,7 @@ type remotePlanMock struct { CalledArgs []string } -func (r *remotePlanMock) RunCommandAsync(log *logging.SimpleLogger, path string, args []string, envs map[string]string, v *version.Version, workspace string) (chan<- string, <-chan terraform.Line) { +func (r *remotePlanMock) RunCommandAsync(log logging.SimpleLogging, path string, args []string, envs map[string]string, v *version.Version, workspace string) (chan<- string, <-chan terraform.Line) { r.CalledArgs = args in := make(chan string) out := make(chan terraform.Line) diff --git a/server/events/runtime/policy/conftest_client.go b/server/events/runtime/policy/conftest_client.go index 053c8a9a76..8e701ebe1b 100644 --- a/server/events/runtime/policy/conftest_client.go +++ b/server/events/runtime/policy/conftest_client.go @@ -127,7 +127,7 @@ type ConfTestExecutorWorkflow struct { Exec runtime_models.Exec } -func NewConfTestExecutorWorkflow(log *logging.SimpleLogger, versionRootDir string, conftestDownloder terraform.Downloader) *ConfTestExecutorWorkflow { +func NewConfTestExecutorWorkflow(log logging.SimpleLogging, versionRootDir string, conftestDownloder terraform.Downloader) *ConfTestExecutorWorkflow { downloader := ConfTestVersionDownloader{ downloader: conftestDownloder, } @@ -201,7 +201,7 @@ func (c *ConfTestExecutorWorkflow) sanitizeOutput(inputFile string, output strin return strings.Replace(output, inputFile, "", -1) } -func (c *ConfTestExecutorWorkflow) EnsureExecutorVersion(log *logging.SimpleLogger, v *version.Version) (string, error) { +func (c *ConfTestExecutorWorkflow) EnsureExecutorVersion(log logging.SimpleLogging, v *version.Version) (string, error) { // we have no information to proceed so fail hard if c.DefaultConftestVersion == nil && v == nil { return "", errors.New("no conftest version configured/specified") diff --git a/server/events/runtime/policy/conftest_client_test.go b/server/events/runtime/policy/conftest_client_test.go index 570a89b2a6..163180332b 100644 --- a/server/events/runtime/policy/conftest_client_test.go +++ b/server/events/runtime/policy/conftest_client_test.go @@ -62,7 +62,7 @@ func TestEnsureExecutorVersion(t *testing.T) { RegisterMockTestingT(t) mockCache := mocks.NewMockExecutionVersionCache() - log := logging.NewNoopLogger() + log := logging.NewNoopLogger(t) t.Run("no specified version or default version", func(t *testing.T) { subject := &ConfTestExecutorWorkflow{ @@ -132,6 +132,7 @@ func TestRun(t *testing.T) { SourceResolver: mockResolver, Exec: mockExec, } + log := logging.NewNoopLogger(t) policySetName1 := "policy1" policySetPath1 := "/some/path" @@ -167,6 +168,7 @@ func TestRun(t *testing.T) { }, ProjectName: "testproj", Workspace: "default", + Log: log, } t.Run("success", func(t *testing.T) { diff --git a/server/events/runtime/policy_check_step_runner_test.go b/server/events/runtime/policy_check_step_runner_test.go index a1b723af90..e19269ea7b 100644 --- a/server/events/runtime/policy_check_step_runner_test.go +++ b/server/events/runtime/policy_check_step_runner_test.go @@ -15,7 +15,7 @@ import ( func TestRun(t *testing.T) { RegisterMockTestingT(t) - logger := logging.NewNoopLogger() + logger := logging.NewNoopLogger(t) workspace := "default" v, _ := version.NewVersion("1.0") workdir := "/path" diff --git a/server/events/runtime/pre_workflow_hook_runner_test.go b/server/events/runtime/pre_workflow_hook_runner_test.go index 70c092a564..75eb4a2b11 100644 --- a/server/events/runtime/pre_workflow_hook_runner_test.go +++ b/server/events/runtime/pre_workflow_hook_runner_test.go @@ -68,7 +68,7 @@ func TestPreWorkflowHookRunner_Run(t *testing.T) { When(terraform.EnsureVersion(matchers.AnyPtrToLoggingSimpleLogger(), matchers2.AnyPtrToGoVersionVersion())). ThenReturn(nil) - logger := logging.NewNoopLogger() + logger := logging.NewNoopLogger(t) r := runtime.DefaultPreWorkflowHookRunner{} t.Run(c.Command, func(t *testing.T) { diff --git a/server/events/runtime/run_step_runner_test.go b/server/events/runtime/run_step_runner_test.go index 04528113c3..165bedbe7b 100644 --- a/server/events/runtime/run_step_runner_test.go +++ b/server/events/runtime/run_step_runner_test.go @@ -102,7 +102,7 @@ func TestRunStepRunner_Run(t *testing.T) { When(terraform.EnsureVersion(matchers.AnyPtrToLoggingSimpleLogger(), matchers2.AnyPtrToGoVersionVersion())). ThenReturn(nil) - logger := logging.NewNoopLogger() + logger := logging.NewNoopLogger(t) r := runtime.RunStepRunner{ TerraformExecutor: terraform, diff --git a/server/events/runtime/runtime.go b/server/events/runtime/runtime.go index fb8656f5dd..a2beb78daa 100644 --- a/server/events/runtime/runtime.go +++ b/server/events/runtime/runtime.go @@ -25,8 +25,8 @@ const ( // TerraformExec brings the interface from TerraformClient into this package // without causing circular imports. type TerraformExec interface { - RunCommandWithVersion(log *logging.SimpleLogger, path string, args []string, envs map[string]string, v *version.Version, workspace string) (string, error) - EnsureVersion(log *logging.SimpleLogger, v *version.Version) error + RunCommandWithVersion(log logging.SimpleLogging, path string, args []string, envs map[string]string, v *version.Version, workspace string) (string, error) + EnsureVersion(log logging.SimpleLogging, v *version.Version) error } // AsyncTFExec brings the interface from TerraformClient into this package @@ -40,7 +40,7 @@ type AsyncTFExec interface { // Callers can use the input channel to pass stdin input to the command. // If any error is passed on the out channel, there will be no // further output (so callers are free to exit). - RunCommandAsync(log *logging.SimpleLogger, path string, args []string, envs map[string]string, v *version.Version, workspace string) (chan<- string, <-chan terraform.Line) + RunCommandAsync(log logging.SimpleLogging, path string, args []string, envs map[string]string, v *version.Version, workspace string) (chan<- string, <-chan terraform.Line) } // StatusUpdater brings the interface from CommitStatusUpdater into this package diff --git a/server/events/runtime/show_step_runner_test.go b/server/events/runtime/show_step_runner_test.go index 977530278f..72250d3a08 100644 --- a/server/events/runtime/show_step_runner_test.go +++ b/server/events/runtime/show_step_runner_test.go @@ -15,7 +15,7 @@ import ( ) func TestShowStepRunnner(t *testing.T) { - logger := logging.NewNoopLogger() + logger := logging.NewNoopLogger(t) path, _ := ioutil.TempDir("", "") resultPath := filepath.Join(path, "test-default.json") envs := map[string]string{"key": "val"} diff --git a/server/events/terraform/mocks/matchers/ptr_to_logging_simplelogger.go b/server/events/terraform/mocks/matchers/ptr_to_logging_simplelogger.go index 04c72791bc..cf9bb5453f 100644 --- a/server/events/terraform/mocks/matchers/ptr_to_logging_simplelogger.go +++ b/server/events/terraform/mocks/matchers/ptr_to_logging_simplelogger.go @@ -2,19 +2,19 @@ package matchers import ( - "reflect" "github.com/petergtz/pegomock" logging "github.com/runatlantis/atlantis/server/logging" + "reflect" ) -func AnyPtrToLoggingSimpleLogger() *logging.SimpleLogger { - pegomock.RegisterMatcher(pegomock.NewAnyMatcher(reflect.TypeOf((*(*logging.SimpleLogger))(nil)).Elem())) - var nullValue *logging.SimpleLogger +func AnyPtrToLoggingSimpleLogger() logging.SimpleLogging { + pegomock.RegisterMatcher(pegomock.NewAnyMatcher(reflect.TypeOf((*(logging.SimpleLogging))(nil)).Elem())) + var nullValue logging.SimpleLogging return nullValue } -func EqPtrToLoggingSimpleLogger(value *logging.SimpleLogger) *logging.SimpleLogger { +func EqPtrToLoggingSimpleLogger(value logging.SimpleLogging) logging.SimpleLogging { pegomock.RegisterMatcher(&pegomock.EqMatcher{Value: value}) - var nullValue *logging.SimpleLogger + var nullValue logging.SimpleLogging return nullValue } diff --git a/server/events/terraform/mocks/mock_terraform_client.go b/server/events/terraform/mocks/mock_terraform_client.go index 329e849eb6..b92077775b 100644 --- a/server/events/terraform/mocks/mock_terraform_client.go +++ b/server/events/terraform/mocks/mock_terraform_client.go @@ -26,7 +26,7 @@ func NewMockClient(options ...pegomock.Option) *MockClient { func (mock *MockClient) SetFailHandler(fh pegomock.FailHandler) { mock.fail = fh } func (mock *MockClient) FailHandler() pegomock.FailHandler { return mock.fail } -func (mock *MockClient) RunCommandWithVersion(log *logging.SimpleLogger, path string, args []string, envs map[string]string, v *go_version.Version, workspace string) (string, error) { +func (mock *MockClient) RunCommandWithVersion(log logging.SimpleLogging, path string, args []string, envs map[string]string, v *go_version.Version, workspace string) (string, error) { if mock == nil { panic("mock must not be nil. Use myMock := NewMockClient().") } @@ -45,7 +45,7 @@ func (mock *MockClient) RunCommandWithVersion(log *logging.SimpleLogger, path st return ret0, ret1 } -func (mock *MockClient) EnsureVersion(log *logging.SimpleLogger, v *go_version.Version) error { +func (mock *MockClient) EnsureVersion(log logging.SimpleLogging, v *go_version.Version) error { if mock == nil { panic("mock must not be nil. Use myMock := NewMockClient().") } @@ -97,7 +97,7 @@ type VerifierMockClient struct { timeout time.Duration } -func (verifier *VerifierMockClient) RunCommandWithVersion(log *logging.SimpleLogger, path string, args []string, envs map[string]string, v *go_version.Version, workspace string) *MockClient_RunCommandWithVersion_OngoingVerification { +func (verifier *VerifierMockClient) RunCommandWithVersion(log logging.SimpleLogging, path string, args []string, envs map[string]string, v *go_version.Version, workspace string) *MockClient_RunCommandWithVersion_OngoingVerification { params := []pegomock.Param{log, path, args, envs, v, workspace} methodInvocations := pegomock.GetGenericMockFrom(verifier.mock).Verify(verifier.inOrderContext, verifier.invocationCountMatcher, "RunCommandWithVersion", params, verifier.timeout) return &MockClient_RunCommandWithVersion_OngoingVerification{mock: verifier.mock, methodInvocations: methodInvocations} @@ -108,17 +108,17 @@ type MockClient_RunCommandWithVersion_OngoingVerification struct { methodInvocations []pegomock.MethodInvocation } -func (c *MockClient_RunCommandWithVersion_OngoingVerification) GetCapturedArguments() (*logging.SimpleLogger, string, []string, map[string]string, *go_version.Version, string) { +func (c *MockClient_RunCommandWithVersion_OngoingVerification) GetCapturedArguments() (logging.SimpleLogging, string, []string, map[string]string, *go_version.Version, string) { log, path, args, envs, v, workspace := c.GetAllCapturedArguments() return log[len(log)-1], path[len(path)-1], args[len(args)-1], envs[len(envs)-1], v[len(v)-1], workspace[len(workspace)-1] } -func (c *MockClient_RunCommandWithVersion_OngoingVerification) GetAllCapturedArguments() (_param0 []*logging.SimpleLogger, _param1 []string, _param2 [][]string, _param3 []map[string]string, _param4 []*go_version.Version, _param5 []string) { +func (c *MockClient_RunCommandWithVersion_OngoingVerification) GetAllCapturedArguments() (_param0 []logging.SimpleLogging, _param1 []string, _param2 [][]string, _param3 []map[string]string, _param4 []*go_version.Version, _param5 []string) { params := pegomock.GetGenericMockFrom(c.mock).GetInvocationParams(c.methodInvocations) if len(params) > 0 { - _param0 = make([]*logging.SimpleLogger, len(c.methodInvocations)) + _param0 = make([]logging.SimpleLogging, len(c.methodInvocations)) for u, param := range params[0] { - _param0[u] = param.(*logging.SimpleLogger) + _param0[u] = param.(logging.SimpleLogging) } _param1 = make([]string, len(c.methodInvocations)) for u, param := range params[1] { @@ -144,7 +144,7 @@ func (c *MockClient_RunCommandWithVersion_OngoingVerification) GetAllCapturedArg return } -func (verifier *VerifierMockClient) EnsureVersion(log *logging.SimpleLogger, v *go_version.Version) *MockClient_EnsureVersion_OngoingVerification { +func (verifier *VerifierMockClient) EnsureVersion(log logging.SimpleLogging, v *go_version.Version) *MockClient_EnsureVersion_OngoingVerification { params := []pegomock.Param{log, v} methodInvocations := pegomock.GetGenericMockFrom(verifier.mock).Verify(verifier.inOrderContext, verifier.invocationCountMatcher, "EnsureVersion", params, verifier.timeout) return &MockClient_EnsureVersion_OngoingVerification{mock: verifier.mock, methodInvocations: methodInvocations} @@ -155,17 +155,17 @@ type MockClient_EnsureVersion_OngoingVerification struct { methodInvocations []pegomock.MethodInvocation } -func (c *MockClient_EnsureVersion_OngoingVerification) GetCapturedArguments() (*logging.SimpleLogger, *go_version.Version) { +func (c *MockClient_EnsureVersion_OngoingVerification) GetCapturedArguments() (logging.SimpleLogging, *go_version.Version) { log, v := c.GetAllCapturedArguments() return log[len(log)-1], v[len(v)-1] } -func (c *MockClient_EnsureVersion_OngoingVerification) GetAllCapturedArguments() (_param0 []*logging.SimpleLogger, _param1 []*go_version.Version) { +func (c *MockClient_EnsureVersion_OngoingVerification) GetAllCapturedArguments() (_param0 []logging.SimpleLogging, _param1 []*go_version.Version) { params := pegomock.GetGenericMockFrom(c.mock).GetInvocationParams(c.methodInvocations) if len(params) > 0 { - _param0 = make([]*logging.SimpleLogger, len(c.methodInvocations)) + _param0 = make([]logging.SimpleLogging, len(c.methodInvocations)) for u, param := range params[0] { - _param0[u] = param.(*logging.SimpleLogger) + _param0[u] = param.(logging.SimpleLogging) } _param1 = make([]*go_version.Version, len(c.methodInvocations)) for u, param := range params[1] { diff --git a/server/events/terraform/terraform_client.go b/server/events/terraform/terraform_client.go index 4f0310ec86..023ba731b1 100644 --- a/server/events/terraform/terraform_client.go +++ b/server/events/terraform/terraform_client.go @@ -40,10 +40,10 @@ type Client interface { // RunCommandWithVersion executes terraform with args in path. If v is nil, // it will use the default Terraform version. workspace is the Terraform // workspace which should be set as an environment variable. - RunCommandWithVersion(log *logging.SimpleLogger, path string, args []string, envs map[string]string, v *version.Version, workspace string) (string, error) + RunCommandWithVersion(log logging.SimpleLogging, path string, args []string, envs map[string]string, v *version.Version, workspace string) (string, error) // EnsureVersion makes sure that terraform version `v` is available to use - EnsureVersion(log *logging.SimpleLogger, v *version.Version) error + EnsureVersion(log logging.SimpleLogging, v *version.Version) error } type DefaultClient struct { @@ -97,7 +97,7 @@ var versionRegex = regexp.MustCompile("Terraform v(.*?)(\\s.*)?\n") // tfDownloader is used to download terraform versions. // Will asynchronously download the required version if it doesn't exist already. func NewClient( - log *logging.SimpleLogger, + log logging.SimpleLogging, binDir string, cacheDir string, tfeToken string, @@ -182,7 +182,7 @@ func (c *DefaultClient) TerraformBinDir() string { } // See Client.EnsureVersion. -func (c *DefaultClient) EnsureVersion(log *logging.SimpleLogger, v *version.Version) error { +func (c *DefaultClient) EnsureVersion(log logging.SimpleLogging, v *version.Version) error { if v == nil { v = c.defaultVersion } @@ -199,7 +199,7 @@ func (c *DefaultClient) EnsureVersion(log *logging.SimpleLogger, v *version.Vers } // See Client.RunCommandWithVersion. -func (c *DefaultClient) RunCommandWithVersion(log *logging.SimpleLogger, path string, args []string, customEnvVars map[string]string, v *version.Version, workspace string) (string, error) { +func (c *DefaultClient) RunCommandWithVersion(log logging.SimpleLogging, path string, args []string, customEnvVars map[string]string, v *version.Version, workspace string) (string, error) { tfCmd, cmd, err := c.prepCmd(log, v, workspace, path, args) if err != nil { return "", err @@ -222,7 +222,7 @@ func (c *DefaultClient) RunCommandWithVersion(log *logging.SimpleLogger, path st // prepCmd builds a ready to execute command based on the version of terraform // v, and args. It returns a printable representation of the command that will // be run and the actual command. -func (c *DefaultClient) prepCmd(log *logging.SimpleLogger, v *version.Version, workspace string, path string, args []string) (string, *exec.Cmd, error) { +func (c *DefaultClient) prepCmd(log logging.SimpleLogging, v *version.Version, workspace string, path string, args []string) (string, *exec.Cmd, error) { if v == nil { v = c.defaultVersion } @@ -279,7 +279,7 @@ type Line struct { // Callers can use the input channel to pass stdin input to the command. // If any error is passed on the out channel, there will be no // further output (so callers are free to exit). -func (c *DefaultClient) RunCommandAsync(log *logging.SimpleLogger, path string, args []string, customEnvVars map[string]string, v *version.Version, workspace string) (chan<- string, <-chan Line) { +func (c *DefaultClient) RunCommandAsync(log logging.SimpleLogging, path string, args []string, customEnvVars map[string]string, v *version.Version, workspace string) (chan<- string, <-chan Line) { outCh := make(chan Line) inCh := make(chan string) @@ -382,7 +382,7 @@ func MustConstraint(v string) version.Constraints { // ensureVersion returns the path to a terraform binary of version v. // It will download this version if we don't have it. -func ensureVersion(log *logging.SimpleLogger, dl Downloader, versions map[string]string, v *version.Version, binDir string, downloadURL string) (string, error) { +func ensureVersion(log logging.SimpleLogging, dl Downloader, versions map[string]string, v *version.Version, binDir string, downloadURL string) (string, error) { if binPath, ok := versions[v.String()]; ok { return binPath, nil } diff --git a/server/events/terraform/terraform_client_internal_test.go b/server/events/terraform/terraform_client_internal_test.go index b2504f6509..8a447fb828 100644 --- a/server/events/terraform/terraform_client_internal_test.go +++ b/server/events/terraform/terraform_client_internal_test.go @@ -104,7 +104,8 @@ func TestDefaultClient_RunCommandWithVersion_EnvVars(t *testing.T) { "ATLANTIS_TERRAFORM_VERSION=$ATLANTIS_TERRAFORM_VERSION", "DIR=$DIR", } - out, err := client.RunCommandWithVersion(nil, tmp, args, map[string]string{}, nil, "workspace") + log := logging.NewNoopLogger(t) + out, err := client.RunCommandWithVersion(log, tmp, args, map[string]string{}, nil, "workspace") Ok(t, err) exp := fmt.Sprintf("TF_IN_AUTOMATION=true TF_PLUGIN_CACHE_DIR=%s WORKSPACE=workspace ATLANTIS_TERRAFORM_VERSION=0.11.11 DIR=%s\n", tmp, tmp) Equals(t, exp, out) @@ -128,7 +129,7 @@ func TestDefaultClient_RunCommandWithVersion_Error(t *testing.T) { "exit", "1", } - log := logging.NewSimpleLogger("test", false, logging.Debug) + log := logging.NewNoopLogger(t) out, err := client.RunCommandWithVersion(log, tmp, args, map[string]string{}, nil, "workspace") ErrEquals(t, fmt.Sprintf(`running "echo dying && exit 1" in %q: exit status 1`, tmp), err) // Test that we still get our output. @@ -154,7 +155,8 @@ func TestDefaultClient_RunCommandAsync_Success(t *testing.T) { "ATLANTIS_TERRAFORM_VERSION=$ATLANTIS_TERRAFORM_VERSION", "DIR=$DIR", } - _, outCh := client.RunCommandAsync(nil, tmp, args, map[string]string{}, nil, "workspace") + log := logging.NewNoopLogger(t) + _, outCh := client.RunCommandAsync(log, tmp, args, map[string]string{}, nil, "workspace") out, err := waitCh(outCh) Ok(t, err) @@ -183,7 +185,8 @@ func TestDefaultClient_RunCommandAsync_BigOutput(t *testing.T) { _, err = f.WriteString(s) Ok(t, err) } - _, outCh := client.RunCommandAsync(nil, tmp, []string{filename}, map[string]string{}, nil, "workspace") + log := logging.NewNoopLogger(t) + _, outCh := client.RunCommandAsync(log, tmp, []string{filename}, map[string]string{}, nil, "workspace") out, err := waitCh(outCh) Ok(t, err) @@ -200,7 +203,7 @@ func TestDefaultClient_RunCommandAsync_StderrOutput(t *testing.T) { terraformPluginCacheDir: tmp, overrideTF: "echo", } - log := logging.NewSimpleLogger("test", false, logging.Debug) + log := logging.NewNoopLogger(t) _, outCh := client.RunCommandAsync(log, tmp, []string{"stderr", ">&2"}, map[string]string{}, nil, "workspace") out, err := waitCh(outCh) @@ -218,7 +221,7 @@ func TestDefaultClient_RunCommandAsync_ExitOne(t *testing.T) { terraformPluginCacheDir: tmp, overrideTF: "echo", } - log := logging.NewSimpleLogger("test", false, logging.Debug) + log := logging.NewNoopLogger(t) _, outCh := client.RunCommandAsync(log, tmp, []string{"dying", "&&", "exit", "1"}, map[string]string{}, nil, "workspace") out, err := waitCh(outCh) @@ -237,7 +240,7 @@ func TestDefaultClient_RunCommandAsync_Input(t *testing.T) { terraformPluginCacheDir: tmp, overrideTF: "read", } - log := logging.NewSimpleLogger("test", false, logging.Debug) + log := logging.NewNoopLogger(t) inCh, outCh := client.RunCommandAsync(log, tmp, []string{"a", "&&", "echo", "$a"}, map[string]string{}, nil, "workspace") inCh <- "echo me\n" diff --git a/server/events/terraform/terraform_client_test.go b/server/events/terraform/terraform_client_test.go index 4b0f7ea0bd..574e506985 100644 --- a/server/events/terraform/terraform_client_test.go +++ b/server/events/terraform/terraform_client_test.go @@ -62,19 +62,21 @@ is 0.11.13. You can update by downloading from www.terraform.io/downloads.html tmp, binDir, cacheDir, cleanup := mkSubDirs(t) defer cleanup() + logger := logging.NewNoopLogger(t) + // We're testing this by adding our own "fake" terraform binary to path that // outputs what would normally come from terraform version. err := ioutil.WriteFile(filepath.Join(tmp, "terraform"), []byte(fmt.Sprintf("#!/bin/sh\necho '%s'", fakeBinOut)), 0755) Ok(t, err) defer tempSetEnv(t, "PATH", fmt.Sprintf("%s:%s", tmp, os.Getenv("PATH")))() - c, err := terraform.NewClient(nil, binDir, cacheDir, "", "", "", cmd.DefaultTFVersionFlag, cmd.DefaultTFDownloadURL, nil, true) + c, err := terraform.NewClient(logger, binDir, cacheDir, "", "", "", cmd.DefaultTFVersionFlag, cmd.DefaultTFDownloadURL, nil, true) Ok(t, err) Ok(t, err) Equals(t, "0.11.10", c.DefaultVersion().String()) - output, err := c.RunCommandWithVersion(nil, tmp, nil, map[string]string{"test": "123"}, nil, "") + output, err := c.RunCommandWithVersion(logger, tmp, nil, map[string]string{"test": "123"}, nil, "") Ok(t, err) Equals(t, fakeBinOut+"\n", output) } @@ -87,6 +89,7 @@ func TestNewClient_LocalTFMatchesFlag(t *testing.T) { Your version of Terraform is out of date! The latest version is 0.11.13. You can update by downloading from www.terraform.io/downloads.html ` + logger := logging.NewNoopLogger(t) tmp, binDir, cacheDir, cleanup := mkSubDirs(t) defer cleanup() @@ -96,13 +99,13 @@ is 0.11.13. You can update by downloading from www.terraform.io/downloads.html Ok(t, err) defer tempSetEnv(t, "PATH", fmt.Sprintf("%s:%s", tmp, os.Getenv("PATH")))() - c, err := terraform.NewClient(nil, binDir, cacheDir, "", "", "0.11.10", cmd.DefaultTFVersionFlag, cmd.DefaultTFDownloadURL, nil, true) + c, err := terraform.NewClient(logger, binDir, cacheDir, "", "", "0.11.10", cmd.DefaultTFVersionFlag, cmd.DefaultTFDownloadURL, nil, true) Ok(t, err) Ok(t, err) Equals(t, "0.11.10", c.DefaultVersion().String()) - output, err := c.RunCommandWithVersion(nil, tmp, nil, map[string]string{}, nil, "") + output, err := c.RunCommandWithVersion(logger, tmp, nil, map[string]string{}, nil, "") Ok(t, err) Equals(t, fakeBinOut+"\n", output) } @@ -110,13 +113,14 @@ is 0.11.13. You can update by downloading from www.terraform.io/downloads.html // Test that if terraform is not in PATH and we didn't set the default-tf flag // that we error. func TestNewClient_NoTF(t *testing.T) { + logger := logging.NewNoopLogger(t) tmp, binDir, cacheDir, cleanup := mkSubDirs(t) defer cleanup() // Set PATH to only include our empty directory. defer tempSetEnv(t, "PATH", tmp)() - _, err := terraform.NewClient(nil, binDir, cacheDir, "", "", "", cmd.DefaultTFVersionFlag, cmd.DefaultTFDownloadURL, nil, true) + _, err := terraform.NewClient(logger, binDir, cacheDir, "", "", "", cmd.DefaultTFVersionFlag, cmd.DefaultTFDownloadURL, nil, true) ErrEquals(t, "terraform not found in $PATH. Set --default-tf-version or download terraform from https://www.terraform.io/downloads.html", err) } @@ -124,6 +128,7 @@ func TestNewClient_NoTF(t *testing.T) { // that we use it. func TestNewClient_DefaultTFFlagInPath(t *testing.T) { fakeBinOut := "Terraform v0.11.10\n" + logger := logging.NewNoopLogger(t) tmp, binDir, cacheDir, cleanup := mkSubDirs(t) defer cleanup() @@ -133,13 +138,13 @@ func TestNewClient_DefaultTFFlagInPath(t *testing.T) { Ok(t, err) defer tempSetEnv(t, "PATH", fmt.Sprintf("%s:%s", tmp, os.Getenv("PATH")))() - c, err := terraform.NewClient(nil, binDir, cacheDir, "", "", "0.11.10", cmd.DefaultTFVersionFlag, cmd.DefaultTFDownloadURL, nil, true) + c, err := terraform.NewClient(logger, binDir, cacheDir, "", "", "0.11.10", cmd.DefaultTFVersionFlag, cmd.DefaultTFDownloadURL, nil, true) Ok(t, err) Ok(t, err) Equals(t, "0.11.10", c.DefaultVersion().String()) - output, err := c.RunCommandWithVersion(nil, tmp, nil, map[string]string{}, nil, "") + output, err := c.RunCommandWithVersion(logger, tmp, nil, map[string]string{}, nil, "") Ok(t, err) Equals(t, fakeBinOut+"\n", output) } @@ -148,6 +153,7 @@ func TestNewClient_DefaultTFFlagInPath(t *testing.T) { // bin dir that we use it. func TestNewClient_DefaultTFFlagInBinDir(t *testing.T) { fakeBinOut := "Terraform v0.11.10\n" + logger := logging.NewNoopLogger(t) tmp, binDir, cacheDir, cleanup := mkSubDirs(t) defer cleanup() @@ -156,13 +162,13 @@ func TestNewClient_DefaultTFFlagInBinDir(t *testing.T) { Ok(t, err) defer tempSetEnv(t, "PATH", fmt.Sprintf("%s:%s", tmp, os.Getenv("PATH")))() - c, err := terraform.NewClient(logging.NewNoopLogger(), binDir, cacheDir, "", "", "0.11.10", cmd.DefaultTFVersionFlag, cmd.DefaultTFDownloadURL, nil, true) + c, err := terraform.NewClient(logging.NewNoopLogger(t), binDir, cacheDir, "", "", "0.11.10", cmd.DefaultTFVersionFlag, cmd.DefaultTFDownloadURL, nil, true) Ok(t, err) Ok(t, err) Equals(t, "0.11.10", c.DefaultVersion().String()) - output, err := c.RunCommandWithVersion(nil, tmp, nil, map[string]string{}, nil, "") + output, err := c.RunCommandWithVersion(logger, tmp, nil, map[string]string{}, nil, "") Ok(t, err) Equals(t, fakeBinOut+"\n", output) } @@ -170,6 +176,7 @@ func TestNewClient_DefaultTFFlagInBinDir(t *testing.T) { // Test that if we don't have that version of TF that we download it. func TestNewClient_DefaultTFFlagDownload(t *testing.T) { RegisterMockTestingT(t) + logger := logging.NewNoopLogger(t) tmp, binDir, cacheDir, cleanup := mkSubDirs(t) defer cleanup() @@ -182,7 +189,7 @@ func TestNewClient_DefaultTFFlagDownload(t *testing.T) { err := ioutil.WriteFile(params[0].(string), []byte("#!/bin/sh\necho '\nTerraform v0.11.10\n'"), 0755) return []pegomock.ReturnValue{err} }) - c, err := terraform.NewClient(nil, binDir, cacheDir, "", "", "0.11.10", cmd.DefaultTFVersionFlag, "https://my-mirror.releases.mycompany.com", mockDownloader, true) + c, err := terraform.NewClient(logger, binDir, cacheDir, "", "", "0.11.10", cmd.DefaultTFVersionFlag, "https://my-mirror.releases.mycompany.com", mockDownloader, true) Ok(t, err) Ok(t, err) @@ -197,21 +204,23 @@ func TestNewClient_DefaultTFFlagDownload(t *testing.T) { // Reset PATH so that it has sh. Ok(t, os.Setenv("PATH", orig)) - output, err := c.RunCommandWithVersion(nil, tmp, nil, map[string]string{}, nil, "") + output, err := c.RunCommandWithVersion(logger, tmp, nil, map[string]string{}, nil, "") Ok(t, err) Equals(t, "\nTerraform v0.11.10\n\n", output) } // Test that we get an error if the terraform version flag is malformed. func TestNewClient_BadVersion(t *testing.T) { + logger := logging.NewNoopLogger(t) _, binDir, cacheDir, cleanup := mkSubDirs(t) defer cleanup() - _, err := terraform.NewClient(nil, binDir, cacheDir, "", "", "malformed", cmd.DefaultTFVersionFlag, cmd.DefaultTFDownloadURL, nil, true) + _, err := terraform.NewClient(logger, binDir, cacheDir, "", "", "malformed", cmd.DefaultTFVersionFlag, cmd.DefaultTFDownloadURL, nil, true) ErrEquals(t, "Malformed version: malformed", err) } // Test that if we run a command with a version we don't have, we download it. func TestRunCommandWithVersion_DLsTF(t *testing.T) { + logger := logging.NewNoopLogger(t) RegisterMockTestingT(t) tmp, binDir, cacheDir, cleanup := mkSubDirs(t) defer cleanup() @@ -229,26 +238,27 @@ func TestRunCommandWithVersion_DLsTF(t *testing.T) { return []pegomock.ReturnValue{err} }) - c, err := terraform.NewClient(nil, binDir, cacheDir, "", "", "0.11.10", cmd.DefaultTFVersionFlag, cmd.DefaultTFDownloadURL, mockDownloader, true) + c, err := terraform.NewClient(logger, binDir, cacheDir, "", "", "0.11.10", cmd.DefaultTFVersionFlag, cmd.DefaultTFDownloadURL, mockDownloader, true) Ok(t, err) Equals(t, "0.11.10", c.DefaultVersion().String()) v, err := version.NewVersion("99.99.99") Ok(t, err) - output, err := c.RunCommandWithVersion(nil, tmp, nil, map[string]string{}, v, "") + output, err := c.RunCommandWithVersion(logger, tmp, nil, map[string]string{}, v, "") Assert(t, err == nil, "err: %s: %s", err, output) Equals(t, "\nTerraform v99.99.99\n\n", output) } // Test the EnsureVersion downloads terraform. func TestEnsureVersion_downloaded(t *testing.T) { + logger := logging.NewNoopLogger(t) RegisterMockTestingT(t) tmp, binDir, cacheDir, cleanup := mkSubDirs(t) defer cleanup() mockDownloader := mocks.NewMockDownloader() - c, err := terraform.NewClient(nil, binDir, cacheDir, "", "", "0.11.10", cmd.DefaultTFVersionFlag, cmd.DefaultTFDownloadURL, mockDownloader, true) + c, err := terraform.NewClient(logger, binDir, cacheDir, "", "", "0.11.10", cmd.DefaultTFVersionFlag, cmd.DefaultTFDownloadURL, mockDownloader, true) Ok(t, err) Equals(t, "0.11.10", c.DefaultVersion().String()) @@ -256,7 +266,7 @@ func TestEnsureVersion_downloaded(t *testing.T) { v, err := version.NewVersion("99.99.99") Ok(t, err) - err = c.EnsureVersion(nil, v) + err = c.EnsureVersion(logger, v) Ok(t, err) diff --git a/server/events/vcs/github_client.go b/server/events/vcs/github_client.go index a0b1db6a46..20d3ab1ae9 100644 --- a/server/events/vcs/github_client.go +++ b/server/events/vcs/github_client.go @@ -41,7 +41,7 @@ type GithubClient struct { client *github.Client v4MutateClient *graphql.Client ctx context.Context - logger *logging.SimpleLogger + logger logging.SimpleLogging } // GithubAppTemporarySecrets holds app credentials obtained from github after creation. @@ -59,7 +59,7 @@ type GithubAppTemporarySecrets struct { } // NewGithubClient returns a valid GitHub client. -func NewGithubClient(hostname string, credentials GithubCredentials, logger *logging.SimpleLogger) (*GithubClient, error) { +func NewGithubClient(hostname string, credentials GithubCredentials, logger logging.SimpleLogging) (*GithubClient, error) { transport, err := credentials.Client() if err != nil { return nil, errors.Wrap(err, "error initializing github authentication transport") diff --git a/server/events/vcs/github_client_internal_test.go b/server/events/vcs/github_client_internal_test.go index 81b0185ace..ebe039d319 100644 --- a/server/events/vcs/github_client_internal_test.go +++ b/server/events/vcs/github_client_internal_test.go @@ -16,19 +16,20 @@ package vcs import ( "testing" + "github.com/runatlantis/atlantis/server/logging" . "github.com/runatlantis/atlantis/testing" ) // If the hostname is github.com, should use normal BaseURL. func TestNewGithubClient_GithubCom(t *testing.T) { - client, err := NewGithubClient("github.com", &GithubUserCredentials{"user", "pass"}, nil) + client, err := NewGithubClient("github.com", &GithubUserCredentials{"user", "pass"}, logging.NewNoopLogger(t)) Ok(t, err) Equals(t, "https://api.github.com/", client.client.BaseURL.String()) } // If the hostname is a non-github hostname should use the right BaseURL. func TestNewGithubClient_NonGithub(t *testing.T) { - client, err := NewGithubClient("example.com", &GithubUserCredentials{"user", "pass"}, nil) + client, err := NewGithubClient("example.com", &GithubUserCredentials{"user", "pass"}, logging.NewNoopLogger(t)) Ok(t, err) Equals(t, "https://example.com/api/v3/", client.client.BaseURL.String()) // If possible in the future, test the GraphQL client's URL as well. But at the diff --git a/server/events/vcs/github_client_test.go b/server/events/vcs/github_client_test.go index dc56d79965..70d719704e 100644 --- a/server/events/vcs/github_client_test.go +++ b/server/events/vcs/github_client_test.go @@ -13,6 +13,7 @@ import ( "github.com/runatlantis/atlantis/server/events/models" "github.com/runatlantis/atlantis/server/events/vcs" + "github.com/runatlantis/atlantis/server/logging" . "github.com/runatlantis/atlantis/testing" "github.com/shurcooL/githubv4" @@ -21,6 +22,7 @@ import ( // GetModifiedFiles should make multiple requests if more than one page // and concat results. func TestGithubClient_GetModifiedFiles(t *testing.T) { + logger := logging.NewNoopLogger(t) respTemplate := `[ { "sha": "bbcd538c8e72b8c175046e27cc8f907076331401", @@ -59,7 +61,7 @@ func TestGithubClient_GetModifiedFiles(t *testing.T) { testServerURL, err := url.Parse(testServer.URL) Ok(t, err) - client, err := vcs.NewGithubClient(testServerURL.Host, &vcs.GithubUserCredentials{"user", "pass"}, nil) + client, err := vcs.NewGithubClient(testServerURL.Host, &vcs.GithubUserCredentials{"user", "pass"}, logger) Ok(t, err) defer disableSSLVerification()() @@ -114,7 +116,7 @@ func TestGithubClient_GetModifiedFilesMovedFile(t *testing.T) { testServerURL, err := url.Parse(testServer.URL) Ok(t, err) - client, err := vcs.NewGithubClient(testServerURL.Host, &vcs.GithubUserCredentials{"user", "pass"}, nil) + client, err := vcs.NewGithubClient(testServerURL.Host, &vcs.GithubUserCredentials{"user", "pass"}, logging.NewNoopLogger(t)) Ok(t, err) defer disableSSLVerification()() @@ -208,7 +210,7 @@ func TestGithubClient_PaginatesComments(t *testing.T) { testServerURL, err := url.Parse(testServer.URL) Ok(t, err) - client, err := vcs.NewGithubClient(testServerURL.Host, &vcs.GithubUserCredentials{"user", "pass"}, nil) + client, err := vcs.NewGithubClient(testServerURL.Host, &vcs.GithubUserCredentials{"user", "pass"}, logging.NewNoopLogger(t)) Ok(t, err) defer disableSSLVerification()() @@ -296,7 +298,7 @@ func TestGithubClient_HideOldComments(t *testing.T) { testServerURL, err := url.Parse(testServer.URL) Ok(t, err) - client, err := vcs.NewGithubClient(testServerURL.Host, &vcs.GithubUserCredentials{"user", "pass"}, nil) + client, err := vcs.NewGithubClient(testServerURL.Host, &vcs.GithubUserCredentials{"user", "pass"}, logging.NewNoopLogger(t)) Ok(t, err) defer disableSSLVerification()() @@ -361,7 +363,7 @@ func TestGithubClient_UpdateStatus(t *testing.T) { testServerURL, err := url.Parse(testServer.URL) Ok(t, err) - client, err := vcs.NewGithubClient(testServerURL.Host, &vcs.GithubUserCredentials{"user", "pass"}, nil) + client, err := vcs.NewGithubClient(testServerURL.Host, &vcs.GithubUserCredentials{"user", "pass"}, logging.NewNoopLogger(t)) Ok(t, err) defer disableSSLVerification()() @@ -447,7 +449,7 @@ func TestGithubClient_PullIsApproved(t *testing.T) { testServerURL, err := url.Parse(testServer.URL) Ok(t, err) - client, err := vcs.NewGithubClient(testServerURL.Host, &vcs.GithubUserCredentials{"user", "pass"}, nil) + client, err := vcs.NewGithubClient(testServerURL.Host, &vcs.GithubUserCredentials{"user", "pass"}, logging.NewNoopLogger(t)) Ok(t, err) defer disableSSLVerification()() @@ -538,7 +540,7 @@ func TestGithubClient_PullIsMergeable(t *testing.T) { })) testServerURL, err := url.Parse(testServer.URL) Ok(t, err) - client, err := vcs.NewGithubClient(testServerURL.Host, &vcs.GithubUserCredentials{"user", "pass"}, nil) + client, err := vcs.NewGithubClient(testServerURL.Host, &vcs.GithubUserCredentials{"user", "pass"}, logging.NewNoopLogger(t)) Ok(t, err) defer disableSSLVerification()() @@ -620,7 +622,7 @@ func TestGithubClient_MergePullHandlesError(t *testing.T) { testServerURL, err := url.Parse(testServer.URL) Ok(t, err) - client, err := vcs.NewGithubClient(testServerURL.Host, &vcs.GithubUserCredentials{"user", "pass"}, nil) + client, err := vcs.NewGithubClient(testServerURL.Host, &vcs.GithubUserCredentials{"user", "pass"}, logging.NewNoopLogger(t)) Ok(t, err) defer disableSSLVerification()() @@ -741,7 +743,7 @@ func TestGithubClient_MergePullCorrectMethod(t *testing.T) { testServerURL, err := url.Parse(testServer.URL) Ok(t, err) - client, err := vcs.NewGithubClient(testServerURL.Host, &vcs.GithubUserCredentials{"user", "pass"}, nil) + client, err := vcs.NewGithubClient(testServerURL.Host, &vcs.GithubUserCredentials{"user", "pass"}, logging.NewNoopLogger(t)) Ok(t, err) defer disableSSLVerification()() @@ -766,7 +768,7 @@ func TestGithubClient_MergePullCorrectMethod(t *testing.T) { } func TestGithubClient_MarkdownPullLink(t *testing.T) { - client, err := vcs.NewGithubClient("hostname", &vcs.GithubUserCredentials{"user", "pass"}, nil) + client, err := vcs.NewGithubClient("hostname", &vcs.GithubUserCredentials{"user", "pass"}, logging.NewNoopLogger(t)) Ok(t, err) pull := models.PullRequest{Num: 1} s, _ := client.MarkdownPullLink(pull) @@ -821,7 +823,7 @@ func TestGithubClient_SplitComments(t *testing.T) { testServerURL, err := url.Parse(testServer.URL) Ok(t, err) - client, err := vcs.NewGithubClient(testServerURL.Host, &vcs.GithubUserCredentials{"user", "pass"}, nil) + client, err := vcs.NewGithubClient(testServerURL.Host, &vcs.GithubUserCredentials{"user", "pass"}, logging.NewNoopLogger(t)) Ok(t, err) defer disableSSLVerification()() pull := models.PullRequest{Num: 1} @@ -879,7 +881,7 @@ func TestGithubClient_Retry404(t *testing.T) { testServerURL, err := url.Parse(testServer.URL) Ok(t, err) - client, err := vcs.NewGithubClient(testServerURL.Host, &vcs.GithubUserCredentials{"user", "pass"}, nil) + client, err := vcs.NewGithubClient(testServerURL.Host, &vcs.GithubUserCredentials{"user", "pass"}, logging.NewNoopLogger(t)) Ok(t, err) defer disableSSLVerification()() repo := models.Repo{ diff --git a/server/events/vcs/github_credentials_test.go b/server/events/vcs/github_credentials_test.go index c643c9706e..7de0c98f4f 100644 --- a/server/events/vcs/github_credentials_test.go +++ b/server/events/vcs/github_credentials_test.go @@ -6,6 +6,7 @@ import ( "github.com/runatlantis/atlantis/server/events/vcs" "github.com/runatlantis/atlantis/server/events/vcs/fixtures" + "github.com/runatlantis/atlantis/server/logging" . "github.com/runatlantis/atlantis/testing" ) @@ -15,7 +16,7 @@ func TestGithubClient_GetUser_AppSlug(t *testing.T) { Ok(t, err) anonCreds := &vcs.GithubAnonymousCredentials{} - anonClient, err := vcs.NewGithubClient(testServer, anonCreds, nil) + anonClient, err := vcs.NewGithubClient(testServer, anonCreds, logging.NewNoopLogger(t)) Ok(t, err) tempSecrets, err := anonClient.ExchangeCode("good-code") Ok(t, err) @@ -45,7 +46,7 @@ func TestGithubClient_AppAuthentication(t *testing.T) { Ok(t, err) anonCreds := &vcs.GithubAnonymousCredentials{} - anonClient, err := vcs.NewGithubClient(testServer, anonCreds, nil) + anonClient, err := vcs.NewGithubClient(testServer, anonCreds, logging.NewNoopLogger(t)) Ok(t, err) tempSecrets, err := anonClient.ExchangeCode("good-code") Ok(t, err) @@ -61,7 +62,7 @@ func TestGithubClient_AppAuthentication(t *testing.T) { KeyPath: keyPath, Hostname: testServer, } - _, err = vcs.NewGithubClient(testServer, appCreds, nil) + _, err = vcs.NewGithubClient(testServer, appCreds, logging.NewNoopLogger(t)) Ok(t, err) token, err := appCreds.GetToken() diff --git a/server/events/vcs/gitlab_client.go b/server/events/vcs/gitlab_client.go index b991eaba30..9cb320f4b7 100644 --- a/server/events/vcs/gitlab_client.go +++ b/server/events/vcs/gitlab_client.go @@ -47,7 +47,7 @@ var commonMarkSupported = MustConstraint(">=11.1") var gitlabClientUnderTest = false // NewGitlabClient returns a valid GitLab client. -func NewGitlabClient(hostname string, token string, logger *logging.SimpleLogger) (*GitlabClient, error) { +func NewGitlabClient(hostname string, token string, logger logging.SimpleLogging) (*GitlabClient, error) { client := &GitlabClient{} // Create the client differently depending on the base URL. diff --git a/server/events/vcs/gitlab_client_test.go b/server/events/vcs/gitlab_client_test.go index 7e9b10abe7..bb0002381c 100644 --- a/server/events/vcs/gitlab_client_test.go +++ b/server/events/vcs/gitlab_client_test.go @@ -9,6 +9,7 @@ import ( version "github.com/hashicorp/go-version" "github.com/runatlantis/atlantis/server/events/models" + "github.com/runatlantis/atlantis/server/logging" gitlab "github.com/xanzy/go-gitlab" . "github.com/runatlantis/atlantis/testing" @@ -54,7 +55,8 @@ func TestNewGitlabClient_BaseURL(t *testing.T) { for _, c := range cases { t.Run(c.Hostname, func(t *testing.T) { - client, err := NewGitlabClient(c.Hostname, "token", nil) + log := logging.NewNoopLogger(t) + client, err := NewGitlabClient(c.Hostname, "token", log) Ok(t, err) Equals(t, c.ExpBaseURL, client.Client.BaseURL().String()) }) diff --git a/server/events/webhooks/mocks/matchers/ptr_to_logging_simplelogger.go b/server/events/webhooks/mocks/matchers/ptr_to_logging_simplelogger.go index 0ce4a1c745..ddb778473e 100644 --- a/server/events/webhooks/mocks/matchers/ptr_to_logging_simplelogger.go +++ b/server/events/webhooks/mocks/matchers/ptr_to_logging_simplelogger.go @@ -8,26 +8,26 @@ import ( logging "github.com/runatlantis/atlantis/server/logging" ) -func AnyPtrToLoggingSimpleLogger() *logging.SimpleLogger { - pegomock.RegisterMatcher(pegomock.NewAnyMatcher(reflect.TypeOf((*(*logging.SimpleLogger))(nil)).Elem())) - var nullValue *logging.SimpleLogger +func AnyPtrToLoggingSimpleLogger() logging.SimpleLogging { + pegomock.RegisterMatcher(pegomock.NewAnyMatcher(reflect.TypeOf((*(logging.SimpleLogging))(nil)).Elem())) + var nullValue logging.SimpleLogging return nullValue } -func EqPtrToLoggingSimpleLogger(value *logging.SimpleLogger) *logging.SimpleLogger { +func EqPtrToLoggingSimpleLogger(value logging.SimpleLogging) logging.SimpleLogging { pegomock.RegisterMatcher(&pegomock.EqMatcher{Value: value}) - var nullValue *logging.SimpleLogger + var nullValue logging.SimpleLogging return nullValue } -func NotEqPtrToLoggingSimpleLogger(value *logging.SimpleLogger) *logging.SimpleLogger { +func NotEqPtrToLoggingSimpleLogger(value logging.SimpleLogging) logging.SimpleLogging { pegomock.RegisterMatcher(&pegomock.NotEqMatcher{Value: value}) - var nullValue *logging.SimpleLogger + var nullValue logging.SimpleLogging return nullValue } -func PtrToLoggingSimpleLoggerThat(matcher pegomock.ArgumentMatcher) *logging.SimpleLogger { +func PtrToLoggingSimpleLoggerThat(matcher pegomock.ArgumentMatcher) logging.SimpleLogging { pegomock.RegisterMatcher(matcher) - var nullValue *logging.SimpleLogger + var nullValue logging.SimpleLogging return nullValue } diff --git a/server/events/webhooks/mocks/mock_sender.go b/server/events/webhooks/mocks/mock_sender.go index 90f8495340..680ab6dce8 100644 --- a/server/events/webhooks/mocks/mock_sender.go +++ b/server/events/webhooks/mocks/mock_sender.go @@ -26,7 +26,7 @@ func NewMockSender(options ...pegomock.Option) *MockSender { func (mock *MockSender) SetFailHandler(fh pegomock.FailHandler) { mock.fail = fh } func (mock *MockSender) FailHandler() pegomock.FailHandler { return mock.fail } -func (mock *MockSender) Send(log *logging.SimpleLogger, applyResult webhooks.ApplyResult) error { +func (mock *MockSender) Send(log logging.SimpleLogging, applyResult webhooks.ApplyResult) error { if mock == nil { panic("mock must not be nil. Use myMock := NewMockSender().") } @@ -78,7 +78,7 @@ type VerifierMockSender struct { timeout time.Duration } -func (verifier *VerifierMockSender) Send(log *logging.SimpleLogger, applyResult webhooks.ApplyResult) *MockSender_Send_OngoingVerification { +func (verifier *VerifierMockSender) Send(log logging.SimpleLogging, applyResult webhooks.ApplyResult) *MockSender_Send_OngoingVerification { params := []pegomock.Param{log, applyResult} methodInvocations := pegomock.GetGenericMockFrom(verifier.mock).Verify(verifier.inOrderContext, verifier.invocationCountMatcher, "Send", params, verifier.timeout) return &MockSender_Send_OngoingVerification{mock: verifier.mock, methodInvocations: methodInvocations} @@ -89,17 +89,17 @@ type MockSender_Send_OngoingVerification struct { methodInvocations []pegomock.MethodInvocation } -func (c *MockSender_Send_OngoingVerification) GetCapturedArguments() (*logging.SimpleLogger, webhooks.ApplyResult) { +func (c *MockSender_Send_OngoingVerification) GetCapturedArguments() (logging.SimpleLogging, webhooks.ApplyResult) { log, applyResult := c.GetAllCapturedArguments() return log[len(log)-1], applyResult[len(applyResult)-1] } -func (c *MockSender_Send_OngoingVerification) GetAllCapturedArguments() (_param0 []*logging.SimpleLogger, _param1 []webhooks.ApplyResult) { +func (c *MockSender_Send_OngoingVerification) GetAllCapturedArguments() (_param0 []logging.SimpleLogging, _param1 []webhooks.ApplyResult) { params := pegomock.GetGenericMockFrom(c.mock).GetInvocationParams(c.methodInvocations) if len(params) > 0 { - _param0 = make([]*logging.SimpleLogger, len(c.methodInvocations)) + _param0 = make([]logging.SimpleLogging, len(c.methodInvocations)) for u, param := range params[0] { - _param0[u] = param.(*logging.SimpleLogger) + _param0[u] = param.(logging.SimpleLogging) } _param1 = make([]webhooks.ApplyResult, len(c.methodInvocations)) for u, param := range params[1] { diff --git a/server/events/webhooks/slack.go b/server/events/webhooks/slack.go index 7e943c1ef0..23ac3a0db6 100644 --- a/server/events/webhooks/slack.go +++ b/server/events/webhooks/slack.go @@ -50,7 +50,7 @@ func NewSlack(r *regexp.Regexp, channel string, client SlackClient) (*SlackWebho } // Send sends the webhook to Slack if the workspace matches the regex. -func (s *SlackWebhook) Send(log *logging.SimpleLogger, applyResult ApplyResult) error { +func (s *SlackWebhook) Send(log logging.SimpleLogging, applyResult ApplyResult) error { if !s.WorkspaceRegex.MatchString(applyResult.Workspace) { return nil } diff --git a/server/events/webhooks/slack_test.go b/server/events/webhooks/slack_test.go index fbb89f9317..096aabbf8e 100644 --- a/server/events/webhooks/slack_test.go +++ b/server/events/webhooks/slack_test.go @@ -42,7 +42,7 @@ func TestSend_PostMessage(t *testing.T) { } t.Log("PostMessage should be called, doesn't matter if it errors or not") - _ = hook.Send(logging.NewNoopLogger(), result) + _ = hook.Send(logging.NewNoopLogger(t), result) client.VerifyWasCalledOnce().PostMessage(channel, result) } @@ -62,7 +62,7 @@ func TestSend_NoopSuccess(t *testing.T) { result := webhooks.ApplyResult{ Workspace: "production", } - err = hook.Send(logging.NewNoopLogger(), result) + err = hook.Send(logging.NewNoopLogger(t), result) Ok(t, err) client.VerifyWasCalled(Never()).PostMessage(channel, result) } diff --git a/server/events/webhooks/webhooks.go b/server/events/webhooks/webhooks.go index dacc267e37..b64001f461 100644 --- a/server/events/webhooks/webhooks.go +++ b/server/events/webhooks/webhooks.go @@ -31,7 +31,7 @@ const ApplyEvent = "apply" // Sender sends webhooks. type Sender interface { // Send sends the webhook (if the implementation thinks it should). - Send(log *logging.SimpleLogger, applyResult ApplyResult) error + Send(log logging.SimpleLogging, applyResult ApplyResult) error } // ApplyResult is the result of a terraform apply. @@ -93,7 +93,7 @@ func NewMultiWebhookSender(configs []Config, client SlackClient) (*MultiWebhookS } // Send sends the webhook using its Webhooks. -func (w *MultiWebhookSender) Send(log *logging.SimpleLogger, result ApplyResult) error { +func (w *MultiWebhookSender) Send(log logging.SimpleLogging, result ApplyResult) error { for _, w := range w.Webhooks { if err := w.Send(log, result); err != nil { log.Warn("error sending slack webhook: %s", err) diff --git a/server/events/webhooks/webhooks_test.go b/server/events/webhooks/webhooks_test.go index 4cd263cd32..0be80faaac 100644 --- a/server/events/webhooks/webhooks_test.go +++ b/server/events/webhooks/webhooks_test.go @@ -161,7 +161,7 @@ func TestSend_SingleSuccess(t *testing.T) { manager := webhooks.MultiWebhookSender{ Webhooks: []webhooks.Sender{sender}, } - logger := logging.NewNoopLogger() + logger := logging.NewNoopLogger(t) result := webhooks.ApplyResult{} manager.Send(logger, result) // nolint: errcheck sender.VerifyWasCalledOnce().Send(logger, result) @@ -178,7 +178,7 @@ func TestSend_MultipleSuccess(t *testing.T) { manager := webhooks.MultiWebhookSender{ Webhooks: []webhooks.Sender{senders[0], senders[1], senders[2]}, } - logger := logging.NewNoopLogger() + logger := logging.NewNoopLogger(t) result := webhooks.ApplyResult{} err := manager.Send(logger, result) Ok(t, err) diff --git a/server/events/working_dir.go b/server/events/working_dir.go index 77125b1779..9670423911 100644 --- a/server/events/working_dir.go +++ b/server/events/working_dir.go @@ -37,7 +37,7 @@ type WorkingDir interface { // absolute path to the root of the cloned repo. It also returns // a boolean indicating if we should warn users that the branch we're // merging into has been updated since we cloned it. - Clone(log *logging.SimpleLogger, headRepo models.Repo, p models.PullRequest, workspace string) (string, bool, error) + Clone(log logging.SimpleLogging, headRepo models.Repo, p models.PullRequest, workspace string) (string, bool, error) // GetWorkingDir returns the path to the workspace for this repo and pull. // If workspace does not exist on disk, error will be of type os.IsNotExist. GetWorkingDir(r models.Repo, p models.PullRequest, workspace string) (string, error) @@ -71,7 +71,7 @@ type FileWorkspace struct { // the right commit it does nothing. This is to support running commands in // multiple dirs of the same repo without deleting existing plans. func (w *FileWorkspace) Clone( - log *logging.SimpleLogger, + log logging.SimpleLogging, headRepo models.Repo, p models.PullRequest, workspace string) (string, bool, error) { @@ -122,7 +122,7 @@ func (w *FileWorkspace) Clone( // Then users won't be getting the merge functionality they expected. // If there are any errors we return false since we prefer things to succeed // vs. stopping the plan/apply. -func (w *FileWorkspace) warnDiverged(log *logging.SimpleLogger, p models.PullRequest, headRepo models.Repo, cloneDir string) bool { +func (w *FileWorkspace) warnDiverged(log logging.SimpleLogging, p models.PullRequest, headRepo models.Repo, cloneDir string) bool { if !w.CheckoutMerge { // It only makes sense to warn that master has diverged if we're using // the checkout merge strategy. If we're just checking out the branch, @@ -177,7 +177,7 @@ func (w *FileWorkspace) warnDiverged(log *logging.SimpleLogger, p models.PullReq return hasDiverged } -func (w *FileWorkspace) forceClone(log *logging.SimpleLogger, +func (w *FileWorkspace) forceClone(log logging.SimpleLogging, cloneDir string, headRepo models.Repo, p models.PullRequest) error { diff --git a/server/events/working_dir_test.go b/server/events/working_dir_test.go index be003ae925..1185e4c9ff 100644 --- a/server/events/working_dir_test.go +++ b/server/events/working_dir_test.go @@ -10,6 +10,7 @@ import ( "github.com/runatlantis/atlantis/server/events" "github.com/runatlantis/atlantis/server/events/models" + "github.com/runatlantis/atlantis/server/logging" . "github.com/runatlantis/atlantis/testing" ) @@ -40,7 +41,7 @@ func TestClone_NoneExisting(t *testing.T) { TestingOverrideHeadCloneURL: fmt.Sprintf("file://%s", repoDir), } - cloneDir, _, err := wd.Clone(nil, models.Repo{}, models.PullRequest{ + cloneDir, _, err := wd.Clone(logging.NewNoopLogger(t), models.Repo{}, models.PullRequest{ BaseRepo: models.Repo{}, HeadBranch: "branch", }, "default") @@ -90,7 +91,7 @@ func TestClone_CheckoutMergeNoneExisting(t *testing.T) { TestingOverrideBaseCloneURL: overrideURL, } - cloneDir, hasDiverged, err := wd.Clone(nil, models.Repo{}, models.PullRequest{ + cloneDir, hasDiverged, err := wd.Clone(logging.NewNoopLogger(t), models.Repo{}, models.PullRequest{ BaseRepo: models.Repo{}, HeadBranch: "branch", BaseBranch: "master", @@ -139,7 +140,7 @@ func TestClone_CheckoutMergeNoReclone(t *testing.T) { TestingOverrideBaseCloneURL: overrideURL, } - _, hasDiverged, err := wd.Clone(nil, models.Repo{}, models.PullRequest{ + _, hasDiverged, err := wd.Clone(logging.NewNoopLogger(t), models.Repo{}, models.PullRequest{ BaseRepo: models.Repo{}, HeadBranch: "branch", BaseBranch: "master", @@ -151,7 +152,7 @@ func TestClone_CheckoutMergeNoReclone(t *testing.T) { runCmd(t, dataDir, "touch", "repos/0/default/proof") // Now run the clone again. - cloneDir, hasDiverged, err := wd.Clone(nil, models.Repo{}, models.PullRequest{ + cloneDir, hasDiverged, err := wd.Clone(logging.NewNoopLogger(t), models.Repo{}, models.PullRequest{ BaseRepo: models.Repo{}, HeadBranch: "branch", BaseBranch: "master", @@ -189,7 +190,7 @@ func TestClone_CheckoutMergeNoRecloneFastForward(t *testing.T) { TestingOverrideBaseCloneURL: overrideURL, } - _, hasDiverged, err := wd.Clone(nil, models.Repo{}, models.PullRequest{ + _, hasDiverged, err := wd.Clone(logging.NewNoopLogger(t), models.Repo{}, models.PullRequest{ BaseRepo: models.Repo{}, HeadBranch: "branch", BaseBranch: "master", @@ -201,7 +202,7 @@ func TestClone_CheckoutMergeNoRecloneFastForward(t *testing.T) { runCmd(t, dataDir, "touch", "repos/0/default/proof") // Now run the clone again. - cloneDir, hasDiverged, err := wd.Clone(nil, models.Repo{}, models.PullRequest{ + cloneDir, hasDiverged, err := wd.Clone(logging.NewNoopLogger(t), models.Repo{}, models.PullRequest{ BaseRepo: models.Repo{}, HeadBranch: "branch", BaseBranch: "master", @@ -244,7 +245,7 @@ func TestClone_CheckoutMergeConflict(t *testing.T) { TestingOverrideBaseCloneURL: overrideURL, } - _, _, err := wd.Clone(nil, models.Repo{}, models.PullRequest{ + _, _, err := wd.Clone(logging.NewNoopLogger(t), models.Repo{}, models.PullRequest{ BaseRepo: models.Repo{}, HeadBranch: "branch", BaseBranch: "master", @@ -275,7 +276,7 @@ func TestClone_NoReclone(t *testing.T) { CheckoutMerge: false, TestingOverrideHeadCloneURL: fmt.Sprintf("file://%s", repoDir), } - cloneDir, hasDiverged, err := wd.Clone(nil, models.Repo{}, models.PullRequest{ + cloneDir, hasDiverged, err := wd.Clone(logging.NewNoopLogger(t), models.Repo{}, models.PullRequest{ BaseRepo: models.Repo{}, HeadBranch: "branch", }, "default") @@ -311,7 +312,7 @@ func TestClone_RecloneWrongCommit(t *testing.T) { CheckoutMerge: false, TestingOverrideHeadCloneURL: fmt.Sprintf("file://%s", repoDir), } - cloneDir, hasDiverged, err := wd.Clone(nil, models.Repo{}, models.PullRequest{ + cloneDir, hasDiverged, err := wd.Clone(logging.NewNoopLogger(t), models.Repo{}, models.PullRequest{ BaseRepo: models.Repo{}, HeadBranch: "branch", HeadCommit: expCommit, @@ -377,7 +378,7 @@ func TestClone_MasterHasDiverged(t *testing.T) { DataDir: repoDir, CheckoutMerge: true, } - _, hasDiverged, err := wd.Clone(nil, models.Repo{CloneURL: repoDir}, models.PullRequest{ + _, hasDiverged, err := wd.Clone(logging.NewNoopLogger(t), models.Repo{CloneURL: repoDir}, models.PullRequest{ BaseRepo: models.Repo{CloneURL: repoDir}, HeadBranch: "second-pr", BaseBranch: "master", @@ -388,7 +389,7 @@ func TestClone_MasterHasDiverged(t *testing.T) { // Run it again but without the checkout merge strategy. It should return // false. wd.CheckoutMerge = false - _, hasDiverged, err = wd.Clone(nil, models.Repo{}, models.PullRequest{ + _, hasDiverged, err = wd.Clone(logging.NewNoopLogger(t), models.Repo{}, models.PullRequest{ BaseRepo: models.Repo{}, HeadBranch: "second-pr", BaseBranch: "master", diff --git a/server/events/yaml/valid/global_cfg_test.go b/server/events/yaml/valid/global_cfg_test.go index 5fbf759ce0..95d04358d1 100644 --- a/server/events/yaml/valid/global_cfg_test.go +++ b/server/events/yaml/valid/global_cfg_test.go @@ -551,7 +551,7 @@ policies: Equals(t, c.exp, - global.MergeProjectCfg(logging.NewNoopLogger(), c.repoID, c.proj, valid.RepoCfg{})) + global.MergeProjectCfg(logging.NewNoopLogger(t), c.repoID, c.proj, valid.RepoCfg{})) }) } } @@ -709,7 +709,7 @@ repos: } global.PolicySets = emptyPolicySets - Equals(t, c.exp, global.MergeProjectCfg(logging.NewNoopLogger(), c.repoID, c.proj, valid.RepoCfg{Workflows: c.repoWorkflows})) + Equals(t, c.exp, global.MergeProjectCfg(logging.NewNoopLogger(t), c.repoID, c.proj, valid.RepoCfg{Workflows: c.repoWorkflows})) }) } } diff --git a/server/events_controller.go b/server/events_controller.go index de08599083..dc7f5c18a9 100644 --- a/server/events_controller.go +++ b/server/events_controller.go @@ -47,7 +47,7 @@ const bitbucketServerSignatureHeader = "X-Hub-Signature" type EventsController struct { CommandRunner events.CommandRunner PullCleaner events.PullCleaner - Logger *logging.SimpleLogger + Logger logging.SimpleLogging Parser events.EventParsing CommentParser events.CommentParsing ApplyDisabled bool diff --git a/server/events_controller_e2e_test.go b/server/events_controller_e2e_test.go index 181ec7ca70..7ee8fd649b 100644 --- a/server/events_controller_e2e_test.go +++ b/server/events_controller_e2e_test.go @@ -630,7 +630,14 @@ func setupE2E(t *testing.T, repoDir string) (server.EventsController, *vcsmocks. e2eGitlabGetter := mocks.NewMockGitlabMergeRequestGetter() // Real dependencies. - logger := logging.NewSimpleLogger("server", true, logging.Error) + logger, err := logging.NewStructuredLogger() + + if err != nil { + panic("Could not setup logger for e2e") + } + + logger.SetLevel(logging.Error) + eventParser := &events.EventParser{ GithubUser: "github-user", GithubToken: "github-token", @@ -860,7 +867,7 @@ func (m *mockLockURLGenerator) GenerateLockURL(lockID string) string { type mockWebhookSender struct{} -func (w *mockWebhookSender) Send(log *logging.SimpleLogger, result webhooks.ApplyResult) error { +func (w *mockWebhookSender) Send(log logging.SimpleLogging, result webhooks.ApplyResult) error { return nil } diff --git a/server/events_controller_test.go b/server/events_controller_test.go index af24490eb8..0b8ab903e5 100644 --- a/server/events_controller_test.go +++ b/server/events_controller_test.go @@ -187,7 +187,7 @@ func TestPost_GitlabCommentNotAllowlisted(t *testing.T) { RegisterMockTestingT(t) vcsClient := vcsmocks.NewMockClient() e := server.EventsController{ - Logger: logging.NewNoopLogger(), + Logger: logging.NewNoopLogger(t), CommentParser: &events.CommentParser{}, GitlabRequestParserValidator: &server.DefaultGitlabRequestParserValidator{}, Parser: &events.EventParser{}, @@ -215,7 +215,7 @@ func TestPost_GitlabCommentNotAllowlistedWithSilenceErrors(t *testing.T) { RegisterMockTestingT(t) vcsClient := vcsmocks.NewMockClient() e := server.EventsController{ - Logger: logging.NewNoopLogger(), + Logger: logging.NewNoopLogger(t), CommentParser: &events.CommentParser{}, GitlabRequestParserValidator: &server.DefaultGitlabRequestParserValidator{}, Parser: &events.EventParser{}, @@ -244,7 +244,7 @@ func TestPost_GithubCommentNotAllowlisted(t *testing.T) { RegisterMockTestingT(t) vcsClient := vcsmocks.NewMockClient() e := server.EventsController{ - Logger: logging.NewNoopLogger(), + Logger: logging.NewNoopLogger(t), GithubRequestValidator: &server.DefaultGithubRequestValidator{}, CommentParser: &events.CommentParser{}, Parser: &events.EventParser{}, @@ -273,7 +273,7 @@ func TestPost_GithubCommentNotAllowlistedWithSilenceErrors(t *testing.T) { RegisterMockTestingT(t) vcsClient := vcsmocks.NewMockClient() e := server.EventsController{ - Logger: logging.NewNoopLogger(), + Logger: logging.NewNoopLogger(t), GithubRequestValidator: &server.DefaultGithubRequestValidator{}, CommentParser: &events.CommentParser{}, Parser: &events.EventParser{}, @@ -471,7 +471,7 @@ func TestPost_AzureDevopsPullRequestIgnoreEvent(t *testing.T) { Ok(t, err) e := server.EventsController{ TestingMode: true, - Logger: logging.NewNoopLogger(), + Logger: logging.NewNoopLogger(t), ApplyDisabled: false, AzureDevopsWebhookBasicUser: user, AzureDevopsWebhookBasicPassword: secret, @@ -635,6 +635,7 @@ func TestPost_BBServerPullClosed(t *testing.T) { RepoAllowlistChecker: allowlist, SupportedVCSHosts: []models.VCSHostType{models.BitbucketServer}, VCSClient: nil, + Logger: logging.NewNoopLogger(t), } // Build HTTP request. @@ -754,7 +755,7 @@ func setup(t *testing.T) (server.EventsController, *mocks.MockGithubRequestValid Ok(t, err) e := server.EventsController{ TestingMode: true, - Logger: logging.NewNoopLogger(), + Logger: logging.NewNoopLogger(t), GithubRequestValidator: v, Parser: p, CommentParser: cp, diff --git a/server/github_app_controller.go b/server/github_app_controller.go index cd8b64e661..4fed5968d0 100644 --- a/server/github_app_controller.go +++ b/server/github_app_controller.go @@ -13,7 +13,7 @@ import ( // GithubAppController handles the creation and setup of a new GitHub app type GithubAppController struct { AtlantisURL *url.URL - Logger *logging.SimpleLogger + Logger logging.SimpleLogging GithubSetupComplete bool GithubHostname string GithubOrg string diff --git a/server/locks_controller.go b/server/locks_controller.go index 66313dce04..8d7eebcfbb 100644 --- a/server/locks_controller.go +++ b/server/locks_controller.go @@ -20,8 +20,8 @@ type LocksController struct { AtlantisVersion string AtlantisURL *url.URL Locker locking.Locker + Logger logging.SimpleLogging ApplyLocker locking.ApplyLocker - Logger *logging.SimpleLogger VCSClient vcs.Client LockDetailTemplate TemplateWriter WorkingDir events.WorkingDir diff --git a/server/locks_controller_test.go b/server/locks_controller_test.go index bdd0d5ae6b..9ec5fb1f93 100644 --- a/server/locks_controller_test.go +++ b/server/locks_controller_test.go @@ -50,7 +50,7 @@ func TestCreateApplyLock(t *testing.T) { }, nil) lc := server.LocksController{ - Logger: logging.NewNoopLogger(), + Logger: logging.NewNoopLogger(t), ApplyLocker: l, } lc.LockApply(w, req) @@ -68,7 +68,7 @@ func TestCreateApplyLock(t *testing.T) { }, errors.New("failed to acquire lock")) lc := server.LocksController{ - Logger: logging.NewNoopLogger(), + Logger: logging.NewNoopLogger(t), ApplyLocker: l, } lc.LockApply(w, req) @@ -86,7 +86,7 @@ func TestUnlockApply(t *testing.T) { When(l.UnlockApply()).ThenReturn(nil) lc := server.LocksController{ - Logger: logging.NewNoopLogger(), + Logger: logging.NewNoopLogger(t), ApplyLocker: l, } lc.UnlockApply(w, req) @@ -102,7 +102,7 @@ func TestUnlockApply(t *testing.T) { When(l.UnlockApply()).ThenReturn(errors.New("failed to delete lock")) lc := server.LocksController{ - Logger: logging.NewNoopLogger(), + Logger: logging.NewNoopLogger(t), ApplyLocker: l, } lc.UnlockApply(w, req) @@ -116,7 +116,7 @@ func TestGetLockRoute_NoLockID(t *testing.T) { req, _ := http.NewRequest("GET", "", bytes.NewBuffer(nil)) w := httptest.NewRecorder() lc := server.LocksController{ - Logger: logging.NewNoopLogger(), + Logger: logging.NewNoopLogger(t), } lc.GetLock(w, req) responseContains(t, w, http.StatusBadRequest, "No lock id in request") @@ -125,7 +125,7 @@ func TestGetLockRoute_NoLockID(t *testing.T) { func TestGetLock_InvalidLockID(t *testing.T) { t.Log("If the lock ID is invalid then we should get a 400") lc := server.LocksController{ - Logger: logging.NewNoopLogger(), + Logger: logging.NewNoopLogger(t), } req, _ := http.NewRequest("GET", "", bytes.NewBuffer(nil)) req = mux.SetURLVars(req, map[string]string{"id": "%A@"}) @@ -140,7 +140,7 @@ func TestGetLock_LockerErr(t *testing.T) { l := mocks.NewMockLocker() When(l.GetLock("id")).ThenReturn(nil, errors.New("err")) lc := server.LocksController{ - Logger: logging.NewNoopLogger(), + Logger: logging.NewNoopLogger(t), Locker: l, } req, _ := http.NewRequest("GET", "", bytes.NewBuffer(nil)) @@ -156,7 +156,7 @@ func TestGetLock_None(t *testing.T) { l := mocks.NewMockLocker() When(l.GetLock("id")).ThenReturn(nil, nil) lc := server.LocksController{ - Logger: logging.NewNoopLogger(), + Logger: logging.NewNoopLogger(t), Locker: l, } req, _ := http.NewRequest("GET", "", bytes.NewBuffer(nil)) @@ -179,7 +179,7 @@ func TestGetLock_Success(t *testing.T) { atlantisURL, err := url.Parse("https://example.com/basepath") Ok(t, err) lc := server.LocksController{ - Logger: logging.NewNoopLogger(), + Logger: logging.NewNoopLogger(t), Locker: l, LockDetailTemplate: tmpl, AtlantisVersion: "1300135", @@ -207,14 +207,14 @@ func TestDeleteLock_NoLockID(t *testing.T) { t.Log("If there is no lock ID in the request then we should get a 400") req, _ := http.NewRequest("GET", "", bytes.NewBuffer(nil)) w := httptest.NewRecorder() - lc := server.LocksController{Logger: logging.NewNoopLogger()} + lc := server.LocksController{Logger: logging.NewNoopLogger(t)} lc.DeleteLock(w, req) responseContains(t, w, http.StatusBadRequest, "No lock id in request") } func TestDeleteLock_InvalidLockID(t *testing.T) { t.Log("If the lock ID is invalid then we should get a 400") - lc := server.LocksController{Logger: logging.NewNoopLogger()} + lc := server.LocksController{Logger: logging.NewNoopLogger(t)} req, _ := http.NewRequest("GET", "", bytes.NewBuffer(nil)) req = mux.SetURLVars(req, map[string]string{"id": "%A@"}) w := httptest.NewRecorder() @@ -229,7 +229,7 @@ func TestDeleteLock_LockerErr(t *testing.T) { When(dlc.DeleteLock("id")).ThenReturn(nil, errors.New("err")) lc := server.LocksController{ DeleteLockCommand: dlc, - Logger: logging.NewNoopLogger(), + Logger: logging.NewNoopLogger(t), } req, _ := http.NewRequest("GET", "", bytes.NewBuffer(nil)) req = mux.SetURLVars(req, map[string]string{"id": "id"}) @@ -245,7 +245,7 @@ func TestDeleteLock_None(t *testing.T) { When(dlc.DeleteLock("id")).ThenReturn(nil, nil) lc := server.LocksController{ DeleteLockCommand: dlc, - Logger: logging.NewNoopLogger(), + Logger: logging.NewNoopLogger(t), } req, _ := http.NewRequest("GET", "", bytes.NewBuffer(nil)) req = mux.SetURLVars(req, map[string]string{"id": "id"}) @@ -262,7 +262,7 @@ func TestDeleteLock_OldFormat(t *testing.T) { When(dlc.DeleteLock("id")).ThenReturn(&models.ProjectLock{}, nil) lc := server.LocksController{ DeleteLockCommand: dlc, - Logger: logging.NewNoopLogger(), + Logger: logging.NewNoopLogger(t), VCSClient: cp, } req, _ := http.NewRequest("GET", "", bytes.NewBuffer(nil)) @@ -315,7 +315,7 @@ func TestDeleteLock_UpdateProjectStatus(t *testing.T) { Ok(t, err) lc := server.LocksController{ DeleteLockCommand: l, - Logger: logging.NewNoopLogger(), + Logger: logging.NewNoopLogger(t), VCSClient: cp, WorkingDirLocker: workingDirLocker, WorkingDir: workingDir, @@ -357,7 +357,7 @@ func TestDeleteLock_CommentFailed(t *testing.T) { Ok(t, err) lc := server.LocksController{ DeleteLockCommand: dlc, - Logger: logging.NewNoopLogger(), + Logger: logging.NewNoopLogger(t), VCSClient: cp, WorkingDir: workingDir, WorkingDirLocker: workingDirLocker, @@ -394,7 +394,7 @@ func TestDeleteLock_CommentSuccess(t *testing.T) { Ok(t, err) lc := server.LocksController{ DeleteLockCommand: dlc, - Logger: logging.NewNoopLogger(), + Logger: logging.NewNoopLogger(t), VCSClient: cp, DB: db, WorkingDir: workingDir, diff --git a/server/logging/logging_test.go b/server/logging/logging_test.go index 8f7b67e2d4..237d1d8b65 100644 --- a/server/logging/logging_test.go +++ b/server/logging/logging_test.go @@ -13,4 +13,22 @@ package logging_test -// purposefully empty to trigger coverage report +import ( + "testing" + + "github.com/runatlantis/atlantis/server/logging" + "github.com/stretchr/testify/assert" +) + +func TestStructuredLoggerSavesHistory(t *testing.T) { + logger := logging.NewNoopLogger(t) + + historyLogger := logger.WithHistory() + + expectedStr := "[DBUG] Hello World\n[INFO] foo bar\n" + + historyLogger.Debug("Hello World") + historyLogger.Info("foo bar") + + assert.Equal(t, expectedStr, historyLogger.GetHistory()) +} diff --git a/server/logging/mocks/matchers/logging_loglevel.go b/server/logging/mocks/matchers/logging_loglevel.go index 660a3cc434..bba8254e73 100644 --- a/server/logging/mocks/matchers/logging_loglevel.go +++ b/server/logging/mocks/matchers/logging_loglevel.go @@ -2,8 +2,9 @@ package matchers import ( - "reflect" "github.com/petergtz/pegomock" + "reflect" + logging "github.com/runatlantis/atlantis/server/logging" ) @@ -18,3 +19,15 @@ func EqLoggingLogLevel(value logging.LogLevel) logging.LogLevel { var nullValue logging.LogLevel return nullValue } + +func NotEqLoggingLogLevel(value logging.LogLevel) logging.LogLevel { + pegomock.RegisterMatcher(&pegomock.NotEqMatcher{Value: value}) + var nullValue logging.LogLevel + return nullValue +} + +func LoggingLogLevelThat(matcher pegomock.ArgumentMatcher) logging.LogLevel { + pegomock.RegisterMatcher(matcher) + var nullValue logging.LogLevel + return nullValue +} diff --git a/server/logging/mocks/matchers/logging_simplelogging.go b/server/logging/mocks/matchers/logging_simplelogging.go new file mode 100644 index 0000000000..502456e7c8 --- /dev/null +++ b/server/logging/mocks/matchers/logging_simplelogging.go @@ -0,0 +1,33 @@ +// Code generated by pegomock. DO NOT EDIT. +package matchers + +import ( + "github.com/petergtz/pegomock" + "reflect" + + logging "github.com/runatlantis/atlantis/server/logging" +) + +func AnyLoggingSimpleLogging() logging.SimpleLogging { + pegomock.RegisterMatcher(pegomock.NewAnyMatcher(reflect.TypeOf((*(logging.SimpleLogging))(nil)).Elem())) + var nullValue logging.SimpleLogging + return nullValue +} + +func EqLoggingSimpleLogging(value logging.SimpleLogging) logging.SimpleLogging { + pegomock.RegisterMatcher(&pegomock.EqMatcher{Value: value}) + var nullValue logging.SimpleLogging + return nullValue +} + +func NotEqLoggingSimpleLogging(value logging.SimpleLogging) logging.SimpleLogging { + pegomock.RegisterMatcher(&pegomock.NotEqMatcher{Value: value}) + var nullValue logging.SimpleLogging + return nullValue +} + +func LoggingSimpleLoggingThat(matcher pegomock.ArgumentMatcher) logging.SimpleLogging { + pegomock.RegisterMatcher(matcher) + var nullValue logging.SimpleLogging + return nullValue +} diff --git a/server/logging/mocks/matchers/ptr_to_logging_simplelogger.go b/server/logging/mocks/matchers/ptr_to_logging_simplelogger.go index 04c72791bc..cf9bb5453f 100644 --- a/server/logging/mocks/matchers/ptr_to_logging_simplelogger.go +++ b/server/logging/mocks/matchers/ptr_to_logging_simplelogger.go @@ -2,19 +2,19 @@ package matchers import ( - "reflect" "github.com/petergtz/pegomock" logging "github.com/runatlantis/atlantis/server/logging" + "reflect" ) -func AnyPtrToLoggingSimpleLogger() *logging.SimpleLogger { - pegomock.RegisterMatcher(pegomock.NewAnyMatcher(reflect.TypeOf((*(*logging.SimpleLogger))(nil)).Elem())) - var nullValue *logging.SimpleLogger +func AnyPtrToLoggingSimpleLogger() logging.SimpleLogging { + pegomock.RegisterMatcher(pegomock.NewAnyMatcher(reflect.TypeOf((*(logging.SimpleLogging))(nil)).Elem())) + var nullValue logging.SimpleLogging return nullValue } -func EqPtrToLoggingSimpleLogger(value *logging.SimpleLogger) *logging.SimpleLogger { +func EqPtrToLoggingSimpleLogger(value logging.SimpleLogging) logging.SimpleLogging { pegomock.RegisterMatcher(&pegomock.EqMatcher{Value: value}) - var nullValue *logging.SimpleLogger + var nullValue logging.SimpleLogging return nullValue } diff --git a/server/logging/mocks/mock_simple_logging.go b/server/logging/mocks/mock_simple_logging.go index 7d2eef71a0..ed2eb414b2 100644 --- a/server/logging/mocks/mock_simple_logging.go +++ b/server/logging/mocks/mock_simple_logging.go @@ -6,7 +6,6 @@ package mocks import ( pegomock "github.com/petergtz/pegomock" logging "github.com/runatlantis/atlantis/server/logging" - log "log" "reflect" "time" ) @@ -81,46 +80,60 @@ func (mock *MockSimpleLogging) Log(level logging.LogLevel, format string, a ...i pegomock.GetGenericMockFrom(mock).Invoke("Log", params, []reflect.Type{}) } -func (mock *MockSimpleLogging) Underlying() *log.Logger { +func (mock *MockSimpleLogging) SetLevel(lvl logging.LogLevel) { + if mock == nil { + panic("mock must not be nil. Use myMock := NewMockSimpleLogging().") + } + params := []pegomock.Param{lvl} + pegomock.GetGenericMockFrom(mock).Invoke("SetLevel", params, []reflect.Type{}) +} + +func (mock *MockSimpleLogging) With(a ...interface{}) logging.SimpleLogging { if mock == nil { panic("mock must not be nil. Use myMock := NewMockSimpleLogging().") } params := []pegomock.Param{} - result := pegomock.GetGenericMockFrom(mock).Invoke("Underlying", params, []reflect.Type{reflect.TypeOf((**log.Logger)(nil)).Elem()}) - var ret0 *log.Logger + for _, param := range a { + params = append(params, param) + } + result := pegomock.GetGenericMockFrom(mock).Invoke("With", params, []reflect.Type{reflect.TypeOf((*logging.SimpleLogging)(nil)).Elem()}) + var ret0 logging.SimpleLogging if len(result) != 0 { if result[0] != nil { - ret0 = result[0].(*log.Logger) + ret0 = result[0].(logging.SimpleLogging) } } return ret0 } -func (mock *MockSimpleLogging) GetLevel() logging.LogLevel { +func (mock *MockSimpleLogging) WithHistory(a ...interface{}) logging.SimpleLogging { if mock == nil { panic("mock must not be nil. Use myMock := NewMockSimpleLogging().") } params := []pegomock.Param{} - result := pegomock.GetGenericMockFrom(mock).Invoke("GetLevel", params, []reflect.Type{reflect.TypeOf((*logging.LogLevel)(nil)).Elem()}) - var ret0 logging.LogLevel + for _, param := range a { + params = append(params, param) + } + result := pegomock.GetGenericMockFrom(mock).Invoke("WithHistory", params, []reflect.Type{reflect.TypeOf((*logging.SimpleLogging)(nil)).Elem()}) + var ret0 logging.SimpleLogging if len(result) != 0 { if result[0] != nil { - ret0 = result[0].(logging.LogLevel) + ret0 = result[0].(logging.SimpleLogging) } } return ret0 } -func (mock *MockSimpleLogging) NewLogger(_param0 string, _param1 bool, _param2 logging.LogLevel) *logging.SimpleLogger { +func (mock *MockSimpleLogging) GetHistory() string { if mock == nil { panic("mock must not be nil. Use myMock := NewMockSimpleLogging().") } - params := []pegomock.Param{_param0, _param1, _param2} - result := pegomock.GetGenericMockFrom(mock).Invoke("NewLogger", params, []reflect.Type{reflect.TypeOf((**logging.SimpleLogger)(nil)).Elem()}) - var ret0 *logging.SimpleLogger + params := []pegomock.Param{} + result := pegomock.GetGenericMockFrom(mock).Invoke("GetHistory", params, []reflect.Type{reflect.TypeOf((*string)(nil)).Elem()}) + var ret0 string if len(result) != 0 { if result[0] != nil { - ret0 = result[0].(*logging.SimpleLogger) + ret0 = result[0].(string) } } return ret0 @@ -133,14 +146,14 @@ func (mock *MockSimpleLogging) VerifyWasCalledOnce() *VerifierMockSimpleLogging } } -func (mock *MockSimpleLogging) VerifyWasCalled(invocationCountMatcher pegomock.Matcher) *VerifierMockSimpleLogging { +func (mock *MockSimpleLogging) VerifyWasCalled(invocationCountMatcher pegomock.InvocationCountMatcher) *VerifierMockSimpleLogging { return &VerifierMockSimpleLogging{ mock: mock, invocationCountMatcher: invocationCountMatcher, } } -func (mock *MockSimpleLogging) VerifyWasCalledInOrder(invocationCountMatcher pegomock.Matcher, inOrderContext *pegomock.InOrderContext) *VerifierMockSimpleLogging { +func (mock *MockSimpleLogging) VerifyWasCalledInOrder(invocationCountMatcher pegomock.InvocationCountMatcher, inOrderContext *pegomock.InOrderContext) *VerifierMockSimpleLogging { return &VerifierMockSimpleLogging{ mock: mock, invocationCountMatcher: invocationCountMatcher, @@ -148,7 +161,7 @@ func (mock *MockSimpleLogging) VerifyWasCalledInOrder(invocationCountMatcher peg } } -func (mock *MockSimpleLogging) VerifyWasCalledEventually(invocationCountMatcher pegomock.Matcher, timeout time.Duration) *VerifierMockSimpleLogging { +func (mock *MockSimpleLogging) VerifyWasCalledEventually(invocationCountMatcher pegomock.InvocationCountMatcher, timeout time.Duration) *VerifierMockSimpleLogging { return &VerifierMockSimpleLogging{ mock: mock, invocationCountMatcher: invocationCountMatcher, @@ -158,7 +171,7 @@ func (mock *MockSimpleLogging) VerifyWasCalledEventually(invocationCountMatcher type VerifierMockSimpleLogging struct { mock *MockSimpleLogging - invocationCountMatcher pegomock.Matcher + invocationCountMatcher pegomock.InvocationCountMatcher inOrderContext *pegomock.InOrderContext timeout time.Duration } @@ -362,71 +375,116 @@ func (c *MockSimpleLogging_Log_OngoingVerification) GetAllCapturedArguments() (_ return } -func (verifier *VerifierMockSimpleLogging) Underlying() *MockSimpleLogging_Underlying_OngoingVerification { - params := []pegomock.Param{} - methodInvocations := pegomock.GetGenericMockFrom(verifier.mock).Verify(verifier.inOrderContext, verifier.invocationCountMatcher, "Underlying", params, verifier.timeout) - return &MockSimpleLogging_Underlying_OngoingVerification{mock: verifier.mock, methodInvocations: methodInvocations} +func (verifier *VerifierMockSimpleLogging) SetLevel(lvl logging.LogLevel) *MockSimpleLogging_SetLevel_OngoingVerification { + params := []pegomock.Param{lvl} + methodInvocations := pegomock.GetGenericMockFrom(verifier.mock).Verify(verifier.inOrderContext, verifier.invocationCountMatcher, "SetLevel", params, verifier.timeout) + return &MockSimpleLogging_SetLevel_OngoingVerification{mock: verifier.mock, methodInvocations: methodInvocations} } -type MockSimpleLogging_Underlying_OngoingVerification struct { +type MockSimpleLogging_SetLevel_OngoingVerification struct { mock *MockSimpleLogging methodInvocations []pegomock.MethodInvocation } -func (c *MockSimpleLogging_Underlying_OngoingVerification) GetCapturedArguments() { +func (c *MockSimpleLogging_SetLevel_OngoingVerification) GetCapturedArguments() logging.LogLevel { + lvl := c.GetAllCapturedArguments() + return lvl[len(lvl)-1] } -func (c *MockSimpleLogging_Underlying_OngoingVerification) GetAllCapturedArguments() { +func (c *MockSimpleLogging_SetLevel_OngoingVerification) GetAllCapturedArguments() (_param0 []logging.LogLevel) { + params := pegomock.GetGenericMockFrom(c.mock).GetInvocationParams(c.methodInvocations) + if len(params) > 0 { + _param0 = make([]logging.LogLevel, len(c.methodInvocations)) + for u, param := range params[0] { + _param0[u] = param.(logging.LogLevel) + } + } + return } -func (verifier *VerifierMockSimpleLogging) GetLevel() *MockSimpleLogging_GetLevel_OngoingVerification { +func (verifier *VerifierMockSimpleLogging) With(a ...interface{}) *MockSimpleLogging_With_OngoingVerification { params := []pegomock.Param{} - methodInvocations := pegomock.GetGenericMockFrom(verifier.mock).Verify(verifier.inOrderContext, verifier.invocationCountMatcher, "GetLevel", params, verifier.timeout) - return &MockSimpleLogging_GetLevel_OngoingVerification{mock: verifier.mock, methodInvocations: methodInvocations} + for _, param := range a { + params = append(params, param) + } + methodInvocations := pegomock.GetGenericMockFrom(verifier.mock).Verify(verifier.inOrderContext, verifier.invocationCountMatcher, "With", params, verifier.timeout) + return &MockSimpleLogging_With_OngoingVerification{mock: verifier.mock, methodInvocations: methodInvocations} } -type MockSimpleLogging_GetLevel_OngoingVerification struct { +type MockSimpleLogging_With_OngoingVerification struct { mock *MockSimpleLogging methodInvocations []pegomock.MethodInvocation } -func (c *MockSimpleLogging_GetLevel_OngoingVerification) GetCapturedArguments() { +func (c *MockSimpleLogging_With_OngoingVerification) GetCapturedArguments() []interface{} { + a := c.GetAllCapturedArguments() + return a[len(a)-1] } -func (c *MockSimpleLogging_GetLevel_OngoingVerification) GetAllCapturedArguments() { +func (c *MockSimpleLogging_With_OngoingVerification) GetAllCapturedArguments() (_param0 [][]interface{}) { + params := pegomock.GetGenericMockFrom(c.mock).GetInvocationParams(c.methodInvocations) + if len(params) > 0 { + _param0 = make([][]interface{}, len(c.methodInvocations)) + for u := 0; u < len(c.methodInvocations); u++ { + _param0[u] = make([]interface{}, len(params)-0) + for x := 0; x < len(params); x++ { + if params[x][u] != nil { + _param0[u][x-0] = params[x][u].(interface{}) + } + } + } + } + return } -func (verifier *VerifierMockSimpleLogging) NewLogger(_param0 string, _param1 bool, _param2 logging.LogLevel) *MockSimpleLogging_NewLogger_OngoingVerification { - params := []pegomock.Param{_param0, _param1, _param2} - methodInvocations := pegomock.GetGenericMockFrom(verifier.mock).Verify(verifier.inOrderContext, verifier.invocationCountMatcher, "NewLogger", params, verifier.timeout) - return &MockSimpleLogging_NewLogger_OngoingVerification{mock: verifier.mock, methodInvocations: methodInvocations} +func (verifier *VerifierMockSimpleLogging) WithHistory(a ...interface{}) *MockSimpleLogging_WithHistory_OngoingVerification { + params := []pegomock.Param{} + for _, param := range a { + params = append(params, param) + } + methodInvocations := pegomock.GetGenericMockFrom(verifier.mock).Verify(verifier.inOrderContext, verifier.invocationCountMatcher, "WithHistory", params, verifier.timeout) + return &MockSimpleLogging_WithHistory_OngoingVerification{mock: verifier.mock, methodInvocations: methodInvocations} } -type MockSimpleLogging_NewLogger_OngoingVerification struct { +type MockSimpleLogging_WithHistory_OngoingVerification struct { mock *MockSimpleLogging methodInvocations []pegomock.MethodInvocation } -func (c *MockSimpleLogging_NewLogger_OngoingVerification) GetCapturedArguments() (string, bool, logging.LogLevel) { - _param0, _param1, _param2 := c.GetAllCapturedArguments() - return _param0[len(_param0)-1], _param1[len(_param1)-1], _param2[len(_param2)-1] +func (c *MockSimpleLogging_WithHistory_OngoingVerification) GetCapturedArguments() []interface{} { + a := c.GetAllCapturedArguments() + return a[len(a)-1] } -func (c *MockSimpleLogging_NewLogger_OngoingVerification) GetAllCapturedArguments() (_param0 []string, _param1 []bool, _param2 []logging.LogLevel) { +func (c *MockSimpleLogging_WithHistory_OngoingVerification) GetAllCapturedArguments() (_param0 [][]interface{}) { params := pegomock.GetGenericMockFrom(c.mock).GetInvocationParams(c.methodInvocations) if len(params) > 0 { - _param0 = make([]string, len(c.methodInvocations)) - for u, param := range params[0] { - _param0[u] = param.(string) - } - _param1 = make([]bool, len(c.methodInvocations)) - for u, param := range params[1] { - _param1[u] = param.(bool) - } - _param2 = make([]logging.LogLevel, len(c.methodInvocations)) - for u, param := range params[2] { - _param2[u] = param.(logging.LogLevel) + _param0 = make([][]interface{}, len(c.methodInvocations)) + for u := 0; u < len(c.methodInvocations); u++ { + _param0[u] = make([]interface{}, len(params)-0) + for x := 0; x < len(params); x++ { + if params[x][u] != nil { + _param0[u][x-0] = params[x][u].(interface{}) + } + } } } return } + +func (verifier *VerifierMockSimpleLogging) GetHistory() *MockSimpleLogging_GetHistory_OngoingVerification { + params := []pegomock.Param{} + methodInvocations := pegomock.GetGenericMockFrom(verifier.mock).Verify(verifier.inOrderContext, verifier.invocationCountMatcher, "GetHistory", params, verifier.timeout) + return &MockSimpleLogging_GetHistory_OngoingVerification{mock: verifier.mock, methodInvocations: methodInvocations} +} + +type MockSimpleLogging_GetHistory_OngoingVerification struct { + mock *MockSimpleLogging + methodInvocations []pegomock.MethodInvocation +} + +func (c *MockSimpleLogging_GetHistory_OngoingVerification) GetCapturedArguments() { +} + +func (c *MockSimpleLogging_GetHistory_OngoingVerification) GetAllCapturedArguments() { +} diff --git a/server/logging/simple_logger.go b/server/logging/simple_logger.go index 0918e43f84..3314d61018 100644 --- a/server/logging/simple_logger.go +++ b/server/logging/simple_logger.go @@ -17,211 +17,197 @@ package logging import ( "bytes" "fmt" - "io/ioutil" - "log" - "os" - "runtime" - "time" - "unicode" + "testing" + + "github.com/pkg/errors" + "go.uber.org/zap" + "go.uber.org/zap/zapcore" + "go.uber.org/zap/zaptest" ) //go:generate pegomock generate -m --use-experimental-model-gen --package mocks -o mocks/mock_simple_logging.go SimpleLogging -// SimpleLogging is the interface that our SimpleLogger implements. -// It's really only used for mocking when we need to test what's being logged. +// SimpleLogging is the interface used for logging throughout the codebase. type SimpleLogging interface { + + // These basically just fmt.Sprintf() the message and args. Debug(format string, a ...interface{}) Info(format string, a ...interface{}) Warn(format string, a ...interface{}) Err(format string, a ...interface{}) Log(level LogLevel, format string, a ...interface{}) - // Underlying returns the underlying logger. - Underlying() *log.Logger - // GetLevel returns the current log level. - GetLevel() LogLevel - NewLogger(string, bool, LogLevel) *SimpleLogger -} - -// SimpleLogger wraps the standard logger with leveled logging -// and the ability to store log history for later adding it -// to a VCS comment. -type SimpleLogger struct { - // Source is added as a prefix to each log entry. - // It's useful if you want to trace a log entry back to a - // context, for example a pull request id. - Source string + SetLevel(lvl LogLevel) + + // With adds a variadic number of fields to the logging context. It accepts a + // mix of strongly-typed Field objects and loosely-typed key-value pairs. When + // processing pairs, the first element of the pair is used as the field key + // and the second as the field value. + With(a ...interface{}) SimpleLogging + + // Creates a new logger with history preserved . log storage + search strategies + // should ideally be used instead of managing this ourselves. + // keeping as a separate method to ensure that usage of history is completely intentional + WithHistory(a ...interface{}) SimpleLogging + + // Fetches the history we've stored associated with the logging context + GetHistory() string + + // Flushes anything left in the buffer + Flush() error +} + +type StructuredLogger struct { + z *zap.SugaredLogger + level zap.AtomicLevel + keepHistory bool // History stores all log entries ever written using // this logger. This is safe for short-lived loggers // like those used during plan/apply commands. - History bytes.Buffer - Logger *log.Logger - KeepHistory bool - Level LogLevel + // TODO: Deprecate this + // this is added here to maintain backwards compatibility + // This doesn't really make sense to keep given that structured logging + // gives us the ability to query our logs across multiple dimensions + // I don't believe we should mix this in with atlantis commands and expose this to the user + history bytes.Buffer } -type LogLevel int - -const ( - Debug LogLevel = iota - Info - Warn - Error -) +func NewStructuredLoggerFromLevel(lvl LogLevel) (SimpleLogging, error) { + cfg := zap.NewProductionConfig() -// NewSimpleLogger creates a new logger. -// source is added as a prefix to each log entry. It's useful if you want to -// trace a log entry back to a specific context, for example a pull request id. -// keepHistory set to true will store all log entries written using this logger. -// level will set the level at which logs >= than that level will be written. -// If keepHistory is set to true, we'll store logs at all levels, regardless of -// what level is set to. -func NewSimpleLogger(source string, keepHistory bool, level LogLevel) *SimpleLogger { - return &SimpleLogger{ - Source: source, - Logger: log.New(os.Stderr, "", 0), - Level: level, - KeepHistory: keepHistory, - } + cfg.Level = zap.NewAtomicLevelAt(lvl.zLevel) + return newStructuredLogger(cfg) } -// NewNoopLogger creates a logger instance that discards all logs and never -// writes them. Used for testing. -func NewNoopLogger() *SimpleLogger { - logger := log.New(os.Stderr, "", 0) - logger.SetOutput(ioutil.Discard) - return &SimpleLogger{ - Source: "", - Logger: logger, - Level: Info, - KeepHistory: false, - } +func NewStructuredLogger() (SimpleLogging, error) { + cfg := zap.NewProductionConfig() + return newStructuredLogger(cfg) } -// NewLogger returns a new logger that reuses the underlying logger. -func (l *SimpleLogger) NewLogger(source string, keepHistory bool, lvl LogLevel) *SimpleLogger { - if l == nil { - return nil - } - return &SimpleLogger{ - Source: source, - Level: lvl, - Logger: l.Underlying(), - KeepHistory: keepHistory, - } -} +func newStructuredLogger(cfg zap.Config) (*StructuredLogger, error) { + baseLogger, err := cfg.Build() -// SetLevel changes the level that this logger is writing at to lvl. -func (l *SimpleLogger) SetLevel(lvl LogLevel) { - if l != nil { - l.Level = lvl - } -} + baseLogger = baseLogger. + // ensures that the caller doesn't just say logging/simple_logger each time + WithOptions(zap.AddCallerSkip(1)). + WithOptions(zap.AddStacktrace(zapcore.WarnLevel)). + // creates isolated context for all future kv pairs, name can be flexible as needed + With(zap.Namespace("json")) -// Debug logs at debug level. -func (l *SimpleLogger) Debug(format string, a ...interface{}) { - if l != nil { - l.Log(Debug, format, a...) + if err != nil { + return nil, errors.Wrap(err, " initializing structured logger") } -} -// Info logs at info level. -func (l *SimpleLogger) Info(format string, a ...interface{}) { - if l != nil { - l.Log(Info, format, a...) - } + return &StructuredLogger{ + z: baseLogger.Sugar(), + level: cfg.Level, + }, nil } -// Warn logs at warn level. -func (l *SimpleLogger) Warn(format string, a ...interface{}) { - if l != nil { - l.Log(Warn, format, a...) +func (l *StructuredLogger) With(a ...interface{}) SimpleLogging { + return &StructuredLogger{ + z: l.z.With(a...), + level: l.level, } } -// Err logs at error level. -func (l *SimpleLogger) Err(format string, a ...interface{}) { - if l != nil { - l.Log(Error, format, a...) +func (l *StructuredLogger) WithHistory(a ...interface{}) SimpleLogging { + logger := &StructuredLogger{ + z: l.z.With(a...), + level: l.level, } + + // ensure that the history is kept across loggers. + logger.keepHistory = true + logger.history = l.history + + return logger } -// Log writes the log at level. -func (l *SimpleLogger) Log(level LogLevel, format string, a ...interface{}) { - if l != nil { - levelStr := l.levelToString(level) - msg := l.capitalizeFirstLetter(fmt.Sprintf(format, a...)) - - // Only log this message if configured to log at this level. - if l.Level <= level { - datetime := time.Now().Format("2006/01/02 15:04:05-0700") - var caller string - if l.Level <= Debug { - file, line := l.callSite(3) - caller = fmt.Sprintf(" %s:%d", file, line) - } - l.Logger.Printf("%s [%s]%s %s: %s\n", datetime, levelStr, caller, l.Source, msg) // noline: errcheck - } - - // Keep history at all log levels. - if l.KeepHistory { - l.saveToHistory(levelStr, msg) - } - } +func (l *StructuredLogger) GetHistory() string { + return l.history.String() } -// Underlying returns the underlying logger. -func (l *SimpleLogger) Underlying() *log.Logger { - return l.Logger +func (l *StructuredLogger) Debug(format string, a ...interface{}) { + l.z.Debugf(format, a...) + l.saveToHistory(Debug, format, a...) } -// GetLevel returns the current log level of the logger. -func (l *SimpleLogger) GetLevel() LogLevel { - return l.Level +func (l *StructuredLogger) Info(format string, a ...interface{}) { + l.z.Infof(format, a...) + l.saveToHistory(Info, format, a...) } -func (l *SimpleLogger) saveToHistory(level string, msg string) { - l.History.WriteString(fmt.Sprintf("[%s] %s\n", level, msg)) +func (l *StructuredLogger) Warn(format string, a ...interface{}) { + l.z.Warnf(format, a...) + l.saveToHistory(Warn, format, a...) } -func (l *SimpleLogger) capitalizeFirstLetter(s string) string { - runes := []rune(s) - runes[0] = unicode.ToUpper(runes[0]) - return string(runes) +func (l *StructuredLogger) Err(format string, a ...interface{}) { + l.z.Errorf(format, a...) + l.saveToHistory(Error, format, a...) } -// levelToString returns the logging level as a 4 character string. DEBUG and ERROR are shortened intentionally -// so that logs line up. -func (l *SimpleLogger) levelToString(level LogLevel) string { +func (l *StructuredLogger) Log(level LogLevel, format string, a ...interface{}) { switch level { case Debug: - return "DBUG" + l.Debug(format, a...) case Info: - return "INFO" + l.Info(format, a...) case Warn: - return "WARN" + l.Warn(format, a...) case Error: - return "EROR" + l.Err(format, a...) } - return "????" } -// callSite returns the location of the caller of this function via its -// filename and line number. skip is the number of stack frames to skip. -func (l *SimpleLogger) callSite(skip int) (string, int) { - _, file, line, ok := runtime.Caller(skip) - if !ok { - return "???", 0 +func (l *StructuredLogger) SetLevel(lvl LogLevel) { + if l != nil { + l.level.SetLevel(lvl.zLevel) } +} + +func (l *StructuredLogger) Flush() error { + return l.z.Sync() +} - // file is the full filepath but we just want the filename. - // NOTE: rather than calling path.Base we're using code from the stdlib - // logging package which I assume is optimized. - short := file - for i := len(file) - 1; i > 0; i-- { - if file[i] == '/' { - short = file[i+1:] - break - } +func (l *StructuredLogger) saveToHistory(lvl LogLevel, format string, a ...interface{}) { + if !l.keepHistory { + return } - return short, line + msg := fmt.Sprintf(format, a...) + l.history.WriteString(fmt.Sprintf("[%s] %s\n", lvl.shortStr, msg)) } + +// NewNoopLogger creates a logger instance that discards all logs and never +// writes them. Used for testing. +func NewNoopLogger(t *testing.T) SimpleLogging { + level := zap.DebugLevel + return &StructuredLogger{ + z: zaptest.NewLogger(t, zaptest.Level(level)).Sugar(), + level: zap.NewAtomicLevelAt(level), + } +} + +type LogLevel struct { + zLevel zapcore.Level + shortStr string +} + +var ( + Debug = LogLevel{ + zLevel: zapcore.DebugLevel, + shortStr: "DBUG", + } + Info = LogLevel{ + zLevel: zapcore.InfoLevel, + shortStr: "INFO", + } + Warn = LogLevel{ + zLevel: zapcore.WarnLevel, + shortStr: "WARN", + } + Error = LogLevel{ + zLevel: zapcore.ErrorLevel, + shortStr: "EROR", + } +) diff --git a/server/middleware.go b/server/middleware.go index 760d71b287..5aee2ebb6d 100644 --- a/server/middleware.go +++ b/server/middleware.go @@ -21,13 +21,13 @@ import ( ) // NewRequestLogger creates a RequestLogger. -func NewRequestLogger(logger *logging.SimpleLogger) *RequestLogger { +func NewRequestLogger(logger logging.SimpleLogging) *RequestLogger { return &RequestLogger{logger} } // RequestLogger logs requests and their response codes. type RequestLogger struct { - logger *logging.SimpleLogger + logger logging.SimpleLogging } // ServeHTTP implements the middleware function. It logs all requests at DEBUG level. diff --git a/server/server.go b/server/server.go index 0d2ae59a7f..23098e4c11 100644 --- a/server/server.go +++ b/server/server.go @@ -82,7 +82,7 @@ type Server struct { Port int PreWorkflowHooksCommandRunner *events.DefaultPreWorkflowHooksCommandRunner CommandRunner *events.DefaultCommandRunner - Logger *logging.SimpleLogger + Logger logging.SimpleLogging Locker locking.Locker ApplyLocker locking.ApplyLocker EventsController *EventsController @@ -125,7 +125,12 @@ type WebhookConfig struct { // its dependencies an error will be returned. This is like the main() function // for the server CLI command because it injects all the dependencies. func NewServer(userConfig UserConfig, config Config) (*Server, error) { - logger := logging.NewSimpleLogger("server", false, userConfig.ToLogLevel()) + logger, err := logging.NewStructuredLoggerFromLevel(userConfig.ToLogLevel()) + + if err != nil { + return nil, err + } + var supportedVCSHosts []models.VCSHostType var githubClient *vcs.GithubClient var githubAppEnabled bool @@ -642,6 +647,8 @@ func (s *Server) Start() error { }, NewRequestLogger(s.Logger)) n.UseHandler(s.Router) + defer s.Logger.Flush() + // Ensure server gracefully drains connections when stopped. stop := make(chan os.Signal, 1) // Stop on SIGINTs and SIGTERMs. diff --git a/server/server_test.go b/server/server_test.go index 27a34ef231..4b22cdf6a4 100644 --- a/server/server_test.go +++ b/server/server_test.go @@ -29,6 +29,7 @@ import ( "github.com/runatlantis/atlantis/server" "github.com/runatlantis/atlantis/server/events/locking/mocks" "github.com/runatlantis/atlantis/server/events/models" + "github.com/runatlantis/atlantis/server/logging" sMocks "github.com/runatlantis/atlantis/server/mocks" . "github.com/runatlantis/atlantis/testing" ) @@ -106,6 +107,7 @@ func TestIndex_Success(t *testing.T) { Router: r, AtlantisVersion: atlantisVersion, AtlantisURL: u, + Logger: logging.NewNoopLogger(t), } req, _ := http.NewRequest("GET", "", bytes.NewBuffer(nil)) w := httptest.NewRecorder() diff --git a/server/status_controller.go b/server/status_controller.go index 7add516714..411176437c 100644 --- a/server/status_controller.go +++ b/server/status_controller.go @@ -11,7 +11,7 @@ import ( // StatusController handles the status of Atlantis. type StatusController struct { - Logger *logging.SimpleLogger + Logger logging.SimpleLogging Drainer *events.Drainer } diff --git a/server/status_controller_test.go b/server/status_controller_test.go index 9ad3a4fc44..9032febb0e 100644 --- a/server/status_controller_test.go +++ b/server/status_controller_test.go @@ -15,7 +15,7 @@ import ( ) func TestStatusController_Startup(t *testing.T) { - logger := logging.NewNoopLogger() + logger := logging.NewNoopLogger(t) r, _ := http.NewRequest("GET", "/status", bytes.NewBuffer(nil)) w := httptest.NewRecorder() dr := &events.Drainer{} @@ -36,7 +36,7 @@ func TestStatusController_Startup(t *testing.T) { } func TestStatusController_InProgress(t *testing.T) { - logger := logging.NewNoopLogger() + logger := logging.NewNoopLogger(t) r, _ := http.NewRequest("GET", "/status", bytes.NewBuffer(nil)) w := httptest.NewRecorder() dr := &events.Drainer{} @@ -59,7 +59,7 @@ func TestStatusController_InProgress(t *testing.T) { } func TestStatusController_Shutdown(t *testing.T) { - logger := logging.NewNoopLogger() + logger := logging.NewNoopLogger(t) r, _ := http.NewRequest("GET", "/status", bytes.NewBuffer(nil)) w := httptest.NewRecorder() dr := &events.Drainer{} From 1cecb869c148db528eeb9dafeeb4bd4a9df8de32 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 7 Apr 2021 09:48:46 -0400 Subject: [PATCH 02/13] build(deps): bump github.com/hashicorp/go-getter from 1.5.2 to 1.5.3 (#1485) Bumps [github.com/hashicorp/go-getter](https://github.com/hashicorp/go-getter) from 1.5.2 to 1.5.3. - [Release notes](https://github.com/hashicorp/go-getter/releases) - [Changelog](https://github.com/hashicorp/go-getter/blob/main/.goreleaser.yml) - [Commits](https://github.com/hashicorp/go-getter/compare/v1.5.2...v1.5.3) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 5 ++--- go.sum | 22 ++++------------------ 2 files changed, 6 insertions(+), 21 deletions(-) diff --git a/go.mod b/go.mod index 22af4dd0ba..5229a87670 100644 --- a/go.mod +++ b/go.mod @@ -26,22 +26,21 @@ require ( github.com/google/go-github/v31 v31.0.0 github.com/google/uuid v1.1.2-0.20200519141726-cb32006e483f // indirect github.com/gorilla/mux v1.8.0 - github.com/hashicorp/go-getter v1.5.2 + github.com/hashicorp/go-getter v1.5.3 github.com/hashicorp/go-version v1.2.1 github.com/hashicorp/hcl/v2 v2.6.0 // indirect github.com/hashicorp/terraform-config-inspect v0.0.0-20200806211835-c481b8bfa41e github.com/inconshreveable/mousetrap v1.0.0 // indirect github.com/jmespath/go-jmespath v0.3.1-0.20200310193758-2437e8417af5 // indirect - github.com/kelseyhightower/envconfig v1.4.1-0.20200624135755-c974cae29cf5 // indirect github.com/leodido/go-urn v1.2.0 // indirect github.com/lusis/slack-test v0.0.0-20190426140909-c40012f20018 // indirect - github.com/lyft/gostats v0.4.5 github.com/mcdafydd/go-azuredevops v0.12.0 github.com/microcosm-cc/bluemonday v1.0.5 github.com/mitchellh/colorstring v0.0.0-20150917214807-8631ce90f286 github.com/mitchellh/go-homedir v1.1.0 github.com/mohae/deepcopy v0.0.0-20170603005431-491d3605edfb github.com/nlopes/slack v0.4.0 + github.com/onsi/ginkgo v1.14.0 // indirect github.com/petergtz/pegomock v2.9.0+incompatible github.com/pkg/errors v0.9.1 github.com/remeh/sizedwaitgroup v1.0.0 diff --git a/go.sum b/go.sum index a497d0b689..2532ca0d29 100644 --- a/go.sum +++ b/go.sum @@ -72,7 +72,6 @@ github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfc github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d h1:U+s90UTSYgptZMwQh2aRr3LuazLJIa+Pg3Kc1ylSYVY= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -89,7 +88,6 @@ github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/flynn-archive/go-shlex v0.0.0-20150515145356-3f9db97f8568 h1:BMXYYRWTLOJKlh+lOBt6nUQgXAfB7oVIQt5cNreqSLI= github.com/flynn-archive/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:rZfgFAXFS/z/lEd6LJmf9HVZ1LkgYiHx5pHhV5DR16M= -github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/fsnotify/fsnotify v1.4.10-0.20200417215612-7f4cf4dd2b52 h1:0NmERxogGTU8hgzOhRKNoKivtBZkDW29GeuJtK9e0sc= @@ -129,7 +127,6 @@ github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:x github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= -github.com/golang/protobuf v1.4.1 h1:ZFgWrT+bLgsYPirOnRfKLYJLvssAegOj/hgyMFdJZe0= github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0= github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= @@ -174,11 +171,11 @@ github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= -github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= -github.com/hashicorp/go-cleanhttp v0.5.1 h1:dH3aiDG9Jvb5r5+bYHsikaOUIpcM0xvgMXVoDkXMzJM= github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= -github.com/hashicorp/go-getter v1.5.2 h1:XDo8LiAcDisiqZdv0TKgz+HtX3WN7zA2JD1R1tjsabE= -github.com/hashicorp/go-getter v1.5.2/go.mod h1:orNH3BTYLu/fIxGIdLjLoAJHWMDQ/UKQr5O4m3iBuoo= +github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ= +github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= +github.com/hashicorp/go-getter v1.5.3 h1:NF5+zOlQegim+w/EUhSLh6QhXHmZMEeHLQzllkQ3ROU= +github.com/hashicorp/go-getter v1.5.3/go.mod h1:BrrV/1clo8cCYu6mxvboYg+KutTiFnXjMEgDD8+i7ZI= github.com/hashicorp/go-hclog v0.9.2 h1:CG6TE5H9/JXsFWJCfoIVpKFIkFe6ysEuHirp4DxCsHI= github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ= github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= @@ -211,7 +208,6 @@ github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2p github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= github.com/hashicorp/terraform-config-inspect v0.0.0-20200806211835-c481b8bfa41e h1:wIsEsIITggCC4FTO9PisDjy561UU7OPL6uTu7tnkHH8= github.com/hashicorp/terraform-config-inspect v0.0.0-20200806211835-c481b8bfa41e/go.mod h1:Z0Nnk4+3Cy89smEbrq+sl1bxc9198gIP4I7wcQF6Kqs= -github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/huandu/xstrings v1.3.1 h1:4jgBlKK6tLKFvO8u5pmYjG91cqytmDCDvGh7ECVFfFs= github.com/huandu/xstrings v1.3.1/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= @@ -230,9 +226,6 @@ github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1 github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= -github.com/kelseyhightower/envconfig v1.4.0/go.mod h1:cccZRl6mQpaq41TPp5QxidR+Sa3axMbJDNb//FQX6Gg= -github.com/kelseyhightower/envconfig v1.4.1-0.20200624135755-c974cae29cf5 h1:TW7YQVw105jR4B+n/tAlkKNbYFSdWRK1RyLL5YYruso= -github.com/kelseyhightower/envconfig v1.4.1-0.20200624135755-c974cae29cf5/go.mod h1:cccZRl6mQpaq41TPp5QxidR+Sa3axMbJDNb//FQX6Gg= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.11.2 h1:MiK62aErc3gIiVEtyzKfeOHgW7atJb5g/KNX5m3c2nQ= @@ -251,8 +244,6 @@ github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y= github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= github.com/lusis/slack-test v0.0.0-20190426140909-c40012f20018 h1:MNApn+Z+fIT4NPZopPfCc1obT6aY3SVM6DOctz1A9ZU= github.com/lusis/slack-test v0.0.0-20190426140909-c40012f20018/go.mod h1:sFlOUpQL1YcjhFVXhg1CG8ZASEs/Mf1oVb6H75JL/zg= -github.com/lyft/gostats v0.4.5 h1:2KYdjsz+RfxeJAWqOpYUlyXgFgYd0SxPFUSFm9PdXM4= -github.com/lyft/gostats v0.4.5/go.mod h1:7ECvCenOq0N9BE6Tn+dtwFoS6xAwbvsx4tVSETO/hmc= github.com/magiconair/properties v1.8.1 h1:ZC2Vc7/ZFkGmsVC9KvOjumD+G5lXy2RtTKyzRKO2BQ4= github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/mattn/go-colorable v0.0.9 h1:UVL0vNpWh04HeJXV0KLcaT7r06gOH2l4OW6ddYRUIY4= @@ -345,7 +336,6 @@ github.com/shurcooL/graphql v0.0.0-20181231061246-d48a9a75455f h1:tygelZueB1EtXk github.com/shurcooL/graphql v0.0.0-20181231061246-d48a9a75455f/go.mod h1:AuYgA5Kyo4c7HfUmvRGs/6rGlMMV/6B1bVnB9JxJEEg= github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= -github.com/sirupsen/logrus v1.0.6/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.6.1-0.20200528085638-6699a89a232f h1:qqqIhBDFUBrbMezIyJkKWIpf+E5CdObleGMjW1s19Hg= github.com/sirupsen/logrus v1.6.1-0.20200528085638-6699a89a232f/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= @@ -421,7 +411,6 @@ golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20200204104054-c9f3fb736b72/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200403201458-baeed622b8d8/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200414173820-0848c9571904/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI= @@ -578,16 +567,13 @@ google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpAD google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= google.golang.org/protobuf v1.25.1-0.20200622203222-a9513ebdb860 h1:tL2Vm8k2K9M9JSKg64klrDP2WV6W4cW7THc8GfJyBsQ= google.golang.org/protobuf v1.25.1-0.20200622203222-a9513ebdb860/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= -gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/cheggaaa/pb.v1 v1.0.27/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= -gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= -gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2/go.mod h1:Xk6kEKp8OKb+X14hQBKWaSkCsqBpgog8nAV2xsGOxlo= gopkg.in/go-playground/assert.v1 v1.2.1 h1:xoYuJVE7KT85PYWrN730RguIQO0ePzVRfFMXadIrXTM= gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE= gopkg.in/go-playground/validator.v9 v9.31.0 h1:bmXmP2RSNtFES+bn4uYuHT7iJFJv7Vj+an+ZQdDaD1M= From 2a8754c04ee2018f14b6d9178c4eb5afd7c7bcfb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 7 Apr 2021 09:48:57 -0400 Subject: [PATCH 03/13] build(deps): bump github.com/xanzy/go-gitlab from 0.47.0 to 0.48.0 (#1486) Bumps [github.com/xanzy/go-gitlab](https://github.com/xanzy/go-gitlab) from 0.47.0 to 0.48.0. - [Release notes](https://github.com/xanzy/go-gitlab/releases) - [Changelog](https://github.com/xanzy/go-gitlab/blob/master/releases_test.go) - [Commits](https://github.com/xanzy/go-gitlab/compare/v0.47.0...v0.48.0) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/go.mod b/go.mod index 5229a87670..29d6a2b2b2 100644 --- a/go.mod +++ b/go.mod @@ -53,7 +53,7 @@ require ( github.com/stretchr/testify v1.6.1 github.com/urfave/cli v1.22.5 github.com/urfave/negroni v0.3.0 - github.com/xanzy/go-gitlab v0.47.0 + github.com/xanzy/go-gitlab v0.48.0 github.com/zclconf/go-cty v1.5.1 // indirect go.etcd.io/bbolt v1.3.5 go.opencensus.io v0.22.3 // indirect diff --git a/go.sum b/go.sum index 2532ca0d29..a440ee28cc 100644 --- a/go.sum +++ b/go.sum @@ -181,8 +181,8 @@ github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrj github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= -github.com/hashicorp/go-retryablehttp v0.6.4 h1:BbgctKO892xEyOXnGiaAwIoSq1QZ/SS4AhjoAh9DnfY= -github.com/hashicorp/go-retryablehttp v0.6.4/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY= +github.com/hashicorp/go-retryablehttp v0.6.8 h1:92lWxgpa+fF3FozM4B3UZtHZMJX8T5XT+TFdCxsPyWs= +github.com/hashicorp/go-retryablehttp v0.6.8/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY= github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= github.com/hashicorp/go-safetemp v1.0.0 h1:2HR189eFNrjHQyENnQMMpCiBAsRxzbTMIgBhEyExpmo= github.com/hashicorp/go-safetemp v1.0.0/go.mod h1:oaerMy3BhqiTbVye6QuFhFtIceqFoDHxNAB65b+Rj1I= @@ -378,8 +378,8 @@ github.com/urfave/cli v1.22.5/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtX github.com/urfave/negroni v0.3.0 h1:PaXOb61mWeZJxc1Ji2xJjpVg9QfPo0rrB+lHyBxGNSU= github.com/urfave/negroni v0.3.0/go.mod h1:Meg73S6kFm/4PpbYdq35yYWoCZ9mS/YSx+lKnmiohz4= github.com/vmihailenco/msgpack v3.3.3+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk= -github.com/xanzy/go-gitlab v0.47.0 h1:nC35CNaGr9skHkJq1HMYZ58R7gZsy7SO37SkA2RIHbM= -github.com/xanzy/go-gitlab v0.47.0/go.mod h1:sPLojNBn68fMUWSxIJtdVVIP8uSBYqesTfDUseX11Ug= +github.com/xanzy/go-gitlab v0.48.0 h1:RP9r4pMDIwE2fbtc+QYiC1euDsPGHcAjPkhje4X3QPU= +github.com/xanzy/go-gitlab v0.48.0/go.mod h1:UW8JJbyBbqtOyBYNHRo261IRdHUFJr2m0y0z1xUiu+E= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/zclconf/go-cty v1.1.0/go.mod h1:xnAOWiHeOqg2nWS62VtQ7pbOu17FtxJNW8RLEih+O3s= From cdb6e3dae862b260f94a34d0ff8c9cfaffa88539 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 7 Apr 2021 13:04:41 -0400 Subject: [PATCH 04/13] build(deps): bump github.com/hashicorp/go-version from 1.2.1 to 1.3.0 (#1484) Bumps [github.com/hashicorp/go-version](https://github.com/hashicorp/go-version) from 1.2.1 to 1.3.0. - [Release notes](https://github.com/hashicorp/go-version/releases) - [Changelog](https://github.com/hashicorp/go-version/blob/master/CHANGELOG.md) - [Commits](https://github.com/hashicorp/go-version/compare/v1.2.1...v1.3.0) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 29d6a2b2b2..779b302775 100644 --- a/go.mod +++ b/go.mod @@ -27,7 +27,7 @@ require ( github.com/google/uuid v1.1.2-0.20200519141726-cb32006e483f // indirect github.com/gorilla/mux v1.8.0 github.com/hashicorp/go-getter v1.5.3 - github.com/hashicorp/go-version v1.2.1 + github.com/hashicorp/go-version v1.3.0 github.com/hashicorp/hcl/v2 v2.6.0 // indirect github.com/hashicorp/terraform-config-inspect v0.0.0-20200806211835-c481b8bfa41e github.com/inconshreveable/mousetrap v1.0.0 // indirect diff --git a/go.sum b/go.sum index a440ee28cc..ded21aa376 100644 --- a/go.sum +++ b/go.sum @@ -191,8 +191,8 @@ github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdv github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-version v1.1.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= -github.com/hashicorp/go-version v1.2.1 h1:zEfKbn2+PDgroKdiOzqiE8rsmLqU2uwi5PB5pBJ3TkI= -github.com/hashicorp/go-version v1.2.1/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go-version v1.3.0 h1:McDWVJIU/y+u1BRV06dPaLfLCaT7fUTJLp5r04x7iNw= +github.com/hashicorp/go-version v1.3.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= From eb27b4d56793fb346af27b023a4cd28a17cb2e8b Mon Sep 17 00:00:00 2001 From: rui Date: Wed, 7 Apr 2021 15:53:16 -0400 Subject: [PATCH 05/13] Revert "build(deps): bump github.com/xanzy/go-gitlab from 0.47.0 to 0.48.0 (#1486)" (#1489) This reverts commit 2a8754c04ee2018f14b6d9178c4eb5afd7c7bcfb. --- go.mod | 2 +- go.sum | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/go.mod b/go.mod index 779b302775..e4bfb15078 100644 --- a/go.mod +++ b/go.mod @@ -53,7 +53,7 @@ require ( github.com/stretchr/testify v1.6.1 github.com/urfave/cli v1.22.5 github.com/urfave/negroni v0.3.0 - github.com/xanzy/go-gitlab v0.48.0 + github.com/xanzy/go-gitlab v0.47.0 github.com/zclconf/go-cty v1.5.1 // indirect go.etcd.io/bbolt v1.3.5 go.opencensus.io v0.22.3 // indirect diff --git a/go.sum b/go.sum index ded21aa376..1b155aec1e 100644 --- a/go.sum +++ b/go.sum @@ -181,8 +181,8 @@ github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrj github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= -github.com/hashicorp/go-retryablehttp v0.6.8 h1:92lWxgpa+fF3FozM4B3UZtHZMJX8T5XT+TFdCxsPyWs= -github.com/hashicorp/go-retryablehttp v0.6.8/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY= +github.com/hashicorp/go-retryablehttp v0.6.4 h1:BbgctKO892xEyOXnGiaAwIoSq1QZ/SS4AhjoAh9DnfY= +github.com/hashicorp/go-retryablehttp v0.6.4/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY= github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= github.com/hashicorp/go-safetemp v1.0.0 h1:2HR189eFNrjHQyENnQMMpCiBAsRxzbTMIgBhEyExpmo= github.com/hashicorp/go-safetemp v1.0.0/go.mod h1:oaerMy3BhqiTbVye6QuFhFtIceqFoDHxNAB65b+Rj1I= @@ -378,8 +378,8 @@ github.com/urfave/cli v1.22.5/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtX github.com/urfave/negroni v0.3.0 h1:PaXOb61mWeZJxc1Ji2xJjpVg9QfPo0rrB+lHyBxGNSU= github.com/urfave/negroni v0.3.0/go.mod h1:Meg73S6kFm/4PpbYdq35yYWoCZ9mS/YSx+lKnmiohz4= github.com/vmihailenco/msgpack v3.3.3+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk= -github.com/xanzy/go-gitlab v0.48.0 h1:RP9r4pMDIwE2fbtc+QYiC1euDsPGHcAjPkhje4X3QPU= -github.com/xanzy/go-gitlab v0.48.0/go.mod h1:UW8JJbyBbqtOyBYNHRo261IRdHUFJr2m0y0z1xUiu+E= +github.com/xanzy/go-gitlab v0.47.0 h1:nC35CNaGr9skHkJq1HMYZ58R7gZsy7SO37SkA2RIHbM= +github.com/xanzy/go-gitlab v0.47.0/go.mod h1:sPLojNBn68fMUWSxIJtdVVIP8uSBYqesTfDUseX11Ug= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/zclconf/go-cty v1.1.0/go.mod h1:xnAOWiHeOqg2nWS62VtQ7pbOu17FtxJNW8RLEih+O3s= From 921ebbc48d8b15ef40b6f7b2aa3c795417966fce Mon Sep 17 00:00:00 2001 From: rui Date: Wed, 7 Apr 2021 21:15:55 -0400 Subject: [PATCH 06/13] deps: tf 0.14.10 (#1488) Signed-off-by: Rui Chen --- .circleci/config.yml | 2 +- Dockerfile | 2 +- testing/Dockerfile | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 3438a49c86..23904323ed 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -19,7 +19,7 @@ jobs: # We do this instead of setting --default-tf-version because setting # that flag starts the download asynchronously so we'd have a race # condition. - TERRAFORM_VERSION: 0.14.9 + TERRAFORM_VERSION: 0.14.10 steps: - checkout - run: make build-service diff --git a/Dockerfile b/Dockerfile index 160cd5330e..32996ca3e1 100644 --- a/Dockerfile +++ b/Dockerfile @@ -3,7 +3,7 @@ FROM runatlantis/atlantis-base:v3.5 LABEL authors="Anubhav Mishra, Luke Kysow" # install terraform binaries -ENV DEFAULT_TERRAFORM_VERSION=0.14.9 +ENV DEFAULT_TERRAFORM_VERSION=0.14.10 # In the official Atlantis image we only have the latest of each Terraform version. RUN AVAILABLE_TERRAFORM_VERSIONS="0.8.8 0.9.11 0.10.8 0.11.14 0.12.30 0.13.6 ${DEFAULT_TERRAFORM_VERSION}" && \ diff --git a/testing/Dockerfile b/testing/Dockerfile index b9c07ad090..d898115179 100644 --- a/testing/Dockerfile +++ b/testing/Dockerfile @@ -5,7 +5,7 @@ FROM circleci/golang:1.16 # Install Terraform -ENV TERRAFORM_VERSION=0.14.9 +ENV TERRAFORM_VERSION=0.14.10 RUN curl -LOks https://releases.hashicorp.com/terraform/${TERRAFORM_VERSION}/terraform_${TERRAFORM_VERSION}_linux_amd64.zip && \ sudo mkdir -p /usr/local/bin/tf/versions/${TERRAFORM_VERSION} && \ sudo unzip terraform_${TERRAFORM_VERSION}_linux_amd64.zip -d /usr/local/bin/tf/versions/${TERRAFORM_VERSION} && \ From db958a0cb255308c499728dda6cbdd0dabd0e1d7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 12 Apr 2021 21:58:54 -0400 Subject: [PATCH 07/13] build(deps): bump github.com/microcosm-cc/bluemonday from 1.0.5 to 1.0.7 (#1492) Bumps [github.com/microcosm-cc/bluemonday](https://github.com/microcosm-cc/bluemonday) from 1.0.5 to 1.0.7. - [Release notes](https://github.com/microcosm-cc/bluemonday/releases) - [Commits](https://github.com/microcosm-cc/bluemonday/compare/v1.0.5...v1.0.7) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 14 ++++++++------ 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/go.mod b/go.mod index e4bfb15078..8fbfcb81f0 100644 --- a/go.mod +++ b/go.mod @@ -35,7 +35,7 @@ require ( github.com/leodido/go-urn v1.2.0 // indirect github.com/lusis/slack-test v0.0.0-20190426140909-c40012f20018 // indirect github.com/mcdafydd/go-azuredevops v0.12.0 - github.com/microcosm-cc/bluemonday v1.0.5 + github.com/microcosm-cc/bluemonday v1.0.7 github.com/mitchellh/colorstring v0.0.0-20150917214807-8631ce90f286 github.com/mitchellh/go-homedir v1.1.0 github.com/mohae/deepcopy v0.0.0-20170603005431-491d3605edfb diff --git a/go.sum b/go.sum index 1b155aec1e..76f5d4a948 100644 --- a/go.sum +++ b/go.sum @@ -61,8 +61,6 @@ github.com/briandowns/spinner v0.0.0-20170614154858-48dbb65d7bd5/go.mod h1:hw/JE github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cheggaaa/pb v1.0.27/go.mod h1:pQciLPpbU0oxA0h+VJYYLxO+XeDQb5pZijXscXHm81s= -github.com/chris-ramon/douceur v0.2.0 h1:IDMEdxlEUUBYBKE4z/mJnFyVXox+MjuEVDJNN27glkU= -github.com/chris-ramon/douceur v0.2.0/go.mod h1:wDW5xjJdeoMm1mRt4sD4c/LbF/mWdEpRXQKjTR8nIBE= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= @@ -255,8 +253,8 @@ github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzp github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/mcdafydd/go-azuredevops v0.12.0 h1:CmG9uheFF6M3WnSykVNVLxR7zXrtg4p3pE2/lNDnPEE= github.com/mcdafydd/go-azuredevops v0.12.0/go.mod h1:B4UDyn7WEj1/97f45j3VnzEfkWKe05+/dCcAPdOET4A= -github.com/microcosm-cc/bluemonday v1.0.5 h1:cF59UCKMmmUgqN1baLvqU/B1ZsMori+duLVTLpgiG3w= -github.com/microcosm-cc/bluemonday v1.0.5/go.mod h1:8iwZnFn2CDDNZ0r6UXhF4xawGvzaqzCRa1n3/lO3W2w= +github.com/microcosm-cc/bluemonday v1.0.7 h1:6yAQfk4XT+PI/dk1ZeBp1gr3Q2Hd1DR0O3aEyPUJVTE= +github.com/microcosm-cc/bluemonday v1.0.7/go.mod h1:HOT/6NaBlR0f9XlxD3zolN6Z3N8Lp4pvhp+jLS5ihnI= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= github.com/mitchellh/colorstring v0.0.0-20150917214807-8631ce90f286 h1:KHyL+3mQOF9sPfs26lsefckcFNDcIZtiACQiECzIUkw= @@ -454,8 +452,9 @@ golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20201021035429-f5854403a974 h1:IX6qOQeG5uLjB/hjjwjedwfjND0hgjPMMyO1RoIXQNI= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20210331212208-0fccb6fa2b5c h1:KHUzaHIpjWVlVVNh65G3hhuj3KB1HnjY6Cq5cTvRQT8= +golang.org/x/net v0.0.0-20210331212208-0fccb6fa2b5c/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181106182150-f42d05182288/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -491,8 +490,11 @@ golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f h1:+Nyd8tzPX9R7BWHguqsrbFdRx3WQ/1ib8I44HXV5yTA= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44 h1:Bli41pIlzTzf3KEY06n+xnzK/BESIg2ze4Pgfh/aI8c= +golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= From 50cba852251b0f92bcbf8569ab2bf7e32fff4031 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 12 Apr 2021 21:59:00 -0400 Subject: [PATCH 08/13] build(deps): bump go.uber.org/zap from 1.15.0 to 1.16.0 (#1495) Bumps [go.uber.org/zap](https://github.com/uber-go/zap) from 1.15.0 to 1.16.0. - [Release notes](https://github.com/uber-go/zap/releases) - [Changelog](https://github.com/uber-go/zap/blob/master/CHANGELOG.md) - [Commits](https://github.com/uber-go/zap/compare/v1.15.0...v1.16.0) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 8fbfcb81f0..053d40a30e 100644 --- a/go.mod +++ b/go.mod @@ -57,7 +57,7 @@ require ( github.com/zclconf/go-cty v1.5.1 // indirect go.etcd.io/bbolt v1.3.5 go.opencensus.io v0.22.3 // indirect - go.uber.org/zap v1.15.0 + go.uber.org/zap v1.16.0 golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 golang.org/x/oauth2 v0.0.0-20191122200657-5d9234df094c // indirect golang.org/x/tools v0.0.0-20201023174141-c8cfbd0f21e6 // indirect diff --git a/go.sum b/go.sum index 76f5d4a948..7083e58ec2 100644 --- a/go.sum +++ b/go.sum @@ -400,8 +400,8 @@ go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKY go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee h1:0mgffUl7nfd+FpvXMVz4IDEaUSmT1ysygQC7qYo7sG4= go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= -go.uber.org/zap v1.15.0 h1:ZZCA22JRF2gQE5FoNmhmrf7jeJJ2uhqDUNRYKm8dvmM= -go.uber.org/zap v1.15.0/go.mod h1:Mb2vm2krFEG5DV0W9qcHBYFtp/Wku1cvYaqPsS/WYfc= +go.uber.org/zap v1.16.0 h1:uFRZXykJGK9lLY4HtgSw44DnIcAM+kRBP7x5m+NpAOM= +go.uber.org/zap v1.16.0/go.mod h1:MA8QOfq0BHJwdXa996Y4dYkAqRKB8/1K1QMMZVaNZjQ= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= From 2e8183c9c51ae5db8a96a035a74c6a6fe7c4c1e2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 12 Apr 2021 22:07:04 -0400 Subject: [PATCH 09/13] build(deps): bump github.com/stretchr/testify from 1.6.1 to 1.7.0 (#1494) Bumps [github.com/stretchr/testify](https://github.com/stretchr/testify) from 1.6.1 to 1.7.0. - [Release notes](https://github.com/stretchr/testify/releases) - [Commits](https://github.com/stretchr/testify/compare/v1.6.1...v1.7.0) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 053d40a30e..9bf4aac3e3 100644 --- a/go.mod +++ b/go.mod @@ -50,7 +50,7 @@ require ( github.com/spf13/cobra v0.0.0-20170905172051-b78744579491 github.com/spf13/pflag v1.0.5 github.com/spf13/viper v1.7.1 - github.com/stretchr/testify v1.6.1 + github.com/stretchr/testify v1.7.0 github.com/urfave/cli v1.22.5 github.com/urfave/negroni v0.3.0 github.com/xanzy/go-gitlab v0.47.0 diff --git a/go.sum b/go.sum index 7083e58ec2..560eb027df 100644 --- a/go.sum +++ b/go.sum @@ -364,8 +364,8 @@ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXf github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= -github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= -github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= From 7e052d3bc91947fd8c8c488c3f2782fe390714d3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 12 Apr 2021 22:08:31 -0400 Subject: [PATCH 10/13] build(deps): bump github.com/xanzy/go-gitlab from 0.47.0 to 0.48.0 (#1493) Bumps [github.com/xanzy/go-gitlab](https://github.com/xanzy/go-gitlab) from 0.47.0 to 0.48.0. - [Release notes](https://github.com/xanzy/go-gitlab/releases) - [Changelog](https://github.com/xanzy/go-gitlab/blob/master/releases_test.go) - [Commits](https://github.com/xanzy/go-gitlab/compare/v0.47.0...v0.48.0) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/go.mod b/go.mod index 9bf4aac3e3..2c6b875d36 100644 --- a/go.mod +++ b/go.mod @@ -53,7 +53,7 @@ require ( github.com/stretchr/testify v1.7.0 github.com/urfave/cli v1.22.5 github.com/urfave/negroni v0.3.0 - github.com/xanzy/go-gitlab v0.47.0 + github.com/xanzy/go-gitlab v0.48.0 github.com/zclconf/go-cty v1.5.1 // indirect go.etcd.io/bbolt v1.3.5 go.opencensus.io v0.22.3 // indirect diff --git a/go.sum b/go.sum index 560eb027df..82a52b4bd8 100644 --- a/go.sum +++ b/go.sum @@ -179,8 +179,8 @@ github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrj github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= -github.com/hashicorp/go-retryablehttp v0.6.4 h1:BbgctKO892xEyOXnGiaAwIoSq1QZ/SS4AhjoAh9DnfY= -github.com/hashicorp/go-retryablehttp v0.6.4/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY= +github.com/hashicorp/go-retryablehttp v0.6.8 h1:92lWxgpa+fF3FozM4B3UZtHZMJX8T5XT+TFdCxsPyWs= +github.com/hashicorp/go-retryablehttp v0.6.8/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY= github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= github.com/hashicorp/go-safetemp v1.0.0 h1:2HR189eFNrjHQyENnQMMpCiBAsRxzbTMIgBhEyExpmo= github.com/hashicorp/go-safetemp v1.0.0/go.mod h1:oaerMy3BhqiTbVye6QuFhFtIceqFoDHxNAB65b+Rj1I= @@ -376,8 +376,8 @@ github.com/urfave/cli v1.22.5/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtX github.com/urfave/negroni v0.3.0 h1:PaXOb61mWeZJxc1Ji2xJjpVg9QfPo0rrB+lHyBxGNSU= github.com/urfave/negroni v0.3.0/go.mod h1:Meg73S6kFm/4PpbYdq35yYWoCZ9mS/YSx+lKnmiohz4= github.com/vmihailenco/msgpack v3.3.3+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk= -github.com/xanzy/go-gitlab v0.47.0 h1:nC35CNaGr9skHkJq1HMYZ58R7gZsy7SO37SkA2RIHbM= -github.com/xanzy/go-gitlab v0.47.0/go.mod h1:sPLojNBn68fMUWSxIJtdVVIP8uSBYqesTfDUseX11Ug= +github.com/xanzy/go-gitlab v0.48.0 h1:RP9r4pMDIwE2fbtc+QYiC1euDsPGHcAjPkhje4X3QPU= +github.com/xanzy/go-gitlab v0.48.0/go.mod h1:UW8JJbyBbqtOyBYNHRo261IRdHUFJr2m0y0z1xUiu+E= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/zclconf/go-cty v1.1.0/go.mod h1:xnAOWiHeOqg2nWS62VtQ7pbOu17FtxJNW8RLEih+O3s= From df106ded117375506d354b20a701a041f18caef2 Mon Sep 17 00:00:00 2001 From: Nish Krishnan Date: Tue, 13 Apr 2021 12:46:47 -0700 Subject: [PATCH 11/13] Make policy checks its own apply requirement. (#61) (#1499) * Make policy checks its own apply requirement. (#61) * Remove warning from docs. --- runatlantis.io/docs/policy-checking.md | 4 - server/events/apply_command_runner.go | 17 -- server/events/command_context.go | 2 + server/events/command_runner.go | 37 ++-- server/events/command_runner_test.go | 14 +- server/events/comment_parser.go | 2 + .../matchers/events_commentparseresult.go | 15 +- .../mocks/matchers/models_vcshosttype.go | 15 +- .../events/mocks/matchers/slice_of_string.go | 15 +- server/events/mocks/mock_comment_building.go | 166 ++++++++++++++++++ server/events/mocks/mock_comment_parsing.go | 13 +- server/events/models/models.go | 2 + server/events/plan_command_runner.go | 10 ++ .../events/project_command_context_builder.go | 20 +++ .../project_command_context_builder_test.go | 83 +++++++++ server/events/project_command_runner.go | 5 + server/events/pull_status_fetcher.go | 8 + server/events/yaml/parser_validator_test.go | 11 +- server/events/yaml/raw/global_cfg.go | 37 +++- server/events/yaml/valid/global_cfg.go | 66 +++++-- server/events/yaml/valid/global_cfg_test.go | 3 - server/events_controller_e2e_test.go | 54 ++++-- server/server.go | 10 +- .../policy-checks-apply-reqs/atlantis.yaml | 4 + .../exp-output-apply-failed.txt | 4 + .../exp-output-apply.txt | 24 +++ .../exp-output-approve-policies.txt | 5 + .../exp-output-auto-policy-check.txt | 15 ++ .../exp-output-autoplan.txt | 36 ++++ .../exp-output-merge.txt | 3 + .../policy-checks-apply-reqs/main.tf | 7 + .../policies/policy.rego | 28 +++ .../policy-checks-apply-reqs/repos.yaml | 12 ++ .../exp-output-apply-failed.txt | 2 +- .../policy-checks-diff-owner/repos.yaml | 3 - .../atlantis.yaml | 4 + .../policy-checks-multi-projects/dir1/main.tf | 7 + .../policy-checks-multi-projects/dir2/main.tf | 7 + .../exp-output-apply.txt | 34 ++++ .../exp-output-approve-policies.txt | 5 + .../exp-output-auto-policy-check.txt | 40 +++++ .../exp-output-autoplan.txt | 71 ++++++++ .../exp-output-merge.txt | 4 + .../policies/policy.rego | 28 +++ .../policy-checks-multi-projects/repos.yaml | 9 + .../policy-checks/exp-output-apply-failed.txt | 2 +- .../test-repos/policy-checks/repos.yaml | 3 - 47 files changed, 857 insertions(+), 109 deletions(-) create mode 100644 server/events/mocks/mock_comment_building.go create mode 100644 server/events/pull_status_fetcher.go create mode 100644 server/testfixtures/test-repos/policy-checks-apply-reqs/atlantis.yaml create mode 100644 server/testfixtures/test-repos/policy-checks-apply-reqs/exp-output-apply-failed.txt create mode 100644 server/testfixtures/test-repos/policy-checks-apply-reqs/exp-output-apply.txt create mode 100644 server/testfixtures/test-repos/policy-checks-apply-reqs/exp-output-approve-policies.txt create mode 100644 server/testfixtures/test-repos/policy-checks-apply-reqs/exp-output-auto-policy-check.txt create mode 100644 server/testfixtures/test-repos/policy-checks-apply-reqs/exp-output-autoplan.txt create mode 100644 server/testfixtures/test-repos/policy-checks-apply-reqs/exp-output-merge.txt create mode 100644 server/testfixtures/test-repos/policy-checks-apply-reqs/main.tf create mode 100644 server/testfixtures/test-repos/policy-checks-apply-reqs/policies/policy.rego create mode 100644 server/testfixtures/test-repos/policy-checks-apply-reqs/repos.yaml create mode 100644 server/testfixtures/test-repos/policy-checks-multi-projects/atlantis.yaml create mode 100644 server/testfixtures/test-repos/policy-checks-multi-projects/dir1/main.tf create mode 100644 server/testfixtures/test-repos/policy-checks-multi-projects/dir2/main.tf create mode 100644 server/testfixtures/test-repos/policy-checks-multi-projects/exp-output-apply.txt create mode 100644 server/testfixtures/test-repos/policy-checks-multi-projects/exp-output-approve-policies.txt create mode 100644 server/testfixtures/test-repos/policy-checks-multi-projects/exp-output-auto-policy-check.txt create mode 100644 server/testfixtures/test-repos/policy-checks-multi-projects/exp-output-autoplan.txt create mode 100644 server/testfixtures/test-repos/policy-checks-multi-projects/exp-output-merge.txt create mode 100644 server/testfixtures/test-repos/policy-checks-multi-projects/policies/policy.rego create mode 100644 server/testfixtures/test-repos/policy-checks-multi-projects/repos.yaml diff --git a/runatlantis.io/docs/policy-checking.md b/runatlantis.io/docs/policy-checking.md index 25fd71f907..297614215e 100644 --- a/runatlantis.io/docs/policy-checking.md +++ b/runatlantis.io/docs/policy-checking.md @@ -17,10 +17,6 @@ Enabling "policy checking" in addition to the [mergeable apply requirement](http ![Policy Check Apply Status Failure](./images/policy-check-apply-status-failure.png) -:::warning -Without the mergeable requirement applies will still go through in the event of a policy failure. -::: - Any failures need to either be addressed in a successive commit, or approved by a blessed owner. This approval is independent of the approval apply requirement which can coexist in the policy checking workflow. After an approval, the apply can proceed. ![Policy Check Approval](./images/policy-check-approval.png) diff --git a/server/events/apply_command_runner.go b/server/events/apply_command_runner.go index 2ccc75bf0f..7327c326dc 100644 --- a/server/events/apply_command_runner.go +++ b/server/events/apply_command_runner.go @@ -93,13 +93,6 @@ func (a *ApplyCommandRunner) Run(ctx *CommandContext, cmd *CommentCommand) { ctx.Log.Warn("unable to get mergeable status: %s. Continuing with mergeable assumed false", err) } - // TODO: This needs to be revisited and new PullMergeable like conditions should - // be added to check against it. - if a.anyFailedPolicyChecks(pull) { - ctx.PullMergeable = false - ctx.Log.Warn("when using policy checks all policies have to be approved or pass. Continuing with mergeable assumed false") - } - ctx.Log.Info("pull request mergeable status: %t", ctx.PullMergeable) if err = a.commitStatusUpdater.UpdateCombined(baseRepo, pull, models.PendingCommitStatus, cmd.CommandName()); err != nil { @@ -182,16 +175,6 @@ func (a *ApplyCommandRunner) updateCommitStatus(ctx *CommandContext, pullStatus } } -func (a *ApplyCommandRunner) anyFailedPolicyChecks(pull models.PullRequest) bool { - policyCheckPullStatus, _ := a.DB.GetPullStatus(pull) - if policyCheckPullStatus != nil && policyCheckPullStatus.StatusCount(models.ErroredPolicyCheckStatus) > 0 { - return true - } - - return false - -} - // applyAllDisabledComment is posted when apply all commands (i.e. "atlantis apply") // are disabled and an apply all command is issued. var applyAllDisabledComment = "**Error:** Running `atlantis apply` without flags is disabled." + diff --git a/server/events/command_context.go b/server/events/command_context.go index de48295dd0..a4d6ebb13a 100644 --- a/server/events/command_context.go +++ b/server/events/command_context.go @@ -46,5 +46,7 @@ type CommandContext struct { // required the Atlantis status to be successful prior to merging. PullMergeable bool + PullStatus *models.PullStatus + Trigger CommandTrigger } diff --git a/server/events/command_runner.go b/server/events/command_runner.go index a851b85cbf..1167b85c71 100644 --- a/server/events/command_runner.go +++ b/server/events/command_runner.go @@ -113,6 +113,7 @@ type DefaultCommandRunner struct { CommentCommandRunnerByCmd map[models.CommandName]CommentCommandRunner Drainer *Drainer PreWorkflowHooksCommandRunner PreWorkflowHooksCommandRunner + PullStatusFetcher PullStatusFetcher } // RunAutoplanCommand runs plan and policy_checks when a pull request is opened or updated. @@ -127,12 +128,19 @@ func (c *DefaultCommandRunner) RunAutoplanCommand(baseRepo models.Repo, headRepo log := c.buildLogger(baseRepo.FullName, pull.Num) defer c.logPanics(baseRepo, pull.Num, log) + status, err := c.PullStatusFetcher.GetPullStatus(pull) + + if err != nil { + log.Err("Unable to fetch pull status, this is likely a bug.", err) + } + ctx := &CommandContext{ - User: user, - Log: log, - Pull: pull, - HeadRepo: headRepo, - Trigger: Auto, + User: user, + Log: log, + Pull: pull, + HeadRepo: headRepo, + PullStatus: status, + Trigger: Auto, } if !c.validateCtxAndComment(ctx) { return @@ -141,7 +149,7 @@ func (c *DefaultCommandRunner) RunAutoplanCommand(baseRepo models.Repo, headRepo return } - err := c.PreWorkflowHooksCommandRunner.RunPreHooks(ctx) + err = c.PreWorkflowHooksCommandRunner.RunPreHooks(ctx) if err != nil { ctx.Log.Err("Error running pre-workflow hooks %s. Proceeding with %s command.", err, models.PlanCommand) @@ -174,12 +182,19 @@ func (c *DefaultCommandRunner) RunCommentCommand(baseRepo models.Repo, maybeHead return } + status, err := c.PullStatusFetcher.GetPullStatus(pull) + + if err != nil { + log.Err("Unable to fetch pull status, this is likely a bug.", err) + } + ctx := &CommandContext{ - User: user, - Log: log, - Pull: pull, - HeadRepo: headRepo, - Trigger: Comment, + User: user, + Log: log, + Pull: pull, + PullStatus: status, + HeadRepo: headRepo, + Trigger: Comment, } if !c.validateCtxAndComment(ctx) { diff --git a/server/events/command_runner_test.go b/server/events/command_runner_test.go index 15d97be5ff..cf53479c98 100644 --- a/server/events/command_runner_test.go +++ b/server/events/command_runner_test.go @@ -123,6 +123,7 @@ func setup(t *testing.T) *vcsmocks.MockClient { policyCheckCommandRunner, autoMerger, parallelPoolSize, + defaultBoltDB, ) applyCommandRunner = events.NewApplyCommandRunner( @@ -175,6 +176,7 @@ func setup(t *testing.T) *vcsmocks.MockClient { AllowForkPRsFlag: "allow-fork-prs-flag", Drainer: drainer, PreWorkflowHooksCommandRunner: preWorkflowHooksCommandRunner, + PullStatusFetcher: defaultBoltDB, } return vcsClient } @@ -531,16 +533,14 @@ func TestApplyMergeablityWhenPolicyCheckFails(t *testing.T) { When(ch.VCSClient.PullIsMergeable(fixtures.GithubRepo, modelPull)).ThenReturn(true, nil) When(projectCommandBuilder.BuildApplyCommands(matchers.AnyPtrToEventsCommandContext(), matchers.AnyPtrToEventsCommentCommand())).Then(func(args []Param) ReturnValues { - ctx := args[0].(*events.CommandContext) - Equals(t, false, ctx.PullMergeable) - return ReturnValues{ []models.ProjectCommandContext{ { - CommandName: models.ApplyCommand, - ProjectName: "default", - Workspace: "default", - RepoRelDir: ".", + CommandName: models.ApplyCommand, + ProjectName: "default", + Workspace: "default", + RepoRelDir: ".", + ProjectPlanStatus: models.ErroredPolicyCheckStatus, }, }, nil, diff --git a/server/events/comment_parser.go b/server/events/comment_parser.go index b0c7f58c72..4613150236 100644 --- a/server/events/comment_parser.go +++ b/server/events/comment_parser.go @@ -57,6 +57,8 @@ type CommentParsing interface { Parse(comment string, vcsHost models.VCSHostType) CommentParseResult } +//go:generate pegomock generate -m --use-experimental-model-gen --package mocks -o mocks/mock_comment_building.go CommentBuilder + // CommentBuilder builds comment commands that can be used on pull requests. type CommentBuilder interface { // BuildPlanComment builds a plan comment for the specified args. diff --git a/server/events/mocks/matchers/events_commentparseresult.go b/server/events/mocks/matchers/events_commentparseresult.go index bcdd017764..194da76f3f 100644 --- a/server/events/mocks/matchers/events_commentparseresult.go +++ b/server/events/mocks/matchers/events_commentparseresult.go @@ -3,8 +3,9 @@ package matchers import ( "github.com/petergtz/pegomock" - events "github.com/runatlantis/atlantis/server/events" "reflect" + + events "github.com/runatlantis/atlantis/server/events" ) func AnyEventsCommentParseResult() events.CommentParseResult { @@ -18,3 +19,15 @@ func EqEventsCommentParseResult(value events.CommentParseResult) events.CommentP var nullValue events.CommentParseResult return nullValue } + +func NotEqEventsCommentParseResult(value events.CommentParseResult) events.CommentParseResult { + pegomock.RegisterMatcher(&pegomock.NotEqMatcher{Value: value}) + var nullValue events.CommentParseResult + return nullValue +} + +func EventsCommentParseResultThat(matcher pegomock.ArgumentMatcher) events.CommentParseResult { + pegomock.RegisterMatcher(matcher) + var nullValue events.CommentParseResult + return nullValue +} diff --git a/server/events/mocks/matchers/models_vcshosttype.go b/server/events/mocks/matchers/models_vcshosttype.go index f2fe24c138..a54447f7de 100644 --- a/server/events/mocks/matchers/models_vcshosttype.go +++ b/server/events/mocks/matchers/models_vcshosttype.go @@ -2,8 +2,9 @@ package matchers import ( - "reflect" "github.com/petergtz/pegomock" + "reflect" + models "github.com/runatlantis/atlantis/server/events/models" ) @@ -18,3 +19,15 @@ func EqModelsVCSHostType(value models.VCSHostType) models.VCSHostType { var nullValue models.VCSHostType return nullValue } + +func NotEqModelsVCSHostType(value models.VCSHostType) models.VCSHostType { + pegomock.RegisterMatcher(&pegomock.NotEqMatcher{Value: value}) + var nullValue models.VCSHostType + return nullValue +} + +func ModelsVCSHostTypeThat(matcher pegomock.ArgumentMatcher) models.VCSHostType { + pegomock.RegisterMatcher(matcher) + var nullValue models.VCSHostType + return nullValue +} diff --git a/server/events/mocks/matchers/slice_of_string.go b/server/events/mocks/matchers/slice_of_string.go index 96f9b24ae2..f9281819dd 100644 --- a/server/events/mocks/matchers/slice_of_string.go +++ b/server/events/mocks/matchers/slice_of_string.go @@ -2,9 +2,8 @@ package matchers import ( - "reflect" "github.com/petergtz/pegomock" - + "reflect" ) func AnySliceOfString() []string { @@ -18,3 +17,15 @@ func EqSliceOfString(value []string) []string { var nullValue []string return nullValue } + +func NotEqSliceOfString(value []string) []string { + pegomock.RegisterMatcher(&pegomock.NotEqMatcher{Value: value}) + var nullValue []string + return nullValue +} + +func SliceOfStringThat(matcher pegomock.ArgumentMatcher) []string { + pegomock.RegisterMatcher(matcher) + var nullValue []string + return nullValue +} diff --git a/server/events/mocks/mock_comment_building.go b/server/events/mocks/mock_comment_building.go new file mode 100644 index 0000000000..2d3fbbbcaa --- /dev/null +++ b/server/events/mocks/mock_comment_building.go @@ -0,0 +1,166 @@ +// Code generated by pegomock. DO NOT EDIT. +// Source: github.com/runatlantis/atlantis/server/events (interfaces: CommentBuilder) + +package mocks + +import ( + pegomock "github.com/petergtz/pegomock" + "reflect" + "time" +) + +type MockCommentBuilder struct { + fail func(message string, callerSkip ...int) +} + +func NewMockCommentBuilder(options ...pegomock.Option) *MockCommentBuilder { + mock := &MockCommentBuilder{} + for _, option := range options { + option.Apply(mock) + } + return mock +} + +func (mock *MockCommentBuilder) SetFailHandler(fh pegomock.FailHandler) { mock.fail = fh } +func (mock *MockCommentBuilder) FailHandler() pegomock.FailHandler { return mock.fail } + +func (mock *MockCommentBuilder) BuildPlanComment(repoRelDir string, workspace string, project string, commentArgs []string) string { + if mock == nil { + panic("mock must not be nil. Use myMock := NewMockCommentBuilder().") + } + params := []pegomock.Param{repoRelDir, workspace, project, commentArgs} + result := pegomock.GetGenericMockFrom(mock).Invoke("BuildPlanComment", params, []reflect.Type{reflect.TypeOf((*string)(nil)).Elem()}) + var ret0 string + if len(result) != 0 { + if result[0] != nil { + ret0 = result[0].(string) + } + } + return ret0 +} + +func (mock *MockCommentBuilder) BuildApplyComment(repoRelDir string, workspace string, project string) string { + if mock == nil { + panic("mock must not be nil. Use myMock := NewMockCommentBuilder().") + } + params := []pegomock.Param{repoRelDir, workspace, project} + result := pegomock.GetGenericMockFrom(mock).Invoke("BuildApplyComment", params, []reflect.Type{reflect.TypeOf((*string)(nil)).Elem()}) + var ret0 string + if len(result) != 0 { + if result[0] != nil { + ret0 = result[0].(string) + } + } + return ret0 +} + +func (mock *MockCommentBuilder) VerifyWasCalledOnce() *VerifierMockCommentBuilder { + return &VerifierMockCommentBuilder{ + mock: mock, + invocationCountMatcher: pegomock.Times(1), + } +} + +func (mock *MockCommentBuilder) VerifyWasCalled(invocationCountMatcher pegomock.InvocationCountMatcher) *VerifierMockCommentBuilder { + return &VerifierMockCommentBuilder{ + mock: mock, + invocationCountMatcher: invocationCountMatcher, + } +} + +func (mock *MockCommentBuilder) VerifyWasCalledInOrder(invocationCountMatcher pegomock.InvocationCountMatcher, inOrderContext *pegomock.InOrderContext) *VerifierMockCommentBuilder { + return &VerifierMockCommentBuilder{ + mock: mock, + invocationCountMatcher: invocationCountMatcher, + inOrderContext: inOrderContext, + } +} + +func (mock *MockCommentBuilder) VerifyWasCalledEventually(invocationCountMatcher pegomock.InvocationCountMatcher, timeout time.Duration) *VerifierMockCommentBuilder { + return &VerifierMockCommentBuilder{ + mock: mock, + invocationCountMatcher: invocationCountMatcher, + timeout: timeout, + } +} + +type VerifierMockCommentBuilder struct { + mock *MockCommentBuilder + invocationCountMatcher pegomock.InvocationCountMatcher + inOrderContext *pegomock.InOrderContext + timeout time.Duration +} + +func (verifier *VerifierMockCommentBuilder) BuildPlanComment(repoRelDir string, workspace string, project string, commentArgs []string) *MockCommentBuilder_BuildPlanComment_OngoingVerification { + params := []pegomock.Param{repoRelDir, workspace, project, commentArgs} + methodInvocations := pegomock.GetGenericMockFrom(verifier.mock).Verify(verifier.inOrderContext, verifier.invocationCountMatcher, "BuildPlanComment", params, verifier.timeout) + return &MockCommentBuilder_BuildPlanComment_OngoingVerification{mock: verifier.mock, methodInvocations: methodInvocations} +} + +type MockCommentBuilder_BuildPlanComment_OngoingVerification struct { + mock *MockCommentBuilder + methodInvocations []pegomock.MethodInvocation +} + +func (c *MockCommentBuilder_BuildPlanComment_OngoingVerification) GetCapturedArguments() (string, string, string, []string) { + repoRelDir, workspace, project, commentArgs := c.GetAllCapturedArguments() + return repoRelDir[len(repoRelDir)-1], workspace[len(workspace)-1], project[len(project)-1], commentArgs[len(commentArgs)-1] +} + +func (c *MockCommentBuilder_BuildPlanComment_OngoingVerification) GetAllCapturedArguments() (_param0 []string, _param1 []string, _param2 []string, _param3 [][]string) { + params := pegomock.GetGenericMockFrom(c.mock).GetInvocationParams(c.methodInvocations) + if len(params) > 0 { + _param0 = make([]string, len(c.methodInvocations)) + for u, param := range params[0] { + _param0[u] = param.(string) + } + _param1 = make([]string, len(c.methodInvocations)) + for u, param := range params[1] { + _param1[u] = param.(string) + } + _param2 = make([]string, len(c.methodInvocations)) + for u, param := range params[2] { + _param2[u] = param.(string) + } + _param3 = make([][]string, len(c.methodInvocations)) + for u, param := range params[3] { + _param3[u] = param.([]string) + } + } + return +} + +func (verifier *VerifierMockCommentBuilder) BuildApplyComment(repoRelDir string, workspace string, project string) *MockCommentBuilder_BuildApplyComment_OngoingVerification { + params := []pegomock.Param{repoRelDir, workspace, project} + methodInvocations := pegomock.GetGenericMockFrom(verifier.mock).Verify(verifier.inOrderContext, verifier.invocationCountMatcher, "BuildApplyComment", params, verifier.timeout) + return &MockCommentBuilder_BuildApplyComment_OngoingVerification{mock: verifier.mock, methodInvocations: methodInvocations} +} + +type MockCommentBuilder_BuildApplyComment_OngoingVerification struct { + mock *MockCommentBuilder + methodInvocations []pegomock.MethodInvocation +} + +func (c *MockCommentBuilder_BuildApplyComment_OngoingVerification) GetCapturedArguments() (string, string, string) { + repoRelDir, workspace, project := c.GetAllCapturedArguments() + return repoRelDir[len(repoRelDir)-1], workspace[len(workspace)-1], project[len(project)-1] +} + +func (c *MockCommentBuilder_BuildApplyComment_OngoingVerification) GetAllCapturedArguments() (_param0 []string, _param1 []string, _param2 []string) { + params := pegomock.GetGenericMockFrom(c.mock).GetInvocationParams(c.methodInvocations) + if len(params) > 0 { + _param0 = make([]string, len(c.methodInvocations)) + for u, param := range params[0] { + _param0[u] = param.(string) + } + _param1 = make([]string, len(c.methodInvocations)) + for u, param := range params[1] { + _param1[u] = param.(string) + } + _param2 = make([]string, len(c.methodInvocations)) + for u, param := range params[2] { + _param2[u] = param.(string) + } + } + return +} diff --git a/server/events/mocks/mock_comment_parsing.go b/server/events/mocks/mock_comment_parsing.go index 24e4281ff4..f92f3abaad 100644 --- a/server/events/mocks/mock_comment_parsing.go +++ b/server/events/mocks/mock_comment_parsing.go @@ -4,12 +4,11 @@ package mocks import ( - "reflect" - "time" - pegomock "github.com/petergtz/pegomock" events "github.com/runatlantis/atlantis/server/events" models "github.com/runatlantis/atlantis/server/events/models" + "reflect" + "time" ) type MockCommentParsing struct { @@ -49,14 +48,14 @@ func (mock *MockCommentParsing) VerifyWasCalledOnce() *VerifierMockCommentParsin } } -func (mock *MockCommentParsing) VerifyWasCalled(invocationCountMatcher pegomock.Matcher) *VerifierMockCommentParsing { +func (mock *MockCommentParsing) VerifyWasCalled(invocationCountMatcher pegomock.InvocationCountMatcher) *VerifierMockCommentParsing { return &VerifierMockCommentParsing{ mock: mock, invocationCountMatcher: invocationCountMatcher, } } -func (mock *MockCommentParsing) VerifyWasCalledInOrder(invocationCountMatcher pegomock.Matcher, inOrderContext *pegomock.InOrderContext) *VerifierMockCommentParsing { +func (mock *MockCommentParsing) VerifyWasCalledInOrder(invocationCountMatcher pegomock.InvocationCountMatcher, inOrderContext *pegomock.InOrderContext) *VerifierMockCommentParsing { return &VerifierMockCommentParsing{ mock: mock, invocationCountMatcher: invocationCountMatcher, @@ -64,7 +63,7 @@ func (mock *MockCommentParsing) VerifyWasCalledInOrder(invocationCountMatcher pe } } -func (mock *MockCommentParsing) VerifyWasCalledEventually(invocationCountMatcher pegomock.Matcher, timeout time.Duration) *VerifierMockCommentParsing { +func (mock *MockCommentParsing) VerifyWasCalledEventually(invocationCountMatcher pegomock.InvocationCountMatcher, timeout time.Duration) *VerifierMockCommentParsing { return &VerifierMockCommentParsing{ mock: mock, invocationCountMatcher: invocationCountMatcher, @@ -74,7 +73,7 @@ func (mock *MockCommentParsing) VerifyWasCalledEventually(invocationCountMatcher type VerifierMockCommentParsing struct { mock *MockCommentParsing - invocationCountMatcher pegomock.Matcher + invocationCountMatcher pegomock.InvocationCountMatcher inOrderContext *pegomock.InOrderContext timeout time.Duration } diff --git a/server/events/models/models.go b/server/events/models/models.go index 4e449a3643..215d42540d 100644 --- a/server/events/models/models.go +++ b/server/events/models/models.go @@ -358,6 +358,8 @@ type ProjectCommandContext struct { Log logging.SimpleLogging // PullMergeable is true if the pull request for this project is able to be merged. PullMergeable bool + // CurrentProjectPlanStatus is the status of the current project prior to this command. + ProjectPlanStatus ProjectPlanStatus // Pull is the pull request we're responding to. Pull PullRequest // ProjectName is the name of the project set in atlantis.yaml. If there was diff --git a/server/events/plan_command_runner.go b/server/events/plan_command_runner.go index ae7c3d167e..c0547a5cc7 100644 --- a/server/events/plan_command_runner.go +++ b/server/events/plan_command_runner.go @@ -18,6 +18,7 @@ func NewPlanCommandRunner( policyCheckCommandRunner *PolicyCheckCommandRunner, autoMerger *AutoMerger, parallelPoolSize int, + pullStatusFetcher PullStatusFetcher, ) *PlanCommandRunner { return &PlanCommandRunner{ silenceVCSStatusNoPlans: silenceVCSStatusNoPlans, @@ -32,6 +33,7 @@ func NewPlanCommandRunner( policyCheckCommandRunner: policyCheckCommandRunner, autoMerger: autoMerger, parallelPoolSize: parallelPoolSize, + pullStatusFetcher: pullStatusFetcher, } } @@ -50,6 +52,7 @@ type PlanCommandRunner struct { policyCheckCommandRunner *PolicyCheckCommandRunner autoMerger *AutoMerger parallelPoolSize int + pullStatusFetcher PullStatusFetcher } func (p *PlanCommandRunner) runAutoplan(ctx *CommandContext) { @@ -121,6 +124,13 @@ func (p *PlanCommandRunner) runAutoplan(ctx *CommandContext) { !(result.HasErrors() || result.PlansDeleted) { // Run policy_check command ctx.Log.Info("Running policy_checks for all plans") + + // refresh ctx's view of pull status since we just wrote to it. + // realistically each command should refresh this at the start, + // however, policy checking is weird since it's called within the plan command itself + // we need to better structure how this command works. + ctx.PullStatus = &pullStatus + p.policyCheckCommandRunner.Run(ctx, policyCheckCmds) } } diff --git a/server/events/project_command_context_builder.go b/server/events/project_command_context_builder.go index 40919264cd..13b43c9a19 100644 --- a/server/events/project_command_context_builder.go +++ b/server/events/project_command_context_builder.go @@ -147,6 +147,25 @@ func newProjectCommandContext(ctx *CommandContext, parallelPlanEnabled bool, verbose bool, ) models.ProjectCommandContext { + + var projectPlanStatus models.ProjectPlanStatus + + if ctx.PullStatus != nil { + for _, project := range ctx.PullStatus.Projects { + + // if name is not used, let's match the directory + if projCfg.Name == "" && project.RepoRelDir == projCfg.RepoRelDir { + projectPlanStatus = project.Status + break + } + + if projCfg.Name != "" && project.ProjectName == projCfg.Name { + projectPlanStatus = project.Status + break + } + } + } + return models.ProjectCommandContext{ CommandName: cmd, ApplyCmd: applyCmd, @@ -160,6 +179,7 @@ func newProjectCommandContext(ctx *CommandContext, HeadRepo: ctx.HeadRepo, Log: ctx.Log, PullMergeable: ctx.PullMergeable, + ProjectPlanStatus: projectPlanStatus, Pull: ctx.Pull, ProjectName: projCfg.Name, ApplyRequirements: projCfg.ApplyRequirements, diff --git a/server/events/project_command_context_builder_test.go b/server/events/project_command_context_builder_test.go index 79457f0dd2..c53408650d 100644 --- a/server/events/project_command_context_builder_test.go +++ b/server/events/project_command_context_builder_test.go @@ -1 +1,84 @@ package events_test + +import ( + "testing" + + . "github.com/petergtz/pegomock" + "github.com/runatlantis/atlantis/server/events" + "github.com/runatlantis/atlantis/server/events/mocks" + "github.com/runatlantis/atlantis/server/events/models" + "github.com/runatlantis/atlantis/server/events/yaml/valid" + "github.com/runatlantis/atlantis/server/logging" + "github.com/stretchr/testify/assert" +) + +func TestProjectCommandContextBuilder_PullStatus(t *testing.T) { + + mockCommentBuilder := mocks.NewMockCommentBuilder() + subject := events.DefaultProjectCommandContextBuilder{ + CommentBuilder: mockCommentBuilder, + } + + projRepoRelDir := "dir1" + projWorkspace := "default" + projName := "project1" + + projCfg := valid.MergedProjectCfg{ + RepoRelDir: projRepoRelDir, + Workspace: projWorkspace, + Name: projName, + Workflow: valid.Workflow{ + Name: valid.DefaultWorkflowName, + Apply: valid.DefaultApplyStage, + }, + } + + pullStatus := &models.PullStatus{ + Projects: []models.ProjectStatus{}, + } + + commandCtx := &events.CommandContext{ + Log: logging.NewNoopLogger(t), + PullStatus: pullStatus, + } + + expectedApplyCmt := "Apply Comment" + expectedPlanCmt := "Plan Comment" + + t.Run("with project name defined", func(t *testing.T) { + When(mockCommentBuilder.BuildPlanComment(projRepoRelDir, projWorkspace, projName, []string{})).ThenReturn(expectedPlanCmt) + When(mockCommentBuilder.BuildApplyComment(projRepoRelDir, projWorkspace, projName)).ThenReturn(expectedApplyCmt) + + pullStatus.Projects = []models.ProjectStatus{ + { + Status: models.ErroredPolicyCheckStatus, + ProjectName: "project1", + RepoRelDir: "dir1", + }, + } + + result := subject.BuildProjectContext(commandCtx, models.PlanCommand, projCfg, []string{}, "some/dir", false, false, false, false) + + assert.Equal(t, models.ErroredPolicyCheckStatus, result[0].ProjectPlanStatus) + }) + + t.Run("with no project name defined", func(t *testing.T) { + projCfg.Name = "" + When(mockCommentBuilder.BuildPlanComment(projRepoRelDir, projWorkspace, "", []string{})).ThenReturn(expectedPlanCmt) + When(mockCommentBuilder.BuildApplyComment(projRepoRelDir, projWorkspace, "")).ThenReturn(expectedApplyCmt) + pullStatus.Projects = []models.ProjectStatus{ + { + Status: models.ErroredPlanStatus, + RepoRelDir: "dir2", + }, + { + Status: models.ErroredPolicyCheckStatus, + RepoRelDir: "dir1", + }, + } + + result := subject.BuildProjectContext(commandCtx, models.PlanCommand, projCfg, []string{}, "some/dir", false, false, false, false) + + assert.Equal(t, models.ErroredPolicyCheckStatus, result[0].ProjectPlanStatus) + }) +} diff --git a/server/events/project_command_runner.go b/server/events/project_command_runner.go index 3d3d72a832..496b995578 100644 --- a/server/events/project_command_runner.go +++ b/server/events/project_command_runner.go @@ -333,6 +333,11 @@ func (p *DefaultProjectCommandRunner) doApply(ctx models.ProjectCommandContext) if !approved { return "", "Pull request must be approved by at least one person other than the author before running apply.", nil } + // this should come before mergeability check since mergeability is a superset of this check. + case valid.PoliciesPassedApplyReq: + if ctx.ProjectPlanStatus == models.ErroredPolicyCheckStatus { + return "", "All policies must pass for project before running apply", nil + } case raw.MergeableApplyRequirement: if !ctx.PullMergeable { return "", "Pull request must be mergeable before running apply.", nil diff --git a/server/events/pull_status_fetcher.go b/server/events/pull_status_fetcher.go new file mode 100644 index 0000000000..126fed720e --- /dev/null +++ b/server/events/pull_status_fetcher.go @@ -0,0 +1,8 @@ +package events + +import "github.com/runatlantis/atlantis/server/events/models" + +// PullStatusFetcher fetches our internal model of a pull requests status +type PullStatusFetcher interface { + GetPullStatus(pull models.PullRequest) (*models.PullStatus, error) +} diff --git a/server/events/yaml/parser_validator_test.go b/server/events/yaml/parser_validator_test.go index 8968c92c70..21ffe793de 100644 --- a/server/events/yaml/parser_validator_test.go +++ b/server/events/yaml/parser_validator_test.go @@ -1191,8 +1191,7 @@ repos: Repos: []valid.Repo{ defaultCfg.Repos[0], { - IDRegex: regexp.MustCompile("github.com/"), - PreWorkflowHooks: []*valid.PreWorkflowHook{}, + IDRegex: regexp.MustCompile("github.com/"), }, }, Workflows: map[string]valid.Workflow{ @@ -1210,9 +1209,8 @@ repos: Repos: []valid.Repo{ defaultCfg.Repos[0], { - ID: "github.com/owner/repo", - PreWorkflowHooks: []*valid.PreWorkflowHook{}, - Workflow: defaultCfg.Repos[0].Workflow, + ID: "github.com/owner/repo", + Workflow: defaultCfg.Repos[0].Workflow, }, }, Workflows: map[string]valid.Workflow{ @@ -1237,7 +1235,6 @@ workflows: { IDRegex: regexp.MustCompile(".*"), BranchRegex: regexp.MustCompile(".*"), - PreWorkflowHooks: []*valid.PreWorkflowHook{}, ApplyRequirements: []string{}, Workflow: &valid.Workflow{ Name: "default", @@ -1430,7 +1427,6 @@ func TestParserValidator_ParseGlobalCfgJSON(t *testing.T) { { IDRegex: regexp.MustCompile(".*"), ApplyRequirements: []string{"mergeable", "approved"}, - PreWorkflowHooks: []*valid.PreWorkflowHook{}, Workflow: &customWorkflow, AllowedWorkflows: []string{"custom"}, AllowedOverrides: []string{"workflow", "apply_requirements"}, @@ -1439,7 +1435,6 @@ func TestParserValidator_ParseGlobalCfgJSON(t *testing.T) { { ID: "github.com/owner/repo", IDRegex: nil, - PreWorkflowHooks: []*valid.PreWorkflowHook{}, ApplyRequirements: nil, AllowedOverrides: nil, AllowCustomWorkflows: nil, diff --git a/server/events/yaml/raw/global_cfg.go b/server/events/yaml/raw/global_cfg.go index b48111505a..f0fefe84e8 100644 --- a/server/events/yaml/raw/global_cfg.go +++ b/server/events/yaml/raw/global_cfg.go @@ -86,6 +86,20 @@ func (g GlobalCfg) Validate() error { func (g GlobalCfg) ToValid(defaultCfg valid.GlobalCfg) valid.GlobalCfg { workflows := make(map[string]valid.Workflow) + + // assumes: globalcfg is always initialized with one repo .* + applyReqs := defaultCfg.Repos[0].ApplyRequirements + + var globalApplyReqs []string + + for _, req := range applyReqs { + for _, nonOverrideableReq := range valid.NonOverrideableApplyReqs { + if req == nonOverrideableReq { + globalApplyReqs = append(globalApplyReqs, req) + } + } + } + for k, v := range g.Workflows { validatedWorkflow := v.ToValid(k) workflows[k] = validatedWorkflow @@ -105,7 +119,7 @@ func (g GlobalCfg) ToValid(defaultCfg valid.GlobalCfg) valid.GlobalCfg { var repos []valid.Repo for _, r := range g.Repos { - repos = append(repos, r.ToValid(workflows)) + repos = append(repos, r.ToValid(workflows, globalApplyReqs)) } repos = append(defaultCfg.Repos, repos...) @@ -171,7 +185,7 @@ func (r Repo) Validate() error { ) } -func (r Repo) ToValid(workflows map[string]valid.Workflow) valid.Repo { +func (r Repo) ToValid(workflows map[string]valid.Workflow, globalApplyReqs []string) valid.Repo { var id string var idRegex *regexp.Regexp if r.HasRegexID() { @@ -197,18 +211,33 @@ func (r Repo) ToValid(workflows map[string]valid.Workflow) valid.Repo { workflow = &ptr } - preWorkflowHooks := make([]*valid.PreWorkflowHook, 0) + var preWorkflowHooks []*valid.PreWorkflowHook if len(r.PreWorkflowHooks) > 0 { for _, hook := range r.PreWorkflowHooks { preWorkflowHooks = append(preWorkflowHooks, hook.ToValid()) } } + var mergedApplyReqs []string + + mergedApplyReqs = append(mergedApplyReqs, r.ApplyRequirements...) + + // only add global reqs if they don't exist already. +OUTER: + for _, globalReq := range globalApplyReqs { + for _, currReq := range r.ApplyRequirements { + if globalReq == currReq { + continue OUTER + } + } + mergedApplyReqs = append(mergedApplyReqs, globalReq) + } + return valid.Repo{ ID: id, IDRegex: idRegex, BranchRegex: branchRegex, - ApplyRequirements: r.ApplyRequirements, + ApplyRequirements: mergedApplyReqs, PreWorkflowHooks: preWorkflowHooks, Workflow: workflow, AllowedWorkflows: r.AllowedWorkflows, diff --git a/server/events/yaml/valid/global_cfg.go b/server/events/yaml/valid/global_cfg.go index fe6af76f82..f91ac4671d 100644 --- a/server/events/yaml/valid/global_cfg.go +++ b/server/events/yaml/valid/global_cfg.go @@ -11,6 +11,7 @@ import ( const MergeableApplyReq = "mergeable" const ApprovedApplyReq = "approved" +const PoliciesPassedApplyReq = "policies_passed" const ApplyRequirementsKey = "apply_requirements" const PreWorkflowHooksKey = "pre_workflow_hooks" const WorkflowKey = "workflow" @@ -19,6 +20,13 @@ const AllowedOverridesKey = "allowed_overrides" const AllowCustomWorkflowsKey = "allow_custom_workflows" const DefaultWorkflowName = "default" +// NonOverrideableApplyReqs will get applied across all "repos" in the server side config. +// If repo config is allowed overrides, they can override this. +// TODO: Make this more customizable, not everyone wants this rigid workflow +// maybe something along the lines of defining overridable/non-overrideable apply +// requirements in the config and removing the flag to enable policy checking. +var NonOverrideableApplyReqs []string = []string{PoliciesPassedApplyReq} + // GlobalCfg is the final parsed version of server-side repo config. type GlobalCfg struct { Repos []Repo @@ -95,7 +103,40 @@ var DefaultPlanStage = Stage{ }, } +// Deprecated: use NewGlobalCfgFromArgs func NewGlobalCfgWithHooks(allowRepoCfg bool, mergeableReq bool, approvedReq bool, preWorkflowHooks []*PreWorkflowHook) GlobalCfg { + return NewGlobalCfgFromArgs(GlobalCfgArgs{ + AllowRepoCfg: allowRepoCfg, + MergeableReq: mergeableReq, + ApprovedReq: approvedReq, + PreWorkflowHooks: preWorkflowHooks, + }) +} + +// NewGlobalCfg returns a global config that respects the parameters. +// allowRepoCfg is true if users want to allow repos full config functionality. +// mergeableReq is true if users want to set the mergeable apply requirement +// for all repos. +// approvedReq is true if users want to set the approved apply requirement +// for all repos. +// Deprecated: use NewGlobalCfgFromArgs +func NewGlobalCfg(allowRepoCfg bool, mergeableReq bool, approvedReq bool) GlobalCfg { + return NewGlobalCfgFromArgs(GlobalCfgArgs{ + AllowRepoCfg: allowRepoCfg, + MergeableReq: mergeableReq, + ApprovedReq: approvedReq, + }) +} + +type GlobalCfgArgs struct { + AllowRepoCfg bool + MergeableReq bool + ApprovedReq bool + PolicyCheckEnabled bool + PreWorkflowHooks []*PreWorkflowHook +} + +func NewGlobalCfgFromArgs(args GlobalCfgArgs) GlobalCfg { defaultWorkflow := Workflow{ Name: DefaultWorkflowName, Apply: DefaultApplyStage, @@ -107,15 +148,19 @@ func NewGlobalCfgWithHooks(allowRepoCfg bool, mergeableReq bool, approvedReq boo applyReqs := []string{} allowedOverrides := []string{} allowedWorkflows := []string{} - if mergeableReq { + if args.MergeableReq { applyReqs = append(applyReqs, MergeableApplyReq) } - if approvedReq { + if args.ApprovedReq { applyReqs = append(applyReqs, ApprovedApplyReq) } + if args.PolicyCheckEnabled { + applyReqs = append(applyReqs, PoliciesPassedApplyReq) + } + allowCustomWorkflows := false - if allowRepoCfg { + if args.AllowRepoCfg { allowedOverrides = []string{ApplyRequirementsKey, WorkflowKey} allowCustomWorkflows = true } @@ -126,7 +171,7 @@ func NewGlobalCfgWithHooks(allowRepoCfg bool, mergeableReq bool, approvedReq boo IDRegex: regexp.MustCompile(".*"), BranchRegex: regexp.MustCompile(".*"), ApplyRequirements: applyReqs, - PreWorkflowHooks: preWorkflowHooks, + PreWorkflowHooks: args.PreWorkflowHooks, Workflow: &defaultWorkflow, AllowedWorkflows: allowedWorkflows, AllowedOverrides: allowedOverrides, @@ -139,19 +184,6 @@ func NewGlobalCfgWithHooks(allowRepoCfg bool, mergeableReq bool, approvedReq boo } } -// NewGlobalCfg returns a global config that respects the parameters. -// allowRepoCfg is true if users want to allow repos full config functionality. -// mergeableReq is true if users want to set the mergeable apply requirement -// for all repos. -// approvedReq is true if users want to set the approved apply requirement -// for all repos. - -func NewGlobalCfg(allowRepoCfg bool, mergeableReq bool, approvedReq bool) GlobalCfg { - preWorkflowHooks := make([]*PreWorkflowHook, 0) - - return NewGlobalCfgWithHooks(allowRepoCfg, mergeableReq, approvedReq, preWorkflowHooks) -} - // IDMatches returns true if the repo ID otherID matches this config. func (r Repo) IDMatches(otherID string) bool { if r.ID != "" { diff --git a/server/events/yaml/valid/global_cfg_test.go b/server/events/yaml/valid/global_cfg_test.go index 95d04358d1..66628de9bb 100644 --- a/server/events/yaml/valid/global_cfg_test.go +++ b/server/events/yaml/valid/global_cfg_test.go @@ -121,9 +121,6 @@ func TestNewGlobalCfg(t *testing.T) { if c.approvedReq { exp.Repos[0].ApplyRequirements = append(exp.Repos[0].ApplyRequirements, "approved") } - if exp.Repos[0].PreWorkflowHooks == nil { - exp.Repos[0].PreWorkflowHooks = []*valid.PreWorkflowHook{} - } Equals(t, exp, act) diff --git a/server/events_controller_e2e_test.go b/server/events_controller_e2e_test.go index 7ee8fd649b..b70ae21321 100644 --- a/server/events_controller_e2e_test.go +++ b/server/events_controller_e2e_test.go @@ -483,24 +483,22 @@ func TestGitHubWorkflowWithPolicyCheck(t *testing.T) { ExpReplies [][]string }{ { - Description: "failing policy approved by the owner", - RepoDir: "policy-checks", - ModifiedFiles: []string{"main.tf"}, + Description: "1 failing policy and 1 passing policy ", + RepoDir: "policy-checks-multi-projects", + ModifiedFiles: []string{"dir1/main.tf,", "dir2/main.tf"}, ExpAutoplan: true, Comments: []string{ - "atlantis approve_policies", "atlantis apply", }, ExpReplies: [][]string{ {"exp-output-autoplan.txt"}, {"exp-output-auto-policy-check.txt"}, - {"exp-output-approve-policies.txt"}, {"exp-output-apply.txt"}, {"exp-output-merge.txt"}, }, }, { - Description: "failing policy without approval", + Description: "failing policy without policies passing", RepoDir: "policy-checks", ModifiedFiles: []string{"main.tf"}, ExpAutoplan: true, @@ -514,6 +512,21 @@ func TestGitHubWorkflowWithPolicyCheck(t *testing.T) { {"exp-output-merge.txt"}, }, }, + { + Description: "failing policy additional apply requirements specified", + RepoDir: "policy-checks-apply-reqs", + ModifiedFiles: []string{"main.tf"}, + ExpAutoplan: true, + Comments: []string{ + "atlantis apply", + }, + ExpReplies: [][]string{ + {"exp-output-autoplan.txt"}, + {"exp-output-auto-policy-check.txt"}, + {"exp-output-apply-failed.txt"}, + {"exp-output-merge.txt"}, + }, + }, { Description: "failing policy approved by non owner", RepoDir: "policy-checks-diff-owner", @@ -550,6 +563,7 @@ func TestGitHubWorkflowWithPolicyCheck(t *testing.T) { // Setup test dependencies. w := httptest.NewRecorder() When(vcsClient.PullIsMergeable(AnyRepo(), matchers.AnyModelsPullRequest())).ThenReturn(true, nil) + When(vcsClient.PullIsApproved(AnyRepo(), matchers.AnyModelsPullRequest())).ThenReturn(true, nil) When(githubGetter.GetPullRequest(AnyRepo(), AnyInt())).ThenReturn(GitHubPullRequestParsed(headSHA), nil) When(vcsClient.GetModifiedFiles(AnyRepo(), matchers.AnyModelsPullRequest())).ThenReturn(c.ModifiedFiles, nil) @@ -630,13 +644,7 @@ func setupE2E(t *testing.T, repoDir string) (server.EventsController, *vcsmocks. e2eGitlabGetter := mocks.NewMockGitlabMergeRequestGetter() // Real dependencies. - logger, err := logging.NewStructuredLogger() - - if err != nil { - panic("Could not setup logger for e2e") - } - - logger.SetLevel(logging.Error) + logger := logging.NewNoopLogger(t) eventParser := &events.EventParser{ GithubUser: "github-user", @@ -666,12 +674,20 @@ func setupE2E(t *testing.T, repoDir string) (server.EventsController, *vcsmocks. defaultTFVersion := terraformClient.DefaultVersion() locker := events.NewDefaultWorkingDirLocker() parser := &yaml.ParserValidator{} - globalCfg := valid.NewGlobalCfgWithHooks(true, false, false, []*valid.PreWorkflowHook{ - { - StepName: "global_hook", - RunCommand: "some dummy command", + + globalCfgArgs := valid.GlobalCfgArgs{ + AllowRepoCfg: true, + MergeableReq: false, + ApprovedReq: false, + PreWorkflowHooks: []*valid.PreWorkflowHook{ + { + StepName: "global_hook", + RunCommand: "some dummy command", + }, }, - }) + PolicyCheckEnabled: userConfig.EnablePolicyChecksFlag, + } + globalCfg := valid.NewGlobalCfgFromArgs(globalCfgArgs) expCfgPath := filepath.Join(absRepoPath(t, repoDir), "repos.yaml") if _, err := os.Stat(expCfgPath); err == nil { globalCfg, err = parser.ParseGlobalCfg(expCfgPath, globalCfg) @@ -784,6 +800,7 @@ func setupE2E(t *testing.T, repoDir string) (server.EventsController, *vcsmocks. policyCheckCommandRunner, autoMerger, parallelPoolSize, + boltdb, ) applyCommandRunner := events.NewApplyCommandRunner( @@ -831,6 +848,7 @@ func setupE2E(t *testing.T, repoDir string) (server.EventsController, *vcsmocks. CommentCommandRunnerByCmd: commentCommandRunnerByCmd, Drainer: drainer, PreWorkflowHooksCommandRunner: preWorkflowHooksCommandRunner, + PullStatusFetcher: boltdb, } repoAllowlistChecker, err := events.NewRepoAllowlistChecker("*") diff --git a/server/server.go b/server/server.go index 23098e4c11..58da901b28 100644 --- a/server/server.go +++ b/server/server.go @@ -344,7 +344,13 @@ func NewServer(userConfig UserConfig, config Config) (*Server, error) { } validator := &yaml.ParserValidator{} - globalCfg := valid.NewGlobalCfg(userConfig.AllowRepoConfig, userConfig.RequireMergeable, userConfig.RequireApproval) + globalCfg := valid.NewGlobalCfgFromArgs( + valid.GlobalCfgArgs{ + AllowRepoCfg: userConfig.AllowRepoConfig, + MergeableReq: userConfig.RequireMergeable, + ApprovedReq: userConfig.RequireApproval, + PolicyCheckEnabled: userConfig.EnablePolicyChecksFlag, + }) if userConfig.RepoConfig != "" { globalCfg, err = validator.ParseGlobalCfg(userConfig.RepoConfig, globalCfg) if err != nil { @@ -504,6 +510,7 @@ func NewServer(userConfig UserConfig, config Config) (*Server, error) { policyCheckCommandRunner, autoMerger, userConfig.ParallelPoolSize, + boltdb, ) applyCommandRunner := events.NewApplyCommandRunner( @@ -555,6 +562,7 @@ func NewServer(userConfig UserConfig, config Config) (*Server, error) { DisableAutoplan: userConfig.DisableAutoplan, Drainer: drainer, PreWorkflowHooksCommandRunner: preWorkflowHooksCommandRunner, + PullStatusFetcher: boltdb, } repoAllowlist, err := events.NewRepoAllowlistChecker(userConfig.RepoAllowlist) if err != nil { diff --git a/server/testfixtures/test-repos/policy-checks-apply-reqs/atlantis.yaml b/server/testfixtures/test-repos/policy-checks-apply-reqs/atlantis.yaml new file mode 100644 index 0000000000..8435733cd2 --- /dev/null +++ b/server/testfixtures/test-repos/policy-checks-apply-reqs/atlantis.yaml @@ -0,0 +1,4 @@ +version: 3 +projects: +- dir: . + workspace: default diff --git a/server/testfixtures/test-repos/policy-checks-apply-reqs/exp-output-apply-failed.txt b/server/testfixtures/test-repos/policy-checks-apply-reqs/exp-output-apply-failed.txt new file mode 100644 index 0000000000..1f57a9176d --- /dev/null +++ b/server/testfixtures/test-repos/policy-checks-apply-reqs/exp-output-apply-failed.txt @@ -0,0 +1,4 @@ +Ran Apply for dir: `.` workspace: `default` + +**Apply Failed**: All policies must pass for project before running apply + diff --git a/server/testfixtures/test-repos/policy-checks-apply-reqs/exp-output-apply.txt b/server/testfixtures/test-repos/policy-checks-apply-reqs/exp-output-apply.txt new file mode 100644 index 0000000000..e6e44deb94 --- /dev/null +++ b/server/testfixtures/test-repos/policy-checks-apply-reqs/exp-output-apply.txt @@ -0,0 +1,24 @@ +Ran Apply for dir: `.` workspace: `default` + +
Show Output + +```diff +null_resource.simple: +null_resource.simple: + +Apply complete! Resources: 1 added, 0 changed, 0 destroyed. + +The state of your infrastructure has been saved to the path +below. This state is required to modify and destroy your +infrastructure, so keep it safe. To inspect the complete state +use the `terraform show` command. + +State path: terraform.tfstate + +Outputs: + +workspace = "default" + +``` +
+ diff --git a/server/testfixtures/test-repos/policy-checks-apply-reqs/exp-output-approve-policies.txt b/server/testfixtures/test-repos/policy-checks-apply-reqs/exp-output-approve-policies.txt new file mode 100644 index 0000000000..f5e100c23e --- /dev/null +++ b/server/testfixtures/test-repos/policy-checks-apply-reqs/exp-output-approve-policies.txt @@ -0,0 +1,5 @@ +Approved Policies for 1 projects: + +1. dir: `.` workspace: `default` + + diff --git a/server/testfixtures/test-repos/policy-checks-apply-reqs/exp-output-auto-policy-check.txt b/server/testfixtures/test-repos/policy-checks-apply-reqs/exp-output-auto-policy-check.txt new file mode 100644 index 0000000000..a922cceca2 --- /dev/null +++ b/server/testfixtures/test-repos/policy-checks-apply-reqs/exp-output-auto-policy-check.txt @@ -0,0 +1,15 @@ +Ran Policy Check for dir: `.` workspace: `default` + +**Policy Check Error** +``` +exit status 1 +Checking plan against the following policies: + test_policy +FAIL - - WARNING: Null Resource creation is prohibited. + +1 test, 0 passed, 0 warnings, 1 failure, 0 exceptions + +``` +* :heavy_check_mark: To **approve** failing policies either request an approval from approvers or address the failure by modifying the codebase. + + diff --git a/server/testfixtures/test-repos/policy-checks-apply-reqs/exp-output-autoplan.txt b/server/testfixtures/test-repos/policy-checks-apply-reqs/exp-output-autoplan.txt new file mode 100644 index 0000000000..d278415b40 --- /dev/null +++ b/server/testfixtures/test-repos/policy-checks-apply-reqs/exp-output-autoplan.txt @@ -0,0 +1,36 @@ +Ran Plan for dir: `.` workspace: `default` + +
Show Output + +```diff + +An execution plan has been generated and is shown below. +Resource actions are indicated with the following symbols: ++ create + +Terraform will perform the following actions: + + # null_resource.simple[0] will be created ++ resource "null_resource" "simple" { + + id = (known after apply) + } + +Plan: 1 to add, 0 to change, 0 to destroy. + +Changes to Outputs: ++ workspace = "default" + +``` + +* :arrow_forward: To **apply** this plan, comment: + * `atlantis apply -d .` +* :put_litter_in_its_place: To **delete** this plan click [here](lock-url) +* :repeat: To **plan** this project again, comment: + * `atlantis plan -d .` +
+ +--- +* :fast_forward: To **apply** all unapplied plans from this pull request, comment: + * `atlantis apply` +* :put_litter_in_its_place: To delete all plans and locks for the PR, comment: + * `atlantis unlock` diff --git a/server/testfixtures/test-repos/policy-checks-apply-reqs/exp-output-merge.txt b/server/testfixtures/test-repos/policy-checks-apply-reqs/exp-output-merge.txt new file mode 100644 index 0000000000..872c5ee40c --- /dev/null +++ b/server/testfixtures/test-repos/policy-checks-apply-reqs/exp-output-merge.txt @@ -0,0 +1,3 @@ +Locks and plans deleted for the projects and workspaces modified in this pull request: + +- dir: `.` workspace: `default` diff --git a/server/testfixtures/test-repos/policy-checks-apply-reqs/main.tf b/server/testfixtures/test-repos/policy-checks-apply-reqs/main.tf new file mode 100644 index 0000000000..582f9ea01d --- /dev/null +++ b/server/testfixtures/test-repos/policy-checks-apply-reqs/main.tf @@ -0,0 +1,7 @@ +resource "null_resource" "simple" { + count = 1 +} + +output "workspace" { + value = terraform.workspace +} diff --git a/server/testfixtures/test-repos/policy-checks-apply-reqs/policies/policy.rego b/server/testfixtures/test-repos/policy-checks-apply-reqs/policies/policy.rego new file mode 100644 index 0000000000..126c2e4591 --- /dev/null +++ b/server/testfixtures/test-repos/policy-checks-apply-reqs/policies/policy.rego @@ -0,0 +1,28 @@ +package main + +import input as tfplan + +deny[reason] { + num_deletes.null_resource > 0 + reason := "WARNING: Null Resource creation is prohibited." +} + +resource_types = {"null_resource"} + +resources[resource_type] = all { + some resource_type + resource_types[resource_type] + all := [name | + name := tfplan.resource_changes[_] + name.type == resource_type + ] +} + +# number of deletions of resources of a given type +num_deletes[resource_type] = num { + some resource_type + resource_types[resource_type] + all := resources[resource_type] + deletions := [res | res := all[_]; res.change.actions[_] == "create"] + num := count(deletions) +} diff --git a/server/testfixtures/test-repos/policy-checks-apply-reqs/repos.yaml b/server/testfixtures/test-repos/policy-checks-apply-reqs/repos.yaml new file mode 100644 index 0000000000..32434be4e3 --- /dev/null +++ b/server/testfixtures/test-repos/policy-checks-apply-reqs/repos.yaml @@ -0,0 +1,12 @@ +repos: +- id: /.*/ + apply_requirements: [approved] +policies: + owners: + users: + - runatlantis + policy_sets: + - name: test_policy + path: policies/policy.rego + source: local + diff --git a/server/testfixtures/test-repos/policy-checks-diff-owner/exp-output-apply-failed.txt b/server/testfixtures/test-repos/policy-checks-diff-owner/exp-output-apply-failed.txt index fbb8325fc7..1f57a9176d 100644 --- a/server/testfixtures/test-repos/policy-checks-diff-owner/exp-output-apply-failed.txt +++ b/server/testfixtures/test-repos/policy-checks-diff-owner/exp-output-apply-failed.txt @@ -1,4 +1,4 @@ Ran Apply for dir: `.` workspace: `default` -**Apply Failed**: Pull request must be mergeable before running apply. +**Apply Failed**: All policies must pass for project before running apply diff --git a/server/testfixtures/test-repos/policy-checks-diff-owner/repos.yaml b/server/testfixtures/test-repos/policy-checks-diff-owner/repos.yaml index a535795f68..136cf258c9 100644 --- a/server/testfixtures/test-repos/policy-checks-diff-owner/repos.yaml +++ b/server/testfixtures/test-repos/policy-checks-diff-owner/repos.yaml @@ -1,6 +1,3 @@ -repos: - - id: /.*/ - apply_requirements: [mergeable] policies: owners: users: diff --git a/server/testfixtures/test-repos/policy-checks-multi-projects/atlantis.yaml b/server/testfixtures/test-repos/policy-checks-multi-projects/atlantis.yaml new file mode 100644 index 0000000000..006db31ba5 --- /dev/null +++ b/server/testfixtures/test-repos/policy-checks-multi-projects/atlantis.yaml @@ -0,0 +1,4 @@ +version: 3 +projects: +- dir: dir1 +- dir: dir2 diff --git a/server/testfixtures/test-repos/policy-checks-multi-projects/dir1/main.tf b/server/testfixtures/test-repos/policy-checks-multi-projects/dir1/main.tf new file mode 100644 index 0000000000..582f9ea01d --- /dev/null +++ b/server/testfixtures/test-repos/policy-checks-multi-projects/dir1/main.tf @@ -0,0 +1,7 @@ +resource "null_resource" "simple" { + count = 1 +} + +output "workspace" { + value = terraform.workspace +} diff --git a/server/testfixtures/test-repos/policy-checks-multi-projects/dir2/main.tf b/server/testfixtures/test-repos/policy-checks-multi-projects/dir2/main.tf new file mode 100644 index 0000000000..8813d4459c --- /dev/null +++ b/server/testfixtures/test-repos/policy-checks-multi-projects/dir2/main.tf @@ -0,0 +1,7 @@ +resource "null_resource" "forbidden" { + count = 1 +} + +output "workspace" { + value = terraform.workspace +} diff --git a/server/testfixtures/test-repos/policy-checks-multi-projects/exp-output-apply.txt b/server/testfixtures/test-repos/policy-checks-multi-projects/exp-output-apply.txt new file mode 100644 index 0000000000..8c3c812762 --- /dev/null +++ b/server/testfixtures/test-repos/policy-checks-multi-projects/exp-output-apply.txt @@ -0,0 +1,34 @@ +Ran Apply for 2 projects: + +1. dir: `dir1` workspace: `default` +1. dir: `dir2` workspace: `default` + +### 1. dir: `dir1` workspace: `default` +
Show Output + +```diff +null_resource.simple: +null_resource.simple: + +Apply complete! Resources: 1 added, 0 changed, 0 destroyed. + +The state of your infrastructure has been saved to the path +below. This state is required to modify and destroy your +infrastructure, so keep it safe. To inspect the complete state +use the `terraform show` command. + +State path: terraform.tfstate + +Outputs: + +workspace = "default" + +``` +
+ +--- +### 2. dir: `dir2` workspace: `default` +**Apply Failed**: All policies must pass for project before running apply + +--- + diff --git a/server/testfixtures/test-repos/policy-checks-multi-projects/exp-output-approve-policies.txt b/server/testfixtures/test-repos/policy-checks-multi-projects/exp-output-approve-policies.txt new file mode 100644 index 0000000000..f5e100c23e --- /dev/null +++ b/server/testfixtures/test-repos/policy-checks-multi-projects/exp-output-approve-policies.txt @@ -0,0 +1,5 @@ +Approved Policies for 1 projects: + +1. dir: `.` workspace: `default` + + diff --git a/server/testfixtures/test-repos/policy-checks-multi-projects/exp-output-auto-policy-check.txt b/server/testfixtures/test-repos/policy-checks-multi-projects/exp-output-auto-policy-check.txt new file mode 100644 index 0000000000..5bc3834f5a --- /dev/null +++ b/server/testfixtures/test-repos/policy-checks-multi-projects/exp-output-auto-policy-check.txt @@ -0,0 +1,40 @@ +Ran Policy Check for 2 projects: + +1. dir: `dir1` workspace: `default` +1. dir: `dir2` workspace: `default` + +### 1. dir: `dir1` workspace: `default` +```diff +Checking plan against the following policies: + test_policy + +1 test, 1 passed, 0 warnings, 0 failures, 0 exceptions + +``` + +* :arrow_forward: To **apply** this plan, comment: + * `atlantis apply -d dir1` +* :put_litter_in_its_place: To **delete** this plan click [here](lock-url) +* :repeat: To re-run policies **plan** this project again by commenting: + * `atlantis plan -d dir1` + +--- +### 2. dir: `dir2` workspace: `default` +**Policy Check Error** +``` +exit status 1 +Checking plan against the following policies: + test_policy +FAIL - - WARNING: Forbidden Resource creation is prohibited. + +1 test, 0 passed, 0 warnings, 1 failure, 0 exceptions + +``` +* :heavy_check_mark: To **approve** failing policies either request an approval from approvers or address the failure by modifying the codebase. + + +--- +* :fast_forward: To **apply** all unapplied plans from this pull request, comment: + * `atlantis apply` +* :put_litter_in_its_place: To delete all plans and locks for the PR, comment: + * `atlantis unlock` diff --git a/server/testfixtures/test-repos/policy-checks-multi-projects/exp-output-autoplan.txt b/server/testfixtures/test-repos/policy-checks-multi-projects/exp-output-autoplan.txt new file mode 100644 index 0000000000..77ef71ca99 --- /dev/null +++ b/server/testfixtures/test-repos/policy-checks-multi-projects/exp-output-autoplan.txt @@ -0,0 +1,71 @@ +Ran Plan for 2 projects: + +1. dir: `dir1` workspace: `default` +1. dir: `dir2` workspace: `default` + +### 1. dir: `dir1` workspace: `default` +
Show Output + +```diff + +An execution plan has been generated and is shown below. +Resource actions are indicated with the following symbols: ++ create + +Terraform will perform the following actions: + + # null_resource.simple[0] will be created ++ resource "null_resource" "simple" { + + id = (known after apply) + } + +Plan: 1 to add, 0 to change, 0 to destroy. + +Changes to Outputs: ++ workspace = "default" + +``` + +* :arrow_forward: To **apply** this plan, comment: + * `atlantis apply -d dir1` +* :put_litter_in_its_place: To **delete** this plan click [here](lock-url) +* :repeat: To **plan** this project again, comment: + * `atlantis plan -d dir1` +
+ +--- +### 2. dir: `dir2` workspace: `default` +
Show Output + +```diff + +An execution plan has been generated and is shown below. +Resource actions are indicated with the following symbols: ++ create + +Terraform will perform the following actions: + + # null_resource.forbidden[0] will be created ++ resource "null_resource" "forbidden" { + + id = (known after apply) + } + +Plan: 1 to add, 0 to change, 0 to destroy. + +Changes to Outputs: ++ workspace = "default" + +``` + +* :arrow_forward: To **apply** this plan, comment: + * `atlantis apply -d dir2` +* :put_litter_in_its_place: To **delete** this plan click [here](lock-url) +* :repeat: To **plan** this project again, comment: + * `atlantis plan -d dir2` +
+ +--- +* :fast_forward: To **apply** all unapplied plans from this pull request, comment: + * `atlantis apply` +* :put_litter_in_its_place: To delete all plans and locks for the PR, comment: + * `atlantis unlock` diff --git a/server/testfixtures/test-repos/policy-checks-multi-projects/exp-output-merge.txt b/server/testfixtures/test-repos/policy-checks-multi-projects/exp-output-merge.txt new file mode 100644 index 0000000000..1a12259187 --- /dev/null +++ b/server/testfixtures/test-repos/policy-checks-multi-projects/exp-output-merge.txt @@ -0,0 +1,4 @@ +Locks and plans deleted for the projects and workspaces modified in this pull request: + +- dir: `dir1` workspace: `default` +- dir: `dir2` workspace: `default` \ No newline at end of file diff --git a/server/testfixtures/test-repos/policy-checks-multi-projects/policies/policy.rego b/server/testfixtures/test-repos/policy-checks-multi-projects/policies/policy.rego new file mode 100644 index 0000000000..4b9e5254e5 --- /dev/null +++ b/server/testfixtures/test-repos/policy-checks-multi-projects/policies/policy.rego @@ -0,0 +1,28 @@ +package main + +import input as tfplan + +deny[reason] { + num_creates[_] > 0 + reason := "WARNING: Forbidden Resource creation is prohibited." +} + +resource_names = {"forbidden"} + +resources[resource_name] = all { + some resource_name + resource_names[resource_name] + all := [res | + res := tfplan.resource_changes[_] + res.name == resource_name + ] +} + +# number of creations of resources of a given name +num_creates[resource_name] = num { + some resource_name + resource_names[resource_name] + all := resources[resource_name] + creations := [res | res := all[_]; res.change.actions[_] == "create"] + num := count(creations) +} diff --git a/server/testfixtures/test-repos/policy-checks-multi-projects/repos.yaml b/server/testfixtures/test-repos/policy-checks-multi-projects/repos.yaml new file mode 100644 index 0000000000..56821996c2 --- /dev/null +++ b/server/testfixtures/test-repos/policy-checks-multi-projects/repos.yaml @@ -0,0 +1,9 @@ +policies: + owners: + users: + - runatlantis + policy_sets: + - name: test_policy + path: ../policies/policy.rego + source: local + diff --git a/server/testfixtures/test-repos/policy-checks/exp-output-apply-failed.txt b/server/testfixtures/test-repos/policy-checks/exp-output-apply-failed.txt index fbb8325fc7..1f57a9176d 100644 --- a/server/testfixtures/test-repos/policy-checks/exp-output-apply-failed.txt +++ b/server/testfixtures/test-repos/policy-checks/exp-output-apply-failed.txt @@ -1,4 +1,4 @@ Ran Apply for dir: `.` workspace: `default` -**Apply Failed**: Pull request must be mergeable before running apply. +**Apply Failed**: All policies must pass for project before running apply diff --git a/server/testfixtures/test-repos/policy-checks/repos.yaml b/server/testfixtures/test-repos/policy-checks/repos.yaml index b1a44de4ca..a5fa0cb9e2 100644 --- a/server/testfixtures/test-repos/policy-checks/repos.yaml +++ b/server/testfixtures/test-repos/policy-checks/repos.yaml @@ -1,6 +1,3 @@ -repos: - - id: /.*/ - apply_requirements: [mergeable] policies: owners: users: From 7987ea18f084031a7935aa533a54a5d37f416363 Mon Sep 17 00:00:00 2001 From: Luke Kysow <1034429+lkysow@users.noreply.github.com> Date: Thu, 15 Apr 2021 09:53:00 -0700 Subject: [PATCH 12/13] Check codecov checksum on download (#1504) --- .circleci/config.yml | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 23904323ed..aac218f6e7 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -8,7 +8,15 @@ jobs: - run: make test-coverage - run: name: post coverage to codecov.io - command: bash <(curl -s https://codecov.io/bash) + command: | + curl -s https://codecov.io/bash > codecov + VERSION=$(grep 'VERSION=\".*\"' codecov | cut -d'"' -f2); + for i in 1 256 512 + do + diff <(shasum -a $i codecov) <(curl -s https://raw.githubusercontent.com/codecov/codecov-bash/$VERSION/SHA${i}SUM) + done + chmod +x codecov + ./codecov - run: make check-fmt - run: make check-lint e2e: From 3bb6f2161f784c6b378d01d9787a22929e44cdc5 Mon Sep 17 00:00:00 2001 From: Luke Kysow <1034429+lkysow@users.noreply.github.com> Date: Thu, 15 Apr 2021 14:12:56 -0700 Subject: [PATCH 13/13] e2e: include cmd output in error messages (#1505) --- e2e/e2e.go | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/e2e/e2e.go b/e2e/e2e.go index 05cddd35e8..ee44a2a73a 100644 --- a/e2e/e2e.go +++ b/e2e/e2e.go @@ -70,8 +70,8 @@ func (t *E2ETester) Start() (*E2EResult, error) { log.Printf("checking out branch %q", branchName) checkoutCmd := exec.Command("git", "checkout", "-b", branchName) checkoutCmd.Dir = cloneDir - if err := checkoutCmd.Run(); err != nil { - return e2eResult, fmt.Errorf("failed to git checkout branch %q: %v", branchName, err) + if output, err := checkoutCmd.CombinedOutput(); err != nil { + return e2eResult, fmt.Errorf("failed to git checkout branch %q: %v: %s", branchName, err, string(output)) } // write a file for running the tests @@ -87,16 +87,15 @@ func (t *E2ETester) Start() (*E2EResult, error) { log.Printf("git add file %q", filePath) addCmd := exec.Command("git", "add", filePath) addCmd.Dir = cloneDir - if err = addCmd.Run(); err != nil { - return e2eResult, fmt.Errorf("failed to git add file %q: %v", filePath, err) + if output, err := addCmd.CombinedOutput(); err != nil { + return e2eResult, fmt.Errorf("failed to git add file %q: %v: %s", filePath, err, string(output)) } // commit the file log.Printf("git commit file %q", filePath) commitCmd := exec.Command("git", "commit", "-am", "test commit") commitCmd.Dir = cloneDir - var output []byte - if output, err = commitCmd.CombinedOutput(); err != nil { + if output, err := commitCmd.CombinedOutput(); err != nil { return e2eResult, fmt.Errorf("failed to run git commit in %q: %v: %v", cloneDir, err, string(output)) } @@ -104,8 +103,8 @@ func (t *E2ETester) Start() (*E2EResult, error) { log.Printf("git push branch %q", branchName) pushCmd := exec.Command("git", "push", "origin", branchName) pushCmd.Dir = cloneDir - if err = pushCmd.Run(); err != nil { - return e2eResult, fmt.Errorf("failed to git push branch %q: %v", branchName, err) + if output, err := pushCmd.CombinedOutput(); err != nil { + return e2eResult, fmt.Errorf("failed to git push branch %q: %v: %s", branchName, err, string(output)) } // create a new pr