diff --git a/docs/data-sources/item.md b/docs/data-sources/item.md index 4f0a39d7..6cbdd8f8 100644 --- a/docs/data-sources/item.md +++ b/docs/data-sources/item.md @@ -34,7 +34,7 @@ data "onepassword_item" "example" { ### Read-Only -- `category` (String) The category of the item. One of ["login" "password" "database" "secure_note" "document" "ssh_key"] +- `category` (String) The category of the item. One of ["login" "password" "database" "secure_note" "document" "ssh_key" "credential"] - `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)) @@ -46,9 +46,10 @@ data "onepassword_item" "example" { - `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"] +- `type` (String) (Applies to the database and API credential categories) The type of database or API credential. For the database category, one of ["db2" "filemaker" "msaccess" "mssql" "mysql" "oracle" "postgresql" "sqlite" "other"]. For API credentials, it can be any string. - `url` (String) The primary URL for the item. - `username` (String) Username for this item. +- `filename` (String) (Applies to the API credential category) Filename for this item. ### Nested Schema for `file` diff --git a/internal/provider/const.go b/internal/provider/const.go index 1b54558d..7c335a4e 100644 --- a/internal/provider/const.go +++ b/internal/provider/const.go @@ -17,15 +17,19 @@ const ( tagsDescription = "An array of strings of the tags assigned to the item." usernameDescription = "Username for this item." 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." + credentialDescription = "(Only applies to the API credential category) API credential for this item." + validFromDescription = "(Only applies to the API credential category) The timestamp from which the API credential is valid." + expiresDescription = "(Only applies to the API credential category) The timestamp when the API credential expires." + filenameDescription = "(Only applies to the API credential category) The filename associated with the API credential." + 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." dbPortDescription = "(Only applies to the database category) The port the database is listening on." - dbTypeDescription = "(Only applies to the database category) The type of database." + dbTypeDescription = "(Only applies to database and API credential categories) For the database category" sectionsDescription = "A list of custom sections in an item" sectionDescription = "A custom section in an item that contains custom fields" @@ -72,6 +76,7 @@ var ( dataSourceCategories = append(categories, strings.ToLower(string(op.Document)), strings.ToLower(string(op.SSHKey)), + strings.ToLower(string(op.ApiCredential)), ) fieldPurposes = []string{ diff --git a/internal/provider/onepassword_item_data_source.go b/internal/provider/onepassword_item_data_source.go index 6c319688..24bbe056 100644 --- a/internal/provider/onepassword_item_data_source.go +++ b/internal/provider/onepassword_item_data_source.go @@ -48,6 +48,9 @@ type OnePasswordItemDataSourceModel struct { Password types.String `tfsdk:"password"` NoteValue types.String `tfsdk:"note_value"` Credential types.String `tfsdk:"credential"` + Filename types.String `tfsdk:"filename"` + ValidFrom types.String `tfsdk:"valid_from"` + Expires types.String `tfsdk:"expires"` PublicKey types.String `tfsdk:"public_key"` PrivateKey types.String `tfsdk:"private_key"` Section []OnePasswordItemSectionModel `tfsdk:"section"` @@ -176,6 +179,18 @@ func (d *OnePasswordItemDataSource) Schema(ctx context.Context, req datasource.S Computed: true, Sensitive: true, }, + "valid_from": schema.StringAttribute{ + MarkdownDescription: validFromDescription, + Computed: true, + }, + "expires": schema.StringAttribute{ + MarkdownDescription: expiresDescription, + Computed: true, + }, + "filename": schema.StringAttribute{ + MarkdownDescription: filenameDescription, + Computed: true, + }, "note_value": schema.StringAttribute{ MarkdownDescription: noteValueDescription, Computed: true, @@ -375,12 +390,16 @@ func (d *OnePasswordItemDataSource) Read(ctx context.Context, req datasource.Rea data.PublicKey = types.StringValue(f.Value) case "private key": data.PrivateKey = types.StringValue(f.Value) + case "credential": + data.Credential = types.StringValue(f.Value) + case "valid_from": + data.ValidFrom = types.StringValue(f.Value) + case "expires": + data.Expires = types.StringValue(f.Value) + case "filename": + data.Filename = types.StringValue(f.Value) } } - - if f.ID == "credential" && item.Category == "API_CREDENTIAL" { - data.Credential = types.StringValue(f.Value) - } } } diff --git a/internal/provider/onepassword_item_data_source_test.go b/internal/provider/onepassword_item_data_source_test.go index bf1c03ff..27ca6763 100644 --- a/internal/provider/onepassword_item_data_source_test.go +++ b/internal/provider/onepassword_item_data_source_test.go @@ -257,6 +257,41 @@ func TestAccItemSSHKey(t *testing.T) { }) } +func TestAccItemDataSourceApiCredential(t *testing.T) { + expectedItem := generateApiCredentialItem() + 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", "username", expectedItem.Fields[0].Value), + resource.TestCheckResourceAttr("data.onepassword_item.test", "credential", expectedItem.Fields[1].Value), + resource.TestCheckResourceAttr("data.onepassword_item.test", "type", expectedItem.Fields[2].Value), + resource.TestCheckResourceAttr("data.onepassword_item.test", "filename", expectedItem.Fields[3].Value), + resource.TestCheckResourceAttr("data.onepassword_item.test", "valid_from", expectedItem.Fields[4].Value), + resource.TestCheckResourceAttr("data.onepassword_item.test", "expires", expectedItem.Fields[5].Value), + resource.TestCheckResourceAttr("data.onepassword_item.test", "hostname", expectedItem.Fields[6].Value), + ), + }, + }, + }) +} + func testAccItemDataSourceConfig(vault, uuid string) string { return fmt.Sprintf(` data "onepassword_item" "test" { diff --git a/internal/provider/test_utils.go b/internal/provider/test_utils.go index c0a2aae0..75335702 100644 --- a/internal/provider/test_utils.go +++ b/internal/provider/test_utils.go @@ -49,6 +49,14 @@ func generateDatabaseItem() *onepassword.Item { return &item } +func generateApiCredentialItem() *onepassword.Item { + item := generateBaseItem() + item.Category = onepassword.Database + item.Fields = generateApiCredentialFields() + + return &item +} + func generatePasswordItem() *onepassword.Item { item := generateBaseItem() item.Category = onepassword.Password @@ -173,6 +181,40 @@ func generateDatabaseFields() []*onepassword.ItemField { return fields } +func generateApiCredentialFields() []*onepassword.ItemField { + fields := []*onepassword.ItemField{ + { + Label: "username", + Value: "test test_user", + }, + { + Label: "credential", + Value: "test_credential", + }, + { + Label: "type", + Value: "test_type", + }, + { + Label: "filename", + Value: "test_filename", + }, + { + Label: "valid_from", + Value: "test_valid_from", + }, + { + Label: "expires", + Value: "expires_expires", + }, + { + Label: "hostname", + Value: "test_hostname", + }, + } + return fields +} + func generatePasswordFields() []*onepassword.ItemField { fields := []*onepassword.ItemField{ {