ConnectorClass

目录

概述

ConnectorClass 是一个集群级别的资源,用于定义特定类型工具的访问模式和行为规范。

以下示例定义了一个支持基本认证的 hello-git 类型连接器:

apiVersion: connectors.alauda.io/v1alpha1
kind: ConnectorClass
metadata:
  name: hello-git
spec:
  address:
    type: string  # 地址为字符串格式
  auth:
    types:
      - name: basicAuth
        secretType: kubernetes.io/basic-auth  # 使用 Basic Auth 进行认证

在 ConnectorClass 中,通过描述以下信息定义连接工具到平台的访问模式和行为规范:

  • 工具访问地址的格式
  • 支持的认证方式
  • 如何检测工具的可访问性
  • 如何验证认证的有效性
  • 工具提供的 API 能力
  • 工具提供的配置能力
  • 用于可读性展示的元数据

本文档还提供示例,帮助读者更好地理解如何自定义 ConnectorClass。示例

地址信息

地址信息定义了访问工具的格式。目前支持字符串类型的地址配置。该地址信息限制了当前类型工具必须满足的字段类型约束。

spec:
  address:
    type: string  # 目前仅支持字符串类型

此时表示连接工具到平台的地址信息必须为 string 类型。

认证信息

认证类型

认证类型定义了工具认证所使用的凭证类型。一个工具可以支持多种认证类型,用户在使用工具时可以选择其中一种。

用户可以通过以下方式为当前认证类型命名:

  • spec.auth.types[].name,必须唯一且不可重复。
  • spec.auth.types[].secretType,指定认证所需的 Secret 类型,对应 Kubernetes Secret 类型

示例:

spec:
  auth:
    types:
      - name: basicAuth  # 认证类型名称
        secretType: kubernetes.io/basic-auth  # 对应 Secret 类型
      - name: sshAuth
        secretType: kubernetes.io/ssh-auth

在内置的 K8S Secret 类型中,除 Opaque 外,所有类型都有字段约束。提供 Secret 时,用户必须确保 Secret 的字段符合类型约束。

使用 Opaque 类型时,必须声明认证参数

同 Kubernetes 一样,也可以使用自定义 Secret 类型,此时必须声明认证参数

认证参数

认证凭证所需的参数由 spec.auth.types[].params 定义。

对于标准 Kubernetes Secret 类型且数据字段明确的,可以省略参数。例如:

  • kubernetes.io/basic-auth:用户名和密码认证
  • kubernetes.io/ssh-auth:SSH 密钥认证

对于自定义认证类型,可以定义所需的认证参数,此时 secretType 标记为 Opaque 或自定义名称。

例如,GitLab 的个人访问令牌(PAT)认证:

spec:
  auth:
    types:
      - name: privateToken
        secretType: Opaque
        params:
          - name: username
            type: string
          - name: private-token
            type: string
      - name: oauth2
        secretType: example.com/oauth2
        params:
          - name: clientID
            type: string
          - name: clientSecret
            type: string

该定义要求工具连接器使用的凭证包含 params 中指定的字段。

可选认证

部分工具支持无认证访问,通过 optional 字段标记认证是否可选:

例如,以下表示 basicAuth 的凭证为可选,而 sshAuth 的凭证为必需。

spec:
  auth:
    types:
      - name: basicAuth
        optional: true  # 标记认证为可选
        secretType: kubernetes.io/basic-auth
      - name: sshAuth
        secretType: kubernetes.io/basic-auth

此时,连接该类型工具到平台时,可以省略 basicAuth 类型的认证。

可访问性检测

可访问性检测用于验证工具是否能正常访问。该类型的检测配置通过 livenessProbe 字段完成。

例如,以下片段表示通过 HTTP 请求进行检测。

spec:
  livenessProbe:
    http:
      path: /

当工具返回 200 状态时,视为可访问。

认证检测

认证检测用于验证该类型工具的认证信息有效性。若不需要认证检测,可省略 authProbes

例如,以下 YAML 表示工具认证检测时,将发起带有注入的 Authorization: abc 头的 http GET 请求。

