ResourceInterface
概述
ResourceInterface 是一个集群级别的资源,定义了外部资源(如 Git 仓库、OCI 工件、Maven 工件)的标准化抽象,以及它们如何集成到流水线工作流中。它作为连接器与流水线编排之间的桥梁,实现资源的无缝集成,减少手动配置。
下面的示例定义了一个描述 Git 仓库访问的 GitCodeRepository 接口:
apiVersion: connectors.alauda.io/v1alpha1
kind: ResourceInterface
metadata:
name: gitcoderepository
labels:
resourceinterface.connectors.cpaas.io/category: "GitCodeRepository"
spec:
params:
- name: repository
type: string
description: "仓库名称"
- name: revision
type: string
default: "refs/heads/main"
description: "Git 修订(分支、标签或提交)"
attributes:
- name: url
type: string
expression: "{connector.spec.address + '/' + params.repository}"
parameterize:
name: git-url
dependsOn:
- params.repository
- connector
workspaces:
- name: git-basic-auth
workspaceMapping:
name: git-basic-auth
value:
csi:
driver: connectors-csi
readOnly: true
volumeAttributes:
connector.name: "{connector.metadata.name}"
connector.namespace: "{connector.metadata.namespace}"
configuration.names: "gitconfig"
token.expiration: 30m
ResourceInterface 定义了资源集成的以下关键方面:
- 资源配置所需的输入参数
- 根据参数和连接器信息计算的输出属性
- 卷和凭据的工作空间定义
本文档提供了ResourceInterface 数据结构定义和示例,帮助读者理解如何自定义 ResourceInterface。
除非您需要自定义 ResourceInterface,否则无需深入理解其细节。
解决的问题
在构建 CI/CD 流水线时,用户通常面临以下挑战:
手动资源输入:用户无法轻松浏览和添加 Git 仓库、OCI 仓库及其他外部服务资源,必须手动输入 URL 并配置工作空间,容易出错且耗时。
重复执行配置:每次运行流水线时,用户都需手动输入版本信息(如 Git 修订、目标 OCI 标签),并重复配置工作空间。
属性分散:同一远程资源的属性常被拆分为不同参数。例如,git-clone 任务需要分别传入 url 和 revision 参数,以及凭据和源码的工作空间配置。
复杂的工作空间选择:流水线工作空间选择过程列出所有可用选项,但对每个工作空间适用的连接器类型缺乏指导。
ResourceInterface 通过提供标准化的方式描述和集成外部资源到流水线工作流,解决了上述问题,使用户能够通过 UI 浏览和选择资源,同时自动生成正确的配置和凭据。
数据结构
ResourceInterface 是一个集群级别的 k8s 资源
- Kind:ResourceInterface
- API 版本:connectors.alauda.io/v1alpha1
ResourceInterface 是标准的 k8s 资源,可以通过 annotations 注解添加人类可读信息。
apiVersion: connectors.alauda.io/v1alpha1
kind: ResourceInterface
metadata:
name: gitcoderepository
annotations:
cpaas.io/display-name: "Git 代码仓库"
cpaas.io/description: "GitCodeRepository 是 Git 代码仓库的资源接口"
也可以使用 style.tekton.dev/descriptors 注解描述参数以支持动态表单。
metadata:
annotations:
style.tekton.dev/descriptors: |-
- path: params.revision
x-descriptors:
- urn:alm:descriptor:widgets:select
- urn:alm:descriptor:expression:props.options:schema:openapi:context.connectorClass.spec.api.openapi:listGitRefs
更多详情请参考动态表单。
资源类别
ResourceInterface 将资源组织为定义通用契约和行为的类别。类别通过标签 resourceinterface.connectors.cpaas.io/category 标记。
metadata:
labels:
resourceinterface.connectors.cpaas.io/category: "GitCodeRepository"
多个 ResourceInterface 可以属于同一类别(例如,gitcoderepository 和 githubcoderepository 都属于 GitCodeRepository 类别)。同类别的资源必须提供相同的标准属性和工作空间,以确保兼容性。
参数
参数定义了集成资源到流水线时所需的输入数据,这些参数影响输出属性的计算。
参数定义在 spec.params 中,遵循 Tekton 参数类型:
- name:参数名称
- type:支持
string、array、object(与 Tekton ParamSpec 类型一致)
- default:默认参数值(可选)
- description:参数描述,用于 UI 显示(可选)
例如:
kind: ResourceInterface
metadata:
name: gitcoderepository
labels:
resourceinterface.connectors.cpaas.io/category: "GitCodeRepository"
spec:
params:
- name: repository
type: string
description: "仓库名称"
- name: revision
type: string
default: "refs/heads/main"
description: "Git 修订(分支、标签或提交)"
属性
属性定义了根据输入参数和连接器信息计算的输出值,可被流水线任务作为参数使用,也可提升为流水线级别参数。
属性定义在 spec.attributes 中:
- name:属性名称
- type:值类型,支持
string、array
- expression:用于计算属性值的 JavaScript 表达式
- parameterize:参数化配置
- name:参数化时的默认参数名
- disable:是否禁用参数化
- dependsOn:依赖的参数或连接器
例如:
spec:
attributes:
- name: url
type: string
expression: "{connector.spec.address + '/' + params.repository}"
parameterize:
name: git-url
dependsOn:
- params.repository
- connector
- name: artifact-versions
type: array
expression: "{params.tags.map(tag => connector.spec.registry + '/' + params.repository + ':' + tag)}"
dependsOn:
- params.repository
- params.tags
- connector
表达式语法
表达式使用 JavaScript 语法,支持:
- 字符串拼接:
params.organization + '/' + params.repository
- 对象属性访问:
connector.metadata.name
- 数组操作:
params.tags.map(tag => connector.spec.address + ':' + tag)
- 内置函数:
url(connector.spec.address).host:获取地址的主机部分
以及其他 JavaScript 语法。
可用上下文:
上下文数据结构为:
{
"params": {
"param-name1": "param-value",
"param-name2": "param-value"
},
"connector": {}
}
安全性:前端在沙箱环境中执行 JavaScript 代码,仅允许安全的沙箱函数。
示例:
{connector.spec.address + '/' + params.repository}:获取仓库地址
{url(connector.spec.address).host + '/' + params.repository + ':' + params.tag}:获取工件地址
{params.tags.map(tag => url(connector.spec.address).host + '/' + params.repository + ':' + tag)}:通过遍历标签数组获取工件地址数组
依赖关系
依赖指定属性计算依赖的参数或连接器信息:
params.<param-name>:依赖特定参数值
connector:依赖连接器选择
工作空间
工作空间定义资源接口提供的卷和凭据,支持自动为流水线任务提供所需资源。
工作空间定义在 spec.workspaces 中:
- name:工作空间名称
- workspaceMapping.name:添加到流水线工作空间时的默认名称
- value:默认工作空间值(遵循 Tekton WorkspaceBinding 格式),与 Tekton WorkspaceBinding 类型一致
例如:
spec:
workspaces:
- name: git-source
workspaceMapping:
name: git-source
value:
volumeClaimTemplate:
spec:
accessModes: [ReadWriteMany]
resources:
requests:
storage: 1Gi
- name: git-basic-auth
workspaceMapping:
name: git-basic-auth
value:
csi:
driver: connectors-csi
readOnly: true
volumeAttributes:
connector.name: "{connector.metadata.name}"
connector.namespace: "{connector.metadata.namespace}"
configuration.names: "gitconfig"
token.expiration: 30m
工作空间值支持表达式,动态引用参数和连接器值,语法与属性相同。
ConnectorClass
ConnectorClass 通过标签 resourceinterface.connectors.cpaas.io/<resource-interface-name>: "true" 标记支持的 ResourceInterface,例如:
metadata:
labels:
resourceinterface.connectors.cpaas.io/gitcoderepository: "true"
resourceinterface.connectors.cpaas.io/githubcoderepository: "true"
系统据此匹配兼容的连接器与 ResourceInterface,并根据 ResourceInterface 定义提供相应的参数表单。
更多关于 ConnectorClass 请参考ConnectorClass 概念
动态表单为流水线集成配置交互式 UI 组件提供声明式方式。通过动态表单,用户可以直接通过连接器浏览和选择 Git 仓库及修订。
概述
使用 style.tekton.dev/descriptors 注解定义参数的动态表单行为。示例如下:
metadata:
annotations:
style.tekton.dev/descriptors: >-
- path: params.repository
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:select:repository
- urn:alm:descriptor:expression:props.options:api:/clusters-rewrite/${context.cluster}${context.connector.status.api.path}/api/v4/projects?simple=true
- urn:alm:descriptor:expression:props.options:label:path:path_with_namespace
- urn:alm:descriptor:expression:props.options:value:path:path_with_namespace
- urn:alm:descriptor:label:en:Repository
- urn:alm:descriptor:label:zh:Repository
- urn:alm:descriptor:description:zh:Repository path including group name or username, e.g. mygroup/my-app.
- urn:alm:descriptor:description:en:Repository path including group name or username, e.g. mygroup/my-app.
语法遵循 Pipeline Dynamic Forms 规范,建议先熟悉该文档。
除了标准功能,ResourceInterface 中的动态表单支持:
- 扩展上下文变量,用于访问连接器和 ResourceInterface 数据
- 在 ConnectorClass 中引用 OpenAPI 显示模式,实现 API 配置集中管理,动态表单使用时可直接引用 API 定义
扩展上下文变量
ResourceInterface 动态表单中可用的上下文变量:
动态表单配置方式
ResourceInterface 中配置动态表单有两种方式:
-
直接调用 API 配置:通过描述符表达式直接调用连接器 API,简单易懂。连接器系统提供了Connector API端点,用于列出仓库、git 引用等。
-
在 ConnectorClass 中引用 OpenAPI 显示模式:在 ConnectorClass 中通过 spec.api.openapi 定义 API 调用和显示映射,实现 API 定义和显示配置的集中管理,避免多个 ResourceInterface 重复配置。动态表单使用时可直接引用 ConnectorClass 中的 API 定义。
两种方式可单独使用,也可结合使用。
直接 API 配置
示例:列出 GitLab 仓库
GitLab 连接器暴露原生 GitLab API,可用于填充仓库选择器:
kind: ResourceInterface
metadata:
name: gitlabcoderepository
annotations:
style.tekton.dev/descriptors: >-
- path: params.repository
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:select:repository
- urn:alm:descriptor:expression:props.options:api:/clusters-rewrite/${context.cluster}${context.connector.status.api.path}/api/v4/projects?simple=true
- urn:alm:descriptor:expression:props.options:label:path:path_with_namespace
- urn:alm:descriptor:expression:props.options:value:path:path_with_namespace
- urn:alm:descriptor:label:en:Repository
- urn:alm:descriptor:label:zh:Repository
- urn:alm:descriptor:description:zh:Repository path including group name or username, e.g. mygroup/my-app.
- urn:alm:descriptor:description:en:Repository path including group name or username, e.g. mygroup/my-app.
示例:列出 Git 引用
Git 连接器提供 gitrefs 端点用于列出分支和标签:
kind: ResourceInterface
metadata:
name: gitcoderepository
annotations:
style.tekton.dev/descriptors: >-
- path: params.revision
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:select:revision
- urn:alm:descriptor:expression:props.options:api:/clusters-rewrite/${context.cluster}${context.connector.status.api.path}/git/gitrefs?repositoryUrl=${context.connector.spec.address + "/" + context.params.repository + ".git"}&search=${current.search}
- urn:alm:descriptor:expression:props.options:path:items
- urn:alm:descriptor:expression:props.options:label:path:name
- urn:alm:descriptor:expression:props.options:value:path:name
- urn:alm:descriptor:label:en:Revision
- urn:alm:descriptor:label:zh:Revision
- urn:alm:descriptor:description:zh:Git 修订引用,例如 refs/heads/main。
- urn:alm:descriptor:description:en:Git 修订引用(例如分支的 refs/heads/main)
引用 OpenAPI 显示模式
为实现 API 定义和显示配置的集中管理,可在 ConnectorClass 中通过 spec.api.openapi 定义 OpenAPI 规范,动态表单可直接引用这些定义,避免 ResourceInterface 中重复配置。
前提条件
- 在 ConnectorClass 中定义 OpenAPI 规范,详见ConnectorClass OpenAPI 描述。
- 添加
x-display-schema 扩展,定义 API 如何与动态表单集成。
显示模式结构
x-display-schema 扩展包含:
示例:Git 引用 API
以下 ConnectorClass 配置定义了 GET /git/gitrefs API 及其显示模式:
repositoryUrl 参数设置为 ${context.connector.spec.address + "/" + context.params.repository + ".git"},作为查询参数传递
search 参数设置为 ${current.search},用于过滤结果
- 响应中的
items 数组映射为选择选项,name 用作标签和值
示例:
kind: ConnectorClass
spec:
api:
openapi:
openapi: 3.0.3
info:
title: Git API
version: v1alpha1
paths:
/git/gitrefs:
get:
x-provider-type: api
x-display-schema:
parameters:
- name: repositoryUrl
value: ${context.connector.spec.address + "/" + context.params.repository + ".git"}
- name: search
value: ${current.search}
descriptors:
- urn:alm:descriptor:expression:props.options:path:items
- urn:alm:descriptor:expression:props.options:label:path:name
- urn:alm:descriptor:expression:props.options:value:path:name
operationId: listGitRefs
parameters:
- name: repositoryUrl
in: query
description: "仓库的可克隆 URL(例如 https://github.com/mygroup/my-app.git)"
required: true
schema:
type: string
- name: search
in: query
description: "返回包含搜索字符串的 git 引用列表"
required: false
schema:
type: string
responses:
'200':
description: "仓库的所有 git 引用"
content:
application/json: {}
在 ResourceInterface 中引用 OpenAPI
API 在 ConnectorClass 中定义后,可在 ResourceInterface 中使用以下语法引用:
urn:alm:descriptor:widgets:select 指定控件类型
schema:openapi:context.connectorClass.spec.api.openapi:<operationId> 引用 ConnectorClass 中的 API 定义
例如:
kind: ResourceInterface
metadata:
name: gitcoderepository
annotations:
style.tekton.dev/descriptors: >-
- path: params.revision
x-descriptors:
- urn:alm:descriptor:widgets:select
- urn:alm:descriptor:expression:props.options:schema:openapi:context.connectorClass.spec.api.openapi:listGitRefs
- urn:alm:descriptor:label:en:Revision
- urn:alm:descriptor:label:zh:Revision
- urn:alm:descriptor:description:zh:Git 修订引用,例如 refs/heads/main。
- urn:alm:descriptor:description:en:Git 修订引用(例如分支的 refs/heads/main)
配置完成后,流水线集成中的 revision 字段将渲染为下拉框,从 listGitRefs API 获取选项。
示例
GitCodeRepository ResourceInterface
apiVersion: connectors.alauda.io/v1alpha1
kind: ResourceInterface
metadata:
name: gitcoderepository
labels:
resourceinterface.connectors.cpaas.io/category: "GitCodeRepository"
spec:
params:
- name: repository
type: string
description: "仓库名称"
- name: revision
type: string
default: "refs/heads/main"
description: "Git 修订"
attributes:
- name: url
type: string
expression: "{connector.spec.address + '/' + params.repository}"
parameterize:
name: git-url
dependsOn:
- params.repository
- connector
- name: revision
type: string
expression: "{params.revision}"
parameterize:
name: git-revision
dependsOn:
- params.revision
workspaces:
- name: git-source
workspaceMapping:
name: git-source
value:
volumeClaimTemplate:
spec:
accessModes: [ReadWriteMany]
resources:
requests:
storage: 200Mi
- name: git-basic-auth
workspaceMapping:
name: git-basic-auth
value:
csi:
driver: connectors-csi
readOnly: true
volumeAttributes:
connector.name: "{connector.metadata.name}"
connector.namespace: "{connector.metadata.namespace}"
configuration.names: "gitconfig"
token.expiration: 30m
OCIArtifact ResourceInterface
apiVersion: connectors.alauda.io/v1alpha1
kind: ResourceInterface
metadata:
name: ociartifact
labels:
resourceinterface.connectors.cpaas.io/category: "OCIArtifact"
spec:
params:
- name: repository
type: string
description: "仓库名称"
- name: tags
type: array
description: "镜像标签"
attributes:
- name: repository-address
type: string
expression: "{connector.spec.registry + '/' + params.repository}"
dependsOn:
- params.repository
- connector
- name: artifact-versions
type: array
expression: "{params.tags.map(tag => connector.spec.registry + '/' + params.repository + ':' + tag)}"
dependsOn:
- params.repository
- params.tags
- connector
workspaces:
- name: docker-config
workspaceMapping:
name: docker-config
value:
csi:
driver: connectors-csi
readOnly: true
volumeAttributes:
connector.name: "{connector.metadata.name}"
connector.namespace: "{connector.metadata.namespace}"
configuration.names: "config"
token.expiration: 60m
后续内容
- 了解 流水线集成,当您想在自定义流水线或任务中集成连接器时。
参考资料