Skip to content

Commit e614895

Browse files
Merge pull request #165 from arunsathiya/add/ngrok
Add support for ngrok
2 parents f0b4724 + 7b61738 commit e614895

6 files changed

Lines changed: 235 additions & 0 deletions

File tree

plugins/ngrok/credentials.go

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
package ngrok
2+
3+
import (
4+
"context"
5+
6+
"github.com/1Password/shell-plugins/sdk"
7+
"github.com/1Password/shell-plugins/sdk/importer"
8+
"github.com/1Password/shell-plugins/sdk/provision"
9+
"github.com/1Password/shell-plugins/sdk/schema"
10+
"github.com/1Password/shell-plugins/sdk/schema/credname"
11+
"github.com/1Password/shell-plugins/sdk/schema/fieldname"
12+
"gopkg.in/yaml.v3"
13+
)
14+
15+
func Credentials() schema.CredentialType {
16+
return schema.CredentialType{
17+
Name: credname.Credentials,
18+
DocsURL: sdk.URL("https://ngrok.com/docs/ngrok-agent/config"),
19+
Fields: []schema.CredentialField{
20+
{
21+
Name: fieldname.AuthToken,
22+
MarkdownDescription: "Auth Token used to authenticate to ngrok.",
23+
Optional: false,
24+
Secret: true,
25+
Composition: &schema.ValueComposition{
26+
Length: 43,
27+
Charset: schema.Charset{
28+
Uppercase: true,
29+
Lowercase: true,
30+
Digits: true,
31+
},
32+
},
33+
},
34+
{
35+
Name: fieldname.APIKey,
36+
MarkdownDescription: "API Key used to authenticate to ngrok API.",
37+
Optional: true,
38+
Secret: true,
39+
Composition: &schema.ValueComposition{
40+
Length: 48,
41+
Charset: schema.Charset{
42+
Uppercase: true,
43+
Lowercase: true,
44+
Digits: true,
45+
},
46+
},
47+
},
48+
},
49+
DefaultProvisioner: provision.TempFile(ngrokConfig, provision.Filename("config.yml"), provision.AddArgs("--config", "{{ .Path }}")),
50+
Importer: importer.TryAll(
51+
importer.TryEnvVarPair(defaultEnvVarMapping),
52+
importer.MacOnly(
53+
TryngrokConfigFile("~/Library/Application Support/ngrok/ngrok.yml"),
54+
),
55+
importer.LinuxOnly(
56+
TryngrokConfigFile("~/.config/ngrok/ngrok.yml"),
57+
),
58+
)}
59+
}
60+
61+
func ngrokConfig(in sdk.ProvisionInput) ([]byte, error) {
62+
config := Config{
63+
AuthToken: in.ItemFields[fieldname.AuthToken],
64+
APIKey: in.ItemFields[fieldname.APIKey],
65+
Version: "2", // required field for ngrok CLI to work when file-based configuration is used; automatically configured by the CLI program and is not configurable by the user
66+
}
67+
contents, err := yaml.Marshal(&config)
68+
if err != nil {
69+
return nil, err
70+
}
71+
return []byte(contents), nil
72+
}
73+
74+
var defaultEnvVarMapping = map[string]sdk.FieldName{
75+
"NGROK_AUTHTOKEN": fieldname.AuthToken,
76+
"NGROK_API_KEY": fieldname.APIKey,
77+
}
78+
79+
func TryngrokConfigFile(path string) sdk.Importer {
80+
return importer.TryFile(path, func(ctx context.Context, contents importer.FileContents, in sdk.ImportInput, out *sdk.ImportAttempt) {
81+
var config Config
82+
if err := contents.ToYAML(&config); err != nil {
83+
out.AddError(err)
84+
return
85+
}
86+
87+
if config.AuthToken == "" || config.APIKey == "" || config.Version == "" {
88+
return
89+
}
90+
91+
out.AddCandidate(sdk.ImportCandidate{
92+
Fields: map[sdk.FieldName]string{
93+
fieldname.AuthToken: config.AuthToken,
94+
fieldname.APIKey: config.APIKey,
95+
},
96+
})
97+
})
98+
}
99+
100+
type Config struct {
101+
AuthToken string `yaml:"authtoken"`
102+
APIKey string `yaml:"api_key"`
103+
Version string
104+
}