spec:
  authProbes:
    - authName: basicAuth  # 对应认证类型
      probe:
        http:
          httpHeaders:
            Authorization: abc
          path: /
          method: GET # 默认为 GET,支持 POST 和 GET 方法
          disableRedirect: false # 默认为 false,允许自动重定向
  • authName 表示使用的认证类型,需要与 spec.auth.types[].name 对应。
  • 认证检测时,直接使用连接器工具的地址信息。
  • spec.authProbes[].probe.http.method 指定认证使用的 HTTP 方法,支持 GET 和 POST,默认 GET。
  • spec.authProbes[].probe.http.disableRedirect 指定认证时是否禁用重定向,默认允许自动重定向。

自定义认证检测参数

部分认证检测可能需要额外参数,例如检测 Git 仓库访问时指定仓库名,可通过 spec.authProbes[].params 指定。

spec:
  authProbes:
    - authName: basicAuth  # 对应认证类型
      params:
        - name: repository
          type: string

认证检测表达式

配置 authProbes 时,可以通过表达式动态获取凭证信息或 Connector 信息。

例如,

spec:
  authProbes:
    - authName: basicAuth  # 对应认证类型
      probe:
        http:
          httpHeaders:
            Authorization: {{ .Secret.StringData.token }}
          path: /
      params:
        - name: repository
          type: string
  • 表达式可用于 httpHeaderspath 字段。
  • 表达式格式为 go template
  • 支持的顶层字段有:
    • .Connector:Connector 本身的信息
    • .Secret:用于 Connector 的 Secret 信息
  • 表达式内可用的方法参考 sprig 文档
    • 例如:b64enc 对字符串进行 Base64 编码,trimPrefix 去除字符串前缀

示例

  • Basic Auth 认证检测
spec:
  authProbes:
    - authName: basicAuth
      params:
        - name: repository
          type: string
      probe:
        http:
          path: /{{- range .Connector.Spec.Auth.Params }}{{- if eq .Name "repository" }}{{ .Value.StringVal }}{{ end }}{{- end }}/info/refs?service=git-upload-pack
          httpHeaders:
          - name: Authorization
            value: >-
              {{- if .Secret }}Basic {{ printf "%s:%s" .Secret.StringData.username .Secret.StringData.password | b64enc }} {{- end }}

连接器将基于 ConnectorClass 中的信息进行有效性检测。

上述 yaml 表示 basic auth 的认证检测:

  • path:利用 Connector 信息中 auth.params 里设置的 repository 值,拼接为 /<repository>/info/refs?service=git-upload-pack
  • Authorization:若 Connector 配置了 Secret,则返回 Secret 中的 usernamepassword 字段的 base64 编码。

基于 Rego 的认证逻辑配置

当工具连接器需要更复杂的认证逻辑时,可以使用基于 Rego 的认证逻辑配置。

Rego 是一种声明式策略语言,允许定义认证逻辑。在 ConnectorClass 中,Rego 策略通过 auth.types[].generator.rego 字段指定:

apiVersion: connectors.alauda.io/v1alpha1
kind: ConnectorClass
metadata:
  name: example
spec:
  address:
    name: address
    type: string
  auth:
    types:
    - name: rego-auth
      secretType: Opaque
      generator:
        rego: |
          package proxy
          auth = {
            "position": "header",
            "auth": {
              "Authorization": concat(" ", ["Bearer", input.token])
            }
          }

Rego 策略必须遵循以下规则:

  • 在 proxy 包下定义规则
  • 生成一个结构如下的 auth 对象:
    • position:注入认证的位置,如 "header"、"query" 或 "body"
    • contentType:body 注入时的内容类型(可选,配合 "body" 使用)
    • auth:认证键值对映射

Rego 策略示例

基本认证
spec:
  auth:
    types:
    - name: basic-rego-auth
      secretType: Opaque
      generator:
        rego: |
          package proxy
          auth = {
            "position": "header",
            "auth": {
              "Authorization": concat(" ", ["Basic", base64.encode(concat(":", [input.username, input.password]))])
            }
          }
