一键导入
一键导入
| name | team-operator-config |
| description | Scaffold a new config option for Posit Team products |
When adding a new configuration option to any Posit Team product:
Before running this skill, know:
MaxConnections)Scheduler.MaxConnections or server.max_connections) - check product documentationImportant: Product config names are often inconsistent with Site CRD naming. Always verify the expected config path from product documentation or existing examples.
site_types.go (SiteSpec)
-> InternalProductSpec (Site-level config)
-> site_controller_{product}.go (Propagation logic)
-> Product CR using PRODUCT'S expected config path
File: team-operator/api/core/v1beta1/site_types.go
Find the relevant Internal{Product}Spec struct and add:
// {Description}
// Maps to product config: {ProductConfigName}
// +optional
{SiteFieldName} {Type} `json:"{jsonFieldName},omitempty"`
File: team-operator/api/core/v1beta1/{product}_types.go
Find the relevant config struct and add the field. Match the product's expected structure.
File: team-operator/internal/controller/core/site_controller_{product}.go
In the reconcile function, add propagation logic mapping Site field to Product config path:
// For simple types:
// Site: {SiteFieldName} -> Product: {ProductConfigPath}
if site.Spec.{Product}.{SiteFieldName} != {ZeroValue} {
target{Product}.Spec.Config.{ProductConfigPath} = site.Spec.{Product}.{SiteFieldName}
}
// For pointer types (optional values):
if site.Spec.{Product}.{SiteFieldName} != nil {
target{Product}.Spec.Config.{ProductConfigPath} = *site.Spec.{Product}.{SiteFieldName}
}
File: team-operator/internal/controller/core/site_controller_{product}_test.go
Add test case verifying the mapping:
It("should propagate {SiteFieldName} to product config {ProductConfigPath}", func() {
site := &v1beta1.Site{
Spec: v1beta1.SiteSpec{
{Product}: v1beta1.Internal{Product}Spec{
{SiteFieldName}: {TestValue},
},
},
}
result := reconcile{Product}(site)
Expect(result.Spec.Config.{ProductConfigPath}).To(Equal({TestValue}))
})
File: docs/guides/product-team-site-management.md
Update the example Site spec to include the new field with a comment.
File: docs/team-operator/{product}-config.md (create if needed)
Document both the Site field name AND the product config it maps to.
// MaxConnections sets the maximum number of connections
// Maps to product config: Scheduler.MaxConnections
// +optional
MaxConnections *int `json:"maxConnections,omitempty"`
// LogLevel sets the logging verbosity
// Maps to product config: Logging.All.LogLevel
// +kubebuilder:validation:Enum=debug;info;warn;error
// +optional
LogLevel string `json:"logLevel,omitempty"`
// GPUSettings configures GPU resources
// +optional
GPUSettings *GPUSettings `json:"gpuSettings,omitempty"`
type GPUSettings struct {
// NvidiaGPULimit sets the GPU limit
// Maps to product config: Scheduler.NvidiaGPULimit
// +optional
NvidiaGPULimit int `json:"nvidiaGpuLimit,omitempty"`
}
// EnableFeatureX enables the experimental feature X
// Maps to product config: Features.ExperimentalX
// +optional
EnableFeatureX bool `json:"enableFeatureX,omitempty"`
Note: For booleans, omitempty will omit false values, so only propagate when explicitly true.
| Product | Site Types | Product Types | Controller |
|---|---|---|---|
| Connect | site_types.go (InternalConnectSpec) | connect_types.go | site_controller_connect.go |
| Workbench | site_types.go (InternalWorkbenchSpec) | workbench_types.go | site_controller_workbench.go |
| Package Manager | site_types.go (InternalPackageManagerSpec) | packagemanager_types.go | site_controller_packagemanager.go |
| Chronicle | site_types.go (InternalChronicleSpec) | chronicle_types.go | site_controller_chronicle.go |
| Keycloak | site_types.go (InternalKeycloakSpec) | keycloak_types.go | site_controller_keycloak.go |
To find the expected product config path:
site_controller_{product}.go for similar optionsvalues.yaml for config structure