plugins/ngrok/credentials_test.go

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
package ngrok
2+
3+
import (
4+
"testing"
5+
6+
"github.com/1Password/shell-plugins/sdk"
7+
"github.com/1Password/shell-plugins/sdk/plugintest"
8+
"github.com/1Password/shell-plugins/sdk/schema/fieldname"
9+
)
10+
11+
func TestCredentialsProvisioner(t *testing.T) {
12+
plugintest.TestProvisioner(t, Credentials().DefaultProvisioner, map[string]plugintest.ProvisionCase{
13+
"temp file": {
14+
ItemFields: map[sdk.FieldName]string{
15+
fieldname.AuthToken: "uSuQ7LUOJLs4xRbIySZ15F4v5KxfTnMknMdFEXAMPLE",
16+
fieldname.APIKey: "L4STpMP3K8FNaQjBo5EAsXA2SThzq0J7BKD3jUZgtEXAMPLE",
17+
},
18+
CommandLine: []string{"ngrok"},
19+
ExpectedOutput: sdk.ProvisionOutput{
20+
CommandLine: []string{"ngrok", "--config", "/tmp/config.yml"},
21+
Files: map[string]sdk.OutputFile{
22+
"/tmp/config.yml": {
23+
Contents: []byte(plugintest.LoadFixture(t, "config.yml")),
24+
},
25+
},
26+
},
27+
},
28+
})
29+
}
30+
31+
func TestCredentialsImporter(t *testing.T) {
32+
plugintest.TestImporter(t, Credentials().Importer, map[string]plugintest.ImportCase{
33+
"environment": {
34+
Environment: map[string]string{
35+
"NGROK_AUTHTOKEN": "uSuQ7LUOJLs4xRbIySZ15F4v5KxfTnMknMdFEXAMPLE",
36+
"NGROK_API_KEY": "L4STpMP3K8FNaQjBo5EAsXA2SThzq0J7BKD3jUZgtEXAMPLE",
37+
},
38+
ExpectedCandidates: []sdk.ImportCandidate{
39+
{
40+
Fields: map[sdk.FieldName]string{
41+
fieldname.AuthToken: "uSuQ7LUOJLs4xRbIySZ15F4v5KxfTnMknMdFEXAMPLE",
42+
fieldname.APIKey: "L4STpMP3K8FNaQjBo5EAsXA2SThzq0J7BKD3jUZgtEXAMPLE",
43+
},
44+
},
45+
},
46+
},
47+
"config file for macos": {
48+
OS: "darwin",
49+
Files: map[string]string{
50+
"~/Library/Application Support/ngrok/ngrok.yml": plugintest.LoadFixture(t, "config.yml"),
51+
},
52+
ExpectedCandidates: []sdk.ImportCandidate{
53+
{
54+
Fields: map[sdk.FieldName]string{
55+
fieldname.AuthToken: "uSuQ7LUOJLs4xRbIySZ15F4v5KxfTnMknMdFEXAMPLE",
56+
fieldname.APIKey: "L4STpMP3K8FNaQjBo5EAsXA2SThzq0J7BKD3jUZgtEXAMPLE",
57+
},
58+
},
59+
},
60+
},
61+
"config file for linux": {
62+
OS: "linux",
63+
Files: map[string]string{
64+
"~/.config/ngrok/ngrok.yml": plugintest.LoadFixture(t, "config.yml"),
65+
},
66+
ExpectedCandidates: []sdk.ImportCandidate{
67+
{
68+
Fields: map[sdk.FieldName]string{
69+
fieldname.AuthToken: "uSuQ7LUOJLs4xRbIySZ15F4v5KxfTnMknMdFEXAMPLE",
70+
fieldname.APIKey: "L4STpMP3K8FNaQjBo5EAsXA2SThzq0J7BKD3jUZgtEXAMPLE",
71+
},
72+
},
73+
},
74+
},
75+
})
76+
}

plugins/ngrok/ngrok.go

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package ngrok
2+
3+
import (
4+
"github.com/1Password/shell-plugins/sdk"
5+
"github.com/1Password/shell-plugins/sdk/needsauth"
6+
"github.com/1Password/shell-plugins/sdk/schema"
7+
"github.com/1Password/shell-plugins/sdk/schema/credname"
8+
)
9+
10+
func ngrokCLI() schema.Executable {
11+
return schema.Executable{
12+
Name: "ngrok CLI",
13+
Runs: []string{"ngrok"},
14+
DocsURL: sdk.URL("https://ngrok.com/docs/ngrok-agent/ngrok"),
15+
NeedsAuth: needsauth.IfAll(
16+
needsauth.NotForHelpOrVersion(),
17+
needsauth.NotWithoutArgs(),
18+
needsauth.NotWhenContainsArgs("--config"),
19+
needsauth.NotForExactArgs("config"),
20+
needsauth.NotForExactArgs("update"),
21+
),
22+
Uses: []schema.CredentialUsage{
23+
{
24+
Name: credname.Credentials,
25+
},
26+
},
27+
}
28+
}

plugins/ngrok/plugin.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package ngrok
2+
3+
import (
4+
"github.com/1Password/shell-plugins/sdk"
5+
"github.com/1Password/shell-plugins/sdk/schema"
6+
)
7+
8+
func New() schema.Plugin {
9+
return schema.Plugin{
10+
Name: "ngrok",
11+
Platform: schema.PlatformInfo{
12+
Name: "ngrok",
13+
Homepage: sdk.URL("https://ngrok.com"),
14+
},
15+
Credentials: []schema.CredentialType{
16+
Credentials(),
17+
},
18+
Executables: []schema.Executable{
19+
ngrokCLI(),
20+
},
21+
}
22+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
authtoken: uSuQ7LUOJLs4xRbIySZ15F4v5KxfTnMknMdFEXAMPLE
2+
api_key: L4STpMP3K8FNaQjBo5EAsXA2SThzq0J7BKD3jUZgtEXAMPLE
3+
version: "2"

sdk/schema/credname/names.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ const (
1313
AuthToken = sdk.CredentialName("Auth Token")
1414
CLIToken = sdk.CredentialName("CLI Token")
1515
Credential = sdk.CredentialName("Credential")
16+
Credentials = sdk.CredentialName("Credentials")
1617
DatabaseCredentials = sdk.CredentialName("Database Credentials")
1718
LoginDetails = sdk.CredentialName("Login Details")
1819
PersonalAPIToken = sdk.CredentialName("Personal API Token")
@@ -32,6 +33,7 @@ func ListAll() []sdk.CredentialName {
3233
AuthToken,
3334
CLIToken,
3435
Credential,
36+
Credentials,
3537
DatabaseCredentials,
3638
LoginDetails,
3739
PersonalAPIToken,

0 commit comments

Comments
 (0)