API Key 认证
spec:
  auth:
    types:
    - name: apikey-rego-auth
      secretType: Opaque
      generator:
        rego: |
          package proxy
          auth = {
            "position": "query",
            "auth": {
              "api_key": input.apikey
            }
          }
JSON Body 认证
spec:
  auth:
    types:
    - name: body-rego-auth
      secretType: Opaque
      generator:
        rego: |
          package proxy
          auth = {
            "position": "body",
            "contentType": "application/json",
            "auth": {
              "username": input.username,
              "password": input.password,
              "client_id": input.client_id
            }
          }

高级 Rego 技巧

可以使用 Rego 的条件逻辑实现不同认证方式:

条件认证
spec:
  auth:
    types:
    - name: conditional-auth
      secretType: Opaque
      generator:
        rego: |
          package proxy

          # 默认使用 API key
          auth = {
            "position": "header",
            "auth": {
              "X-API-Key": input.apikey
            }
          }

          # 如果存在 OAuth token,则使用它
          auth = {
            "position": "header",
            "auth": {
              "Authorization": concat(" ", ["Bearer", input.oauth_token])
            }
          } {
            input.oauth_token != ""
          }
基于时间的认证
spec:
  auth:
    types:
    - name: time-based-auth
      secretType: Opaque
      generator:
        rego: |
          package proxy

          import time

          # 获取当前时间
          current_time := time.now_ns() / 1000000000

          auth = {
            "position": "header",
            "auth": {
              "X-Timestamp": sprintf("%d", [current_time]),
              "X-Signature": hmac.sha256(input.api_secret, sprintf("%d", [current_time]))
            }
          }

更多 Rego 语言详情,请参考:

ConnectorClass API

为当前 ConnectorClass 提供 RESTful API,方便客户端在使用 Connectors 时访问工具内的资源。

如果不需要为工具提供 API 能力,spec.api 可不定义。

ConnectorClass API 需在 spec.api 字段配置,例如:

spec:
  api:
    ref:
      kind: Service
      name: git
      namespace: default

可以通过 spec.api.ref 指定 API 的 Service 信息。如果 ConnectorClass 的 API 地址有固定前缀,可以通过 spec.api.uri 指定。例如:

spec:
  api:
    ref:
      kind: Service
      name: git
      namespace: default
    uri: /api

此外,也可以使用 spec.api.uri 指定 API 的绝对路径。例如:

spec:
  api:
    uri: https://git.example.com/api

无论哪种形式,最终解析出的 API 地址会存储在 status.api.address.url 中。例如:

通过 service 指定 connectorclass API:

spec:
  api:
    ref:
      kind: Service
      name: git
      namespace: default
status:
  api:
    address:
      url: https://git.default.svc

通过 uri 指定 connectorclass API:

spec:
  api:
    uri: https://git.default.svc/api
status:
  api:
    address:
      url: https://git.default.svc/api

通过 svc 指定 connectorclass API,同时使用 spec.api.uri 指定 API 路径:

spec:
  api:
    ref:
      kind: Service
      name: git
      namespace: default
    uri: /api
status:
  api:
    address:
      url: https://git.default.svc/api

更多信息请参考:

配置能力

配置能力用于定义该类型工具的配置信息。该配置信息可结合 connectors-csi-driver 挂载到 Pod 中。

如果客户端访问工具时不需要依赖配置信息,spec.configurations 可不定义。

配置信息通过 spec.configurations 指定。例如:

kind: ConnectorClass
metadata:
  name: git
spec:
  configurations:
  - name: config
    data:
      .gitconfig: |
        this is git config

通常我们可以为一类工具指定某种配置,方便使用时配置。例如:

  • git 类型工具,提供 .gitconfig 配置
  • oci registry 类型工具,提供 config.json 配置

配置内容支持变量使用,可在挂载时动态渲染。详情请参考 connectors-csi-driver 中的“配置文件渲染”说明。

示例

以下 ConnectorClass 提供一个名为 .gitconfig 的文件,用于在 git clone 时忽略 SSL 验证。

kind: ConnectorClass
metadata:
  name: git
