Skip to content

Conversation

@stas-schaller
Copy link
Collaborator

@stas-schaller stas-schaller commented Dec 3, 2025

Summary

Extends Terraform Provider custom field support to 5 field types (text, multiline, secret, url, email) across all 22 resource types, enabling users to add arbitrary custom fields to secrets stored in Keeper.

Changes

Extended Type Support

  • 5 field types: text, multiline, secret, url, email
  • 22 resource types: All standard, personal info, and PAM resources
  • Full CRUD operations: Create, Read, Update for custom fields
  • Type validation: Comprehensive tests for all field types

Implementation Details

Schema (record_fields.go):

  • schemaCustomField(): Schema definition supporting type, label, value, required, privacy_screen
  • convertFieldToMap(): Helper function for Update operations (converts SDK structs to RecordDict maps)

Resources (all 22 resource_*.go files):

  • Create functions: Process custom fields using switch statement for 5 types
  • Read functions: Extract custom fields from Record.RecordDict["custom"]
  • Update functions: Handle custom field changes via RecordDict manipulation

Provider (provider.go):

  • Added "custom": "custom" to field name mapping
  • Uses existing getFieldItemsResourceData() for custom field reads

Resources Supporting Custom Fields

Standard Records (11):

  • login, database_credentials, server_credentials, ssh_keys, encrypted_notes, driver_license, passport, birth_certificate, ssn_card, photo, file

Complex Nested Records (7):

  • bank_account, bank_card, payment_card, contact, health_insurance, membership, software_license

PAM Records (4):

  • pam_user, pam_machine, pam_database, pam_directory

Other (1):

  • address

Tests Added

Representative Tests (4 tests covering all 22 resources):

  1. TestAccResourceLogin_customFields - Covers 11 simple resources
  2. TestAccResourceBankAccount_customFields - Covers 7 complex nested resources
  3. TestAccResourcePamUser_customFields - Covers 4 PAM resources
  4. TestAccResourceAddress_customFields - Covers address resource

Type Validation Test:

  1. TestAccResourceLogin_customFieldTypes - Validates all 5 types (text, multiline, secret, url, email)

All tests verify:

  • Create with 2 custom fields
  • Update to 3 custom fields with value changes
  • Correct persistence across operations

Supported Field Types

All 5 types share identical SDK structure ([]string value):

type Text struct {
    KeeperRecordField
    Required      bool     `json:"required,omitempty"`
    PrivacyScreen bool     `json:"privacyScreen,omitempty"`
    Value         []string `json:"value,omitempty"`
}
// Multiline, Secret, Url, Email have identical structure

Example Usage

resource "secretsmanager_login" "employee_account" {
  folder_uid = var.folder_uid
  title      = "Employee Portal"
  
  login {
    value = "[email protected]"
  }
  
  password {
    value = "securepassword123"
  }
  
  # Text custom field
  custom {
    type  = "text"
    label = "Department"
    value = "Engineering"
  }
  
  # Multiline custom field
  custom {
    type  = "multiline"
    label = "Notes"
    value = "Line 1\nLine 2\nLine 3"
  }
  
  # Secret custom field
  custom {
    type  = "secret"
    label = "API Key"
    value = "sk_live_abc123..."
  }
  
  # URL custom field
  custom {
    type  = "url"
    label = "Dashboard"
    value = "https://dashboard.example.com"
  }
  
  # Email custom field
  custom {
    type  = "email"
    label = "Support Email"
    value = "[email protected]"
  }
}

Testing

Run all custom field tests:

export TF_ACC=1
export KEEPER_CREDENTIAL="$(cat ~/.keeper/credential)"
go test ./secretsmanager -v -run "TestAccResource.*_customField" -timeout 20m

Test Results:

