Skip to content

Latest commit

 

History

History
352 lines (286 loc) · 11.2 KB

File metadata and controls

352 lines (286 loc) · 11.2 KB
title Trait API Reference

Trait

A Trait represents a cross-cutting concern that can be attached to components to add additional capabilities like persistent storage, observability, security policies, or service mesh integration. Traits modify or extend the resources generated by ComponentTypes without requiring changes to the ComponentType itself.

API Version

openchoreo.dev/v1alpha1

Resource Definition

Metadata

Traits are namespace-scoped resources typically created in an Organization's namespace to be available for components in that organization.

apiVersion: openchoreo.dev/v1alpha1
kind: Trait
metadata:
  name: <trait-name>
  namespace: <org-namespace>  # Organization namespace

Spec Fields

Field Type Required Default Description
schema TraitSchema No - Configurable parameters for this trait
creates [TraitCreate] No [] New Kubernetes resources to create
patches [TraitPatch] No [] Modifications to existing ComponentType resources

TraitSchema

Defines the configurable parameters that developers can set when attaching this trait to a component.

Field Type Required Default Description
types object No - Reusable type definitions referenced in parameters
parameters object No - Developer-facing configuration options
envOverrides object No - Parameters that can be overridden per environment

Parameter Schema Syntax

Uses the same inline schema syntax as ComponentType: a single pipe after the type, then space-separated constraints:

fieldName: "type | default=value enum=val1,val2"

Example:

schema:
  parameters:
    volumeName: string
    mountPath: string
    containerName: "string | default=app"

  envOverrides:
    size: "string | default=10Gi"
    storageClass: "string | default=standard"

TraitCreate

Defines a new Kubernetes resource to be created when the trait is applied.

Field Type Required Description
template object Yes Kubernetes resource template with CEL expressions

CEL expressions in trait templates have access to:

  • metadata.* - Component metadata
  • trait.* - Trait parameters and instance name
  • parameters.* - Component parameters
  • environment.* - Environment information

TraitPatch

Defines modifications to existing resources generated by the ComponentType.

Field Type Required Description
forEach string No CEL expression for iterating over a list
var string No Variable name for forEach iterations (required if forEach set)
target PatchTarget Yes Specifies which resource to patch
operations [JSONPatchOperation] Yes List of JSONPatch operations to apply

PatchTarget

Specifies which Kubernetes resource to modify.

Field Type Required Description
group string No API group (empty for core resources)
version string Yes API version (e.g., "v1", "v1beta1")
kind string Yes Resource type (e.g., "Deployment", "StatefulSet")
where string No CEL expression to filter which resources to patch

JSONPatchOperation

Defines a modification using JSONPatch format (RFC 6902) with OpenChoreo extensions.

Field Type Required Description
op string Yes Operation: add, replace, remove
path string Yes JSON Pointer to the field (RFC 6901)
value any No Value to set (not used for remove)

Supported Operations

  • add: Add a new field or array element
  • replace: Replace an existing field value
  • remove: Delete a field

Path Syntax

Supports array filters for targeting specific elements:

/spec/containers[?(@.name=='app')]/volumeMounts/-

Examples

Persistent Volume Trait

apiVersion: openchoreo.dev/v1alpha1
kind: Trait
metadata:
  name: persistent-volume
  namespace: default
spec:
  schema:
    parameters:
      volumeName: string
      mountPath: string
      containerName: "string | default=app"

    envOverrides:
      size: "string | default=10Gi"
      storageClass: "string | default=standard"

  creates:
    - template:
        apiVersion: v1
        kind: PersistentVolumeClaim
        metadata:
          name: ${metadata.name}-${trait.instanceName}
          namespace: ${metadata.namespace}
        spec:
          accessModes:
            - ReadWriteOnce
          storageClassName: ${trait.parameters.storageClass}
          resources:
            requests:
              storage: ${trait.parameters.size}

  patches:
    - target:
        group: apps
        version: v1
        kind: Deployment
      operations:
        - op: add
          path: /spec/template/spec/containers[?(@.name=='${trait.parameters.containerName}')]/volumeMounts/-
          value:
            name: ${trait.parameters.volumeName}
            mountPath: ${trait.parameters.mountPath}
        - op: add
          path: /spec/template/spec/volumes/-
          value:
            name: ${trait.parameters.volumeName}
            persistentVolumeClaim:
              claimName: ${metadata.name}-${trait.instanceName}

