Skip to content

Commit

Permalink
Add support for SSH Key Item category in data source (#158)
Browse files Browse the repository at this point in the history
Signed-off-by: Abhinav Tamaskar <abhinav@narmi.com>
Co-authored-by: Eddy Filip <eddy.filip@agilebits.com>
  • Loading branch information
atammy-narmi and edif2008 authored Jun 17, 2024
1 parent b0ed23b commit a8d1021
Show file tree
Hide file tree
Showing 63 changed files with 15,667 additions and 3 deletions.
4 changes: 3 additions & 1 deletion docs/data-sources/item.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,16 @@ data "onepassword_item" "example" {

### Read-Only

- `category` (String) The category of the item. One of ["login" "password" "database" "secure_note" "document"]
- `category` (String) The category of the item. One of ["login" "password" "database" "secure_note" "document" "ssh_key"]
- `credential` (String, Sensitive) API credential for this item.
- `database` (String) (Only applies to the database category) The name of the database.
- `file` (Block List) A list of files attached to the item. (see [below for nested schema](#nestedblock--file))
- `hostname` (String) (Only applies to the database category) The address where the database can be found
- `id` (String) The Terraform resource identifier for this item in the format `vaults/<vault_id>/items/<item_id>`.
- `password` (String, Sensitive) Password for this item.
- `port` (String) (Only applies to the database category) The port the database is listening on.
- `private_key` (String, Sensitive) SSH Private Key for this item.
- `public_key` (String) SSH Public Key for this item.
- `section` (Block List) A list of custom sections in an item (see [below for nested schema](#nestedblock--section))
- `tags` (List of String) An array of strings of the tags assigned to the item.
- `type` (String) (Only applies to the database category) The type of database. One of ["db2" "filemaker" "msaccess" "mssql" "mysql" "oracle" "postgresql" "sqlite" "other"]
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ require (
github.com/hashicorp/terraform-plugin-go v0.23.0
github.com/hashicorp/terraform-plugin-log v0.9.0
github.com/hashicorp/terraform-plugin-testing v1.7.0
golang.org/x/crypto v0.23.0
)

require (
Expand Down Expand Up @@ -76,7 +77,6 @@ require (
github.com/zclconf/go-cty v1.14.4 // indirect
go.abhg.dev/goldmark/frontmatter v0.2.0 // indirect
go.uber.org/atomic v1.11.0 // indirect
golang.org/x/crypto v0.23.0 // indirect
golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df // indirect
golang.org/x/mod v0.17.0 // indirect
golang.org/x/net v0.25.0 // indirect
Expand Down
7 changes: 6 additions & 1 deletion internal/provider/const.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ const (
passwordDescription = "Password for this item."
credentialDescription = "API credential for this item."
noteValueDescription = "Secure Note value."
publicKeyDescription = "SSH Public Key for this item."
privateKeyDescription = "SSH Private Key for this item."

dbHostnameDescription = "(Only applies to the database category) The address where the database can be found"
dbDatabaseDescription = "(Only applies to the database category) The name of the database."
Expand Down Expand Up @@ -67,7 +69,10 @@ var (
strings.ToLower(string(op.Database)),
strings.ToLower(string(op.SecureNote)),
}
dataSourceCategories = append(categories, strings.ToLower(string(op.Document)))
dataSourceCategories = append(categories,
strings.ToLower(string(op.Document)),
strings.ToLower(string(op.SSHKey)),
)

fieldPurposes = []string{
string(op.FieldPurposeUsername),
Expand Down
15 changes: 15 additions & 0 deletions internal/provider/onepassword_item_data_source.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ type OnePasswordItemDataSourceModel struct {
Password types.String `tfsdk:"password"`
NoteValue types.String `tfsdk:"note_value"`
Credential types.String `tfsdk:"credential"`
PublicKey types.String `tfsdk:"public_key"`
PrivateKey types.String `tfsdk:"private_key"`
Section []OnePasswordItemSectionModel `tfsdk:"section"`
File []OnePasswordItemFileModel `tfsdk:"file"`
}
Expand Down Expand Up @@ -180,6 +182,15 @@ func (d *OnePasswordItemDataSource) Schema(ctx context.Context, req datasource.S
Optional: true,
Sensitive: true,
},
"public_key": schema.StringAttribute{
MarkdownDescription: publicKeyDescription,
Computed: true,
},
"private_key": schema.StringAttribute{
MarkdownDescription: privateKeyDescription,
Computed: true,
Sensitive: true,
},
},
Blocks: map[string]schema.Block{
"section": schema.ListNestedBlock{
Expand Down Expand Up @@ -360,6 +371,10 @@ func (d *OnePasswordItemDataSource) Read(ctx context.Context, req datasource.Rea
data.Port = types.StringValue(f.Value)
case "type":
data.Type = types.StringValue(f.Value)
case "public key":
data.PublicKey = types.StringValue(f.Value)
case "private key":
data.PrivateKey = types.StringValue(f.Value)
}
}

Expand Down
30 changes: 30 additions & 0 deletions internal/provider/onepassword_item_data_source_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,36 @@ func TestAccItemLoginWithFiles(t *testing.T) {
})
}

func TestAccItemSSHKey(t *testing.T) {
expectedItem := generateSSHKeyItem()
expectedVault := op.Vault{
ID: expectedItem.Vault.ID,
Name: "Name of the vault",
Description: "This vault will be retrieved",
}

testServer := setupTestServer(expectedItem, expectedVault, t)
defer testServer.Close()

resource.Test(t, resource.TestCase{
ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
Steps: []resource.TestStep{
{
Config: testAccProviderConfig(testServer.URL) + testAccItemDataSourceConfig(expectedItem.Vault.ID, expectedItem.ID),
Check: resource.ComposeAggregateTestCheckFunc(
resource.TestCheckResourceAttr("data.onepassword_item.test", "id", fmt.Sprintf("vaults/%s/items/%s", expectedVault.ID, expectedItem.ID)),
resource.TestCheckResourceAttr("data.onepassword_item.test", "vault", expectedVault.ID),
resource.TestCheckResourceAttr("data.onepassword_item.test", "title", expectedItem.Title),
resource.TestCheckResourceAttr("data.onepassword_item.test", "uuid", expectedItem.ID),
resource.TestCheckResourceAttr("data.onepassword_item.test", "category", strings.ToLower(string(expectedItem.Category))),
resource.TestCheckResourceAttr("data.onepassword_item.test", "private_key", expectedItem.Fields[0].Value),
resource.TestCheckResourceAttr("data.onepassword_item.test", "public_key", expectedItem.Fields[1].Value),
),
},
},
})
}

func testAccItemDataSourceConfig(vault, uuid string) string {
return fmt.Sprintf(`
data "onepassword_item" "test" {
Expand Down
40 changes: 40 additions & 0 deletions internal/provider/test_utils.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
package provider

import (
"crypto/rand"
"crypto/rsa"
"crypto/x509"
"encoding/base64"
"encoding/pem"
"fmt"

"github.com/1Password/connect-sdk-go/onepassword"
"golang.org/x/crypto/ssh"
)

func generateBaseItem() onepassword.Item {
Expand Down Expand Up @@ -65,6 +71,14 @@ func generateLoginItem() *onepassword.Item {
return &item
}

func generateSSHKeyItem() *onepassword.Item {
item := generateBaseItem()
item.Category = onepassword.SSHKey
item.Fields = generateSSHKeyFields()

return &item
}

func generateSecureNoteItem() *onepassword.Item {
item := generateBaseItem()
item.Category = onepassword.SecureNote
Expand Down Expand Up @@ -186,3 +200,29 @@ func generateLoginFields() []*onepassword.ItemField {
}
return fields
}

func generateSSHKeyFields() []*onepassword.ItemField {
bitSize := 2048
privateKey, err := rsa.GenerateKey(rand.Reader, bitSize)
if err != nil {
panic(err)
}
privateKeyPem := &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(privateKey)}
publicRSAKey, err := ssh.NewPublicKey(&privateKey.PublicKey)
if err != nil {
panic(err)
}
publicKey := "ssh-rsa " + base64.StdEncoding.EncodeToString(publicRSAKey.Marshal())

fields := []*onepassword.ItemField{
{
Label: "private key",
Value: string(pem.EncodeToMemory(privateKeyPem)),
},
{
Label: "public key",
Value: publicKey,
},
}
return fields
}
16 changes: 16 additions & 0 deletions vendor/golang.org/x/crypto/chacha20/chacha_arm64.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit a8d1021

Please sign in to comment.