Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
96296d9
feat: add shared status types and condition helpers
ian-flores Feb 19, 2026
18c58f3
feat: add conditions and deployment health monitoring to Connect status
ian-flores Feb 19, 2026
24fa6ac
feat: add conditions and deployment health monitoring to Workbench st…
ian-flores Feb 19, 2026
3061f8e
feat: add conditions and deployment health monitoring to PackageManag…
ian-flores Feb 19, 2026
7c23676
feat: add conditions and deployment health monitoring to Chronicle st…
ian-flores Feb 19, 2026
fc1b528
feat: add conditions and deployment health monitoring to Flightdeck s…
ian-flores Feb 19, 2026
0d3f2f1
feat: add conditions to PostgresDatabase status
ian-flores Feb 19, 2026
5820d84
feat: add aggregate status to Site from child component health
ian-flores Feb 19, 2026
8e52a94
fix: address review findings in status implementation
ian-flores Feb 19, 2026
dd620c6
fix: address PR and per-commit review findings
ian-flores Feb 19, 2026
c48796b
Merge branch 'main' into improve-status-fields
ian-flores Feb 19, 2026
fa7ad75
fix: mark Ready field as optional to fix status patch validation
ian-flores Feb 19, 2026
5b0a13c
fix: register status subresource in fake test client
ian-flores Feb 19, 2026
cc9328a
fix: go fmt alignment in status struct fields
ian-flores Feb 19, 2026
a7f03c6
feat: allow disabling Workbench, Package Manager, and Chronicle witho…
ian-flores Feb 23, 2026
0eaa2cf
fix: address review findings for enable/disable/teardown extension
ian-flores Feb 23, 2026
4755815
chore: sync Helm chart CRDs with config/crd after code generation
ian-flores Feb 23, 2026
1a74d7d
Merge branch 'main' into extend-enable-disable-teardown
ian-flores Feb 24, 2026
8035b25
Merge remote-tracking branch 'origin/main' into improve-status-fields
ian-flores Feb 24, 2026
d3dbc37
Merge remote-tracking branch 'origin/extend-enable-disable-teardown' …
ian-flores Feb 24, 2026
67c2c6f
fix: skip disabled products when computing site readiness
ian-flores Feb 24, 2026
388d817
Address review findings (job 35)
ian-flores Feb 24, 2026
7bbc188
Address review findings (job 39)
ian-flores Feb 24, 2026
370fdc1
chore: sync CRD and Helm chart after mgenerate
ian-flores Feb 24, 2026
46eb46a
Address review findings (job 42)
ian-flores Feb 24, 2026
4dbe1e8
fix: address code review findings from improve-status-fields PR
ian-flores Feb 24, 2026
7a86fab
Address review findings (job 131)
ian-flores Feb 24, 2026
fe85bcb
Address review findings (job 132)
ian-flores Feb 24, 2026
bcb7387
Address review findings (job 150)
ian-flores Feb 24, 2026
2f6f747
Address review findings (job 155)
ian-flores Feb 24, 2026
fa565df
Address review findings (job 158)
ian-flores Feb 24, 2026
4645ecc
Address review findings (job 135)
ian-flores Feb 24, 2026
ab7dbb7
Address review findings (job 136)
ian-flores Feb 24, 2026
04428ef
Address review findings (job 137)
ian-flores Feb 24, 2026
9efdb8b
chore: remove accidentally committed .claude/tsc-cache files
ian-flores Mar 5, 2026
ad65b1b
chore: add .claude/tsc-cache to .gitignore
ian-flores Mar 5, 2026
e267231
Merge remote-tracking branch 'origin/main' into improve-status-fields
ian-flores Mar 6, 2026
805ccd8
chore: regenerate CRDs and helm chart after merge with main
ian-flores Mar 6, 2026
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
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,7 @@ go.work.sum
# Editor/IDE
# .idea/
# .vscode/

# Claude Code cache
.claude/tsc-cache/
.claude/tsc-cache/
4 changes: 4 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,8 @@ help: ## Display this help.
.PHONY: manifests
manifests: controller-gen ## Generate WebhookConfiguration, ClusterRole and CustomResourceDefinition objects.
$(CONTROLLER_GEN) rbac:roleName=manager-role crd webhook paths="./..." output:crd:artifacts:config=config/crd/bases
# Normalize jsonPath filter quoting: controller-gen emits single quotes, kubectl prefers double
$(SED) -i "s/@.type=='Ready'/@.type==\"Ready\"/g" config/crd/bases/core.posit.team_connects.yaml config/crd/bases/core.posit.team_postgresdatabases.yaml config/crd/bases/core.posit.team_sites.yaml

