mirror of
https://git.vectorsigma.ru/public/atlantis.git
synced 2026-07-28 19:38:24 +00:00
864 lines
28 KiB
Go
864 lines
28 KiB
Go
// Copyright 2017 HootSuite Media Inc.
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the License);
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an AS IS BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
// Modified hereafter by contributors to runatlantis/atlantis.
|
|
|
|
package cmd_test
|
|
|
|
import (
|
|
"io/ioutil"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/mitchellh/go-homedir"
|
|
"github.com/runatlantis/atlantis/cmd"
|
|
"github.com/runatlantis/atlantis/server"
|
|
. "github.com/runatlantis/atlantis/testing"
|
|
"github.com/spf13/cobra"
|
|
"github.com/spf13/viper"
|
|
)
|
|
|
|
// passedConfig is set to whatever config ended up being passed to NewServer.
|
|
// Used for testing.
|
|
var passedConfig server.UserConfig
|
|
|
|
type ServerCreatorMock struct{}
|
|
|
|
func (s *ServerCreatorMock) NewServer(userConfig server.UserConfig, config server.Config) (cmd.ServerStarter, error) {
|
|
passedConfig = userConfig
|
|
return &ServerStarterMock{}, nil
|
|
}
|
|
|
|
type ServerStarterMock struct{}
|
|
|
|
func (s *ServerStarterMock) Start() error {
|
|
return nil
|
|
}
|
|
|
|
func TestExecute_NoConfigFlag(t *testing.T) {
|
|
t.Log("If there is no config flag specified Execute should return nil.")
|
|
c := setupWithDefaults(map[string]interface{}{
|
|
cmd.ConfigFlag: "",
|
|
})
|
|
err := c.Execute()
|
|
Ok(t, err)
|
|
}
|
|
|
|
func TestExecute_ConfigFileExtension(t *testing.T) {
|
|
t.Log("If the config file doesn't have an extension then error.")
|
|
c := setupWithDefaults(map[string]interface{}{
|
|
cmd.ConfigFlag: "does-not-exist",
|
|
})
|
|
err := c.Execute()
|
|
Equals(t, "invalid config: reading does-not-exist: Unsupported Config Type \"\"", err.Error())
|
|
}
|
|
|
|
func TestExecute_ConfigFileMissing(t *testing.T) {
|
|
t.Log("If the config file doesn't exist then error.")
|
|
c := setupWithDefaults(map[string]interface{}{
|
|
cmd.ConfigFlag: "does-not-exist.yaml",
|
|
})
|
|
err := c.Execute()
|
|
Equals(t, "invalid config: reading does-not-exist.yaml: open does-not-exist.yaml: no such file or directory", err.Error())
|
|
}
|
|
|
|
func TestExecute_ConfigFileExists(t *testing.T) {
|
|
t.Log("If the config file exists then there should be no error.")
|
|
tmpFile := tempFile(t, "")
|
|
defer os.Remove(tmpFile) // nolint: errcheck
|
|
c := setupWithDefaults(map[string]interface{}{
|
|
cmd.ConfigFlag: tmpFile,
|
|
})
|
|
err := c.Execute()
|
|
Ok(t, err)
|
|
}
|
|
|
|
func TestExecute_InvalidConfig(t *testing.T) {
|
|
t.Log("If the config file contains invalid yaml there should be an error.")
|
|
tmpFile := tempFile(t, "invalidyaml")
|
|
defer os.Remove(tmpFile) // nolint: errcheck
|
|
c := setupWithDefaults(map[string]interface{}{
|
|
cmd.ConfigFlag: tmpFile,
|
|
})
|
|
err := c.Execute()
|
|
Assert(t, strings.Contains(err.Error(), "unmarshal errors"), "should be an unmarshal error")
|
|
}
|
|
|
|
func TestExecute_RequireRepoWhitelist(t *testing.T) {
|
|
t.Log("If no repo whitelist set should error.")
|
|
c := setup(map[string]interface{}{
|
|
cmd.GHUserFlag: "user",
|
|
cmd.GHTokenFlag: "token",
|
|
})
|
|
err := c.Execute()
|
|
Assert(t, err != nil, "should be an error")
|
|
Equals(t, "--repo-whitelist must be set for security purposes", err.Error())
|
|
}
|
|
|
|
// Should error if the repo whitelist contained a scheme.
|
|
func TestExecute_RepoWhitelistScheme(t *testing.T) {
|
|
c := setup(map[string]interface{}{
|
|
cmd.GHUserFlag: "user",
|
|
cmd.GHTokenFlag: "token",
|
|
cmd.RepoWhitelistFlag: "http://github.com/*",
|
|
})
|
|
err := c.Execute()
|
|
Assert(t, err != nil, "should be an error")
|
|
Equals(t, "--repo-whitelist cannot contain ://, should be hostnames only", err.Error())
|
|
}
|
|
|
|
func TestExecute_ValidateLogLevel(t *testing.T) {
|
|
t.Log("Should validate log level.")
|
|
c := setupWithDefaults(map[string]interface{}{
|
|
cmd.LogLevelFlag: "invalid",
|
|
})
|
|
err := c.Execute()
|
|
Assert(t, err != nil, "should be an error")
|
|
Equals(t, "invalid log level: not one of debug, info, warn, error", err.Error())
|
|
}
|
|
|
|
func TestExecute_ValidateSSLConfig(t *testing.T) {
|
|
expErr := "--ssl-key-file and --ssl-cert-file are both required for ssl"
|
|
cases := []struct {
|
|
description string
|
|
flags map[string]interface{}
|
|
expectError bool
|
|
}{
|
|
{
|
|
"neither option set",
|
|
make(map[string]interface{}),
|
|
false,
|
|
},
|
|
{
|
|
"just ssl-key-file set",
|
|
map[string]interface{}{
|
|
cmd.SSLKeyFileFlag: "file",
|
|
},
|
|
true,
|
|
},
|
|
{
|
|
"just ssl-cert-file set",
|
|
map[string]interface{}{
|
|
cmd.SSLCertFileFlag: "flag",
|
|
},
|
|
true,
|
|
},
|
|
{
|
|
"both flags set",
|
|
map[string]interface{}{
|
|
cmd.SSLCertFileFlag: "cert",
|
|
cmd.SSLKeyFileFlag: "key",
|
|
},
|
|
false,
|
|
},
|
|
}
|
|
for _, testCase := range cases {
|
|
t.Log("Should validate ssl config when " + testCase.description)
|
|
c := setupWithDefaults(testCase.flags)
|
|
err := c.Execute()
|
|
if testCase.expectError {
|
|
Assert(t, err != nil, "should be an error")
|
|
Equals(t, expErr, err.Error())
|
|
} else {
|
|
Ok(t, err)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestExecute_ValidateVCSConfig(t *testing.T) {
|
|
expErr := "--gh-user/--gh-token or --gitlab-user/--gitlab-token or --bitbucket-user/--bitbucket-token must be set"
|
|
cases := []struct {
|
|
description string
|
|
flags map[string]interface{}
|
|
expectError bool
|
|
}{
|
|
{
|
|
"no config set",
|
|
make(map[string]interface{}),
|
|
true,
|
|
},
|
|
{
|
|
"just github token set",
|
|
map[string]interface{}{
|
|
cmd.GHTokenFlag: "token",
|
|
},
|
|
true,
|
|
},
|
|
{
|
|
"just gitlab token set",
|
|
map[string]interface{}{
|
|
cmd.GitlabTokenFlag: "token",
|
|
},
|
|
true,
|
|
},
|
|
{
|
|
"just bitbucket token set",
|
|
map[string]interface{}{
|
|
cmd.BitbucketTokenFlag: "token",
|
|
},
|
|
true,
|
|
},
|
|
{
|
|
"just github user set",
|
|
map[string]interface{}{
|
|
cmd.GHUserFlag: "user",
|
|
},
|
|
true,
|
|
},
|
|
{
|
|
"just gitlab user set",
|
|
map[string]interface{}{
|
|
cmd.GitlabUserFlag: "user",
|
|
},
|
|
true,
|
|
},
|
|
{
|
|
"just bitbucket user set",
|
|
map[string]interface{}{
|
|
cmd.BitbucketUserFlag: "user",
|
|
},
|
|
true,
|
|
},
|
|
{
|
|
"github user and gitlab token set",
|
|
map[string]interface{}{
|
|
cmd.GHUserFlag: "user",
|
|
cmd.GitlabTokenFlag: "token",
|
|
},
|
|
true,
|
|
},
|
|
{
|
|
"gitlab user and github token set",
|
|
map[string]interface{}{
|
|
cmd.GitlabUserFlag: "user",
|
|
cmd.GHTokenFlag: "token",
|
|
},
|
|
true,
|
|
},
|
|
{
|
|
"github user and bitbucket token set",
|
|
map[string]interface{}{
|
|
cmd.GHUserFlag: "user",
|
|
cmd.BitbucketTokenFlag: "token",
|
|
},
|
|
true,
|
|
},
|
|
{
|
|
"github user and github token set and should be successful",
|
|
map[string]interface{}{
|
|
cmd.GHUserFlag: "user",
|
|
cmd.GHTokenFlag: "token",
|
|
},
|
|
false,
|
|
},
|
|
{
|
|
"gitlab user and gitlab token set and should be successful",
|
|
map[string]interface{}{
|
|
cmd.GitlabUserFlag: "user",
|
|
cmd.GitlabTokenFlag: "token",
|
|
},
|
|
false,
|
|
},
|
|
{
|
|
"bitbucket user and bitbucket token set and should be successful",
|
|
map[string]interface{}{
|
|
cmd.BitbucketUserFlag: "user",
|
|
cmd.BitbucketTokenFlag: "token",
|
|
},
|
|
false,
|
|
},
|
|
{
|
|
"all set should be successful",
|
|
map[string]interface{}{
|
|
cmd.GHUserFlag: "user",
|
|
cmd.GHTokenFlag: "token",
|
|
cmd.GitlabUserFlag: "user",
|
|
cmd.GitlabTokenFlag: "token",
|
|
cmd.BitbucketUserFlag: "user",
|
|
cmd.BitbucketTokenFlag: "token",
|
|
},
|
|
false,
|
|
},
|
|
}
|
|
for _, testCase := range cases {
|
|
t.Log("Should validate vcs config when " + testCase.description)
|
|
testCase.flags[cmd.RepoWhitelistFlag] = "*"
|
|
|
|
c := setup(testCase.flags)
|
|
err := c.Execute()
|
|
if testCase.expectError {
|
|
Assert(t, err != nil, "should be an error")
|
|
Equals(t, expErr, err.Error())
|
|
} else {
|
|
Ok(t, err)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestExecute_Defaults(t *testing.T) {
|
|
t.Log("Should set the defaults for all unspecified flags.")
|
|
c := setup(map[string]interface{}{
|
|
cmd.GHUserFlag: "user",
|
|
cmd.GHTokenFlag: "token",
|
|
cmd.GitlabUserFlag: "gitlab-user",
|
|
cmd.GitlabTokenFlag: "gitlab-token",
|
|
cmd.BitbucketUserFlag: "bitbucket-user",
|
|
cmd.BitbucketTokenFlag: "bitbucket-token",
|
|
cmd.RepoWhitelistFlag: "*",
|
|
})
|
|
err := c.Execute()
|
|
Ok(t, err)
|
|
|
|
// Get our hostname since that's what gets defaulted to
|
|
hostname, err := os.Hostname()
|
|
Ok(t, err)
|
|
Equals(t, "http://"+hostname+":4141", passedConfig.AtlantisURL)
|
|
Equals(t, false, passedConfig.AllowForkPRs)
|
|
Equals(t, false, passedConfig.AllowRepoConfig)
|
|
|
|
// Get our home dir since that's what gets defaulted to
|
|
dataDir, err := homedir.Expand("~/.atlantis")
|
|
Ok(t, err)
|
|
Equals(t, dataDir, passedConfig.DataDir)
|
|
|
|
Equals(t, "github.com", passedConfig.GithubHostname)
|
|
Equals(t, "token", passedConfig.GithubToken)
|
|
Equals(t, "user", passedConfig.GithubUser)
|
|
Equals(t, "", passedConfig.GithubWebhookSecret)
|
|
Equals(t, "gitlab.com", passedConfig.GitlabHostname)
|
|
Equals(t, "gitlab-token", passedConfig.GitlabToken)
|
|
Equals(t, "gitlab-user", passedConfig.GitlabUser)
|
|
Equals(t, "", passedConfig.GitlabWebhookSecret)
|
|
Equals(t, "https://api.bitbucket.org", passedConfig.BitbucketBaseURL)
|
|
Equals(t, "bitbucket-token", passedConfig.BitbucketToken)
|
|
Equals(t, "bitbucket-user", passedConfig.BitbucketUser)
|
|
Equals(t, "", passedConfig.BitbucketWebhookSecret)
|
|
Equals(t, "info", passedConfig.LogLevel)
|
|
Equals(t, 4141, passedConfig.Port)
|
|
Equals(t, false, passedConfig.RequireApproval)
|
|
Equals(t, "", passedConfig.SSLCertFile)
|
|
Equals(t, "", passedConfig.SSLKeyFile)
|
|
}
|
|
|
|
func TestExecute_ExpandHomeInDataDir(t *testing.T) {
|
|
t.Log("If ~ is used as a data-dir path, should expand to absolute home path")
|
|
c := setup(map[string]interface{}{
|
|
cmd.GHUserFlag: "user",
|
|
cmd.GHTokenFlag: "token",
|
|
cmd.RepoWhitelistFlag: "*",
|
|
cmd.DataDirFlag: "~/this/is/a/path",
|
|
})
|
|
err := c.Execute()
|
|
Ok(t, err)
|
|
|
|
home, err := homedir.Dir()
|
|
Ok(t, err)
|
|
Equals(t, home+"/this/is/a/path", passedConfig.DataDir)
|
|
}
|
|
|
|
func TestExecute_RelativeDataDir(t *testing.T) {
|
|
t.Log("Should convert relative dir to absolute.")
|
|
c := setupWithDefaults(map[string]interface{}{
|
|
cmd.DataDirFlag: "../",
|
|
})
|
|
|
|
// Figure out what ../ should be as an absolute path.
|
|
expectedAbsolutePath, err := filepath.Abs("../")
|
|
Ok(t, err)
|
|
|
|
err = c.Execute()
|
|
Ok(t, err)
|
|
Equals(t, expectedAbsolutePath, passedConfig.DataDir)
|
|
}
|
|
|
|
func TestExecute_GithubUser(t *testing.T) {
|
|
t.Log("Should remove the @ from the github username if it's passed.")
|
|
c := setup(map[string]interface{}{
|
|
cmd.GHUserFlag: "@user",
|
|
cmd.GHTokenFlag: "token",
|
|
cmd.RepoWhitelistFlag: "*",
|
|
})
|
|
err := c.Execute()
|
|
Ok(t, err)
|
|
|
|
Equals(t, "user", passedConfig.GithubUser)
|
|
}
|
|
|
|
func TestExecute_GitlabUser(t *testing.T) {
|
|
t.Log("Should remove the @ from the gitlab username if it's passed.")
|
|
c := setup(map[string]interface{}{
|
|
cmd.GitlabUserFlag: "@user",
|
|
cmd.GitlabTokenFlag: "token",
|
|
cmd.RepoWhitelistFlag: "*",
|
|
})
|
|
err := c.Execute()
|
|
Ok(t, err)
|
|
|
|
Equals(t, "user", passedConfig.GitlabUser)
|
|
}
|
|
|
|
func TestExecute_BitbucketUser(t *testing.T) {
|
|
t.Log("Should remove the @ from the bitbucket username if it's passed.")
|
|
c := setup(map[string]interface{}{
|
|
cmd.BitbucketUserFlag: "@user",
|
|
cmd.BitbucketTokenFlag: "token",
|
|
cmd.RepoWhitelistFlag: "*",
|
|
})
|
|
err := c.Execute()
|
|
Ok(t, err)
|
|
|
|
Equals(t, "user", passedConfig.BitbucketUser)
|
|
}
|
|
|
|
func TestExecute_Flags(t *testing.T) {
|
|
t.Log("Should use all flags that are set.")
|
|
c := setup(map[string]interface{}{
|
|
cmd.AtlantisURLFlag: "url",
|
|
cmd.AllowForkPRsFlag: true,
|
|
cmd.AllowRepoConfigFlag: true,
|
|
cmd.BitbucketBaseURLFlag: "https://bitbucket-base-url.com",
|
|
cmd.BitbucketTokenFlag: "bitbucket-token",
|
|
cmd.BitbucketUserFlag: "bitbucket-user",
|
|
cmd.BitbucketWebhookSecretFlag: "bitbucket-secret",
|
|
cmd.DataDirFlag: "/path",
|
|
cmd.GHHostnameFlag: "ghhostname",
|
|
cmd.GHTokenFlag: "token",
|
|
cmd.GHUserFlag: "user",
|
|
cmd.GHWebhookSecretFlag: "secret",
|
|
cmd.GitlabHostnameFlag: "gitlab-hostname",
|
|
cmd.GitlabTokenFlag: "gitlab-token",
|
|
cmd.GitlabUserFlag: "gitlab-user",
|
|
cmd.GitlabWebhookSecretFlag: "gitlab-secret",
|
|
cmd.LogLevelFlag: "debug",
|
|
cmd.PortFlag: 8181,
|
|
cmd.RepoWhitelistFlag: "github.com/runatlantis/atlantis",
|
|
cmd.RequireApprovalFlag: true,
|
|
cmd.SSLCertFileFlag: "cert-file",
|
|
cmd.SSLKeyFileFlag: "key-file",
|
|
})
|
|
err := c.Execute()
|
|
Ok(t, err)
|
|
|
|
Equals(t, "url", passedConfig.AtlantisURL)
|
|
Equals(t, true, passedConfig.AllowForkPRs)
|
|
Equals(t, true, passedConfig.AllowRepoConfig)
|
|
Equals(t, "https://bitbucket-base-url.com", passedConfig.BitbucketBaseURL)
|
|
Equals(t, "bitbucket-token", passedConfig.BitbucketToken)
|
|
Equals(t, "bitbucket-user", passedConfig.BitbucketUser)
|
|
Equals(t, "bitbucket-secret", passedConfig.BitbucketWebhookSecret)
|
|
Equals(t, "/path", passedConfig.DataDir)
|
|
Equals(t, "ghhostname", passedConfig.GithubHostname)
|
|
Equals(t, "token", passedConfig.GithubToken)
|
|
Equals(t, "user", passedConfig.GithubUser)
|
|
Equals(t, "secret", passedConfig.GithubWebhookSecret)
|
|
Equals(t, "gitlab-hostname", passedConfig.GitlabHostname)
|
|
Equals(t, "gitlab-token", passedConfig.GitlabToken)
|
|
Equals(t, "gitlab-user", passedConfig.GitlabUser)
|
|
Equals(t, "gitlab-secret", passedConfig.GitlabWebhookSecret)
|
|
Equals(t, "debug", passedConfig.LogLevel)
|
|
Equals(t, 8181, passedConfig.Port)
|
|
Equals(t, "github.com/runatlantis/atlantis", passedConfig.RepoWhitelist)
|
|
Equals(t, true, passedConfig.RequireApproval)
|
|
Equals(t, "cert-file", passedConfig.SSLCertFile)
|
|
Equals(t, "key-file", passedConfig.SSLKeyFile)
|
|
}
|
|
|
|
func TestExecute_ConfigFile(t *testing.T) {
|
|
t.Log("Should use all the values from the config file.")
|
|
tmpFile := tempFile(t, `---
|
|
atlantis-url: "url"
|
|
allow-fork-prs: true
|
|
allow-repo-config: true
|
|
bitbucket-base-url: "https://mydomain.com"
|
|
bitbucket-token: "bitbucket-token"
|
|
bitbucket-user: "bitbucket-user"
|
|
bitbucket-webhook-secret: "bitbucket-secret"
|
|
data-dir: "/path"
|
|
gh-hostname: "ghhostname"
|
|
gh-token: "token"
|
|
gh-user: "user"
|
|
gh-webhook-secret: "secret"
|
|
gitlab-hostname: "gitlab-hostname"
|
|
gitlab-token: "gitlab-token"
|
|
gitlab-user: "gitlab-user"
|
|
gitlab-webhook-secret: "gitlab-secret"
|
|
log-level: "debug"
|
|
port: 8181
|
|
repo-whitelist: "github.com/runatlantis/atlantis"
|
|
require-approval: true
|
|
ssl-cert-file: cert-file
|
|
ssl-key-file: key-file
|
|
`)
|
|
defer os.Remove(tmpFile) // nolint: errcheck
|
|
c := setup(map[string]interface{}{
|
|
cmd.ConfigFlag: tmpFile,
|
|
})
|
|
|
|
err := c.Execute()
|
|
Ok(t, err)
|
|
Equals(t, "url", passedConfig.AtlantisURL)
|
|
Equals(t, true, passedConfig.AllowForkPRs)
|
|
Equals(t, true, passedConfig.AllowRepoConfig)
|
|
Equals(t, "https://mydomain.com", passedConfig.BitbucketBaseURL)
|
|
Equals(t, "bitbucket-token", passedConfig.BitbucketToken)
|
|
Equals(t, "bitbucket-user", passedConfig.BitbucketUser)
|
|
Equals(t, "bitbucket-secret", passedConfig.BitbucketWebhookSecret)
|
|
Equals(t, "/path", passedConfig.DataDir)
|
|
Equals(t, "ghhostname", passedConfig.GithubHostname)
|
|
Equals(t, "token", passedConfig.GithubToken)
|
|
Equals(t, "user", passedConfig.GithubUser)
|
|
Equals(t, "secret", passedConfig.GithubWebhookSecret)
|
|
Equals(t, "gitlab-hostname", passedConfig.GitlabHostname)
|
|
Equals(t, "gitlab-token", passedConfig.GitlabToken)
|
|
Equals(t, "gitlab-user", passedConfig.GitlabUser)
|
|
Equals(t, "gitlab-secret", passedConfig.GitlabWebhookSecret)
|
|
Equals(t, "debug", passedConfig.LogLevel)
|
|
Equals(t, 8181, passedConfig.Port)
|
|
Equals(t, "github.com/runatlantis/atlantis", passedConfig.RepoWhitelist)
|
|
Equals(t, true, passedConfig.RequireApproval)
|
|
Equals(t, "cert-file", passedConfig.SSLCertFile)
|
|
Equals(t, "key-file", passedConfig.SSLKeyFile)
|
|
}
|
|
|
|
func TestExecute_EnvironmentOverride(t *testing.T) {
|
|
t.Log("Environment variables should override config file flags.")
|
|
tmpFile := tempFile(t, `---
|
|
atlantis-url: "url"
|
|
allow-fork-prs: true
|
|
allow-repo-config: true
|
|
bitbucket-base-url: "https://mydomain.com"
|
|
bitbucket-token: "bitbucket-token"
|
|
bitbucket-user: "bitbucket-user"
|
|
bitbucket-webhook-secret: "bitbucket-secret"
|
|
data-dir: "/path"
|
|
gh-hostname: "ghhostname"
|
|
gh-token: "token"
|
|
gh-user: "user"
|
|
gh-webhook-secret: "secret"
|
|
gitlab-hostname: "gitlab-hostname"
|
|
gitlab-token: "gitlab-token"
|
|
gitlab-user: "gitlab-user"
|
|
gitlab-webhook-secret: "gitlab-secret"
|
|
log-level: "debug"
|
|
port: 8181
|
|
repo-whitelist: "github.com/runatlantis/atlantis"
|
|
require-approval: true
|
|
ssl-cert-file: cert-file
|
|
ssl-key-file: key-file
|
|
`)
|
|
defer os.Remove(tmpFile) // nolint: errcheck
|
|
|
|
// NOTE: We add the ATLANTIS_ prefix below.
|
|
for name, value := range map[string]string{
|
|
"ATLANTIS_URL": "override-url",
|
|
"ALLOW_FORK_PRS": "false",
|
|
"ALLOW_REPO_CONFIG": "false",
|
|
"BITBUCKET_BASE_URL": "https://override-bitbucket-base-url",
|
|
"BITBUCKET_TOKEN": "override-bitbucket-token",
|
|
"BITBUCKET_USER": "override-bitbucket-user",
|
|
"BITBUCKET_WEBHOOK_SECRET": "override-bitbucket-secret",
|
|
"DATA_DIR": "/override-path",
|
|
"GH_HOSTNAME": "override-gh-hostname",
|
|
"GH_TOKEN": "override-gh-token",
|
|
"GH_USER": "override-gh-user",
|
|
"GH_WEBHOOK_SECRET": "override-gh-webhook-secret",
|
|
"GITLAB_HOSTNAME": "override-gitlab-hostname",
|
|
"GITLAB_TOKEN": "override-gitlab-token",
|
|
"GITLAB_USER": "override-gitlab-user",
|
|
"GITLAB_WEBHOOK_SECRET": "override-gitlab-webhook-secret",
|
|
"LOG_LEVEL": "info",
|
|
"PORT": "8282",
|
|
"REPO_WHITELIST": "override,override",
|
|
"REQUIRE_APPROVAL": "false",
|
|
"SSL_CERT_FILE": "override-cert-file",
|
|
"SSL_KEY_FILE": "override-key-file",
|
|
} {
|
|
os.Setenv("ATLANTIS_"+name, value) // nolint: errcheck
|
|
}
|
|
c := setup(map[string]interface{}{
|
|
cmd.ConfigFlag: tmpFile,
|
|
})
|
|
err := c.Execute()
|
|
Ok(t, err)
|
|
Equals(t, "override-url", passedConfig.AtlantisURL)
|
|
Equals(t, false, passedConfig.AllowForkPRs)
|
|
Equals(t, false, passedConfig.AllowRepoConfig)
|
|
Equals(t, "https://override-bitbucket-base-url", passedConfig.BitbucketBaseURL)
|
|
Equals(t, "override-bitbucket-token", passedConfig.BitbucketToken)
|
|
Equals(t, "override-bitbucket-user", passedConfig.BitbucketUser)
|
|
Equals(t, "override-bitbucket-secret", passedConfig.BitbucketWebhookSecret)
|
|
Equals(t, "/override-path", passedConfig.DataDir)
|
|
Equals(t, "override-gh-hostname", passedConfig.GithubHostname)
|
|
Equals(t, "override-gh-token", passedConfig.GithubToken)
|
|
Equals(t, "override-gh-user", passedConfig.GithubUser)
|
|
Equals(t, "override-gh-webhook-secret", passedConfig.GithubWebhookSecret)
|
|
Equals(t, "override-gitlab-hostname", passedConfig.GitlabHostname)
|
|
Equals(t, "override-gitlab-token", passedConfig.GitlabToken)
|
|
Equals(t, "override-gitlab-user", passedConfig.GitlabUser)
|
|
Equals(t, "override-gitlab-webhook-secret", passedConfig.GitlabWebhookSecret)
|
|
Equals(t, "info", passedConfig.LogLevel)
|
|
Equals(t, 8282, passedConfig.Port)
|
|
Equals(t, "override,override", passedConfig.RepoWhitelist)
|
|
Equals(t, false, passedConfig.RequireApproval)
|
|
Equals(t, "override-cert-file", passedConfig.SSLCertFile)
|
|
Equals(t, "override-key-file", passedConfig.SSLKeyFile)
|
|
}
|
|
|
|
func TestExecute_FlagConfigOverride(t *testing.T) {
|
|
t.Log("Flags should override config file flags.")
|
|
tmpFile := tempFile(t, `---
|
|
atlantis-url: "url"
|
|
allow-fork-prs: true
|
|
allow-repo-config: true
|
|
bitbucket-base-url: "https://bitbucket-base-url"
|
|
bitbucket-token: "bitbucket-token"
|
|
bitbucket-user: "bitbucket-user"
|
|
bitbucket-webhook-secret: "bitbucket-secret"
|
|
data-dir: "/path"
|
|
gh-hostname: "ghhostname"
|
|
gh-token: "token"
|
|
gh-user: "user"
|
|
gh-webhook-secret: "secret"
|
|
gitlab-hostname: "gitlab-hostname"
|
|
gitlab-token: "gitlab-token"
|
|
gitlab-user: "gitlab-user"
|
|
gitlab-webhook-secret: "gitlab-secret"
|
|
log-level: "debug"
|
|
port: 8181
|
|
repo-whitelist: "github.com/runatlantis/atlantis"
|
|
require-approval: true
|
|
ssl-cert-file: cert-file
|
|
ssl-key-file: key-file
|
|
`)
|
|
|
|
defer os.Remove(tmpFile) // nolint: errcheck
|
|
c := setup(map[string]interface{}{
|
|
cmd.AtlantisURLFlag: "override-url",
|
|
cmd.AllowForkPRsFlag: false,
|
|
cmd.AllowRepoConfigFlag: false,
|
|
cmd.BitbucketBaseURLFlag: "https://override-bitbucket-base-url",
|
|
cmd.BitbucketTokenFlag: "override-bitbucket-token",
|
|
cmd.BitbucketUserFlag: "override-bitbucket-user",
|
|
cmd.BitbucketWebhookSecretFlag: "override-bitbucket-secret",
|
|
cmd.DataDirFlag: "/override-path",
|
|
cmd.GHHostnameFlag: "override-gh-hostname",
|
|
cmd.GHTokenFlag: "override-gh-token",
|
|
cmd.GHUserFlag: "override-gh-user",
|
|
cmd.GHWebhookSecretFlag: "override-gh-webhook-secret",
|
|
cmd.GitlabHostnameFlag: "override-gitlab-hostname",
|
|
cmd.GitlabTokenFlag: "override-gitlab-token",
|
|
cmd.GitlabUserFlag: "override-gitlab-user",
|
|
cmd.GitlabWebhookSecretFlag: "override-gitlab-webhook-secret",
|
|
cmd.LogLevelFlag: "info",
|
|
cmd.PortFlag: 8282,
|
|
cmd.RepoWhitelistFlag: "override,override",
|
|
cmd.RequireApprovalFlag: false,
|
|
cmd.SSLCertFileFlag: "override-cert-file",
|
|
cmd.SSLKeyFileFlag: "override-key-file",
|
|
})
|
|
err := c.Execute()
|
|
Ok(t, err)
|
|
Equals(t, "override-url", passedConfig.AtlantisURL)
|
|
Equals(t, false, passedConfig.AllowForkPRs)
|
|
Equals(t, "https://override-bitbucket-base-url", passedConfig.BitbucketBaseURL)
|
|
Equals(t, "override-bitbucket-token", passedConfig.BitbucketToken)
|
|
Equals(t, "override-bitbucket-user", passedConfig.BitbucketUser)
|
|
Equals(t, "override-bitbucket-secret", passedConfig.BitbucketWebhookSecret)
|
|
Equals(t, "/override-path", passedConfig.DataDir)
|
|
Equals(t, "override-gh-hostname", passedConfig.GithubHostname)
|
|
Equals(t, "override-gh-token", passedConfig.GithubToken)
|
|
Equals(t, "override-gh-user", passedConfig.GithubUser)
|
|
Equals(t, "override-gh-webhook-secret", passedConfig.GithubWebhookSecret)
|
|
Equals(t, "override-gitlab-hostname", passedConfig.GitlabHostname)
|
|
Equals(t, "override-gitlab-token", passedConfig.GitlabToken)
|
|
Equals(t, "override-gitlab-user", passedConfig.GitlabUser)
|
|
Equals(t, "override-gitlab-webhook-secret", passedConfig.GitlabWebhookSecret)
|
|
Equals(t, "info", passedConfig.LogLevel)
|
|
Equals(t, 8282, passedConfig.Port)
|
|
Equals(t, "override,override", passedConfig.RepoWhitelist)
|
|
Equals(t, false, passedConfig.RequireApproval)
|
|
Equals(t, "override-cert-file", passedConfig.SSLCertFile)
|
|
Equals(t, "override-key-file", passedConfig.SSLKeyFile)
|
|
}
|
|
|
|
func TestExecute_FlagEnvVarOverride(t *testing.T) {
|
|
t.Log("Flags should override environment variables.")
|
|
|
|
envVars := map[string]string{
|
|
"ATLANTIS_URL": "url",
|
|
"ALLOW_FORK_PRS": "true",
|
|
"ALLOW_REPO_CONFIG": "true",
|
|
"BITBUCKET_BASE_URL": "https://bitbucket-base-url",
|
|
"BITBUCKET_TOKEN": "bitbucket-token",
|
|
"BITBUCKET_USER": "bitbucket-user",
|
|
"BITBUCKET_WEBHOOK_SECRET": "bitbucket-secret",
|
|
"DATA_DIR": "/path",
|
|
"GH_HOSTNAME": "gh-hostname",
|
|
"GH_TOKEN": "gh-token",
|
|
"GH_USER": "gh-user",
|
|
"GH_WEBHOOK_SECRET": "gh-webhook-secret",
|
|
"GITLAB_HOSTNAME": "gitlab-hostname",
|
|
"GITLAB_TOKEN": "gitlab-token",
|
|
"GITLAB_USER": "gitlab-user",
|
|
"GITLAB_WEBHOOK_SECRET": "gitlab-webhook-secret",
|
|
"LOG_LEVEL": "debug",
|
|
"PORT": "8181",
|
|
"REPO_WHITELIST": "*",
|
|
"REQUIRE_APPROVAL": "true",
|
|
"SSL_CERT_FILE": "cert-file",
|
|
"SSL_KEY_FILE": "key-file",
|
|
}
|
|
for name, value := range envVars {
|
|
os.Setenv("ATLANTIS_"+name, value) // nolint: errcheck
|
|
}
|
|
defer func() {
|
|
// Unset after this test finishes.
|
|
for name := range envVars {
|
|
os.Unsetenv("ATLANTIS_" + name) // nolint: errcheck
|
|
}
|
|
}()
|
|
|
|
c := setup(map[string]interface{}{
|
|
cmd.AtlantisURLFlag: "override-url",
|
|
cmd.AllowForkPRsFlag: false,
|
|
cmd.AllowRepoConfigFlag: false,
|
|
cmd.BitbucketBaseURLFlag: "https://override-bitbucket-base-url",
|
|
cmd.BitbucketTokenFlag: "override-bitbucket-token",
|
|
cmd.BitbucketUserFlag: "override-bitbucket-user",
|
|
cmd.BitbucketWebhookSecretFlag: "override-bitbucket-secret",
|
|
cmd.DataDirFlag: "/override-path",
|
|
cmd.GHHostnameFlag: "override-gh-hostname",
|
|
cmd.GHTokenFlag: "override-gh-token",
|
|
cmd.GHUserFlag: "override-gh-user",
|
|
cmd.GHWebhookSecretFlag: "override-gh-webhook-secret",
|
|
cmd.GitlabHostnameFlag: "override-gitlab-hostname",
|
|
cmd.GitlabTokenFlag: "override-gitlab-token",
|
|
cmd.GitlabUserFlag: "override-gitlab-user",
|
|
cmd.GitlabWebhookSecretFlag: "override-gitlab-webhook-secret",
|
|
cmd.LogLevelFlag: "info",
|
|
cmd.PortFlag: 8282,
|
|
cmd.RepoWhitelistFlag: "override,override",
|
|
cmd.RequireApprovalFlag: false,
|
|
cmd.SSLCertFileFlag: "override-cert-file",
|
|
cmd.SSLKeyFileFlag: "override-key-file",
|
|
})
|
|
err := c.Execute()
|
|
Ok(t, err)
|
|
|
|
Equals(t, "override-url", passedConfig.AtlantisURL)
|
|
Equals(t, false, passedConfig.AllowForkPRs)
|
|
Equals(t, false, passedConfig.AllowRepoConfig)
|
|
Equals(t, "https://override-bitbucket-base-url", passedConfig.BitbucketBaseURL)
|
|
Equals(t, "override-bitbucket-token", passedConfig.BitbucketToken)
|
|
Equals(t, "override-bitbucket-user", passedConfig.BitbucketUser)
|
|
Equals(t, "override-bitbucket-secret", passedConfig.BitbucketWebhookSecret)
|
|
Equals(t, "/override-path", passedConfig.DataDir)
|
|
Equals(t, "override-gh-hostname", passedConfig.GithubHostname)
|
|
Equals(t, "override-gh-token", passedConfig.GithubToken)
|
|
Equals(t, "override-gh-user", passedConfig.GithubUser)
|
|
Equals(t, "override-gh-webhook-secret", passedConfig.GithubWebhookSecret)
|
|
Equals(t, "override-gitlab-hostname", passedConfig.GitlabHostname)
|
|
Equals(t, "override-gitlab-token", passedConfig.GitlabToken)
|
|
Equals(t, "override-gitlab-user", passedConfig.GitlabUser)
|
|
Equals(t, "override-gitlab-webhook-secret", passedConfig.GitlabWebhookSecret)
|
|
Equals(t, "info", passedConfig.LogLevel)
|
|
Equals(t, 8282, passedConfig.Port)
|
|
Equals(t, "override,override", passedConfig.RepoWhitelist)
|
|
Equals(t, false, passedConfig.RequireApproval)
|
|
Equals(t, "override-cert-file", passedConfig.SSLCertFile)
|
|
Equals(t, "override-key-file", passedConfig.SSLKeyFile)
|
|
}
|
|
|
|
// If using bitbucket cloud, webhook secrets are not supported.
|
|
func TestExecute_BitbucketCloudWithWebhookSecret(t *testing.T) {
|
|
c := setup(map[string]interface{}{
|
|
cmd.BitbucketUserFlag: "user",
|
|
cmd.BitbucketTokenFlag: "token",
|
|
cmd.RepoWhitelistFlag: "*",
|
|
cmd.BitbucketWebhookSecretFlag: "my secret",
|
|
})
|
|
err := c.Execute()
|
|
ErrEquals(t, "--bitbucket-webhook-secret cannot be specified for Bitbucket Cloud because it is not supported by Bitbucket", err)
|
|
}
|
|
|
|
// Base URL must have a scheme.
|
|
func TestExecute_BitbucketServerBaseURLScheme(t *testing.T) {
|
|
c := setup(map[string]interface{}{
|
|
cmd.BitbucketUserFlag: "user",
|
|
cmd.BitbucketTokenFlag: "token",
|
|
cmd.RepoWhitelistFlag: "*",
|
|
cmd.BitbucketBaseURLFlag: "mydomain.com",
|
|
})
|
|
ErrEquals(t, "--bitbucket-base-url must have http:// or https://, got \"mydomain.com\"", c.Execute())
|
|
|
|
c = setup(map[string]interface{}{
|
|
cmd.BitbucketUserFlag: "user",
|
|
cmd.BitbucketTokenFlag: "token",
|
|
cmd.RepoWhitelistFlag: "*",
|
|
cmd.BitbucketBaseURLFlag: "://mydomain.com",
|
|
})
|
|
ErrEquals(t, "error parsing --bitbucket-webhook-secret flag value \"://mydomain.com\": parse ://mydomain.com: missing protocol scheme", c.Execute())
|
|
}
|
|
|
|
// Port should be retained on base url.
|
|
func TestExecute_BitbucketServerBaseURLPort(t *testing.T) {
|
|
c := setup(map[string]interface{}{
|
|
cmd.BitbucketUserFlag: "user",
|
|
cmd.BitbucketTokenFlag: "token",
|
|
cmd.RepoWhitelistFlag: "*",
|
|
cmd.BitbucketBaseURLFlag: "http://mydomain.com:7990",
|
|
})
|
|
Ok(t, c.Execute())
|
|
Equals(t, "http://mydomain.com:7990", passedConfig.BitbucketBaseURL)
|
|
}
|
|
|
|
func setup(flags map[string]interface{}) *cobra.Command {
|
|
vipr := viper.New()
|
|
for k, v := range flags {
|
|
vipr.Set(k, v)
|
|
}
|
|
c := &cmd.ServerCmd{
|
|
ServerCreator: &ServerCreatorMock{},
|
|
Viper: vipr,
|
|
SilenceOutput: true,
|
|
}
|
|
return c.Init()
|
|
}
|
|
|
|
func setupWithDefaults(flags map[string]interface{}) *cobra.Command {
|
|
vipr := viper.New()
|
|
flags[cmd.GHUserFlag] = "user"
|
|
flags[cmd.GHTokenFlag] = "token"
|
|
flags[cmd.RepoWhitelistFlag] = "*"
|
|
|
|
for k, v := range flags {
|
|
vipr.Set(k, v)
|
|
}
|
|
c := &cmd.ServerCmd{
|
|
ServerCreator: &ServerCreatorMock{},
|
|
Viper: vipr,
|
|
SilenceOutput: true,
|
|
}
|
|
return c.Init()
|
|
}
|
|
|
|
func tempFile(t *testing.T, contents string) string {
|
|
f, err := ioutil.TempFile("", "")
|
|
Ok(t, err)
|
|
newName := f.Name() + ".yaml"
|
|
err = os.Rename(f.Name(), newName)
|
|
Ok(t, err)
|
|
ioutil.WriteFile(newName, []byte(contents), 0644) // nolint: errcheck
|
|
return newName
|
|
}
|