Skip to content

Add implementation and helpers for ResourceSetLatest and ResourceSync - #34

Open
zainawaisn wants to merge 1 commit into
mainfrom
zain/add-update-namespace
Open

zainawaisn wants to merge 1 commit into
mainfrom
zain/add-update-namespace

Conversation

@zainawaisn

@zainawaisn zainawaisn commented Oct 26, 2026 •

Copy link
Copy Markdown
Collaborator

What was changed

Issue #8

Implements ResourceSetLatest and ResourceSync for the Namespace reconciler. The operator can now create a Temporal Cloud namespace from a CR and keep its spec and tags in sync.

  • Upgrade go.temporal.io/cloud-sdk v0.7.1 → v0.20.0. v0.7.1 had no proto fields for several CRD fields (project, replicas, fairness, encryptionValidation, description, disablePassivePollerForwarding).
  • ResourceSetLatest now fetches the namespace from Temporal Cloud and rewrites latest's spec and status to match. If Status.ID is empty, it looks the namespace up by name with GetNamespaces(). This is how the qualified ID gets saved after a create, and it prevents duplicate creates if status is lost. A namespace that isn't found clears the spec and status, so ResourceSync recreates it.
  • ResourceSync makes at most one cloud call per reconcile and then requeues, because a namespace with an async operation in progress rejects new ones. In order: create if there's no ID; wait while Activating or Updating; terminal error on a failed state or a project mismatch; UpdateNamespace if the spec differs; UpdateNamespaceTags if the tags differ.
  • convert.go contains CRD ↔ proto converters for the spec, status, enums and timestamps. Unknown spec enum values keep their proto name so they show up as a difference. Unknown resource states map to "", because the status field is enum-validated.
  • Unit tests for the converters, findNamespaceByName and tagsDiff. Every function in convert.go has test coverage.

In-Progress changes

One integration test (TestReconciler_ResourceSetLatest/mutates_latest_resource) is failing:

--- FAIL: TestReconciler_ResourceSetLatest/mutates_latest_resource (35.08s)
    reconcile_test.go:127:
        Error:  Expected nil, but got: &fmt.wrapError{msg:"failed listing tcloud namespaces: rpc error: code = Unavailable desc = name resolver error: produced zero addresses", err:(*status.Error)(0x2f6e262880b0)}

The test will require a fake client, since now it sends a GetNamespaces() request.

@tomba7 tomba7 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suggest we comment out TestReconciler_ResourceSetLatest for now and I can do that as a follow up after you merge. The fake cloud server looks like the right thing to use for this.


// resourceStateFromProto converts a Temporal Cloud resource state to its CR
// name. Unspecified and unknown states map to "": the CR field is
// enum-validated, so an unrecognized value would fail the status patch.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a good candidate to go under a common covert package IMO

}
}

func timeFromProto(ts *timestamppb.Timestamp) *metav1.Time {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Smae with this.


// resourceStatusFromProto returns the [cloudcommon.ResourceStatus] that
// represents the supplied Temporal Cloud Namespace.
func resourceStatusFromProto(

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is also a good shared candidate. Plus I wanted to call out making it have the shape recommended here in this proposal comment

ctrlerrors.ErrResourceSync, id, state,
))
}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would only Active fall through here?

// async operation, and a namespace with an operation in flight rejects new
// ones, so after each call we requeue and let the next reconcile observe the
// result and take the next step.
func syncNamespace(

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be good to add a few unit tests for this as there are a few important paths to cover here, esp the ones requiring a requeue with the right errors. But I'm fine doing it as a follow up.

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