better docs for build trait and use parameters (#1304)

This commit is contained in:
Jianbo Sun
2021-03-26 07:04:52 +08:00
committed by GitHub
parent ec7eed3e37
commit 94b7cbff21
3 changed files with 65 additions and 121 deletions
+1 -1
View File
@@ -13,7 +13,7 @@
- [Definition CRD](/en/platform-engineers/definition-and-templates.md)
- [Auto-generated Schema](/en/platform-engineers/openapi-v3-json-schema.md)
- [Defining Components](/en/platform-engineers/component.md)
<!-- - [Defining Traits](/en/platform-engineers/trait.md) -->
- [Defining Traits](/en/platform-engineers/trait.md)
<!-- - [Defining Cloud Service](/en/platform-engineers/cloud-services.md) -->
- Using CUE
@@ -1,105 +1,27 @@
# Auto-generated OpenAPI v3 JSON Schema for Capability
# Auto-generated Schema for Capability Parameters
For any installed capability, KubeVela will automatically generate OpenAPI v3 JSON Schema for it.
For any installed capabilities from [definition files](./definition-and-templates.md),
KubeVela will automatically generate OpenAPI v3 JSON Schema for the parameters defined.
So end users can learn how to write the Application Object from it.
## Why?
Platform builders can integrate the schema API to build a new UI for their end users.
In definition objects, [parameter](https://kubevela.io/#/en/platform-engineers/workload-type?id=_4-define-template) section are expected to be set by developers when creating `Application` object.
While there is another GUI way for developers to input all parameter fields by rendering `parameter` section to [OpenAPI v3 Specification](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md#format).
## An integration workflow
For example, after you created a definition object, KubeVela will generate OpenAPI v3 JSON Schema from `parameter` of Workload Type [webservice](https://kubevela.io/#/en/developers/references/workload-types/webservice).
In definition objects, `parameter` is always required as the entrance for encapsulation of the capabilities.
```json
{
"properties": {
"cmd": {
"description": "Commands to run in the container",
"items": {
"type": "string"
},
"title": "cmd",
"type": "array"
},
"cpu": {
"description": "Number of CPU units for the service, like `0.5` (0.5 CPU core), `1` (1 CPU core)",
"title": "cpu",
"type": "string"
},
"env": {
"description": "Define arguments by using environment variables",
"items": {
"properties": {
"name": {
"description": "Environment variable name",
"title": "name",
"type": "string"
},
"value": {
"description": "The value of the environment variable",
"title": "value",
"type": "string"
},
"valueFrom": {
"description": "Specifies a source the value of this var should come from",
"properties": {
"secretKeyRef": {
"description": "Selects a key of a secret in the pod's namespace",
"properties": {
"key": {
"description": "The key of the secret to select from. Must be a valid secret key",
"title": "key",
"type": "string"
},
"name": {
"description": "The name of the secret in the pod's namespace to select from",
"title": "name",
"type": "string"
}
},
"required": ["name", "key"],
"title": "secretKeyRef",
"type": "object"
}
},
"required": ["secretKeyRef"],
"title": "valueFrom",
"type": "object"
}
},
"required": ["name"],
"type": "object"
},
"title": "env",
"type": "array"
},
"image": {
"description": "Which image would you like to use for your service",
"title": "image",
"type": "string"
},
"port": {
"default": 80,
"description": "Which port do you want customer traffic sent to",
"title": "port",
"type": "integer"
}
},
"required": ["image", "port"],
"type": "object"
}
```
* CUE: the [`parameter`](../cue/component.md#Write-ComponentDefinition) is a `keyword` in CUE template.
* HELM: the [`parameter``](../helm/component.md#Write-ComponentDefinition) is generated from `values.yaml` in HELM chart.
You can render the schema by [form-render](https://github.com/alibaba/form-render) or [React JSON Schema form](https://github.com/rjsf-team/react-jsonschema-form). A web form can be as below.
When a new ComponentDefinition or TraitDefinition applied in K8s, KubeVela will watch the resources and
generate a `ConfigMap` in the same namespace with the definition object.
![](../../resources/json-schema-render-example.jpg)
The default KubeVela system namespace is `vela-system`, the built-in capabilities are laid there.
## How to use the generated JSON Schema of definition
When a platform builder applies a ComponentDefinition or TraitDefinition, a ConfigMap will be created in a namespace same
as the definition (by default it will be in `vela-system` namespace) and labeled with `definition.oam.dev=schema`.
The ConfigMap will have a common label `definition.oam.dev=schema`, so you can find easily by:
```shell
$ kubectl get cm -n vela-system -l definition.oam.dev=schema
$ kubectl get configmap -n vela-system -l definition.oam.dev=schema
NAME DATA AGE
schema-ingress 1 19s
schema-scaler 1 19s
@@ -108,12 +30,18 @@ schema-webservice 1 19s
schema-worker 1 20s
```
The ConfigMap name is in the format `schema-$definitionName`, and the key of ConfigMap data is `openapi-v3-json-schema`.
The ConfigMap name is in the format of `schema-<your-definition-name>`,
and the `key` of ConfigMap is `openapi-v3-json-schema`.
For example, we can use the following command to get the JSON Schema of `webservice`.
```shell
$ kubectl get cm schema-webservice -n vela-system -o yaml
$ kubectl get configmap schema-webservice -n vela-system -o yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: schema-webservice
namespace: vela-system
data:
openapi-v3-json-schema: '{"properties":{"cmd":{"description":"Commands to run in
the container","items":{"type":"string"},"title":"cmd","type":"array"},"cpu":{"description":"Number
@@ -127,11 +55,13 @@ data:
name of the secret in the pod''s namespace to select from","title":"name","type":"string"}},"required":["name","key"],"title":"secretKeyRef","type":"object"}},"required":["secretKeyRef"],"title":"valueFrom","type":"object"}},"required":["name"],"type":"object"},"title":"env","type":"array"},"image":{"description":"Which
image would you like to use for your service","title":"image","type":"string"},"port":{"default":80,"description":"Which
port do you want customer traffic sent to","title":"port","type":"integer"}},"required":["image","port"],"type":"object"}'
kind: ConfigMap
metadata:
name: schema-webservice
namespace: vela-system
```
If you adopt [KubeVela API Server](https://github.com/oam-dev/kubevela/tree/master/references/apiserver), you can get the
schema by API [/api/definitions/{definitionName}](https://kubevela.io/en/developers/references/restful-api/index.html#api-Definitions-getDefinition).
Then the platform builder can follow the [OpenAPI v3 Specification](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md#format)
to build their own GUI for end users.
For example, you can render the schema by [form-render](https://github.com/alibaba/form-render) or [React JSON Schema form](https://github.com/rjsf-team/react-jsonschema-form).
A web form rendered from the `schema-webservice` can be as below.
![](../../resources/json-schema-render-example.jpg)
+34 -20
View File
@@ -8,7 +8,6 @@ The KubeVela trait system is very powerful. Generally, you could define a trait(
just writing some CUE template is enough. Refer to ["Defining Traits in CUE"](https://kubevela.io/#/en/cue/trait) for
more details in this case.
## Extend CRD Operator as Trait
In the following tutorial, you will learn to extend traits into KubeVela with [KEDA](https://keda.sh/) as example.
@@ -22,16 +21,16 @@ KEDA is a very cool Event Driven Autoscaler.
To register KEDA as a new trait in KubeVela, the only thing needed is to create an `TraitDefinition` object for it.
A full example can be found in this [keda.yaml](https://github.com/oam-dev/catalog/blob/master/registry/keda.yaml).
A full example can be found in this [keda.yaml](https://github.com/oam-dev/catalog/blob/master/registry/keda-scaler.yaml).
Several highlights are list below.
#### 1. Describe The Trait Usage
```yaml
...
name: kubewatch
annotations:
definition.oam.dev/description: "Add a watch for resource"
name: keda-scaler
annotations:
definition.oam.dev/description: "keda supports multiple event to elastically scale applications, this scaler only applies to deployment as example"
...
```
@@ -44,17 +43,15 @@ It will be shown in helper commands such as `$ vela traits`.
...
spec:
definitionRef:
name: kubewatches.labs.bitnami.com
name: scaledobjects.keda.sh
...
```
This is how you register Kubewatch's API resource (`kubewatches.labs.bitnami.com`) as the Trait.
This is how you register KEDA ScaledObject's API resource (`scaledobjects.keda.sh`) as the Trait.
KubeVela uses Kubernetes API resource discovery mechanism to manage all registered capabilities.
#### 3. Define Workloads this trait can apply to
```yaml
@@ -66,7 +63,7 @@ spec:
...
```
A trait can work on specified workload or any kinds of workload, that deponds on what you describe here.
A trait can work on specified workload or any kinds of workload, that depends on what you describe here.
Use `"*"` to represent your trait can work on any workloads.
You can also specify the trait can only work on K8s Deployment and Statefulset by describe like below:
@@ -101,27 +98,44 @@ Platform builders only need to declare this info here once, then the OAM framewo
```yaml
...
template: |
outputs: kubewatch: {
apiVersion: "labs.bitnami.com/v1alpha1"
kind: "KubeWatch"
spec: handler: webhook: url: parameter.webhook
schematic:
cue:
template: |-
outputs: cpu-scaler: {
apiVersion: "keda.sh/v1alpha1"
kind: "ScaledObject"
metadata: {
name: context.name
}
spec: {
scaleTargetRef: {
name: context.name
}
triggers: [{
type: paramter.type
metadata: {
type: "Utilization"
value: paramter.value
}
}]
}
}
parameter: {
webhook: string
paramter: {
// +usage=Types of triggering application elastic scaling, Optional: cpu, memory
type: string
// +usage=Value to trigger scaling actions, represented as a percentage of the requested value of the resource for the pods. like: "60"(60%)
value: string
}
```
This is a CUE based template to define end user abstraction for this workload type. Please check the [templating documentation](../cue/trait.md) for more detail.
Note that in this example, we only need to give the webhook url as parameter for using KubeWatch.
### Step 2: Register New Trait to KubeVela
As long as the definition file is ready, you just need to apply it to Kubernetes.
```bash
$ kubectl apply -f https://raw.githubusercontent.com/oam-dev/catalog/master/registry/kubewatch.yaml
$ kubectl apply -f https://raw.githubusercontent.com/oam-dev/catalog/master/registry/keda-scaler.yaml
```
And the new trait will immediately become available for developers to use in KubeVela.