Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
58 commits
Select commit Hold shift + click to select a range
7045c59
Add standard conditions field to TemporalWorkerDeployment status
jlegrone Sep 4, 2025
134674f
Add meaningful status fields to TemporalConnection
jlegrone Sep 4, 2025
4dff70c
Replace TODO comments with proper field documentation
jlegrone Sep 4, 2025
47083c4
Add field validation markers to TemporalConnection spec
jlegrone Sep 4, 2025
a74daf9
Replace float32 with int32 for percentage fields
jlegrone Sep 4, 2025
b447562
Add validation markers for numeric count fields
jlegrone Sep 4, 2025
dc4f4c8
Fix inconsistent +optional usage by adding omitempty
jlegrone Sep 4, 2025
4e7df00
Add kubebuilder resource annotations to TemporalConnection
jlegrone Sep 4, 2025
cdba7b9
Add validation patterns to WorkerOptions fields
jlegrone Sep 4, 2025
7a84702
Add missing kubebuilder default markers
jlegrone Sep 4, 2025
68fb13f
Replace string references with LocalObjectReference types
jlegrone Sep 4, 2025
caafd7f
Make Selector field required instead of optional
jlegrone Sep 4, 2025
17705b4
Revert LocalObjectReference change to avoid breaking API
jlegrone Sep 4, 2025
7087a57
Properly implement object references with Ref suffix
jlegrone Sep 4, 2025
886f265
Replace LocalObjectReference with well-focused reference types
jlegrone Sep 4, 2025
c47a175
Add required int64 range validation for ApproximateBacklogCount
jlegrone Sep 4, 2025
594ebfb
Replace float32 rate fields with int64 fixed-point representation
jlegrone Sep 4, 2025
3a54bde
make generate
jlegrone Sep 4, 2025
1102cdb
make manifests
jlegrone Sep 4, 2025
9ccb6cb
Delete QueueStatistics struct and fix RampPercentage precision
jlegrone Sep 4, 2025
b49b4fd
Address code review feedback: simplify annotations and add TODOs
jlegrone Sep 4, 2025
a0d39f8
Actually implement code review feedback
jlegrone Sep 4, 2025
f196834
Fix field references after API changes
jlegrone Sep 4, 2025
a2cc6f2
Fix all test failures after API field changes
jlegrone Sep 4, 2025
8ca2208
Address PR review comments for k8s API conventions
jlegrone Sep 8, 2025
2ee1c55
Update generated CRDs and remove remaining outdated TODOs
jlegrone Sep 8, 2025
b238d15
Refactor inline function into top-level getMutualTLSSecretName function
jlegrone Sep 8, 2025
0899159
Refactor status ramp percentage to use floating point
jlegrone Sep 8, 2025
e6e562a
Refactor RolloutStep to use simple percentage integers
jlegrone Sep 8, 2025
734382b
Fix all references after ramp percentage field refactoring
jlegrone Sep 8, 2025
d8725b4
make manifests
jlegrone Sep 8, 2025
1d0471f
Delete label selector from spec
jlegrone Sep 8, 2025
a70752d
Fix tests after Selector field removal
jlegrone Sep 8, 2025
f3f8f91
Apply suggestions from code review
jlegrone Sep 8, 2025
6835c90
make generate / manifests
jlegrone Sep 8, 2025
bd26624
Address PR review comments
jlegrone Sep 8, 2025
6a0cdc2
Update api/v1alpha1/worker_types.go
jlegrone Sep 9, 2025
125a35a
Remove types_test.go
jlegrone Sep 9, 2025
77d896d
Update demo YAML to use new API field names
jlegrone Sep 9, 2025
788c76a
Update api/v1alpha1/temporalconnection_types.go
jlegrone Sep 9, 2025
e6763c0
Fix constant references in deployments_test.go after rebase
jlegrone Sep 9, 2025
454afff
Fix CI issues: format imports and remove trailing whitespace
jlegrone Sep 9, 2025
4c10c62
Fix remaining field references in integration tests
jlegrone Sep 9, 2025
a6b78a4
make fmt-imports
jlegrone Sep 9, 2025
6f8e88f
Fix fmt.Errorf argument count mismatch in validation helpers
jlegrone Sep 9, 2025
f1e978f
Fix Kubernetes label validation by cleaning deployment names
jlegrone Sep 9, 2025
157d3b3
Use namespaced name rather than full name in pod labels
jlegrone Sep 9, 2025
7ec24e4
Fix temporal client logger configuration in test helpers
jlegrone Sep 9, 2025
c41182e
Fix ProgressiveStep function to use direct percentage values
jlegrone Sep 9, 2025
e24dca6
Fix test helper percentage calculation consistency
jlegrone Sep 9, 2025
4a1aedf
Remove all references to basis points from planner code
jlegrone Sep 9, 2025
6caf3f9
Fix integration tests
jlegrone Sep 9, 2025
16653ba
Fix progressive rollout RampPercentage type consistency
jlegrone Sep 9, 2025
7bd313d
Update internal/tests/internal/validation_helpers.go
jlegrone Sep 9, 2025
6c21727
Fix log spam (#135)
carlydf Sep 5, 2025
115d3a8
fix build id issue
carlydf Sep 10, 2025
d4260b7
Merge branch 'jlegrone/k8s-api-conventions' of github.com:temporalio/…
carlydf Sep 10, 2025
f1808cc
fmt imports
carlydf Sep 10, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 17 additions & 4 deletions api/v1alpha1/temporalconnection_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,28 +10,41 @@ import (

// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized.

// SecretReference contains the name of a Secret resource in the same namespace.
type SecretReference struct {
// Name of the Secret resource.
// +kubebuilder:validation:Required
// +kubebuilder:validation:Pattern=`^[a-z0-9]([-a-z0-9]*[a-z0-9])?$`
Comment thread
jlegrone marked this conversation as resolved.
Name string `json:"name"`
}

// TemporalConnectionSpec defines the desired state of TemporalConnection
type TemporalConnectionSpec struct {
// The host and port of the Temporal server.
// +kubebuilder:validation:Pattern=`^[a-zA-Z0-9.-]+:[0-9]+$`
Comment thread
jlegrone marked this conversation as resolved.
HostPort string `json:"hostPort"`

// MutualTLSSecret is the name of the Secret that contains the TLS certificate and key
// MutualTLSSecretRef is the name of the Secret that contains the TLS certificate and key
// for mutual TLS authentication. The secret must be `type: kubernetes.io/tls` and exist
// in the same Kubernetes namespace as the TemporalConnection resource.
//
// More information about creating a TLS secret:
// https://kubernetes.io/docs/concepts/configuration/secret/#tls-secrets
MutualTLSSecret string `json:"mutualTLSSecret,omitempty"`
// +optional
MutualTLSSecretRef *SecretReference `json:"mutualTLSSecretRef,omitempty"`
}

// TemporalConnectionStatus defines the observed state of TemporalConnection
type TemporalConnectionStatus struct {
// INSERT ADDITIONAL STATUS FIELD - define observed state of cluster
// Important: Run "make" to regenerate code after modifying this file
// TODO(jlegrone): Add additional status fields following Kubernetes API conventions
// https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
}

//+kubebuilder:object:root=true
//+kubebuilder:subresource:status
//+kubebuilder:resource:shortName=tconn
//+kubebuilder:printcolumn:name="Host",type="string",JSONPath=".spec.hostPort",description="Temporal server endpoint"
//+kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp",description="Age"

// TemporalConnection is the Schema for the temporalconnections API
type TemporalConnection struct {
Expand Down
2 changes: 1 addition & 1 deletion api/v1alpha1/temporalworker_webhook.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ func validateRolloutStrategy(s RolloutStrategy) []*field.Error {
field.Invalid(field.NewPath("spec.rollout.steps"), rolloutSteps, "steps are required for Progressive rollout"),
)
}
var lastRamp float32
var lastRamp int
for i, s := range rolloutSteps {
// Check duration >= 30s
if s.PauseDuration.Duration < 30*time.Second {
Expand Down
75 changes: 39 additions & 36 deletions api/v1alpha1/worker_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,30 +11,33 @@ import (

// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized.

// TemporalConnectionReference contains the name of a TemporalConnection resource
// in the same namespace as the TemporalWorkerDeployment.
type TemporalConnectionReference struct {
// Name of the TemporalConnection resource.
// +kubebuilder:validation:Required
// +kubebuilder:validation:Pattern=`^[a-z0-9]([-a-z0-9]*[a-z0-9])?$`
Comment thread
jlegrone marked this conversation as resolved.
Name string `json:"name"`
}

type WorkerOptions struct {
// The name of a TemporalConnection in the same namespace as the TemporalWorkerDeployment.
TemporalConnection string `json:"connection"`
TemporalConnectionRef TemporalConnectionReference `json:"connectionRef"`
// The Temporal namespace for the worker to connect to.
// +kubebuilder:validation:MinLength=1
Comment thread
jlegrone marked this conversation as resolved.
TemporalNamespace string `json:"temporalNamespace"`
}

// TemporalWorkerDeploymentSpec defines the desired state of TemporalWorkerDeployment
type TemporalWorkerDeploymentSpec struct {
// Important: Run "make" to regenerate code after modifying this file

// Number of desired pods. This is a pointer to distinguish between explicit
// zero and not specified. Defaults to 1.
// This field makes TemporalWorkerDeploymentSpec implement the scale subresource, which is compatible with auto-scalers.
// TODO(jlegrone): Configure min replicas per thousand workflow/activity tasks?
// +optional
// +kubebuilder:default=1
Replicas *int32 `json:"replicas,omitempty" protobuf:"varint,1,opt,name=replicas"`

// Label selector for pods. Existing ReplicaSets whose pods are
// selected by this will be the ones affected by this deployment.
// It must match the pod template's labels.
// +optional
Comment thread
jlegrone marked this conversation as resolved.
Selector *metav1.LabelSelector `json:"selector" protobuf:"bytes,2,opt,name=selector"`

// Template describes the pods that will be created.
// The only allowed template.spec.restartPolicy value is "Always".
Template corev1.PodTemplateSpec `json:"template"`
Expand All @@ -43,13 +46,15 @@ type TemporalWorkerDeploymentSpec struct {
// without any of its container crashing, for it to be considered available.
// Defaults to 0 (pod will be considered available as soon as it is ready)
// +optional
// +kubebuilder:default=0
MinReadySeconds int32 `json:"minReadySeconds,omitempty"`

// The maximum time in seconds for a deployment to make progress before it
// is considered to be failed. The deployment controller will continue to
// process failed deployments and a condition with a ProgressDeadlineExceeded
// reason will be surfaced in the deployment status. Note that progress will
// not be estimated during the time a deployment is paused. Defaults to 600s.
// +kubebuilder:default=600
ProgressDeadlineSeconds *int32 `json:"progressDeadlineSeconds,omitempty" protobuf:"varint,9,opt,name=progressDeadlineSeconds"`

// How to rollout new workflow executions to the target version.
Expand All @@ -58,7 +63,7 @@ type TemporalWorkerDeploymentSpec struct {
// How to manage sunsetting drained versions.
SunsetStrategy SunsetStrategy `json:"sunset"`

// TODO(jlegrone): add godoc
// WorkerOptions configures the worker's connection to Temporal.
WorkerOptions WorkerOptions `json:"workerOptions"`
}

Expand Down Expand Up @@ -128,7 +133,11 @@ type TemporalWorkerDeploymentStatus struct {
// VersionCount is the total number of versions currently known by the worker deployment.
// This includes current, target, ramping, and deprecated versions.
// +optional
// +kubebuilder:validation:Minimum=0
VersionCount int32 `json:"versionCount,omitempty"`

// TODO(jlegrone): Add additional status fields following Kubernetes API conventions
// https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
}

// WorkflowExecutionStatus describes the current state of a workflow.
Expand Down Expand Up @@ -173,11 +182,11 @@ type BaseWorkerDeploymentVersion struct {

// Healthy indicates whether the deployment version is healthy.
// +optional
HealthySince *metav1.Time `json:"healthySince"`
HealthySince *metav1.Time `json:"healthySince,omitempty"`

// A pointer to the version's managed k8s deployment.
// +optional
Deployment *corev1.ObjectReference `json:"deployment"`
Deployment *corev1.ObjectReference `json:"deployment,omitempty"`

// TaskQueues is a list of task queues that are associated with this version.
TaskQueues []TaskQueue `json:"taskQueues,omitempty"`
Expand All @@ -204,15 +213,18 @@ type TargetWorkerDeploymentVersion struct {
TestWorkflows []WorkflowExecution `json:"testWorkflows,omitempty"`

// RampPercentage is the percentage of new workflow executions that are
// configured to start on this version. Only set when Status is VersionStatusRamping.
// configured to start on this version. For example, 1.5 means 1.5%.
// Only set when Status is VersionStatusRamping.
//
// Acceptable range is [0,100].
// Acceptable range is [0.0,100.0] (0% to 100%).
// +kubebuilder:validation:Minimum=0.0
// +kubebuilder:validation:Maximum=100.0
RampPercentage *float32 `json:"rampPercentage,omitempty"`

// RampingSince is time when the version first started ramping.
// Only set when Status is VersionStatusRamping.
// +optional
RampingSince *metav1.Time `json:"rampingSince"`
RampingSince *metav1.Time `json:"rampingSince,omitempty"`

// RampLastModifiedAt is the time when the ramp percentage was last changed for the target version.
// +optional
Expand All @@ -227,7 +239,7 @@ type DeprecatedWorkerDeploymentVersion struct {
// DrainedSince is the time at which the version became drained.
// Only set when Status is VersionStatusDrained.
// +optional
DrainedSince *metav1.Time `json:"drainedSince"`
DrainedSince *metav1.Time `json:"drainedSince,omitempty"`

// A Version is eligible for deletion if it is drained and has no pollers on any task queue.
// After pollers stop polling, the server will still consider them present until `matching.PollerHistoryTTL`
Expand Down Expand Up @@ -286,11 +298,13 @@ type SunsetStrategy struct {
// ScaledownDelay specifies how long to wait after a version is drained before scaling its Deployment to zero.
// Defaults to 1 hour.
// +optional
// +kubebuilder:default="1h"
ScaledownDelay *metav1.Duration `json:"scaledownDelay"`

// DeleteDelay specifies how long to wait after a version is drained before deleting its Deployment.
// Defaults to 24 hours.
// +optional
// +kubebuilder:default="24h"
DeleteDelay *metav1.Duration `json:"deleteDelay"`
}

Expand All @@ -299,37 +313,26 @@ type AllAtOnceRolloutStrategy struct{}
type RolloutStep struct {
// RampPercentage indicates what percentage of new workflow executions should be
// routed to the new worker deployment version while this step is active.
// For example, 15 means 15%.
//
// Acceptable range is [0,100].
RampPercentage float32 `json:"rampPercentage"`
// Acceptable range is [1,99] (1% to 99%).
// +kubebuilder:validation:Minimum=1
// +kubebuilder:validation:Maximum=99
RampPercentage int `json:"rampPercentage"`

// PauseDuration indicates how long to pause before progressing to the next step.
PauseDuration metav1.Duration `json:"pauseDuration"`
}

type ManualRolloutStrategy struct{}

type QueueStatistics struct {
// The approximate number of tasks backlogged in this task queue. May count expired tasks but eventually converges
// to the right value.
ApproximateBacklogCount int64 `json:"approximateBacklogCount,omitempty"`
// Approximate age of the oldest task in the backlog based on the creation timestamp of the task at the head of the queue.
ApproximateBacklogAge metav1.Duration `json:"approximateBacklogAge,omitempty"`
// Approximate tasks per second added to the task queue based on activity within a fixed window. This includes both backlogged and
// sync-matched tasks.
TasksAddRate float32 `json:"tasksAddRate,omitempty"`
// Approximate tasks per second dispatched to workers based on activity within a fixed window. This includes both backlogged and
// sync-matched tasks.
TasksDispatchRate float32 `json:"tasksDispatchRate,omitempty"`
}

//+kubebuilder:object:root=true
//+kubebuilder:subresource:status
// +kubebuilder:resource:shortName=twd;twdeployment;tworkerdeployment
//+kubebuilder:printcolumn:name="Current",type="string",JSONPath=".status.currentVersion.buildID",description="Current Version Build ID"
//+kubebuilder:printcolumn:name="Target",type="string",JSONPath=".status.targetVersion.buildID",description="Build ID of the target worker (based on the pod template)"
//+kubebuilder:printcolumn:name="Target-Ramp",type="number",JSONPath=".status.targetVersion.rampPercentage",description="Percentage of new workflows starting on Target Version"
//+kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp"
//+kubebuilder:printcolumn:name="Current",type="string",JSONPath=".status.currentVersion.buildID",description="Current build ID"
//+kubebuilder:printcolumn:name="Target",type="string",JSONPath=".status.targetVersion.buildID",description="Target build ID"
//+kubebuilder:printcolumn:name="Ramp %",type="number",JSONPath=".status.targetVersion.rampPercentage",description="Ramp percentage"
//+kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp",description="Age"

// TemporalWorkerDeployment is the Schema for the temporalworkerdeployments API
type TemporalWorkerDeployment struct {
Expand Down
69 changes: 42 additions & 27 deletions api/v1alpha1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading