Skip to content

Commit

Permalink
Merge pull request #93 from runatlantis/bootstrap
Browse files Browse the repository at this point in the history
Use custom ngrok config so we can specify api url.
  • Loading branch information
lkysow authored Mar 29, 2018
2 parents 9e47d11 + 551f895 commit e84ce0b
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 28 deletions.
32 changes: 23 additions & 9 deletions bootstrap/bootstrap.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ package bootstrap
import (
"context"
"fmt"
"net"
"io/ioutil"
"os"
"os/exec"
"os/signal"
Expand Down Expand Up @@ -129,16 +129,30 @@ Follow these instructions to create a token (we don't store any tokens):
// Create ngrok tunnel.
colorstring.Println("[white]=> creating secure tunnel")
s.Start()
// Check if there is already an ngrok running by seeing if there's already
// something bound to its API port.
conn, err := net.Dial("tcp", ngrokAPIURL)
// We expect an error.
if err == nil {
conn.Close() // nolint: errcheck
return errors.New("unable to start ngrok because there is already something bound to its API port: " + ngrokAPIURL)

// We use a config file so we can set ngrok's API port (web_addr). We use
// the API to get the public URL and if there's already ngrok running, it
// will just choose a random API port and we won't be able to get the right
// url.
ngrokConfig := fmt.Sprintf(`
web_addr: %s
tunnels:
atlantis:
addr: %d
bind_tls: true
proto: http
`, ngrokAPIURL, atlantisPort)

ngrokConfigFile, err := ioutil.TempFile("", "")
if err != nil {
return errors.Wrap(err, "creating ngrok config file")
}
err = ioutil.WriteFile(ngrokConfigFile.Name(), []byte(ngrokConfig), 0600)
if err != nil {
return errors.Wrap(err, "writing ngrok config file")
}

ngrokCmd, err := executeCmd("/tmp/ngrok", []string{"http", "4141"})
ngrokCmd, err := executeCmd("/tmp/ngrok", []string{"start", "atlantis", "--config", ngrokConfigFile.Name()})
if err != nil {
return errors.Wrapf(err, "creating ngrok tunnel")
}
Expand Down
43 changes: 24 additions & 19 deletions bootstrap/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,15 @@ import (
"path/filepath"
"syscall"

"github.com/pkg/errors"
"golang.org/x/crypto/ssh/terminal"
)

var hashicorpReleasesURL = "https://releases.hashicorp.com"
var terraformVersion = "0.10.8"
var ngrokDownloadURL = "https://bin.equinox.io/c/4VmDzA7iaHb"
var ngrokAPIURL = "localhost:4040"
const hashicorpReleasesURL = "https://releases.hashicorp.com"
const terraformVersion = "0.10.8"
const ngrokDownloadURL = "https://bin.equinox.io/c/4VmDzA7iaHb"
const ngrokAPIURL = "localhost:41414" // We hope this isn't used.
const atlantisPort = 4141

func readPassword() (string, error) {
password, err := terminal.ReadPassword(syscall.Stdin)
Expand Down Expand Up @@ -90,35 +92,38 @@ func unzip(archive, target string) error {
}

func getTunnelAddr() (string, error) {
response, err := http.Get(fmt.Sprintf("http://%s/api/tunnels", ngrokAPIURL))
tunAPI := fmt.Sprintf("http://%s/api/tunnels", ngrokAPIURL)
response, err := http.Get(tunAPI)
if err != nil {
return "", err
}
defer response.Body.Close() // nolint: errcheck

type tunnel struct {
Name string `json:"name"`
URI string `json:"uri"`
PublicURL string `json:"public_url"`
Proto string `json:"http"`
}

type tunnels struct {
Tunnels []tunnel
Tunnels []struct {
PublicURL string `json:"public_url"`
Proto string `json:"proto"`
Config struct {
Addr string `json:"addr"`
} `json:"config"`
} `json:"tunnels"`
}

var t tunnels

err = json.NewDecoder(response.Body).Decode(&t)
if err != nil {
return "", err
if err = json.NewDecoder(response.Body).Decode(&t); err != nil {
return "", errors.Wrapf(err, "parsing ngrok api at %s", tunAPI)
}

if len(t.Tunnels) != 2 {
return "", fmt.Errorf("didn't find tunnels that were expected to be created")
// Find the tunnel we just created.
expAtlantisURL := fmt.Sprintf("localhost:%d", atlantisPort)
for _, tun := range t.Tunnels {
if tun.Proto == "https" && tun.Config.Addr == expAtlantisURL {
return tun.PublicURL, nil
}
}

return t.Tunnels[1].PublicURL, nil
return "", fmt.Errorf("did not find ngrok tunnel with proto 'https' and config.addr '%s' in list of tunnels at %s", expAtlantisURL, tunAPI)
}

// nolint: unparam
Expand Down

0 comments on commit e84ce0b

Please sign in to comment.