Skip to content

Commit a8d1021

Browse files
Add support for SSH Key Item category in data source (#158)
Signed-off-by: Abhinav Tamaskar <[email protected]> Co-authored-by: Eddy Filip <[email protected]>
1 parent b0ed23b commit a8d1021

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

63 files changed

+15667
-3
lines changed

docs/data-sources/item.md

+3-1
Original file line numberDiff line numberDiff line change
@@ -34,14 +34,16 @@ data "onepassword_item" "example" {
3434

3535
### Read-Only
3636

37-
- `category` (String) The category of the item. One of ["login" "password" "database" "secure_note" "document"]
37+
- `category` (String) The category of the item. One of ["login" "password" "database" "secure_note" "document" "ssh_key"]
3838
- `credential` (String, Sensitive) API credential for this item.
3939
- `database` (String) (Only applies to the database category) The name of the database.
4040
- `file` (Block List) A list of files attached to the item. (see [below for nested schema](#nestedblock--file))
4141
- `hostname` (String) (Only applies to the database category) The address where the database can be found
4242
- `id` (String) The Terraform resource identifier for this item in the format `vaults/<vault_id>/items/<item_id>`.
4343
- `password` (String, Sensitive) Password for this item.
4444
- `port` (String) (Only applies to the database category) The port the database is listening on.
45+
- `private_key` (String, Sensitive) SSH Private Key for this item.
46+
- `public_key` (String) SSH Public Key for this item.
4547
- `section` (Block List) A list of custom sections in an item (see [below for nested schema](#nestedblock--section))
4648
- `tags` (List of String) An array of strings of the tags assigned to the item.
4749
- `type` (String) (Only applies to the database category) The type of database. One of ["db2" "filemaker" "msaccess" "mssql" "mysql" "oracle" "postgresql" "sqlite" "other"]

go.mod

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ require (
1414
github.com/hashicorp/terraform-plugin-go v0.23.0
1515
github.com/hashicorp/terraform-plugin-log v0.9.0
1616
github.com/hashicorp/terraform-plugin-testing v1.7.0
17+
golang.org/x/crypto v0.23.0
1718
)
1819

1920
require (
@@ -76,7 +77,6 @@ require (
7677
github.com/zclconf/go-cty v1.14.4 // indirect
7778
go.abhg.dev/goldmark/frontmatter v0.2.0 // indirect
7879
go.uber.org/atomic v1.11.0 // indirect
79-
golang.org/x/crypto v0.23.0 // indirect
8080
golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df // indirect
8181
golang.org/x/mod v0.17.0 // indirect
8282
golang.org/x/net v0.25.0 // indirect

internal/provider/const.go

+6-1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ const (
1919
passwordDescription = "Password for this item."
2020
credentialDescription = "API credential for this item."
2121
noteValueDescription = "Secure Note value."
22+
publicKeyDescription = "SSH Public Key for this item."
23+
privateKeyDescription = "SSH Private Key for this item."
2224

2325
dbHostnameDescription = "(Only applies to the database category) The address where the database can be found"
2426
dbDatabaseDescription = "(Only applies to the database category) The name of the database."
@@ -67,7 +69,10 @@ var (
6769
strings.ToLower(string(op.Database)),
6870
strings.ToLower(string(op.SecureNote)),
6971
}
70-
dataSourceCategories = append(categories, strings.ToLower(string(op.Document)))
72+
dataSourceCategories = append(categories,
73+
strings.ToLower(string(op.Document)),
74+
strings.ToLower(string(op.SSHKey)),
75+
)
7176

7277
fieldPurposes = []string{
7378
string(op.FieldPurposeUsername),

internal/provider/onepassword_item_data_source.go

+15
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ type OnePasswordItemDataSourceModel struct {
4848
Password types.String `tfsdk:"password"`
4949
NoteValue types.String `tfsdk:"note_value"`
5050
Credential types.String `tfsdk:"credential"`
51+
PublicKey types.String `tfsdk:"public_key"`
52+
PrivateKey types.String `tfsdk:"private_key"`
5153
Section []OnePasswordItemSectionModel `tfsdk:"section"`
5254
File []OnePasswordItemFileModel `tfsdk:"file"`
5355
}
@@ -180,6 +182,15 @@ func (d *OnePasswordItemDataSource) Schema(ctx context.Context, req datasource.S
180182
Optional: true,
181183
Sensitive: true,
182184
},
185+
"public_key": schema.StringAttribute{
186+
MarkdownDescription: publicKeyDescription,
187+
Computed: true,
188+
},
189+
"private_key": schema.StringAttribute{
190+
MarkdownDescription: privateKeyDescription,
191+
Computed: true,
192+
Sensitive: true,
193+
},
183194
},
184195
Blocks: map[string]schema.Block{
185196
"section": schema.ListNestedBlock{
@@ -360,6 +371,10 @@ func (d *OnePasswordItemDataSource) Read(ctx context.Context, req datasource.Rea
360371
data.Port = types.StringValue(f.Value)
361372
case "type":
362373
data.Type = types.StringValue(f.Value)
374+
case "public key":
375+
data.PublicKey = types.StringValue(f.Value)
376+
case "private key":
377+
data.PrivateKey = types.StringValue(f.Value)
363378
}
364379
}
365380

internal/provider/onepassword_item_data_source_test.go

+30
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,36 @@ func TestAccItemLoginWithFiles(t *testing.T) {
227227
})
228228
}
229229

230+
func TestAccItemSSHKey(t *testing.T) {
231+
expectedItem := generateSSHKeyItem()
232+
expectedVault := op.Vault{
233+
ID: expectedItem.Vault.ID,
234+
Name: "Name of the vault",
235+
Description: "This vault will be retrieved",
236+
}
237+
238+
testServer := setupTestServer(expectedItem, expectedVault, t)
239+
defer testServer.Close()
240+
241+
resource.Test(t, resource.TestCase{
242+
ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
243+
Steps: []resource.TestStep{
244+
{
245+
Config: testAccProviderConfig(testServer.URL) + testAccItemDataSourceConfig(expectedItem.Vault.ID, expectedItem.ID),
246+
Check: resource.ComposeAggregateTestCheckFunc(
247+
resource.TestCheckResourceAttr("data.onepassword_item.test", "id", fmt.Sprintf("vaults/%s/items/%s", expectedVault.ID, expectedItem.ID)),
248+
resource.TestCheckResourceAttr("data.onepassword_item.test", "vault", expectedVault.ID),
249+
resource.TestCheckResourceAttr("data.onepassword_item.test", "title", expectedItem.Title),
250+
resource.TestCheckResourceAttr("data.onepassword_item.test", "uuid", expectedItem.ID),
251+
resource.TestCheckResourceAttr("data.onepassword_item.test", "category", strings.ToLower(string(expectedItem.Category))),
252+
resource.TestCheckResourceAttr("data.onepassword_item.test", "private_key", expectedItem.Fields[0].Value),
253+
resource.TestCheckResourceAttr("data.onepassword_item.test", "public_key", expectedItem.Fields[1].Value),
254+
),
255+
},
256+
},
257+
})
258+
}
259+
230260
func testAccItemDataSourceConfig(vault, uuid string) string {
231261
return fmt.Sprintf(`
232262
data "onepassword_item" "test" {

internal/provider/test_utils.go

+40
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,15 @@
11
package provider
22

33
import (
4+
"crypto/rand"
5+
"crypto/rsa"
6+
"crypto/x509"
7+
"encoding/base64"
8+
"encoding/pem"
49
"fmt"
510

611
"github.com/1Password/connect-sdk-go/onepassword"
12+
"golang.org/x/crypto/ssh"
713
)
814

915
func generateBaseItem() onepassword.Item {
@@ -65,6 +71,14 @@ func generateLoginItem() *onepassword.Item {
6571
return &item
6672
}
6773

74+
func generateSSHKeyItem() *onepassword.Item {
75+
item := generateBaseItem()
76+
item.Category = onepassword.SSHKey
77+
item.Fields = generateSSHKeyFields()
78+
79+
return &item
80+
}
81+
6882
func generateSecureNoteItem() *onepassword.Item {
6983
item := generateBaseItem()
7084
item.Category = onepassword.SecureNote
@@ -186,3 +200,29 @@ func generateLoginFields() []*onepassword.ItemField {
186200
}
187201
return fields
188202
}
203+
204+
func generateSSHKeyFields() []*onepassword.ItemField {
205+
bitSize := 2048
206+
privateKey, err := rsa.GenerateKey(rand.Reader, bitSize)
207+
if err != nil {
208+
panic(err)
209+
}
210+
privateKeyPem := &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(privateKey)}
211+
publicRSAKey, err := ssh.NewPublicKey(&privateKey.PublicKey)
212+
if err != nil {
213+
panic(err)
214+
}
215+
publicKey := "ssh-rsa " + base64.StdEncoding.EncodeToString(publicRSAKey.Marshal())
216+
217+
fields := []*onepassword.ItemField{
218+
{
219+
Label: "private key",
220+
Value: string(pem.EncodeToMemory(privateKeyPem)),
221+
},
222+
{
223+
Label: "public key",
224+
Value: publicKey,
225+
},
226+
}
227+
return fields
228+
}

vendor/golang.org/x/crypto/chacha20/chacha_arm64.go

+16
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)