Skip to content

feat: Add custom search attributes support to TemporalNamespace#984

Open
ido-trumer wants to merge 6 commits intoalexandrevilain:mainfrom
ido-trumer:feat/custom-search-attributes
Open

feat: Add custom search attributes support to TemporalNamespace#984
ido-trumer wants to merge 6 commits intoalexandrevilain:mainfrom
ido-trumer:feat/custom-search-attributes

Conversation

@ido-trumer
Copy link

@ido-trumer ido-trumer commented Mar 16, 2026

Closes #567
Supersedes #776

Summary

Adds the ability to declare custom search attributes on TemporalNamespace resources. Attributes are reconciled against the Temporal server via the OperatorService API during each namespace reconciliation cycle.

New spec fields

apiVersion: temporal.io/v1beta1
kind: TemporalNamespace
metadata:
  name: default
spec:
  clusterRef:
    name: temporal
  retentionPeriod: 336h
  customSearchAttributes:
    CustomerId: Keyword
    OrderTotal: Double
    IsVIP: Bool
  allowSearchAttributeDeletion: false
  • customSearchAttributes — map of attribute name → type. Supported types: Text, Keyword, Int, Double, Bool, DateTime, KeywordList.
  • allowSearchAttributeDeletion — safety flag. When false (default), attributes removed from the spec are left on the server. When true, stale attributes are deleted.

Reconciliation behavior

  1. Lists existing custom attributes from the Temporal server
  2. Detects type mismatches (returns error — Temporal does not allow type changes)
  3. Adds new attributes not yet on the server
  4. Removes stale attributes only if allowSearchAttributeDeletion: true

Files changed

  • api/v1beta1/temporalnamespace_types.go — two new fields on TemporalNamespaceSpec
  • api/v1beta1/zz_generated.deepcopy.go — generated
  • config/crd/bases/temporal.io_temporalnamespaces.yaml — generated CRD
  • controllers/temporalnamespace_controller.go — +15 lines to call ReconcileSearchAttributes after namespace register/update
  • pkg/temporal/search_attributes.go — core reconciliation logic with OperatorServiceClient interface for testability
  • pkg/temporal/search_attributes_test.go — 11 unit test cases

Difference from #776

This is a fresh implementation, not a continuation of #776. Key differences:

#776 This PR
Controller changes +166 lines (inline logic) +15 lines (delegates to pkg/temporal)
Unit tests None 11 test cases
Safe deletion flag No (allowSearchAttributeDeletion) Yes
Type mismatch handling None Explicit error
Testable via interface No Yes (OperatorServiceClient)

Note on test location

Unit tests are co-located at pkg/temporal/search_attributes_test.go. While the other files in pkg/temporal/ (e.g., namespace.go, client.go) don't have co-located unit tests, this file uses a mock OperatorServiceClient interface and doesn't require a live cluster, so it doesn't fit in tests/e2e/. The co-located pattern is consistent with other packages in the repo (pkg/version/, pkg/kubernetes/, internal/resource/persistence/). Happy to move it if you prefer a different location.

Test plan

  • Unit tests pass (go test ./pkg/temporal/... — 11 search attribute test cases)
  • go vet clean
  • golangci-lint clean (v1.64.8, matching CI)
  • License check clean (make check-license)
  • Full project compiles (go build ./...)
  • Manual e2e on minikube: deployed operator with PostgreSQL-backed TemporalCluster, verified attributes appear on server via ListSearchAttributes API and Temporal UI
    • Create namespace with 4 attributes → all 4 present
    • Add 2 more → 6 total
    • Remove 4 with allowSearchAttributeDeletion: true → 2 remain
    • Remove attribute with allowSearchAttributeDeletion: false → preserved on server

Adds the ability to configure custom search attributes on TemporalNamespace
resources, enabling workflow search by custom attributes. Attributes are
reconciled via the Temporal OperatorService API during namespace reconciliation.

Closes alexandrevilain#567
@ido-trumer ido-trumer changed the title feat: Add custom search attributes support to TemporalNamespace [WIP] feat: Add custom search attributes support to TemporalNamespace Mar 16, 2026
Reduce cognitive complexity of ReconcileSearchAttributes by extracting
helper functions. Replace duplicated test namespace literal with constant
and fix gofmt/unparam lint issues.
Log key lifecycle events: existing attribute count, when attributes are
up to date, additions with count, and removals with count and names.
Only log at INFO when actually adding or removing attributes.
Listing and up-to-date checks are debug (V(1)) to reduce noise.
Match namespace.go's import style (unaliased enums instead of enumsv1).
Replace init() with a static map literal for the reverse type mapping.
@ido-trumer ido-trumer changed the title [WIP] feat: Add custom search attributes support to TemporalNamespace feat: Add custom search attributes support to TemporalNamespace Mar 16, 2026
Remove TestSearchAttributeTypeFromString, TestSearchAttributeTypeToString
(just mirror the map data), and error propagation tests (just verify
fmt.Errorf wrapping). Keep tests that exercise actual reconciliation logic.
@sonarqubecloud
Copy link

@ido-trumer
Copy link
Author

@alexandrevilain Thank you for triggering the CI, looks like everything works. Let me know if you have any comments or other thoughts :)

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.

Add Custom Search Attributes to TemporalNamespace

1 participant