Skip to content

Commit 24adb36

Browse files
committed
feat(plugin): add cockroach sql support
Adds the ability to read Database Credentials and inject for `cockroach sql`. Signed-off-by: Anton Antonov <[email protected]>
1 parent 61135fa commit 24adb36

File tree

4 files changed

+282
-0
lines changed

4 files changed

+282
-0
lines changed

plugins/cockroachdb/cockroach.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package cockroachdb
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 Cockroach() schema.Executable {
11+
return schema.Executable{
12+
Name: "cockroach",
13+
Runs: []string{"cockroach"},
14+
DocsURL: sdk.URL("https://www.cockroachlabs.com/docs/stable/cockroach-sql.html"),
15+
NeedsAuth: needsauth.IfAll(
16+
needsauth.NotForHelpOrVersion(),
17+
needsauth.ForCommand("sql"),
18+
needsauth.NotWithoutArgs(),
19+
),
20+
Uses: []schema.CredentialUsage{
21+
{
22+
Name: credname.DatabaseCredentials,
23+
},
24+
},
25+
}
26+
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
package cockroachdb
2+
3+
import (
4+
"github.com/1Password/shell-plugins/sdk"
5+
"github.com/1Password/shell-plugins/sdk/importer"
6+
"github.com/1Password/shell-plugins/sdk/provision"
7+
"github.com/1Password/shell-plugins/sdk/schema"
8+
"github.com/1Password/shell-plugins/sdk/schema/credname"
9+
"github.com/1Password/shell-plugins/sdk/schema/fieldname"
10+
)
11+
12+
func DatabaseCredentials() schema.CredentialType {
13+
return schema.CredentialType{
14+
Name: credname.DatabaseCredentials,
15+
DocsURL: sdk.URL("https://www.cockroachlabs.com/docs/stable/connection-parameters.html"),
16+
ManagementURL: sdk.URL("https://cockroachlabs.cloud/"),
17+
Fields: []schema.CredentialField{
18+
{
19+
Name: fieldname.Host,
20+
MarkdownDescription: "CockroachDB host to connect to.",
21+
},
22+
{
23+
Name: fieldname.Port,
24+
MarkdownDescription: "Port used to connect to CockroachDB.",
25+
Optional: true,
26+
},
27+
{
28+
Name: fieldname.User,
29+
MarkdownDescription: "CockroachDB user to authenticate as.",
30+
},
31+
{
32+
Name: fieldname.Password,
33+
MarkdownDescription: "Password used to authenticate to CockroachDB.",
34+
Secret: true,
35+
Optional: true,
36+
},
37+
{
38+
Name: fieldname.Database,
39+
MarkdownDescription: "Database name to connect to. Defaults to 'defaultdb'.",
40+
Optional: true,
41+
},
42+
{
43+
Name: "insecure",
44+
MarkdownDescription: "Connect in insecure mode (skip TLS verification). Set to '1' to skip TLS verification.",
45+
Optional: true,
46+
},
47+
},
48+
DefaultProvisioner: provision.EnvVars(defaultEnvVarMapping),
49+
Importer: importer.TryEnvVarPair(defaultEnvVarMapping),
50+
}
51+
}
52+
53+
var defaultEnvVarMapping = map[string]sdk.FieldName{
54+
"COCKROACH_HOST": fieldname.Host,
55+
"COCKROACH_PORT": fieldname.Port,
56+
"COCKROACH_USER": fieldname.User,
57+
"COCKROACH_PASSWORD": fieldname.Password,
58+
"COCKROACH_DATABASE": fieldname.Database,
59+
"COCKROACH_INSECURE": "insecure",
60+
}
Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
1+
package cockroachdb
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"
9+
"github.com/1Password/shell-plugins/sdk/schema/credname"
10+
"github.com/1Password/shell-plugins/sdk/schema/fieldname"
11+
)
12+
13+
func TestDatabaseCredentialsImporter(t *testing.T) {
14+
plugintest.TestImporter(t, DatabaseCredentials().Importer, map[string]plugintest.ImportCase{
15+
"environment variables - complete": {
16+
Environment: map[string]string{
17+
"COCKROACH_HOST": "localhost",
18+
"COCKROACH_PORT": "26257",
19+
"COCKROACH_USER": "root",
20+
"COCKROACH_PASSWORD": "password123",
21+
"COCKROACH_DATABASE": "defaultdb",
22+
"COCKROACH_INSECURE": "1",
23+
},
24+
ExpectedCandidates: []sdk.ImportCandidate{
25+
{
26+
Fields: map[sdk.FieldName]string{
27+
fieldname.Host: "localhost",
28+
fieldname.Port: "26257",
29+
fieldname.User: "root",
30+
fieldname.Password: "password123",
31+
fieldname.Database: "defaultdb",
32+
"insecure": "1",
33+
},
34+
},
35+
},
36+
},
37+
"environment variables - minimal": {
38+
Environment: map[string]string{
39+
"COCKROACH_HOST": "cockroach.example.com",
40+
"COCKROACH_USER": "admin",
41+
},
42+
ExpectedCandidates: []sdk.ImportCandidate{
43+
{
44+
Fields: map[sdk.FieldName]string{
45+
fieldname.Host: "cockroach.example.com",
46+
fieldname.User: "admin",
47+
},
48+
},
49+
},
50+
},
51+
"environment variables - production secure": {
52+
Environment: map[string]string{
53+
"COCKROACH_HOST": "prod-cluster.cockroachlabs.cloud",
54+
"COCKROACH_PORT": "26257",
55+
"COCKROACH_USER": "produser",
56+
"COCKROACH_PASSWORD": "securepass123",
57+
"COCKROACH_DATABASE": "proddb",
58+
"COCKROACH_INSECURE": "0",
59+
},
60+
ExpectedCandidates: []sdk.ImportCandidate{
61+
{
62+
Fields: map[sdk.FieldName]string{
63+
fieldname.Host: "prod-cluster.cockroachlabs.cloud",
64+
fieldname.Port: "26257",
65+
fieldname.User: "produser",
66+
fieldname.Password: "securepass123",
67+
fieldname.Database: "proddb",
68+
"insecure": "0",
69+
},
70+
},
71+
},
72+
},
73+
})
74+
}
75+
76+
func TestDatabaseCredentialsProvisioner(t *testing.T) {
77+
plugintest.TestProvisioner(t, DatabaseCredentials().DefaultProvisioner, map[string]plugintest.ProvisionCase{
78+
"local development - insecure": {
79+
ItemFields: map[sdk.FieldName]string{
80+
fieldname.Host: "localhost",
81+
fieldname.Port: "26257",
82+
fieldname.User: "root",
83+
fieldname.Password: "password123",
84+
fieldname.Database: "defaultdb",
85+
"insecure": "1",
86+
},
87+
ExpectedOutput: sdk.ProvisionOutput{
88+
Environment: map[string]string{
89+
"COCKROACH_HOST": "localhost",
90+
"COCKROACH_PORT": "26257",
91+
"COCKROACH_USER": "root",
92+
"COCKROACH_PASSWORD": "password123",
93+
"COCKROACH_DATABASE": "defaultdb",
94+
"COCKROACH_INSECURE": "1",
95+
},
96+
},
97+
},
98+
"production - secure": {
99+
ItemFields: map[sdk.FieldName]string{
100+
fieldname.Host: "prod-cluster.cockroachlabs.cloud",
101+
fieldname.Port: "26257",
102+
fieldname.User: "produser",
103+
fieldname.Password: "securepass123",
104+
fieldname.Database: "proddb",
105+
},
106+
ExpectedOutput: sdk.ProvisionOutput{
107+
Environment: map[string]string{
108+
"COCKROACH_HOST": "prod-cluster.cockroachlabs.cloud",
109+
"COCKROACH_PORT": "26257",
110+
"COCKROACH_USER": "produser",
111+
"COCKROACH_PASSWORD": "securepass123",
112+
"COCKROACH_DATABASE": "proddb",
113+
},
114+
},
115+
},
116+
"minimal configuration": {
117+
ItemFields: map[sdk.FieldName]string{
118+
fieldname.Host: "cockroach.example.com",
119+
fieldname.User: "admin",
120+
},
121+
ExpectedOutput: sdk.ProvisionOutput{
122+
Environment: map[string]string{
123+
"COCKROACH_HOST": "cockroach.example.com",
124+
"COCKROACH_USER": "admin",
125+
},
126+
},
127+
},
128+
})
129+
}
130+
131+
// TestCockroachSQLExecutable tests the cockroach sql executable configuration
132+
func TestCockroachSQLExecutable(t *testing.T) {
133+
plugin := New()
134+
135+
// Find the cockroach sql executable
136+
var cockroachSQL *schema.Executable
137+
for _, exec := range plugin.Executables {
138+
if exec.Name == "cockroach" {
139+
cockroachSQL = &exec
140+
break
141+
}
142+
}
143+
144+
if cockroachSQL == nil {
145+
t.Fatal("cockroach sql executable not found in plugin")
146+
}
147+
148+
// Test that it uses database credentials
149+
if len(cockroachSQL.Uses) != 1 {
150+
t.Errorf("Expected 1 credential usage, got %d", len(cockroachSQL.Uses))
151+
}
152+
153+
if cockroachSQL.Uses[0].Name != credname.DatabaseCredentials {
154+
t.Errorf("Expected DatabaseCredentials, got %s", cockroachSQL.Uses[0].Name)
155+
}
156+
}
157+
158+
// TestPluginValidation tests that the plugin passes all validation checks
159+
func TestPluginValidation(t *testing.T) {
160+
plugin := New()
161+
162+
// Basic plugin validation
163+
if plugin.Name != "cockroachdb" {
164+
t.Errorf("Expected plugin name 'cockroachdb', got '%s'", plugin.Name)
165+
}
166+
167+
if len(plugin.Credentials) != 1 {
168+
t.Errorf("Expected 1 credential type, got %d", len(plugin.Credentials))
169+
}
170+
171+
if len(plugin.Executables) != 1 {
172+
t.Errorf("Expected 1 executable, got %d", len(plugin.Executables))
173+
}
174+
}

plugins/cockroachdb/plugin.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package cockroachdb
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: "cockroachdb",
11+
Platform: schema.PlatformInfo{
12+
Name: "CockroachDB",
13+
Homepage: sdk.URL("https://www.cockroachlabs.com"),
14+
},
15+
Credentials: []schema.CredentialType{
16+
DatabaseCredentials(),
17+
},
18+
Executables: []schema.Executable{
19+
Cockroach(),
20+
},
21+
}
22+
}

0 commit comments

Comments
 (0)