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

update(ngrok): switch to envvars provisioner for ngrok 3.2.1 and higher #222

Merged
1 change: 1 addition & 0 deletions go.mod
Expand Up @@ -51,6 +51,7 @@ require (
github.com/oklog/run v1.0.0 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966 // indirect
golang.org/x/mod v0.9.0
arunsathiya marked this conversation as resolved.
Show resolved Hide resolved
golang.org/x/net v0.8.0 // indirect
golang.org/x/sys v0.6.0 // indirect
golang.org/x/term v0.6.0 // indirect
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Expand Up @@ -136,6 +136,8 @@ golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL
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-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/mod v0.9.0 h1:KENHtAZL2y3NLMYZeHY9DW8HW8V+kQyJsY/V9JlKvCs=
golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/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-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
Expand Down
2 changes: 1 addition & 1 deletion plugins/ngrok/credentials.go
Expand Up @@ -45,7 +45,7 @@ func Credentials() schema.CredentialType {
},
},
},
DefaultProvisioner: newNgrokProvisioner(),
DefaultProvisioner: ngrokEnvVarProvisioner{},
arunsathiya marked this conversation as resolved.
Show resolved Hide resolved
Importer: importer.TryAll(
importer.TryEnvVarPair(defaultEnvVarMapping),
importer.MacOnly(
Expand Down
2 changes: 1 addition & 1 deletion plugins/ngrok/credentials_test.go
Expand Up @@ -10,7 +10,7 @@ import (
)

func TestCredentialsProvisioner(t *testing.T) {
plugintest.TestProvisioner(t, Credentials().DefaultProvisioner, map[string]plugintest.ProvisionCase{
plugintest.TestProvisioner(t, ngrokProvisioner(), map[string]plugintest.ProvisionCase{
"temp file": {
ItemFields: map[sdk.FieldName]string{
fieldname.Authtoken: "uSuQ7LUOJLs4xRbIySZ15F4v5KxfTnMknMdFEXAMPLE",
Expand Down
42 changes: 42 additions & 0 deletions plugins/ngrok/env_var_provisioner.go
@@ -0,0 +1,42 @@
package ngrok

import (
"context"
"fmt"

"github.com/1Password/shell-plugins/sdk"
"github.com/1Password/shell-plugins/sdk/schema/fieldname"
"golang.org/x/mod/semver"
)

type ngrokEnvVarProvisioner struct {
}

func (p ngrokEnvVarProvisioner) Provision(ctx context.Context, in sdk.ProvisionInput, out *sdk.ProvisionOutput) {
currentVersion, err := getNgrokVersion()
if err != nil {
out.AddError(err)
return
}

// If the current ngrok CLI version is 3.2.1 or higher,
// use environment variables to provision the Shell Plugin credentials
//
// semver.Compare resulting in 0 means 3.2.1 is in use
// semver.Compare resulting in +1 means >3.2.1 is in use
if semver.Compare(currentVersion, envVarAuthVersion) == -1 {
out.AddError(fmt.Errorf("ngrok version %s is not supported. Please upgrade to version %s or higher", currentVersion, envVarAuthVersion))
return
}

out.AddEnvVar("NGROK_AUTHTOKEN", in.ItemFields[fieldname.Authtoken])
out.AddEnvVar("NGROK_API_KEY", in.ItemFields[fieldname.APIKey])
}

func (p ngrokEnvVarProvisioner) Deprovision(ctx context.Context, in sdk.DeprovisionInput, out *sdk.DeprovisionOutput) {
// Nothing to do here: environment variables get wiped automatically when the process exits.
}

func (p ngrokEnvVarProvisioner) Description() string {
return "Provision ngrok credentials as environment variables NGROK_AUTH_TOKEN and NGROK_API_KEY"
}
3 changes: 2 additions & 1 deletion plugins/ngrok/ngrok.go
Expand Up @@ -23,7 +23,8 @@ func ngrokCLI() schema.Executable {
),
Uses: []schema.CredentialUsage{
{
Name: credname.Credentials,
Name: credname.Credentials,
Provisioner: ngrokProvisioner(),
},
},
}
Expand Down
44 changes: 43 additions & 1 deletion plugins/ngrok/provisioner.go
Expand Up @@ -2,15 +2,18 @@ package ngrok

import (
"context"
"errors"
"fmt"
"os"
"os/exec"
"path/filepath"
"runtime"
"strings"

"github.com/1Password/shell-plugins/sdk"
"github.com/1Password/shell-plugins/sdk/importer"
"github.com/1Password/shell-plugins/sdk/schema/fieldname"
"golang.org/x/mod/semver"
"gopkg.in/yaml.v3"
)

Expand All @@ -19,12 +22,30 @@ const (
apiKeyYamlName = "api_key"
authTokenYamlName = "authtoken"
versionYamlName = "version"
envVarAuthVersion = "v3.2.1"
)

type fileProvisioner struct {
}

func newNgrokProvisioner() sdk.Provisioner {
func ngrokProvisioner() sdk.Provisioner {
currentVersion, err := getNgrokVersion()
if err != nil {
// When ngrok version check fails for any reason,
// use config file to provision as a fallback
return fileProvisioner{}
}

// If the current ngrok CLI version is 3.2.1 or higher,
// use environment variables to provision credentials
//
// semver.Compare resulting in 0 means 3.2.1 is in use
// semver.Compare resulting in +1 means >3.2.1 is in use
if semver.Compare(currentVersion, envVarAuthVersion) >= 0 {
return ngrokEnvVarProvisioner{}
}

// Otherwise use config file to provision credentials
return fileProvisioner{}
}

Expand Down Expand Up @@ -95,6 +116,27 @@ func getConfigValueAndNewArgs(args []string, newFilePath string) (string, []stri
return "", append(args, fmt.Sprintf("--config=%s", newFilePath))
}

// Get installed ngrok version and required version
func getNgrokVersion() (string, error) {
cmd := exec.Command("ngrok", "--version")
ngrokVersion, err := cmd.Output()
if err != nil {
return "", errors.New("ngrok not found")
}

// Example: "ngrok version 3.1.1\n" to "3.1.1\n"
currentVersion := strings.TrimPrefix(string(ngrokVersion), "ngrok version ")

// Example: "3.1.1\n" to "3.1.1"
currentVersion = strings.Trim(currentVersion, "\n")

// Example: "3.1.1" to "v3.1.1" as that's the format
// the package semver expects
currentVersion = "v" + currentVersion

return currentVersion, nil
}

func (f fileProvisioner) Deprovision(ctx context.Context, in sdk.DeprovisionInput, out *sdk.DeprovisionOutput) {
// nothing to do here: files get deleted automatically by 1Password CLI
}
Expand Down