.PHONY: generate-all
generate-all: generate generate-client generate-openapi
Expand Down Expand Up @@ -239,6 +241,8 @@ helm-generate: manifests kubebuilder ## Regenerate Helm chart from kustomize
rm -f dist/chart/templates/rbac/auth_proxy_service.yaml
# Remove kubebuilder-generated test workflow - we use our own CI workflows
rm -f .github/workflows/test-chart.yml
# Normalize jsonPath filter quoting in Helm chart CRDs (matches config/crd/bases fixup above)
$(SED) -i "s/@.type=='Ready'/@.type==\"Ready\"/g" dist/chart/templates/crd/core.posit.team_connects.yaml dist/chart/templates/crd/core.posit.team_postgresdatabases.yaml dist/chart/templates/crd/core.posit.team_sites.yaml

.PHONY: helm-lint
helm-lint: ## Lint the Helm chart
Expand Down
10 changes: 10 additions & 0 deletions api/core/v1beta1/chronicle_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@ import (

// ChronicleSpec defines the desired state of Chronicle
type ChronicleSpec struct {
// Suspended indicates Chronicle should not run serving resources (StatefulSet, Service)
// but should preserve configuration. Set by the Site controller.
// +optional
Suspended *bool `json:"suspended,omitempty"`

Config ChronicleConfig `json:"config,omitempty"`

// ImagePullSecrets is a set of image pull secrets to use for all image pulls. These names / secrets
Expand All @@ -38,12 +43,17 @@ type ChronicleSpec struct {

// ChronicleStatus defines the observed state of Chronicle
type ChronicleStatus struct {
CommonProductStatus `json:",inline"`
// +optional
Ready bool `json:"ready"`
}

// +kubebuilder:object:root=true
// +kubebuilder:subresource:status
// +kubebuilder:resource:shortName={pcr,chr},path=chronicles
// +kubebuilder:printcolumn:name="Ready",type=string,JSONPath=`.status.conditions[?(@.type=='Ready')].status`
// +kubebuilder:printcolumn:name="Version",type=string,JSONPath=`.status.version`
// +kubebuilder:printcolumn:name="Age",type=date,JSONPath=`.metadata.creationTimestamp`
// +genclient
// +k8s:openapi-gen=true

Expand Down
9 changes: 7 additions & 2 deletions api/core/v1beta1/connect_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -155,13 +155,18 @@ type ConnectSpec struct {

// ConnectStatus defines the observed state of Connect
type ConnectStatus struct {
KeySecretRef corev1.SecretReference `json:"keySecretRef,omitempty"`
Ready bool `json:"ready"`
CommonProductStatus `json:",inline"`
KeySecretRef corev1.SecretReference `json:"keySecretRef,omitempty"`
// +optional
Ready bool `json:"ready"`
}

//+kubebuilder:object:root=true
//+kubebuilder:subresource:status
//+kubebuilder:resource:shortName={con,cons},path=connects
//+kubebuilder:printcolumn:name="Ready",type="string",JSONPath=".status.conditions[?(@.type=='Ready')].status"
//+kubebuilder:printcolumn:name="Version",type="string",JSONPath=".status.version"
//+kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp"
//+genclient
//+k8s:openapi-gen=true

Expand Down
5 changes: 5 additions & 0 deletions api/core/v1beta1/flightdeck_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,12 +65,17 @@ type FlightdeckSpec struct {

// FlightdeckStatus defines the observed state of Flightdeck
type FlightdeckStatus struct {
CommonProductStatus `json:",inline"`
// Ready indicates whether the Flightdeck deployment is ready
// +optional
Ready bool `json:"ready"`
}

//+kubebuilder:object:root=true
//+kubebuilder:subresource:status
//+kubebuilder:printcolumn:name="Ready",type=string,JSONPath=`.status.conditions[?(@.type=='Ready')].status`
//+kubebuilder:printcolumn:name="Version",type=string,JSONPath=`.status.version`
//+kubebuilder:printcolumn:name="Age",type=date,JSONPath=`.metadata.creationTimestamp`
//+genclient
//+k8s:openapi-gen=true

Expand Down
14 changes: 12 additions & 2 deletions api/core/v1beta1/packagemanager_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@ import (

// PackageManagerSpec defines the desired state of PackageManager
type PackageManagerSpec struct {
// Suspended indicates Package Manager should not run serving resources (Deployment, Service, Ingress)
// but should preserve data resources (PVC, database, secrets). Set by the Site controller.
// +optional
Suspended *bool `json:"suspended,omitempty"`

License product.LicenseSpec `json:"license,omitempty"`
Config *PackageManagerConfig `json:"config,omitempty"`
Volume *product.VolumeSpec `json:"volume,omitempty"`
Expand Down Expand Up @@ -83,13 +88,18 @@ type PackageManagerSpec struct {

// PackageManagerStatus defines the observed state of PackageManager
type PackageManagerStatus struct {
KeySecretRef v1.SecretReference `json:"keySecretRef,omitempty"`
Ready bool `json:"ready"`
CommonProductStatus `json:",inline"`
KeySecretRef v1.SecretReference `json:"keySecretRef,omitempty"`
// +optional
Ready bool `json:"ready"`
}

//+kubebuilder:object:root=true
//+kubebuilder:subresource:status
//+kubebuilder:resource:shortName={pm,pms},path=packagemanagers
//+kubebuilder:printcolumn:name="Ready",type=string,JSONPath=`.status.conditions[?(@.type=='Ready')].status`
//+kubebuilder:printcolumn:name="Version",type=string,JSONPath=`.status.version`
//+kubebuilder:printcolumn:name="Age",type=date,JSONPath=`.metadata.creationTimestamp`
//+genclient
//+k8s:openapi-gen=true

Expand Down
6 changes: 5 additions & 1 deletion api/core/v1beta1/postgresdatabase_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,15 @@ type PostgresDatabaseSpecTeardown struct {
}

// PostgresDatabaseStatus defines the observed state of PostgresDatabase
type PostgresDatabaseStatus struct{}
type PostgresDatabaseStatus struct {
CommonProductStatus `json:",inline"`
}

//+kubebuilder:object:root=true
//+kubebuilder:subresource:status
//+kubebuilder:resource:shortName={pgdb,pgdbs},path=postgresdatabases
//+kubebuilder:printcolumn:name="Ready",type="string",JSONPath=".status.conditions[?(@.type=='Ready')].status"
//+kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp"
//+genclient

// PostgresDatabase is the Schema for the postgresdatabases API
Expand Down
69 changes: 67 additions & 2 deletions api/core/v1beta1/site_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,21 @@ type FeatureEnablerConfig struct {
}

type InternalPackageManagerSpec struct {
// Enabled controls whether Package Manager is running. Defaults to true.
// Setting to false suspends Package Manager: stops pods and removes ingress/service,
// but preserves PVC, database, and secrets so data is retained.
// Re-enabling restores full service without data loss.
// +kubebuilder:default=true
// +optional
Enabled *bool `json:"enabled,omitempty"`

// Teardown permanently destroys all Package Manager resources including the database,
// secrets, and persistent volume claim. Only takes effect when Enabled is false.
// Re-enabling after teardown starts fresh with a new empty database.
// +kubebuilder:default=false
// +optional
Teardown *bool `json:"teardown,omitempty"`

License product.LicenseSpec `json:"license,omitempty"`

Volume *product.VolumeSpec `json:"volume,omitempty"`
Expand Down Expand Up @@ -341,6 +356,21 @@ type InternalConnectExperimentalFeatures struct {
}

type InternalWorkbenchSpec struct {
// Enabled controls whether Workbench is running. Defaults to true.
// Setting to false suspends Workbench: stops pods and removes ingress/service,
// but preserves PVC, database, and secrets so data is retained.
// Re-enabling restores full service without data loss.
// +kubebuilder:default=true
// +optional
Enabled *bool `json:"enabled,omitempty"`

// Teardown permanently destroys all Workbench resources including the database,
// secrets, and persistent volume claim. Only takes effect when Enabled is false.
// Re-enabling after teardown starts fresh with a new empty database.
// +kubebuilder:default=false
// +optional
Teardown *bool `json:"teardown,omitempty"`

Databricks map[string]DatabricksConfig `json:"databricks,omitempty"`

Snowflake SnowflakeConfig `json:"snowflake,omitempty"`
Expand Down Expand Up @@ -509,6 +539,20 @@ type InternalWorkbenchExperimentalFeatures struct {
}

type InternalChronicleSpec struct {
// Enabled controls whether Chronicle is running. Defaults to true.
// Setting to false suspends Chronicle: stops the StatefulSet and removes the service.
// Re-enabling restores full service.
// +kubebuilder:default=true
// +optional
Enabled *bool `json:"enabled,omitempty"`

// Teardown permanently destroys all Chronicle resources.
// Only takes effect when Enabled is false.
// Re-enabling after teardown starts fresh.
// +kubebuilder:default=false
// +optional
Teardown *bool `json:"teardown,omitempty"`

NodeSelector map[string]string `json:"nodeSelector,omitempty"`

Image string `json:"image,omitempty"`
Expand Down Expand Up @@ -574,12 +618,33 @@ type ApiSettingsConfig struct {

// SiteStatus defines the observed state of Site
type SiteStatus struct {
// INSERT ADDITIONAL STATUS FIELD - define observed state of cluster
// Important: Run "make" to regenerate code after modifying this file
CommonProductStatus `json:",inline"`

// ConnectReady indicates whether the Connect child resource is ready.
// +optional
ConnectReady bool `json:"connectReady,omitempty"`

// WorkbenchReady indicates whether the Workbench child resource is ready.
// +optional
WorkbenchReady bool `json:"workbenchReady,omitempty"`

// PackageManagerReady indicates whether the PackageManager child resource is ready.
// +optional
PackageManagerReady bool `json:"packageManagerReady,omitempty"`

// ChronicleReady indicates whether the Chronicle child resource is ready.
// +optional
ChronicleReady bool `json:"chronicleReady,omitempty"`

// FlightdeckReady indicates whether the Flightdeck child resource is ready.
// +optional
FlightdeckReady bool `json:"flightdeckReady,omitempty"`
}

//+kubebuilder:object:root=true
//+kubebuilder:subresource:status
//+kubebuilder:printcolumn:name="Ready",type="string",JSONPath=".status.conditions[?(@.type=='Ready')].status"
//+kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp"
//+genclient
//+k8s:openapi-gen=true

Expand Down
29 changes: 29 additions & 0 deletions api/core/v1beta1/status.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// SPDX-License-Identifier: MIT
// Copyright (c) 2023-2026 Posit Software, PBC

package v1beta1

import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

// CommonProductStatus contains the common status fields shared by all product CRDs.
// Embed this struct inline in product-specific Status types.
type CommonProductStatus struct {
// Conditions represent the latest available observations of the resource's current state.
// +optional
// +patchMergeKey=type
// +patchStrategy=merge
// +listType=map
// +listMapKey=type
Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type"`

// ObservedGeneration is the most recent generation observed for this resource.
// It corresponds to the resource's generation, which is updated on mutation by the API Server.
// +optional
ObservedGeneration int64 `json:"observedGeneration,omitempty"`

// Version is the version of the product image being deployed.
// +optional
Version string `json:"version,omitempty"`
}
10 changes: 10 additions & 0 deletions api/core/v1beta1/workbench_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@ const MaxLoginPageHtmlSize = 64 * 1024

// WorkbenchSpec defines the desired state of Workbench
type WorkbenchSpec struct {
// Suspended indicates Workbench should not run serving resources (Deployment, Service, Ingress)
// but should preserve data resources (PVC, database, secrets). Set by the Site controller.
// +optional
Suspended *bool `json:"suspended,omitempty"`

License product.LicenseSpec `json:"license,omitempty"`
Config WorkbenchConfig `json:"config,omitempty"`
SecretConfig WorkbenchSecretConfig `json:"secretConfig,omitempty"`
Expand Down Expand Up @@ -115,13 +120,18 @@ type WorkbenchSpec struct {

// WorkbenchStatus defines the observed state of Workbench
type WorkbenchStatus struct {
CommonProductStatus `json:",inline"`
// +optional
Ready bool `json:"ready"`
KeySecretRef corev1.SecretReference `json:"keySecretRef,omitempty"`
}

//+kubebuilder:object:root=true
//+kubebuilder:subresource:status
//+kubebuilder:resource:shortName={wb,wbs},path=workbenches,singular=workbench
//+kubebuilder:printcolumn:name="Ready",type=string,JSONPath=`.status.conditions[?(@.type=='Ready')].status`
//+kubebuilder:printcolumn:name="Version",type=string,JSONPath=`.status.version`
//+kubebuilder:printcolumn:name="Age",type=date,JSONPath=`.metadata.creationTimestamp`
//+genclient
//+k8s:openapi-gen=true

Expand Down
Loading