spec:
  configurations:
  - name: config
    data:
      .gitconfig: |
        [http]
          sslVerify = false

以下 ConnectorClass 提供一个名为 .gitconfig 的文件,用于在 git clone 时自动注入头部并替换 git URL。

kind: ConnectorClass
metadata:
  name: git
spec:
  configurations:
  - name: config
    data:
      .gitconfig: |
        [http]
            extraHeader = Authorization: Basic {{ printf ":%s" .context.token | b64enc }}
        [url "{{ .connector.status.proxyAddress }}"]
            insteadOf = {{.connector.spec.address}}

更多信息

用于可读性展示的元数据信息

ConnectorClass 是标准的 k8s 资源,可以通过 labelsannotations 打上自定义信息。

例如:

描述
ui.cpaas.io/iconConnectorClass 的图标,可选。格式:data:image/svg+xml;base64,PD94bWwgdmVyc2...
cpaas.io/display-nameConnectorClass 的显示名称,可选。
cpaas.io/descriptionConnectorClass 的描述,可选。
connectors.cpaas.io/readmeConnectorClass 的使用说明,可选。通常用于自定义场景无法提供 docs-link 时。支持 Markdown 格式。
connectors.cpaas.io/docs-linkConnectorClass 的文档链接,可选。支持相对或绝对路径。

例如:

apiVersion: connectors.alauda.io/v1alpha1
kind: ConnectorClass
metadata:
  name: git
  labels:
    connectors.cpaas.io/git: "true"
  annotations:
    ui.cpaas.io/icon: "data:image/svg+xml;base64,PD94bWwgdmVyc2..."
    cpaas.io/display-name: Git
    cpaas.io/description: "Connect to any Git tool"
    connectors.cpaas.io/readme: "this is readme..."
    connectors.cpaas.io/docs-link: "/alauda-devops-connectors/concepts/connectorclass/git"

ConnectorClass 代理

ConnectorClass 代理用于配置 ConnectorClass 的代理地址。

ConnectorClass 代理通过 spec.proxy 配置。例如:

spec:
  proxy:
    ref:
      kind: Service
      name: proxy
      namespace: default
    uri: https://proxy.example.com

Connector 会使用代理地址代理请求到 ConnectorClass。更多信息

解析器类型

ConnectorClass 的代理地址将根据指定的 resolver 类型进行解析。

resolver 类型通过注解 connectors.cpaas.io/proxy-resolver 配置。例如:

apiVersion: connectors.alauda.io/v1alpha1
kind: ConnectorClass
metadata:
  name: oci
  annotations:
    connectors.cpaas.io/proxy-resolver: "path"

该字段是 ConnectorClass-Proxy 与 Connector 之间的约定,非必填。

支持值:hostpath。默认值为 host

  • host 格式:http://{.ConnectorClass.Status.ProxyAddress.URL}
  • path 格式:http://{.ConnectorClass.Status.ProxyAddress.URL}/namespaces/{namespace}/connectors/{connector-name}

状态信息

定义 ConnectorClass 资源后,资源的状态信息将存储在 status 中。

status.conditions 类型包括:

  • APIReady:API 能力的状态信息
  • ProxyReady:代理能力的状态信息
  • Ready:标记当前 ConnectorClass 的整体状态

Ready Condition

Ready Condition 用于标记当前 ConnectorClass 的状态,聚合其他 Condition 的状态。

  • 其他 Condition 均为 True 时,当前 Condition 为 True。
  • 任何其他 Condition 为 False 时,当前 Condition 为 False。
  • 任何其他 Condition 为 Unknown 时,当前 Condition 为 Unknown。

APIReady Condition

表示 ConnectorClass 配置的 API 服务的状态信息。API 服务通过 ConnectorClass 的 spec.api 配置。

状态原因描述
TrueNonAPI未配置 spec.api,当前 ConnectorClass 无 API 能力
True已定义 spec.api,API 服务正常
False已定义 spec.api,API 能力异常或检测本身异常
UnknownAPI 能力检测中

