Version: v1.1

X-Definition

In OAM model, Application used by end user consists many declarative moduels such as Component, Trait, Policy and Workflow etc. These types are actually shaped by many definitions behind them. The module definition (X-Definition) supported by the current OAM model includes ComponentDefinition, TraitDefinition, PolicyDefinition and WorkflowStepDefinition etc.

ComponentDefinition

The design goal of ComponentDefinition is to allow platform administrators to encapsulate any type of deployable products into “components” to be delivered. Once defined, this type of component can be referenced, instantiated and delivered by users in the Application.

Common component types include Helm Chart, Kustomize directory, a set of Kubernetes YAML files, container images, cloud resource IaC files, or CUE configuration file modules, etc. The component supplier corresponds to the real-world role, which is generally a third-party software distributor (ISV), a DevOps team engineer, or a code package and image generated by the CI system you built.

ComponentDefinition can be shared and reused. For example, for an Alibaba Cloud RDS component type, end users can select the same Alibaba Cloud RDS component type in different applications and instantiate them into cloud database instances with different specifications and different parameter configurations.

Let’s take a look at the frame format of ComponentDefinition:

  1. apiVersion: core.oam.dev/v1beta1
  2. kind: ComponentDefinition
  3. metadata:
  4. name: <ComponentDefinition name>
  5. annotations:
  6. definition.oam.dev/description: <Function description>
  7. spec:
  8. workload: # Workload description
  9. definition:
  10. apiVersion: <Kubernetes Workload resource group>
  11. kind: <Kubernetes Workload types>
  12. schematic: # Component description
  13. cue: # Details of components defined by CUE language
  14. template: <CUE format template>

Here is a complete example to introduce how to use ComponentDefinition.

  1. apiVersion: core.oam.dev/v1beta1
  2. kind: ComponentDefinition
  3. metadata:
  4. name: helm
  5. namespace: vela-system
  6. annotations:
  7. definition.oam.dev/description: "helm release is a group of K8s resources from either git repository or helm repo"
  8. spec:
  9. workload:
  10. type: autodetects.core.oam.dev
  11. schematic:
  12. cue:
  13. template: |
  14. output: {
  15. apiVersion: "source.toolkit.fluxcd.io/v1beta1"
  16. metadata: {
  17. name: context.name
  18. }
  19. if parameter.repoType == "git" {
  20. kind: "GitRepository"
  21. spec: {
  22. url: parameter.repoUrl
  23. ref:
  24. branch: parameter.branch
  25. interval: parameter.pullInterval
  26. }
  27. }
  28. if parameter.repoType == "helm" {
  29. kind: "HelmRepository"
  30. spec: {
  31. interval: parameter.pullInterval
  32. url: parameter.repoUrl
  33. if parameter.secretRef != _|_ {
  34. secretRef: {
  35. name: parameter.secretRef
  36. }
  37. }
  38. }
  39. }
  40. }
  41. outputs: release: {
  42. apiVersion: "helm.toolkit.fluxcd.io/v2beta1"
  43. kind: "HelmRelease"
  44. metadata: {
  45. name: context.name
  46. }
  47. spec: {
  48. interval: parameter.pullInterval
  49. chart: {
  50. spec: {
  51. chart: parameter.chart
  52. version: parameter.version
  53. sourceRef: {
  54. if parameter.repoType == "git" {
  55. kind: "GitRepository"
  56. }
  57. if parameter.repoType == "helm" {
  58. kind: "HelmRepository"
  59. }
  60. name: context.name
  61. namespace: context.namespace
  62. }
  63. interval: parameter.pullInterval
  64. }
  65. }
  66. if parameter.targetNamespace != _|_ {
  67. targetNamespace: parameter.targetNamespace
  68. }
  69. if parameter.values != _|_ {
  70. values: parameter.values
  71. }
  72. }
  73. }
  74. parameter: {
  75. repoType: "git" | "helm"
  76. // +usage=The Git or Helm repository URL, accept HTTP/S or SSH address as git url.
  77. repoUrl: string
  78. // +usage=The interval at which to check for repository and relese updates.
  79. pullInterval: *"5m" | string
  80. // +usage=1.The relative path to helm chart for git source. 2. chart name for helm resource
  81. chart: string
  82. // +usage=Chart version
  83. version?: string
  84. // +usage=The Git reference to checkout and monitor for changes, defaults to master branch.
  85. branch: *"master" | string
  86. // +usage=The name of the secret containing authentication credentials for the Helm repository.
  87. secretRef?: string
  88. // +usage=The namespace for helm chart
  89. targetNamespace?: string
  90. // +usage=Chart version
  91. value?: #nestedmap
  92. }
  93. #nestedmap: {
  94. ...
  95. }

TraitDefinition

TraitDefinition provides a series of DevOps actions for the component that can be bound on demand. These operation and maintenance actions are usually provided by the platform administrator, such as adding a load balancing strategy, routing strategy, or performing scaler, gray release strategy, etc.

The format and field functions of the TraitDefinition are as follows:

  1. apiVersion: core.oam.dev/v1beta1
  2. kind: TraitDefinition
  3. metadata:
  4. name: <TraitDefinition name>
  5. annotations:
  6. definition.oam.dev/description: <function description>
  7. spec:
  8. definition:
  9. apiVersion: <corresponding Kubernetes resource group>
  10. kind: <corresponding Kubernetes resource type>
  11. workloadRefPath: <The path to the reference field of the Workload object in the Trait>
  12. podDisruptive: <whether the parameter update of Trait cause the underlying resource (pod) to restart>
  13. manageWorkload: <Whether the workload is managed by this Trait>
  14. skipRevisionAffect: <Whether this Trait is not included in the calculation of version changes>
  15. appliesToWorkloads:
  16. - <Workload that TraitDefinition can adapt to>
  17. conflictsWith:
  18. - <other Traits that conflict with this><>
  19. revisionEnabled: <whether Trait is aware of changes in component version>
  20. schematic: # Abstract
  21. cue: # There are many abstracts
  22. template: <CUE format template>

Let’s look at a practical example:

  1. apiVersion: core.oam.dev/v1beta1
  2. kind: TraitDefinition
  3. metadata:
  4. annotations:
  5. definition.oam.dev/description: "configure k8s Horizontal Pod Autoscaler for Component which using Deployment as worklaod"
  6. name: hpa
  7. spec:
  8. appliesToWorkloads:
  9. - deployments.apps
  10. workloadRefPath: spec.scaleTargetRef
  11. schematic:
  12. cue:
  13. template: |
  14. outputs: hpa: {
  15. apiVersion: "autoscaling/v2beta2"
  16. kind: "HorizontalPodAutoscaler"
  17. spec: {
  18. minReplicas: parameter.min
  19. maxReplicas: parameter.max
  20. metrics: [{
  21. type: "Resource"
  22. resource: {
  23. name: "cpu"
  24. target: {
  25. type: "Utilization"
  26. averageUtilization: parameter.cpuUtil
  27. }
  28. }
  29. }]
  30. }
  31. }
  32. parameter: {
  33. min: *1 | int
  34. max: *10 | int
  35. cpuUtil: *50 | int
  36. }

PolicyDefinition

PolicyDefinition is simimarly to TraitDefinition, the difference is that TraitDefinition acts on a single component but PolicyDefinition is to act on the entire application as a whole (multiple components).

It can provide global policy for applications, commonly including global security policies (such as RBAC permissions, auditing, and key management), application insights (such as application SLO management, etc.).

The format is as follows:

  1. apiVersion: core.oam.dev/v1beta1
  2. kind: PolicyDefinition
  3. metadata:
  4. name: <PolicyDefinition name>
  5. annotations:
  6. definition.oam.dev/description: <function description>
  7. spec:
  8. schematic: # strategy description
  9. cue:
  10. template: <CUE format template>