Sidecar Container Trait

apiVersion: openchoreo.dev/v1alpha1
kind: Trait
metadata:
  name: logging-sidecar
  namespace: default
spec:
  schema:
    parameters:
      logPath: "string | default=/var/log/app"
      sidecarImage: "string | default=fluent/fluent-bit:latest"

  patches:
    - target:
        group: apps
        version: v1
        kind: Deployment
      operations:
        - op: add
          path: /spec/template/spec/containers/-
          value:
            name: log-collector
            image: ${trait.parameters.sidecarImage}
            volumeMounts:
              - name: logs
                mountPath: ${trait.parameters.logPath}
        - op: add
          path: /spec/template/spec/volumes/-
          value:
            name: logs
            emptyDir: {}

Resource Limits Trait

apiVersion: openchoreo.dev/v1alpha1
kind: Trait
metadata:
  name: resource-limits
  namespace: default
spec:
  schema:
    envOverrides:
      cpuLimit: "string | default=1000m"
      memoryLimit: "string | default=512Mi"

  patches:
    - target:
        group: apps
        version: v1
        kind: Deployment
      operations:
        - op: add
          path: /spec/template/spec/containers[?(@.name=='main')]/resources/limits/cpu
          value: ${trait.parameters.cpuLimit}
        - op: add
          path: /spec/template/spec/containers[?(@.name=='main')]/resources/limits/memory
          value: ${trait.parameters.memoryLimit}

Multi-Container Trait with forEach

apiVersion: openchoreo.dev/v1alpha1
kind: Trait
metadata:
  name: multi-volume
  namespace: default
spec:
  schema:
    types:
      Mount:
        name: string
        path: string
    parameters:
      mounts: "[]Mount"

  patches:
    - target:
        group: apps
        version: v1
        kind: Deployment
      forEach: ${trait.parameters.mounts}
      var: mount
      operations:
        - op: add
          path: /spec/template/spec/volumes/-
          value:
            name: ${mount.name}
            emptyDir: {}
        - op: add
          path: /spec/template/spec/containers[?(@.name=='app')]/volumeMounts/-
          value:
            name: ${mount.name}
            mountPath: ${mount.path}

Usage

Developers attach traits to components in the Component specification:

apiVersion: openchoreo.dev/v1alpha1
kind: Component
metadata:
  name: my-service
spec:
  componentType: deployment/service

  traits:
    - name: persistent-volume
      instanceName: data-storage
      parameters:
        volumeName: data
        mountPath: /var/data
        containerName: app
      envOverrides:
        size: 20Gi
        storageClass: fast-ssd

Platform engineers can also override trait parameters in ComponentDeployment:

apiVersion: openchoreo.dev/v1alpha1
kind: ComponentDeployment
metadata:
  name: my-service-production
spec:
  componentName: my-service
  environment: production

  traitOverrides:
    - instanceName: data-storage
      parameters:
        size: 100Gi
        storageClass: production-ssd

Best Practices

  1. Single Responsibility: Each trait should address one cross-cutting concern
  2. Naming: Use descriptive names that indicate the capability being added
  3. Parameters: Provide sensible defaults for all non-required parameters
  4. Target Specificity: Use where clauses when needed to avoid unintended modifications
  5. Testing: Test traits with different ComponentTypes to ensure compatibility
  6. Documentation: Document which ComponentTypes a trait is designed to work with
  7. Idempotency: Ensure traits can be safely applied multiple times

Trait vs ComponentType

Aspect ComponentType Trait
Purpose Defines core deployment pattern Adds cross-cutting concerns
Scope One per component Multiple can be attached to one component
Resources Creates primary workload resources Creates supplementary resources or patches existing ones
Modification Determines base resource structure Modifies or extends ComponentType resources
Examples Service, WebApp, ScheduledTask Persistent Storage, Logging, Security

Related Resources