注意:

  • API 检测仅尝试请求链接,不会对 HTTP 返回值做判断。API 服务的健康检查应依赖 API 服务自身的健康检查机制。
  • 由于 API 服务可能随时变更,API 状态信息无法反映实时信息,建议客户端将该状态信息作为提示,而非依赖其阻断客户端行为。

ProxyReady Condition

表示 ConnectorClass 配置的代理服务的状态信息。代理服务通过 ConnectorClass 的 spec.proxy 配置。

状态原因描述
TrueNonProxy未配置 spec.proxy,当前 ConnectorClass 无代理能力
True已定义 spec.proxy,代理服务正常
False已定义 spec.proxy,代理能力异常或检测本身异常
Unknown代理能力检测中

兼容性

ConnectorClass 的更新可能影响已有的 Connectors。如果 ConnectorClass 存在不兼容变更,可能导致之前创建的 Connectors 失效。以下是可能导致不兼容的变更示例:

  1. 认证信息变更:如果 ConnectorClass 修改了支持的认证类型或方式,可能导致使用旧认证方式的 Connectors 失效。

  2. 配置信息变更:如果 ConnectorClass 的配置信息发生变更,如移除已有配置,可能导致依赖旧配置的 Kubernetes 工作负载异常。

建议在更新 ConnectorClass 时确认影响范围,必要时创建新的 ConnectorClass。

更多示例

  • 支持 basic-auth 认证类型的 ConnectorClass
apiVersion: connectors.alauda.io/v1alpha1
kind: ConnectorClass
metadata:
  name: git
spec:
  address:
    type: string
  auth:
    types:
      - name: basicAuth
        secretType: kubernetes.io/basic-auth
        optional: true
  • 自定义认证类型 ConnectorClass
apiVersion: connectors.alauda.io/v1alpha1
kind: ConnectorClass
metadata:
  name: sample
spec:
  address:
    type: string
  auth:
    types:
      - name: patAuth
        optional: true
        secretType: Opaque
        params:
        - name: username
        - name: privateToken
  • 配置了 liveness probe 的 ConnectorClass
apiVersion: connectors.alauda.io/v1alpha1
kind: ConnectorClass
metadata:
  name: git
spec:
  address:
    type: string
  auth:
    types:
      - name: basicAuth
        optional: true
        secretType: kubernetes.io/basic-auth
  livenessProbe:
    http:
      path: /
  • 配置了 auth probe 的 ConnectorClass
apiVersion: connectors.alauda.io/v1alpha1
kind: ConnectorClass
metadata:
  name: git
  labels:
    connectors.cpaas.io/git: "true"
spec:
  address:
    type: string
  auth:
    types:
      - name: basicAuth
        secretType: kubernetes.io/basic-auth
        optional: true
  livenessProbe:
    http:
      path: /
  authProbes:
    - authName: basicAuth
      params:
        - name: repository
          type: string
      probe:
        http:
          path: /{{- range .Connector.Spec.Auth.Params }}{{- if eq .Name "repository" }}{{ .Value.StringVal }}{{ end }}{{- end }}/info/refs?service=git-upload-pack
          httpHeaders:
          - name: Authorization
            value: >-
              {{- if .Secret }}Basic {{ printf "%s:%s" .Secret.StringData.username .Secret.StringData.password | b64enc }} {{- end }}
  • 完整的 Git 连接器配置示例:
apiVersion: connectors.alauda.io/v1alpha1
kind: ConnectorClass
metadata:
  name: git
spec:
  address:
    name: address
    type: string
  auth:
    types:
      - name: basicAuth
        secretType: kubernetes.io/basic-auth
        optional: true
  livenessProbe:
    http:
      path: /
  authProbes:
    - authName: basicAuth
      params:
        - name: repository
          type: string
      probe:
        http:
          path: /{{- range .Connector.Spec.Auth.Params }}{{- if eq .Name "repository" }}{{ .Value.StringVal }}{{ end }}{{- end }}/info/refs?service=git-upload-pack
          httpHeaders:
          - name: Authorization
            value: >-
              {{- if .Secret }}Basic {{ printf "%s:%s" .Secret.StringData.username .Secret.StringData.password | b64enc }} {{- end }}

更多