Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Add scm integrations commands #444

Merged
merged 25 commits into from Aug 20, 2019
Merged
Show file tree
Hide file tree
Changes from 24 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
bbde388
Add base of list, create and destroy integrations commands
brandon-welsch Jun 18, 2019
4be5a00
Merge branch 'master' into feature/423/add_integrations_commands
brandon-welsch Jun 18, 2019
f87ceed
Rename scm_type variable to scmType
brandon-welsch Jun 18, 2019
5ef03ae
Add check on destroy integrations command
brandon-welsch Jun 19, 2019
87ad11c
Change "External Integrations" to "Integrations"
brandon-welsch Jun 20, 2019
0eed709
Merge branch 'master' of github.com:Scalingo/cli into feature/423/add…
brandon-welsch Jul 9, 2019
c4d93aa
Added import_keys in integrations commands
brandon-welsch Jul 10, 2019
fcf1c2b
Update gitignore
brandon-welsch Jul 10, 2019
ec8fc7d
Added integrations import keys and list of integrations
brandon-welsch Jul 10, 2019
e23ba30
Added destroy integration command
brandon-welsch Jul 10, 2019
98b0a5c
Added create command and improved list and imports keys command for i…
brandon-welsch Jul 10, 2019
58f99f6
Improve create integrations command
brandon-welsch Jul 11, 2019
37273d1
Sort imports and uncomment regions code
brandon-welsch Jul 11, 2019
fee8e11
Updated gopkg.toml and added vendor directory
brandon-welsch Jul 11, 2019
dd3f65d
Updated gopkg file and go-scalingo package
brandon-welsch Jul 29, 2019
33877dd
Fix requested changes of PR
brandon-welsch Jul 29, 2019
3feec88
Merge remote-tracking branch 'origin' into feature/423/add_integratio…
brandon-welsch Jul 29, 2019
6f46618
Rework calls and removed google/uuid package
brandon-welsch Jul 30, 2019
df7be21
Updated go-scalingo
brandon-welsch Aug 2, 2019
218807f
Update scm integrations calls
brandon-welsch Aug 2, 2019
6f3b6fa
Do not return error in checkIfIntegrationAlreadyExist, return false i…
brandon-welsch Aug 5, 2019
146a318
Updated README.md
brandon-welsch Aug 5, 2019
6b3f955
Better wording and handle case when there is no key coming from the i…
Soulou Aug 7, 2019
1e2bd86
Merge branch 'master' into feature/423/add_integrations_commands
Soulou Aug 7, 2019
a867159
Explain purpose of linking Scalingo account and SCM account
EtienneM Aug 20, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 6 additions & 0 deletions .gitignore
Expand Up @@ -7,3 +7,9 @@ scalingo/scalingo
src/github.com
src/code.google.com
Godeps/Readme

# Executable
scalingo-cli

# IDE
.idea/
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -2,6 +2,7 @@

### To be Released

* Add `scm-integrations`, `scm-integrations-create`, `scm-integrations-destroy` and `scm-integrations-import-keys` commands [#444](https://github.com/Scalingo/cli/pull/444)
* Bugfix: Do not disconnect user if the API returns 401 [#462](https://github.com/Scalingo/cli/issues/462)

### 1.15.1
Expand Down
6 changes: 3 additions & 3 deletions Gopkg.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 4 additions & 4 deletions Gopkg.toml
Expand Up @@ -36,11 +36,11 @@
name = "github.com/cheggaaa/pb"
version = "1.0.28"

[[constraint]]
name = "github.com/Scalingo/go-utils"
version = "^5"

[prune]
non-go = true
go-tests = true
unused-packages = true

[[constraint]]
name = "github.com/Scalingo/go-utils"
version = "^5"
6 changes: 6 additions & 0 deletions README.md
Expand Up @@ -181,6 +181,12 @@ COMMANDS:
stacks List the available runtime stacks
stacks-set Set the runtime stack of an app

SCM Integrations:
scm-integrations List your SCM integrations
scm-integrations-create Link your Scalingo account with your account on a SCM tool
scm-integrations-delete Unlink your Scalingo account and your account on a SCM tool
scm-integrations-import-keys Import public SSH keys from SCM account

GLOBAL OPTIONS:
--addon value ID of the current addon (default: "<addon_id>") [$SCALINGO_ADDON]
--app value, -a value Name of the app (default: "<name>") [$SCALINGO_APP]
Expand Down
11 changes: 9 additions & 2 deletions cmd/commands.go
Expand Up @@ -3,11 +3,12 @@ package cmd
import (
"os"

"github.com/urfave/cli"

"github.com/Scalingo/cli/config"
"github.com/Scalingo/cli/session"
scalingo "github.com/Scalingo/go-scalingo"
"github.com/Scalingo/go-scalingo"
"github.com/Scalingo/go-scalingo/debug"
"github.com/urfave/cli"
)

type AppCommands struct {
Expand Down Expand Up @@ -213,6 +214,12 @@ var (
AddSSHKeyCommand,
RemoveSSHKeyCommand,

// SCM Integrations
scmIntegrationsListCommand,
scmIntegrationsCreateCommand,
scmIntegrationsDeleteCommand,
scmIntegrationsImportKeysCommand,

// Sessions
LoginCommand,
LogoutCommand,
Expand Down
167 changes: 167 additions & 0 deletions cmd/scm_integrations.go
@@ -0,0 +1,167 @@
package cmd

import (
"net/url"

"github.com/urfave/cli"
"gopkg.in/errgo.v1"

"github.com/Scalingo/cli/cmd/autocomplete"
"github.com/Scalingo/cli/scm_integrations"
"github.com/Scalingo/go-scalingo"
)

var (
scmIntegrationsListCommand = cli.Command{
Name: "scm-integrations",
Category: "SCM Integrations",
Usage: "List your SCM integrations",
Description: `List all the SCM integrations associated with your account:

$ scalingo scm-integrations

# See also commands 'scm-integrations-create', 'scm-integrations-delete', 'scm-integrations-import-keys'`,

Action: func(c *cli.Context) {
err := scm_integrations.List()
if err != nil {
errorQuit(err)
}
},
BashComplete: func(c *cli.Context) {
_ = autocomplete.CmdFlagsAutoComplete(c, "scm-integrations")
},
}

scmIntegrationsCreateCommand = cli.Command{
Name: "scm-integrations-create",
Category: "SCM Integrations",
Flags: []cli.Flag{appFlag,
cli.StringFlag{Name: "url", Usage: "URL of the SCM integration"},
cli.StringFlag{Name: "token", Usage: "Token of the SCM integration"},
},
Usage: "Link your Scalingo account with your account on a SCM tool",
Description: `Link your Scalingo account with your account on a SCM tool:
EtienneM marked this conversation as resolved.
Show resolved Hide resolved

For github.com:
$ scalingo scm-integrations-create github

For gitlab.com:
$ scalingo scm-integrations-create gitlab

For GitHub Enterprise:
$ scalingo scm-integrations-create github-enterprise --url https://ghe.example.com --token personal-access-token

For GitLab Self-hosted:
$ scalingo scm-integrations-create gitlab-self-hosted --url https://gitlab.example.com --token personal-access-token

# See also commands 'scm-integrations', 'scm-integrations-delete', 'scm-integrations-import-keys'`,

Action: func(c *cli.Context) {
if c.NArg() != 1 {
_ = cli.ShowCommandHelp(c, "scm-integrations-create")
return
}

link := c.String("url")
token := c.String("token")
scmType := scalingo.SCMType(c.Args()[0])

switch scmType {
case scalingo.SCMGithubType, scalingo.SCMGitlabType:
break
case scalingo.SCMGithubEnterpriseType, scalingo.SCMGitlabSelfHostedType:
if link == "" || token == "" {
errorQuit(errgo.New("both --url and --token must be set"))
}

u, err := url.Parse(link)
if err != nil || u.Scheme == "" || u.Host == "" {
errorQuit(errgo.Newf("'%s' is not a valid URL", link))
}
default:
errorQuit(errgo.New(
"Unknown SCM integration, available SCM integrations: github, github-enterprise, gitlab, gitlab-self-hosted",
))
}

args := scm_integrations.CreateArgs{
SCMType: scmType,
URL: link,
Token: token,
}

err := scm_integrations.Create(args)
if err != nil {
errorQuit(err)
}
},
BashComplete: func(c *cli.Context) {
_ = autocomplete.CmdFlagsAutoComplete(c, "scm-integrations-create")
},
}

scmIntegrationsDeleteCommand = cli.Command{
Name: "scm-integrations-delete",
Category: "SCM Integrations",
Usage: "Unlink your Scalingo account and your account on a SCM tool",
Description: `Unlink your Scalingo account and your account on a SCM tool:

$ scalingo scm-integrations-delete integration-type
OR
$ scalingo scm-integrations-delete integration-uuid

Examples:
$ scalingo scm-integrations-delete github-enterprise
$ scalingo scm-integrations-delete gitlab

# See also commands 'scm-integrations', 'scm-integrations-create', 'scm-integrations-import-keys'`,

Action: func(c *cli.Context) {
if c.NArg() != 1 {
_ = cli.ShowCommandHelp(c, "scm-integrations-delete")
return
}

err := scm_integrations.Delete(c.Args()[0])
if err != nil {
errorQuit(err)
}
},
BashComplete: func(c *cli.Context) {
_ = autocomplete.CmdFlagsAutoComplete(c, "scm-integrations-delete")
},
}

scmIntegrationsImportKeysCommand = cli.Command{
Name: "scm-integrations-import-keys",
Category: "SCM Integrations",
Usage: "Import public SSH keys from SCM account",
Description: `Import public SSH keys from SCM account:

$ scalingo scm-integrations-import-keys integration-type
OR
$ scalingo scm-integrations-import-keys integration-uuid

Examples:
$ scalingo scm-integrations-import-keys github
$ scalingo scm-integrations-import-keys gitlab-self-hosted

# See also commands 'scm-integrations', 'scm-integrations-create', 'scm-integrations-delete'`,

Action: func(c *cli.Context) {
if c.NArg() != 1 {
_ = cli.ShowCommandHelp(c, "scm-integrations-import-keys")
return
}

err := scm_integrations.ImportKeys(c.Args()[0])
if err != nil {
errorQuit(err)
}
},
BashComplete: func(c *cli.Context) {
_ = autocomplete.CmdFlagsAutoComplete(c, "scm-integrations-import-keys")
},
}
)
42 changes: 42 additions & 0 deletions scm_integrations/create.go
@@ -0,0 +1,42 @@
package scm_integrations

import (
"gopkg.in/errgo.v1"

"github.com/Scalingo/cli/config"
"github.com/Scalingo/cli/io"
"github.com/Scalingo/go-scalingo"
)

type CreateArgs struct {
SCMType scalingo.SCMType
URL string
Token string
}

func Create(args CreateArgs) error {
c, err := config.ScalingoClient()
if err != nil {
return errgo.Notef(err, "fail to get Scalingo client")
}

integrationExist := checkIfIntegrationAlreadyExist(c, args.SCMType.Str())
if integrationExist {
io.Statusf("SCM Integration '%s' is already linked with your Scalingo account.\n", args.SCMType)
return nil
}

if args.SCMType == scalingo.SCMGithubType || args.SCMType == scalingo.SCMGitlabType {
io.Statusf("Please follow this URL to create the %s SCM integration :\n", args.SCMType)
io.Statusf("%s/users/%s/link\n", config.C.ScalingoAuthUrl, args.SCMType)
return nil
}

_, err = c.SCMIntegrationsCreate(args.SCMType, args.URL, args.Token)
if err != nil {
return errgo.Notef(err, "fail to create the SCM integration")
}

io.Statusf("Your Scalingo account has been linked to your '%s' account.\n", args.SCMType)
return nil
}
28 changes: 28 additions & 0 deletions scm_integrations/delete.go
@@ -0,0 +1,28 @@
package scm_integrations

import (
"gopkg.in/errgo.v1"

"github.com/Scalingo/cli/config"
"github.com/Scalingo/cli/io"
)

func Delete(id string) error {
c, err := config.ScalingoClient()
if err != nil {
return errgo.Notef(err, "fail to get Scalingo client")
}

integration, err := c.SCMIntegrationsShow(id)
if err != nil {
return errgo.Notef(err, "not linked SCM integration or unknown SCM integration")
}

err = c.SCMIntegrationsDelete(id)
if err != nil {
return errgo.Notef(err, "fail to destroy SCM integration")
}

io.Statusf("Your Scalingo account and your '%s' account are unlinked.\n", integration.SCMType)
return nil
}