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. Примеры

Информация об адресе

Информация об адресе определяет формат доступа к инструменту. В настоящее время поддерживаются конфигурации адреса типа string. Эта информация ограничивает тип поля, которому должен соответствовать текущий тип инструмента.

spec:
  address:
    type: string  # В настоящее время поддерживается только тип 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 необходимо объявить параметры аутентификации.

Как и в k8s, можно использовать собственный тип Secret. В этом случае также нужно объявить параметры аутентификации.

Параметры аутентификации

Параметры, необходимые для учетных данных при аутентификации, определяются в spec.auth.types[].params.

Для стандартных типов Kubernetes Secret с явно определёнными полями данных параметры можно опустить. Например:

  • kubernetes.io/basic-auth: аутентификация по имени пользователя и паролю
  • kubernetes.io/ssh-auth: аутентификация по SSH-ключу

Для пользовательских типов аутентификации можно определить необходимые параметры аутентификации, при этом secretType отмечается как Opaque или с пользовательским именем.

Например, для аутентификации GitLab с использованием Personal Access Token (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 указывает, что при проверке аутентификации инструмента будет выполнен HTTP GET-запрос с добавленным заголовком Authorization: abc.

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
  • Выражения можно использовать в полях httpHeaders и path.
  • Формат выражений — go template
  • Поддерживаемые верхнеуровневые поля:
    • .Connector: информация самого Connector
    • .Secret: информация Secret, используемого для данных Connector
  • Методы, доступные в выражениях, можно посмотреть в документации 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: использует значение repository, заданное в auth.params внутри информации Connector, объединённое в строку /<repository>/info/refs?service=git-upload-pack
  • Authorization: если в Connector настроен Secret, возвращаются поля username и password из Secret в 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")
    • 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 ключом
spec:
  auth:
    types:
    - name: apikey-rego-auth
      secretType: Opaque
      generator:
        rego: |
          package proxy
          auth = {
            "position": "query",
            "auth": {
              "api_key": input.apikey
            }
          }
Аутентификация с JSON телом
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 ключ
          auth = {
            "position": "header",
            "auth": {
              "X-API-Key": input.apikey
            }
          }

          # Использовать OAuth токен, если он есть
          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 см.:

API ConnectorClass

Предоставляет RESTful API для текущего ConnectorClass, позволяя клиентам легко получать доступ к ресурсам внутри инструментов при использовании Connectors.

Если нет необходимости предоставлять API возможности для инструмента, spec.api можно не определять.

API ConnectorClass настраивается в поле spec.api, например:

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

Можно указать информацию о Service API через spec.api.ref. Если у API ConnectorClass есть фиксированный префикс адреса, его можно указать через 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. Например:

Указание API connectorclass через service:

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

Указание API connectorclass через uri:

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

Указание API connectorclass через svc с использованием spec.api.uri для указания пути API:

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

Для дополнительной информации см.:

Возможности конфигурации

Возможности конфигурации используются для определения конфигурационной информации для данного типа инструмента. Эта конфигурационная информация может быть смонтирована в Pods совместно с connectors-csi-driver.

Если клиенту не требуется опираться на конфигурационную информацию при доступе к инструменту, 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, который используется для игнорирования проверки SSL при git clone.

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

Следующий ConnectorClass предоставляет файл с именем .gitconfig, который автоматически внедряет заголовки и заменяет URL git при git clone.

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, который можно помечать пользовательской информацией с помощью labels и annotations.

Например:

КлючОписание
ui.cpaas.io/iconИконка для ConnectorClass, необязательно. Формат: data:image/svg+xml;base64,PD94bWwgdmVyc2...
cpaas.io/display-nameОтображаемое имя для ConnectorClass, необязательно.
cpaas.io/descriptionОписание для ConnectorClass, необязательно.
connectors.cpaas.io/readmeИнструкция по использованию ConnectorClass, необязательно. Обычно используется для кастомных сценариев, когда docs-link недоступна. Поддерживает Markdown.
connectors.cpaas.io/docs-linkСсылка на документацию ConnectorClass, необязательно. Относительный или абсолютный путь.

Пример:

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"

Proxy ConnectorClass

Proxy ConnectorClass используется для настройки адреса прокси для ConnectorClass.

Proxy ConnectorClass настраивается через spec.proxy. Например:

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

Коннектор будет использовать адрес прокси для проксирования запросов к 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. Необязательно.

Поддерживаемые значения: host, path. По умолчанию 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: статус Proxy возможностей
  • Ready: отмечает общий статус текущего ConnectorClass

Условие Ready

Ready Condition используется для отметки статуса текущего ConnectorClass. Оно агрегирует статусы других условий.

  • Если все другие Conditions True, текущее Condition True.
  • Если любое другое Condition False, текущее Condition False.
  • Если любое другое Condition Unknown, текущее Condition Unknown.

Условие APIReady

Отражает статус API сервиса, настроенного для ConnectorClass. API сервис настраивается через spec.api ConnectorClass.

СтатусПричинаОписание
TrueNonAPIspec.api не настроен, у текущего ConnectorClass нет API возможностей
Truespec.api определён, API сервис работает нормально
Falsespec.api определён, API возможности работают некорректно или проверка неудачна
UnknownПроверка API возможностей в процессе

Примечания:

  • Проверка API будет только пытаться запросить ссылку и не будет делать выводы по HTTP коду ответа. Проверка здоровья API сервиса должна опираться на механизм проверки самого API сервиса.
  • Поскольку API сервис может изменяться в любой момент, статус API не отражает информацию в реальном времени. Рекомендуется использовать эту информацию как подсказку, а не для блокировки поведения клиента.

Условие ProxyReady

Отражает статус Proxy сервиса, настроенного для ConnectorClass. Proxy сервис настраивается через spec.proxy ConnectorClass.

СтатусПричинаОписание
TrueNonProxyspec.proxy не настроен, у текущего ConnectorClass нет Proxy возможностей
Truespec.proxy определён, Proxy сервис работает нормально
Falsespec.proxy определён, Proxy возможности работают некорректно или проверка неудачна
UnknownПроверка Proxy возможностей в процессе

Совместимость

Обновления ConnectorClass могут повлиять на существующие Connectors. Если в ConnectorClass внесены несовместимые изменения, это может привести к тому, что ранее созданные Connectors станут недействительными. Возможные изменения, приводящие к несовместимости:

  1. Изменения в информации об аутентификации: если ConnectorClass изменяет поддерживаемые типы или методы аутентификации, это может привести к сбоям Connectors, использующих старый метод аутентификации.

  2. Изменения в конфигурационной информации: если изменяется конфигурация ConnectorClass, например удаляется существующая конфигурация, это может привести к сбоям Kubernetes workloads, зависящих от старой конфигурации.

Рекомендуется при обновлении ConnectorClass подтверждать область влияния или при необходимости создавать новый ConnectorClass.

Дополнительные примеры

  • ConnectorClass, поддерживающий тип аутентификации basic-auth

    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
  • ConnectorClass с настроенной liveness probe

    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: /
  • ConnectorClass с настроенной auth probe

    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 }}

Дополнительно