=== RUN   TestAccResourceAddress_customFields
--- PASS: TestAccResourceAddress_customFields (2.45s)
=== RUN   TestAccResourceBankAccount_customFields
--- PASS: TestAccResourceBankAccount_customFields (1.40s)
=== RUN   TestAccResourceLogin_customFields
--- PASS: TestAccResourceLogin_customFields (1.33s)
=== RUN   TestAccResourceLogin_customFieldTypes
--- PASS: TestAccResourceLogin_customFieldTypes (2.48s)
=== RUN   TestAccResourcePamUser_customFields
--- PASS: TestAccResourcePamUser_customFields (4.16s)
PASS
ok  	github.com/keeper-security/terraform-provider-secretsmanager/secretsmanager	11.293s

Technical Details

Custom Field Storage

Custom fields are stored separately from standard fields:

  • Standard fields: Record.RecordDict["fields"]
  • Custom fields: Record.RecordDict["custom"]

CRUD Operations

Create: Uses typed SDK structs (core.Text, core.Multiline, etc.)

field := &core.Text{
    KeeperRecordField: core.KeeperRecordField{Type: "text"},
    Label: "Department",
    Value: []string{"Engineering"},
}
nrc.Custom = append(nrc.Custom, field)

Read: Extracts from RecordDict via getFieldItemsResourceData()

customItems := getFieldItemsResourceData("custom", secret)
d.Set("custom", customItems)

Update: Manipulates RecordDict directly

fieldMap := convertFieldToMap(f.Type, f.Label, f.Required, f.PrivacyScreen, f.Value)
customFields = append(customFields, fieldMap)
secret.RecordDict["custom"] = customFields

Related Issues

Implement custom field create, read, and update operations for login resources,
allowing users to add arbitrary custom fields to their secrets. This addresses
GitHub issue #16 and Jira ticket KSM-388.

Features:
- Add custom schema field to resource_login accepting list of custom fields
- Support text-type custom fields with label, value, required, and privacy_screen
- Process custom fields during resource Create operation
- Read custom fields during resource Read operation
- Update custom fields during resource Update operation
- Custom fields stored in Record.Custom array via Go SDK

Tests:
- TestAccResourceLogin_customFields: Create with 2 custom fields
- TestAccResourceLogin_customFields: Update to 3 custom fields with value changes
- Validates custom field count, labels, and values persist correctly

Schema:
- schemaCustomField(): Writable custom field schema (Optional vs Computed)
- Fields: type (required), label, value, required, privacy_screen

Helper Functions:
- getFieldItemsResourceData(): Read custom fields from Record into Terraform state
- Custom fields processed same as standard fields using NewFieldFromSchema
- ApplyFieldChange() already supports "custom" section

References: GitHub issue #16, Jira KSM-388
@stas-schaller stas-schaller force-pushed the KSM-388-custom-fields-write branch 2 times, most recently from 98ee6a5 to 2293061 Compare December 4, 2025 20:51
Add custom field write support to all resource types, enabling users to add
text-type custom fields to any Keeper record via Terraform.

Changes per resource (21 resources extended):
- Schema: Added 'custom' field using schemaCustomField()
- Create: Process custom fields from Terraform config to Record.Custom
- Read: Read custom fields from Record.Custom to Terraform state
- Update: Handle custom field changes via ApplyFieldChange()

All resources now support the same custom field pattern as resource_login
(implemented in commit 042c8a5).

Extended resources:
- address, bank_account, bank_card, birth_certificate, contact
- database_credentials, driver_license, encrypted_notes, file
- health_insurance, membership, pam_database, pam_directory
- pam_machine, pam_user, passport, photo, server_credentials
- software_license, ssh_keys, ssn_card

References: GitHub issue #16, Jira KSM-388
…d email types

Previously, custom fields only supported "text" type. This commit extends
support to include multiline, secret, url, and email types - all of which
share the same structure ([]string value) in the Go SDK.

Changes:
- Updated Create functions across all 22 resources to handle 5 field types
- Updated Update functions to properly sync all 5 types to vault
- Added convertFieldToMap helper to record_fields.go for Update operations
- Added TestAccResourceLogin_customFieldTypes to validate all types
- All existing custom field tests continue to pass

All 5 types work correctly for Create, Read, Update operations.
@stas-schaller stas-schaller force-pushed the KSM-388-custom-fields-write branch from 2293061 to 8b42042 Compare December 4, 2025 20:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants