Skip to content

Commit

Permalink
Add gitlab cli options
Browse files Browse the repository at this point in the history
  • Loading branch information
lkysow committed Nov 12, 2017
1 parent b608d83 commit b0e38f6
Show file tree
Hide file tree
Showing 2 changed files with 172 additions and 27 deletions.
56 changes: 46 additions & 10 deletions cmd/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ const (
GHTokenFlag = "gh-token"
GHUserFlag = "gh-user"
GHWebHookSecret = "gh-webhook-secret"
GitlabHostnameFlag = "gitlab-hostname"
GitlabTokenFlag = "gitlab-token"
GitlabUserFlag = "gitlab-user"
GitlabWebHookSecret = "gitlab-webhook-secret"
LogLevelFlag = "log-level"
PortFlag = "port"
RequireApprovalFlag = "require-approval"
Expand All @@ -49,19 +53,39 @@ var stringFlags = []stringFlag{
description: "Hostname of your Github Enterprise installation. If using github.com, no need to set.",
value: "github.com",
},
{
name: GHUserFlag,
description: "GitHub username of API user.",
},
{
name: GHTokenFlag,
description: "[REQUIRED] GitHub token of API user. Can also be specified via the ATLANTIS_GH_TOKEN environment variable.",
description: "GitHub token of API user. Can also be specified via the ATLANTIS_GH_TOKEN environment variable.",
env: "ATLANTIS_GH_TOKEN",
},
{
name: GHUserFlag,
description: "[REQUIRED] GitHub username of API user.",
name: GHWebHookSecret,
description: "Optional secret used to validate GitHub webhooks (see https://developer.github.com/webhooks/securing/)." +
" If not specified, Atlantis won't be able to validate that the incoming webhook call came from GitHub.",
env: "ATLANTIS_GH_WEBHOOK_SECRET",
},
{
name: GitlabHostnameFlag,
description: "Hostname of your GitLab Enterprise installation. If using gitlab.com, no need to set.",
value: "gitlab.com",
},
{
name: GHWebHookSecret,
description: "Optional secret used for GitHub webhooks (see https://developer.github.com/webhooks/securing/). If not specified, Atlantis won't validate the incoming webhook call.",
env: "ATLANTIS_GH_WEBHOOK_SECRET",
name: GitlabUserFlag,
description: "GitLab username of API user.",
},
{
name: GitlabTokenFlag,
description: "GitLab token of API user. Can also be specified via the ATLANTIS_GITLAB_TOKEN environment variable.",
env: "ATLANTIS_GITLAB_TOKEN",
},
{
name: GitlabWebHookSecret,
description: "Optional secret used to validate GitLab webhooks. If not specified, Atlantis won't be able to validate that the incoming webhook call came from GitLab.",
env: "ATLANTIS_GITLAB_WEBHOOK_SECRET",
},
{
name: LogLevelFlag,
Expand Down Expand Up @@ -221,11 +245,23 @@ func validate(config server.Config) error {
if logLevel != "debug" && logLevel != "info" && logLevel != "warn" && logLevel != "error" {
return errors.New("invalid log level: not one of debug, info, warn, error")
}
if config.GithubUser == "" {
return fmt.Errorf("--%s must be set", GHUserFlag)
vcsErr := fmt.Errorf("--%s/--%s or --%s/--%s must be set", GHUserFlag, GHTokenFlag, GitlabUserFlag, GitlabTokenFlag)

// The following combinations are valid.
// 1. github user and token
// 2. gitlab user and token
// 3. all 4 set
// We validate using contradiction (I think).
if config.GithubUser != "" && config.GithubToken == "" || config.GithubToken != "" && config.GithubUser == "" {
return vcsErr
}
if config.GitlabUser != "" && config.GitlabToken == "" || config.GitlabToken != "" && config.GitlabUser == "" {
return vcsErr
}
if config.GithubToken == "" {
return fmt.Errorf("--%s must be set", GHTokenFlag)
// At this point, we know that there can't be a single user/token without
// its pair, but we haven't checked if any user/token is set at all.
if config.GithubUser == "" && config.GitlabUser == "" {
return vcsErr
}
return nil
}
Expand Down
143 changes: 126 additions & 17 deletions cmd/server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,57 +90,131 @@ func TestExecute_InvalidConfig(t *testing.T) {
Assert(t, strings.Contains(err.Error(), "unmarshal errors"), "should be an unmarshal error")
}

func TestExecute_Validation(t *testing.T) {
func TestExecute_ValidateLogLevel(t *testing.T) {
t.Log("Should validate log level.")
c := setup(map[string]interface{}{
cmd.LogLevelFlag: "invalid",
cmd.GHUserFlag: "user",
cmd.GHTokenFlag: "token",
})
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_ValidateVCSConfig(t *testing.T) {
expErr := "--gh-user/--gh-token or --gitlab-user/--gitlab-token must be set"
cases := []struct {
description string
flags map[string]interface{}
expErr string
expectError bool
}{
{
"Should validate log level.",
"no config set",
nil,
true,
},
{
"just github token set",
map[string]interface{}{
cmd.LogLevelFlag: "invalid",
cmd.GHUserFlag: "user",
cmd.GHTokenFlag: "token",
cmd.GHTokenFlag: "token",
},
"invalid log level: not one of debug, info, warn, error",
true,
},
{
"Should ensure github user is set.",
"just gitlab token set",
map[string]interface{}{
cmd.GHTokenFlag: "token",
cmd.GitlabTokenFlag: "token",
},
"--gh-user must be set",
true,
},
{
"Should ensure github token is set.",
"just github user set",
map[string]interface{}{
cmd.GHUserFlag: "user",
},
"--gh-token must be set",
true,
},
{
"just gitlab user set",
map[string]interface{}{
cmd.GitlabUserFlag: "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 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,
},
{
"github and gitlab user and github and gitlab token set and should be successful",
map[string]interface{}{
cmd.GHUserFlag: "user",
cmd.GHTokenFlag: "token",
cmd.GitlabUserFlag: "user",
cmd.GitlabTokenFlag: "token",
},
false,
},
}
for _, testCase := range cases {
t.Log(testCase.description)
t.Log("Should validate vcs config when " + testCase.description)
c := setup(testCase.flags)
err := c.Execute()
Assert(t, err != nil, "should be an error")
Equals(t, testCase.expErr, err.Error())
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.GHUserFlag: "user",
cmd.GHTokenFlag: "token",
cmd.GitlabUserFlag: "gitlab-user",
cmd.GitlabTokenFlag: "gitlab-token",
})
err := c.Execute()
Ok(t, err)

Equals(t, "user", passedConfig.GithubUser)
Equals(t, "token", passedConfig.GithubToken)
Equals(t, "", passedConfig.GithubWebHookSecret)
Equals(t, "gitlab-user", passedConfig.GitlabUser)
Equals(t, "gitlab-token", passedConfig.GitlabToken)
Equals(t, "", passedConfig.GitlabWebHookSecret)
// Get our hostname since that's what gets defaulted to
hostname, err := os.Hostname()
Ok(t, err)
Expand All @@ -151,6 +225,7 @@ func TestExecute_Defaults(t *testing.T) {
Ok(t, err)
Equals(t, dataDir, passedConfig.DataDir)
Equals(t, "github.com", passedConfig.GithubHostname)
Equals(t, "gitlab.com", passedConfig.GitlabHostname)
Equals(t, "info", passedConfig.LogLevel)
Equals(t, false, passedConfig.RequireApproval)
Equals(t, 4141, passedConfig.Port)
Expand Down Expand Up @@ -192,6 +267,10 @@ func TestExecute_Flags(t *testing.T) {
cmd.GHUserFlag: "user",
cmd.GHTokenFlag: "token",
cmd.GHWebHookSecret: "secret",
cmd.GitlabHostnameFlag: "gitlab-hostname",
cmd.GitlabUserFlag: "gitlab-user",
cmd.GitlabTokenFlag: "gitlab-token",
cmd.GitlabWebHookSecret: "gitlab-secret",
cmd.LogLevelFlag: "debug",
cmd.PortFlag: 8181,
cmd.RequireApprovalFlag: true,
Expand All @@ -205,6 +284,10 @@ func TestExecute_Flags(t *testing.T) {
Equals(t, "user", passedConfig.GithubUser)
Equals(t, "token", passedConfig.GithubToken)
Equals(t, "secret", passedConfig.GithubWebHookSecret)
Equals(t, "gitlab-hostname", passedConfig.GitlabHostname)
Equals(t, "gitlab-user", passedConfig.GitlabUser)
Equals(t, "gitlab-token", passedConfig.GitlabToken)
Equals(t, "gitlab-secret", passedConfig.GitlabWebHookSecret)
Equals(t, "debug", passedConfig.LogLevel)
Equals(t, 8181, passedConfig.Port)
Equals(t, true, passedConfig.RequireApproval)
Expand All @@ -219,6 +302,10 @@ gh-hostname: "ghhostname"
gh-user: "user"
gh-token: "token"
gh-webhook-secret: "secret"
gitlab-hostname: "gitlab-hostname"
gitlab-user: "gitlab-user"
gitlab-token: "gitlab-token"
gitlab-webhook-secret: "gitlab-secret"
log-level: "debug"
port: 8181
require-approval: true`)
Expand All @@ -235,6 +322,10 @@ require-approval: true`)
Equals(t, "user", passedConfig.GithubUser)
Equals(t, "token", passedConfig.GithubToken)
Equals(t, "secret", passedConfig.GithubWebHookSecret)
Equals(t, "gitlab-hostname", passedConfig.GitlabHostname)
Equals(t, "gitlab-user", passedConfig.GitlabUser)
Equals(t, "gitlab-token", passedConfig.GitlabToken)
Equals(t, "gitlab-secret", passedConfig.GitlabWebHookSecret)
Equals(t, "debug", passedConfig.LogLevel)
Equals(t, 8181, passedConfig.Port)
Equals(t, true, passedConfig.RequireApproval)
Expand Down Expand Up @@ -279,6 +370,24 @@ func TestExecute_FlagEnvVarOverride(t *testing.T) {
Equals(t, "override", passedConfig.GithubToken)
}

func TestExecute_EnvVars(t *testing.T) {
t.Log("Setting flags by env var should work.")
os.Setenv("ATLANTIS_GH_TOKEN", "gh-token") // nolint: errcheck
os.Setenv("ATLANTIS_GH_WEBHOOK_SECRET", "gh-webhook") // nolint: errcheck
os.Setenv("ATLANTIS_GITLAB_TOKEN", "gitlab-token") // nolint: errcheck
os.Setenv("ATLANTIS_GITLAB_WEBHOOK_SECRET", "gitlab-webhook") // nolint: errcheck
c := setup(map[string]interface{}{
cmd.GHUserFlag: "user",
cmd.GitlabUserFlag: "user",
})
err := c.Execute()
Ok(t, err)
Equals(t, "gh-token", passedConfig.GithubToken)
Equals(t, "gh-webhook", passedConfig.GithubWebHookSecret)
Equals(t, "gitlab-token", passedConfig.GitlabToken)
Equals(t, "gitlab-webhook", passedConfig.GitlabWebHookSecret)
}

func setup(flags map[string]interface{}) *cobra.Command {
viper := viper.New()
for k, v := range flags {
Expand Down

0 comments on commit b0e38f6

Please sign in to comment.