Repository navigation
feat: Add custom search attributes support to TemporalNamespace - #984
Merged
alexandrevilain merged 6 commits intoMar 29, 2026
Merged
alexandrevilain merged 6 commits into
alexandrevilain merged 6 commits into
Conversation
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
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.
Remove TestSearchAttributeTypeFromString, TestSearchAttributeTypeToString (just mirror the map data), and error propagation tests (just verify fmt.Errorf wrapping). Keep tests that exercise actual reconciliation logic.
|
Contributor
Author
|
@alexandrevilain Thank you for triggering the CI, looks like everything works. Let me know if you have any comments or other thoughts :) |
|
@alexandrevilain |
alexandrevilain
approved these changes
Mar 29, 2026
Owner
|
Thanks for the contribution @ido-trumer ! |
ElanHasson
added a commit
to eh-homelab/temporal-operator
that referenced
this pull request
Oct 27, 2026
…in#987, plus 1.32) Squashes alexandrevilain#987 (head 97a684d, by CrunchyMonkies, with cherry-picked fixes by johnduhart): support for Temporal 1.29, 1.30 and 1.31, including 1.30's removal of dockerize from the server image and of curl/jq from admin-tools; Go 1.26.4, go.temporal.io/server v1.31.1, controller-runtime v0.23.3, controller-gen v0.21.0, kustomize v5.8.1. It also brings upstream main's custom search attributes on TemporalNamespace (alexandrevilain#984), which alexandrevilain#987 is based on. On top: - Supported range raised to < 1.33.0. 1.32 changes no image contents or static config format; its breaking changes are dynamic config and APIs. - TestValidateSupportedRange pins both range ends and the sequential path 1.28.4 -> 1.29.7 -> 1.30.8 -> 1.31.4 -> 1.32.1. - The upstream-golden config test now allows exactly three new lines, the empty values of fields go.temporal.io/server v1.31 added (sql.passwordCommand, authorization.audience/permissionsRegex). Temporal < 1.31 loads its config with plain yaml.Unmarshal and ignores them; they do roll the server pods once when the operator is swapped. - Bundle CRDs copied from config/crd/bases: alexandrevilain#987's operator-sdk pin no longer supports this project's go.kubebuilder.io/v3 layout, so `make bundle` fails. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0149PKDkbRQfDuVf5UU6vuPZ
ElanHasson
added a commit
to eh-homelab/temporal-operator
that referenced
this pull request
Oct 27, 2026
… images (#1) * feat: optional clusterMetadata for multi-cluster replication Adds spec.clusterMetadata to TemporalCluster: enableGlobalNamespace, initialFailoverVersion (1-9, default 1) and dcRedirectionPolicy. Unset, the rendered server config is what v0.22.0 renders. Once global namespaces are enabled, the webhook makes initialFailoverVersion immutable. Also points the release manifest at ghcr.io/eh-homelab/temporal-operator and adds eh-release.yaml, which builds and pushes the image and publishes the CRD and operator manifests on a v*-eh.* tag. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0149PKDkbRQfDuVf5UU6vuPZ * fix: lock global-namespace settings once enabled; verify the image is public Temporal 1.28 persists enableGlobalNamespace and initialFailoverVersion when global namespaces are first enabled, then ignores config changes to either (temporal/fx.go, updateCurrentClusterMetadataRecord and overwriteCurrentClusterMetadataWithDBRecord). The webhook now forbids disabling global namespaces or changing the version after that point, so the CR cannot drift from the running cluster. - Nil-safe ClusterMetadataSpec helpers and a FailoverVersionIncrement constant shared by the builder and the webhook. - Five ValidateUpdate cases for the new rules. - Release: set the image with kustomize edit instead of sed, and fail if the pushed image is not anonymously pullable (a new GHCR package is private). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0149PKDkbRQfDuVf5UU6vuPZ * test: pin the unset config to upstream v0.22.0; regenerate chart and bundle CRDs - TestConfigmapBuilderMatchesUpstream renders a scadbuddy-shaped cluster without clusterMetadata and compares it byte for byte with a golden file generated by upstream v0.22.0's own builder. - TestConfigmapBuilderClusterMetadata covers the rendered clusterMetadata and dcRedirectionPolicy when the block is set. - make helm bundle: the chart and OLM bundle CRDs now carry spec.clusterMetadata. The chart's copy had been left at v0.20.0's CRDs upstream, so it also gains the fields added since. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0149PKDkbRQfDuVf5UU6vuPZ * feat: support Temporal 1.29 to 1.32 (squash of upstream alexandrevilain#987, plus 1.32) Squashes alexandrevilain#987 (head 97a684d, by CrunchyMonkies, with cherry-picked fixes by johnduhart): support for Temporal 1.29, 1.30 and 1.31, including 1.30's removal of dockerize from the server image and of curl/jq from admin-tools; Go 1.26.4, go.temporal.io/server v1.31.1, controller-runtime v0.23.3, controller-gen v0.21.0, kustomize v5.8.1. It also brings upstream main's custom search attributes on TemporalNamespace (alexandrevilain#984), which alexandrevilain#987 is based on. On top: - Supported range raised to < 1.33.0. 1.32 changes no image contents or static config format; its breaking changes are dynamic config and APIs. - TestValidateSupportedRange pins both range ends and the sequential path 1.28.4 -> 1.29.7 -> 1.30.8 -> 1.31.4 -> 1.32.1. - The upstream-golden config test now allows exactly three new lines, the empty values of fields go.temporal.io/server v1.31 added (sql.passwordCommand, authorization.audience/permissionsRegex). Temporal < 1.31 loads its config with plain yaml.Unmarshal and ignores them; they do roll the server pods once when the operator is swapped. - Bundle CRDs copied from config/crd/bases: alexandrevilain#987's operator-sdk pin no longer supports this project's go.kubebuilder.io/v3 layout, so `make bundle` fails. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0149PKDkbRQfDuVf5UU6vuPZ * feat: accept fully pinned image references, so Dependabot can bump them Dependabot's docker parser reads only `image: name:tag` values, and the CR split every image into `image` plus a separate version, while the schema jobs computed their admin-tools tag inside the operator. Now: - spec.image may carry a tag (and digest). The defaulting webhook sets spec.version from the tag, so a Dependabot tag bump moves the version and the schema migrations with it; the sequential-upgrade check still applies. A tag that is not a version is rejected. - spec.admintools.image may be pinned (e.g. 1.28@sha256:...) and the schema jobs use it as written. Its tag must be for the server's major.minor, since those jobs apply the schema the image carries. - spec.ui.image may be pinned. - Untagged images behave as before. - .github/dependabot.yml for the fork's Dockerfile and Actions. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0149PKDkbRQfDuVf5UU6vuPZ --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.



Closes #567
Supersedes #776
Summary
Adds the ability to declare custom search attributes on
TemporalNamespaceresources. Attributes are reconciled against the Temporal server via the OperatorService API during each namespace reconciliation cycle.New spec fields
customSearchAttributes— map of attribute name → type. Supported types:Text,Keyword,Int,Double,Bool,DateTime,KeywordList.allowSearchAttributeDeletion— safety flag. Whenfalse(default), attributes removed from the spec are left on the server. Whentrue, stale attributes are deleted.Reconciliation behavior
allowSearchAttributeDeletion: trueFiles changed
api/v1beta1/temporalnamespace_types.go— two new fields onTemporalNamespaceSpecapi/v1beta1/zz_generated.deepcopy.go— generatedconfig/crd/bases/temporal.io_temporalnamespaces.yaml— generated CRDcontrollers/temporalnamespace_controller.go— +15 lines to callReconcileSearchAttributesafter namespace register/updatepkg/temporal/search_attributes.go— core reconciliation logic withOperatorServiceClientinterface for testabilitypkg/temporal/search_attributes_test.go— 11 unit test casesDifference from #776
This is a fresh implementation, not a continuation of #776. Key differences:
pkg/temporal)allowSearchAttributeDeletion)OperatorServiceClient)Note on test location
Unit tests are co-located at
pkg/temporal/search_attributes_test.go. While the other files inpkg/temporal/(e.g.,namespace.go,client.go) don't have co-located unit tests, this file uses a mockOperatorServiceClientinterface and doesn't require a live cluster, so it doesn't fit intests/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
go test ./pkg/temporal/...— 11 search attribute test cases)go vetcleangolangci-lintclean (v1.64.8, matching CI)make check-license)go build ./...)ListSearchAttributesAPI and Temporal UIallowSearchAttributeDeletion: true→ 2 remainallowSearchAttributeDeletion: false→ preserved on server