A specific example is shown below:

  1. apiVersion: core.oam.dev/v1beta1
  2. kind: PolicyDefinition
  3. metadata:
  4. name: env-binding
  5. annotations:
  6. definition.oam.dev/description: <Provide differentiated configuration and environmental scheduling strategies for applications>
  7. spec:
  8. schematic:
  9. cue:
  10. template: |
  11. output: {
  12. apiVersion: "core.oam.dev/v1alpha1"
  13. kind: "EnvBinding"
  14. spec: {
  15. engine: parameter.engine
  16. appTemplate: {
  17. apiVersion: "core.oam.dev/v1beta1"
  18. kind: "Application"
  19. metadata: {
  20. name: context.appName
  21. namespace: context.namespace
  22. }
  23. spec: {
  24. components: context.components
  25. }
  26. }
  27. envs: parameter.envs
  28. }
  29. }
  30. #Env: {
  31. name: string
  32. patch: components: [...{
  33. name: string
  34. type: string
  35. properties: {...}
  36. }]
  37. placement: clusterSelector: {
  38. labels?: [string]: string
  39. name?: string
  40. }
  41. }
  42. parameter: {
  43. engine: *"ocm" | string
  44. envs: [...#Env]
  45. }

WorkflowStepDefinition

WorkflowStepDefinition is used to describe a series of steps that can be declared in the workflow, such as the deployment of execution resources, status check, data output, dependent input, external script call, etc.

  1. apiVersion: core.oam.dev/v1beta1
  2. kind: WorkflowStepDefinition
  3. metadata:
  4. name: <WorkflowStepDefinition name>
  5. annotations:
  6. definition.oam.dev/description: <function description>
  7. spec:
  8. schematic: # node description
  9. cue:
  10. template: <CUE format template>

An actual WorkflowStepDefinition is as follows:

  1. apiVersion: core.oam.dev/v1beta1
  2. kind: WorkflowStepDefinition
  3. metadata:
  4. name: apply-component
  5. spec:
  6. schematic:
  7. cue:
  8. template: |
  9. import ("vela/op")
  10. parameter: {
  11. component: string
  12. }
  13. // load component from application
  14. component: op.#Load & {
  15. component: parameter.component
  16. }
  17. // apply workload to kubernetes cluster
  18. apply: op.#ApplyComponent & {
  19. component: parameter.name
  20. }
  21. // wait until workload.status equal "Running"
  22. wait: op.#ConditionalWait & {
  23. continue: apply.status.phase =="Running"
  24. }

WorkloadDefinition

WorkloadDefinition is a system-level feature. It’s not a field that users should care about but as metadata checked, verified, and used by the OAM system itself.

The format is as follows:

  1. apiVersion: core.oam.dev/v1beta1
  2. kind: WorkloadDefinition
  3. metadata:
  4. name: <WorkloadDefinition name>
  5. spec:
  6. definitionRef:
  7. name: <corresponding Kubernetes resource group>
  8. version: <corresponding Kubernetes resource version>
  9. podSpecPath: <path to the Pod field in the Workload>
  10. childResourceKinds:
  11. - apiVersion: <resource group>
  12. kind: <resource type>

In addition, other Kubernetes resource type that need to be introduced into OAM model in the future will also be added as fields to the workload definition.

The Standard Protocol Behind Abstraction

Once the application is created, KubeVela will tag the created resources with a series of tags, which include the version, name, type, etc. of the application. Through these standard protocols, application components, traits and policies can be coordinated. The specific metadata list is as follows:

LabelDescription
workload.oam.dev/typeCorresponds to the name of ComponentDefinition
trait.oam.dev/typeCorresponds to the name of TraitDefinition
app.oam.dev/nameApplication name
app.oam.dev/componentComponent name
trait.oam.dev/resourceoutputs.\<resource type\>in Trait
app.oam.dev/appRevisionApplication Revision Name

X-Definition Runtime Context

In the X-Definition, some runtime context information can be obtained through the context variable. The specific list is as follows, where the scope indicates which module definitions the Context variable can be used in:

Context VariableDescriptionScope
context.appRevisionThe app version name corresponding to the current instance of the applicationComponentDefinition, TraitDefinition
context.appRevisionNumThe app version number corresponding to the current instance of the application.ComponentDefinition, TraitDefinition
context.appNameThe app name corresponding to the current instance of the application.ComponentDefinition, TraitDefinition
context.namecomponent name in ComponentDefinition and TraitDefinition,policy in PolicyDefinitionComponentDefinition, TraitDefinition, PolicyDefinition
context.namespaceThe namespace of the current instance of the applicationComponentDefinition, TraitDefinition
context.revisionThe version name of the current component instanceComponentDefinition, TraitDefinition
context.parameterThe parameters of the current component instance, it can be obtained in the traitTraitDefinition
context.outputObject structure after instantiation of current componentComponentDefinition, TraitDefinition
context.outputs.<resourceName>Structure after instantiation of current component and traitComponentDefinition, TraitDefinition

At the same time, in the Workflow system, because the context has to act on the application level, it is very different from the above usage. We introduce it separately:

Context VariableDescriptionScope
context.nameThe name of the current instance of the applicationWorkflowStepDefinition
context.namespaceThe namespace of the current instance of the applicationWorkflowStepDefinition
context.labelsThe labels of the current instance of the applicationWorkflowStepDefinition
context.annotationsThe annotations of the current instance of the applicationWorkflowStepDefinition

Please note that all the X-Definition concepts introduced in this section only need to be understood by the platform administrator when they want to expand the functions of KubeVela, and end users do not need to have any perception of these concepts.