• Русский
  • Как настроить динамические формы

    Обзор функции

    Функция конфигурации динамических форм позволяет декларативно настраивать удобный интерактивный интерфейс для таких ресурсов, как Pipeline и Task. Без написания frontend-кода, просто добавив конфигурацию style.tekton.dev/descriptors в annotations ресурса, вы можете получить:

    • Генерация динамических форм: автоматическое создание интерактивных форм для параметров ресурса, что обеспечивает более удобную работу при оркестрации и запуске Pipeline и Task.
    • Поддержка богатого набора компонентов: доступны различные компоненты формы, такие как текстовые поля, селекторы, переключатели, YAML-редакторы и т. д.
    • Проверка полей: встроенные правила валидации, гарантирующие, что вводимые пользователем данные соответствуют требованиям.
    • Динамическая загрузка данных: поддерживает динамическую загрузку данных для вариантов через API.

    Сценарии использования

    • Оркестрация/выполнение Pipeline: позволяет пользователям заполнять такие параметры, как namespace и secrets, через удобные формы при оркестрации или запуске Pipeline
    • Повторное использование Task: предоставляет значения по умолчанию, варианты в выпадающем списке и валидацию для общих параметров на уровне шаблона Task или Pipeline
    • Выбор для нескольких окружений: динамически запрашивает доступные окружения или конфигурации через API и использует их как варианты выбора

    Быстрый старт

    Базовая структура конфигурации

    Все конфигурации определяются через поле style.tekton.dev/descriptors в annotations:

    metadata:
      annotations:
        style.tekton.dev/descriptors: |
          - path: params.parameter-name
            x-descriptors:
              - configuration-item1
              - configuration-item2

    Описание конфигурации

    • path: задает путь к параметру в формате params.parameter-name
    • x-descriptors: массив элементов конфигурации, каждый элемент конфигурации начинается с urn:alm:descriptor:

    Простой пример

    Настройка обязательного текстового поля для параметра Task:

    apiVersion: tekton.dev/v1
    kind: Task
    metadata:
      name: simple-task
      annotations:
        style.tekton.dev/descriptors: |
          - path: params.gitURL
            x-descriptors:
              - urn:alm:descriptor:label:zh:GitRepo
              - urn:alm:descriptor:com.tectonic.ui:text
              - urn:alm:descriptor:placeholder:zh:Git URL
              - urn:alm:descriptor:com.tectonic.ui:validation:required
    spec:
      params:
        - name: gitURL
          type: string
      steps:
        - name: clone
          image: alpine/git
          script: |
            git clone $(params.gitURL)

    Базовая конфигурация формы

    Метка формы

    # Label for the form
    - urn:alm:descriptor:label:en:English Name
    - urn:alm:descriptor:label:zh:Chinese name

    Описание формы

    # Description for the form
    - urn:alm:descriptor:description:en:English Description
    - urn:alm:descriptor:description:zh:Chinese Description

    Подсказка в плейсхолдере

    # Placeholder for the form
    - urn:alm:descriptor:placeholder:en:This is a Placeholder
    - urn:alm:descriptor:placeholder:zh:This is a Placeholder

    Всплывающая подсказка формы

    # Help tooltip for the form
    - urn:alm:descriptor:tooltip:en:This is a Help Tip
    - urn:alm:descriptor:tooltip:zh:This is a Help Tip

    Отключенное состояние формы

    # Whether the form is disabled
    - urn:alm:descriptor:com.tectonic.ui:disabled

    Поддерживаемые типы полей

    Текстовый ввод

    # value: string
    - urn:alm:descriptor:com.tectonic.ui:text

    Многострочный текстовый ввод

    # value: string
    - urn:alm:descriptor:com.tectonic.ui:textarea

    Ввод тегов

    # value: array
    - urn:alm:descriptor:com.tectonic.ui:tagsInput

    Radio

    # Declare a radio option with value "option-a"
    - urn:alm:descriptor:com.tectonic.ui:radio:option-a
    # Set the English display label of option-a to "Option A"
    - urn:alm:descriptor:com.tectonic.ui:radio:option-a:en:Option A
    # Set the Chinese display label of option-a to "Option A(zh)"
    - urn:alm:descriptor:com.tectonic.ui:radio:option-a:zh:Option A(zh)
    # Declare a radio option with value "option-b"
    - urn:alm:descriptor:com.tectonic.ui:radio:option-b
    # Set the English display label of option-b to "Option B"
    - urn:alm:descriptor:com.tectonic.ui:radio:option-b:en:Option B
    # Set the Chinese display label of option-b to "Option B(zh)"
    - urn:alm:descriptor:com.tectonic.ui:radio:option-b:zh:Option B(zh)
    # Set the default selected option to "option-a"
    - urn:alm:descriptor:com.tectonic.default:option-a

    Switch

    # value: boolean
    - urn:alm:descriptor:com.tectonic.ui:booleanSwitch
    
    # Map value to specified string
    # When switch is on, value is True
    - urn:alm:descriptor:props:booleanSwitch:true:True
    # When switch is off, value is False
    - urn:alm:descriptor:props:booleanSwitch:false:False

    YAML-редактор

    # value: string
    - urn:alm:descriptor:com.tectonic.ui:yaml

    Поле выбора

    Базовая конфигурация содержимого

    # value: string
    - urn:alm:descriptor:com.tectonic.ui:select
    # Options
    - urn:alm:descriptor:props:select:options:valueA
    - urn:alm:descriptor:props:select:options:valueB
    # Set the select box to multiple selection mode
    # value: array
    - urn:alm:descriptor:props:select:multiple
    # Manually entered content can be used as selection items
    - urn:alm:descriptor:props:select:allowCreate
    # Content can be cleared
    - urn:alm:descriptor:props:select:clearable

    Конфигурация динамических вариантов через API

    Когда элементам формы нужно динамически загружать доступные варианты на основе текущего окружения (например, доступные namespaces, secrets и т. д.), вы можете использовать динамическую конфигурацию API для получения вариантов выпадающего списка из backend-интерфейсов в реальном времени.

    В этом режиме URL API обычно используется в сочетании с context variables для динамического построения путей запроса на основе текущего cluster, namespace, project пользователя или заполненных параметров. Например:

    # Use ${context.cluster} variable in URL to dynamically retrieve namespace list for current cluster
    - urn:alm:descriptor:expression:props.options:api:apiPath
    - urn:alm:descriptor:expression:props.options:api:/kubernetes/${context.cluster}/api/v1/namespaces

    Доступные context variables

    В динамических путях API можно использовать ${variable} для ссылки на информацию контекста во время выполнения.

    • Общие context variables
    VariableDescription
    ${context.cluster}Current cluster name
    ${context.namespace}Current namespace
    ${context.project}Current project
    ${current.search}Get the current search input from the dropdown box
    • Context variables, связанные с Pipeline/Task
    VariableDescription
    ${context.params}Parameters object, e.g., ${context.params.repo} can reference the current value of the repo parameter in the form

    Обычно эти переменные используются вместе с URL API для динамического построения адресов запросов в разных окружениях, что позволяет реализовать логику загрузки вариантов с учетом окружения. Например:

    - urn:alm:descriptor:expression:props.options:api:apiPath
    - urn:alm:descriptor:expression:props.options:api:/api/v1/${context.namespace}/deployments?repo=${context.params.repo}

    Настройка пути данных для возвращаемых данных

    - urn:alm:descriptor:expression:props.options:path:spec.items

    Когда API возвращает сложную структуру, например:

    {
      "spec": {
        "items": [ ... ]
      }
    }

    Вы можете использовать path, чтобы указать, как извлечь массив вариантов из структуры.

    Настройка полей сопоставления метки и значения для вариантов

    Если возвращаемый объект данных сложный и требуется указать внутренние поля как "display name" и "option value", можно использовать:

    - urn:alm:descriptor:expression:props.options:label:path:metadata.name
    - urn:alm:descriptor:expression:props.options:value:path:metadata.name

    Когда API возвращает простой массив string[], эта конфигурация не требуется.

    Настройка параметров запроса API

    Если нужно передать параметры запроса в API request (например, ключевые слова поиска или фильтры), можно использовать:

    # Add query parameter named "search" with user input as value
    - urn:alm:descriptor:widgets:select
    - urn:alm:descriptor:expression:props.options:api:/kubernetes/${context.cluster}/apis/tekton.dev/v1/namespaces/${context.namespace}/pipelineruns
    - urn:alm:descriptor:expression:props.options:path:items
    - urn:alm:descriptor:expression:props.options:label:path:metadata.name
    - urn:alm:descriptor:expression:props.options:value:path:metadata.name
    - urn:alm:descriptor:expression:props.options:api:params:search:${current.search}

    Когда пользователь вводит "test" в выпадающем списке, фактический запрос будет:

    /kubernetes/.../pipelineruns?search=test

    Расширенное использование: поддерживаются JavaScript expressions, например:

    ${context.params.map(p => p.name).join(',')}

    Значения параметров по умолчанию

    Фиксированное значение по умолчанию

    - urn:alm:descriptor:expression:props.default:default-value

    Динамическое значение по умолчанию на основе выражения

    Доступные переменные:

    • option: исходные данные варианта

    • index: индекс варианта

    • length: общее количество вариантов

    • context: параметры контекста

      # Select options with specific labels
      - urn:alm:descriptor:expression:props.default.exp:option.metadata.labels['default']==='true'
      # Default to select the first item
      - urn:alm:descriptor:expression:props.default.exp:index === 0
      # Default to select the last item
      - urn:alm:descriptor:expression:props.default.exp:index === length - 1
      # Default to select when there is only one option
      - urn:alm:descriptor:expression:props.default.exp:length === 1
      # Default to select the current namespace
      - urn:alm:descriptor:expression:props.default:${context.namespace}
      # Complex conditions
      - urn:alm:descriptor:expression:props.default.exp:option.metadata.name.includes('test') && option.status.conditions.some(c => c.status==='True')
      
    INFO

    Для правил синтаксиса условий в сложных сценариях см. JavaScript syntax.

    Валидация формы

    Поддерживается настройка различных правил валидации, несколько правил можно применять одновременно.

    Проверка обязательности

    - urn:alm:descriptor:com.tectonic.ui:validation:required

    Проверка длины

    # Minimum length
    - urn:alm:descriptor:com.tectonic.ui:validation:minLength:6
    # Maximum length
    - urn:alm:descriptor:com.tectonic.ui:validation:maxLength:64

    Проверка числового диапазона

    # Minimum value (applicable to numeric types)
    - urn:alm:descriptor:com.tectonic.ui:validation:minimum:1
    # Maximum value
    - urn:alm:descriptor:com.tectonic.ui:validation:maximum:100

    Проверка регулярным выражением

    # Positive integer
    - urn:alm:descriptor:com.tectonic.ui:validation:pattern:[1-9]\d*
    # Kubernetes resource name (lowercase letters, numbers, hyphens)
    - urn:alm:descriptor:com.tectonic.ui:validation:pattern:[a-z0-9]([-a-z0-9]*[a-z0-9])?

    Пример с объединением: настройка поля пароля с полной валидацией

    - path: params.password
      x-descriptors:
        - urn:alm:descriptor:label:zh:password
        - urn:alm:descriptor:com.tectonic.ui:text
        - urn:alm:descriptor:description:zh:At least 8 characters, including letters and numbers.
        - urn:alm:descriptor:com.tectonic.ui:validation:required
        - urn:alm:descriptor:com.tectonic.ui:validation:minLength:8
        - urn:alm:descriptor:com.tectonic.ui:validation:maxLength:32

    Расширенные возможности

    В сложных CI/CD-сценариях следующие расширенные компоненты формы помогут вам решать более сложные задачи конфигурации.

    Компонент объединения

    В сложных CI/CD-сценариях может возникнуть ситуация, когда один параметр массива должен собирать данные из нескольких разных источников (разных API). Например, параметр workloads может включать и "Deployments", и "StatefulSets", для которых требуется получать данные из совершенно разных Kubernetes API.

    Чтобы реализовать это, можно использовать Combine Component (widgets:combine). Он позволяет разделить один параметр на несколько независимых подкомпонентов формы в UI (например, radio button для выбора типа ресурса и select box для выбора конкретных ресурсов), а затем объединить их значения в итоговый массив или JSON object с помощью JavaScript expressions перед отправкой в Pipeline.

    Конфигурация

    # Declare the use of the combine widget
    - urn:alm:descriptor:widgets:combine
    
    # Parent combine logic: defines how to merge all sub-component values into the final parameter
    # Available variable: items (contains all sub-component values)
    # Example: (items.deployments || []).concat(items.statefulsets || []) - merge multiple arrays into one
    - urn:alm:descriptor:combine:value.exp:<js-expression>
    
    # Parent: define sub-components
    - urn:alm:descriptor:combine:items:
        - path: <sub-component-name-1>
          x-descriptors:
            # Child split logic: defines how to extract this sub-component's value from the parent for echo display
            # Available variable: parent (the current parameter value)
            # Example: (parent || []).filter(p => p.startsWith('deploy:')) - extract items with 'deploy:' prefix
            - urn:alm:descriptor:combine:value.exp:<js-expression>
            # ... other descriptors for this sub-component
    
        - path: <sub-component-name-2>
          x-descriptors:
            # Child split logic: defines how to extract this sub-component's value from the parent for echo display
            - urn:alm:descriptor:combine:value.exp:<js-expression>
            # ... other descriptors for this sub-component

    Для более подробного синтаксиса js-expression см. JavaScript syntax.

    Пример: настройка параметра множественного выбора target_resources, который позволяет пользователям выбирать ресурсы как из Deployments, так и из StatefulSets. Итоговое значение параметра будет представлять собой массив, объединяющий выбор из обоих API, с добавлением специальных префиксов для различения типов (например, ["deploy:app-v1", "sts:db-v1"]).

    - path: params.target_resources
      x-descriptors:
        # Declare the use of the combine widget
        - urn:alm:descriptor:widgets:combine
        
        # [Parent] Combine logic: concat the arrays from both 'deployments' and 'statefulsets' sub-components
        - urn:alm:descriptor:combine:value.exp:(items.deployments || []).concat(items.statefulsets || [])
        
        # Define sub-components
        - urn:alm:descriptor:combine:items:
            
            # Sub-component 1: Select Deployments
            - path: deployments
              x-descriptors:
                # [Child 1] Split logic: extract items starting with 'deploy:' from the parent array
                - urn:alm:descriptor:combine:value.exp:(parent || []).filter(p => p.startsWith('deploy:'))
                - urn:alm:descriptor:label:en:Deployments
                - urn:alm:descriptor:label:zh:Deployments
                - urn:alm:descriptor:widgets:select
                - urn:alm:descriptor:props:select:multiple
                - urn:alm:descriptor:expression:props.options:api:/kubernetes/${context.cluster}/apis/apps/v1/namespaces/${context.namespace}/deployments
                - urn:alm:descriptor:expression:props.options:path:items
                - urn:alm:descriptor:expression:props.options:label:path:metadata.name
                # Prepend 'deploy:' prefix
                - urn:alm:descriptor:expression:props.options:value:path.exp:'deploy:'+$.metadata.name
                
            # Sub-component 2: Select StatefulSets
            - path: statefulsets
              x-descriptors:
                # [Child 2] Split logic: extract items starting with 'sts:' from the parent array
                - urn:alm:descriptor:combine:value.exp:(parent || []).filter(p => p.startsWith('sts:'))
                - urn:alm:descriptor:label:en:StatefulSets
                - urn:alm:descriptor:label:zh:StatefulSets
                - urn:alm:descriptor:widgets:select
                - urn:alm:descriptor:props:select:multiple
                - urn:alm:descriptor:expression:props.options:api:/kubernetes/${context.cluster}/apis/apps/v1/namespaces/${context.namespace}/statefulsets
                - urn:alm:descriptor:expression:props.options:path:items
                - urn:alm:descriptor:expression:props.options:label:path:metadata.name
                # Prepend 'sts:' prefix
                - urn:alm:descriptor:expression:props.options:value:path.exp:'sts:'+$.metadata.name

    Как это работает в UI:

    1. Пользователь одновременно видит два отдельных поля множественного выбора: "Deployments" и "StatefulSets".

    2. Поле Deployments получает данные из Deployment API, а StatefulSets — из StatefulSet API.

    3. Когда пользователь выбирает dummy и alm в Deployments, а также db-1 в StatefulSets, итоговый массив target_resources, отправляемый в Task, объединяется естественным образом:

      - name: target_resources
        value:
          - deploy:dummy
          - deploy:alm
          - sts:db-1

    Компонент предпросмотра

    Preview Component позволяет пользователям просматривать YAML-содержимое выбранного ресурса непосредственно из формы. Это особенно полезно в сценариях, когда нужно проверить конфигурацию ресурса перед использованием в Pipelines, например при проверке содержимого ConfigMap, валидации данных Secret или просмотре определений YAML для Task/Pipeline.

    Например, когда пользователь выбирает ConfigMap из выпадающего списка для использования в качестве источника volume mount или environment variable в Task, он может просмотреть данные ConfigMap прямо в форме, чтобы убедиться, что выбран правильный ресурс.

    Конфигурация

    # Enable preview - show button when parameter has value
    - urn:alm:descriptor:enhance:preview:context.params.<param-name>
    
    # API endpoint to fetch resource content
    - urn:alm:descriptor:preview:resource:api:<api-url>
    
    # JSONPath or JS expression to extract content from response
    - urn:alm:descriptor:preview:resource:path:<jsonpath>
    - urn:alm:descriptor:preview:resource:path.exp:<js-expression>

    Пример: настройка выпадающего списка для выбора ConfigMap с кнопкой предпросмотра для просмотра YAML-содержимого.

    - path: params.configmap
      x-descriptors:
        # Form label
        - urn:alm:descriptor:label:en:ConfigMap
        - urn:alm:descriptor:label:zh:ConfigMap
    
        # Dropdown to select ConfigMap from current namespace
        - urn:alm:descriptor:com.tectonic.ui:select
        - urn:alm:descriptor:expression:props.options:api:/kubernetes/${context.cluster}/api/v1/namespaces/${context.namespace}/configmaps
        - urn:alm:descriptor:expression:props.options:path:items
        - urn:alm:descriptor:expression:props.options:label:path:metadata.name
        - urn:alm:descriptor:expression:props.options:value:path:metadata.name
        - urn:alm:descriptor:com.tectonic.ui:validation:required
    
        # Preview feature
        - urn:alm:descriptor:enhance:preview:context.params.configmap
        - urn:alm:descriptor:preview:resource:api:/kubernetes/${context.cluster}/api/v1/namespaces/${context.namespace}/configmaps?fieldSelector=metadata.name%3D${context.params.configmap}
        - urn:alm:descriptor:preview:resource:path:items[0]

    Как это работает в UI:

    1. Пользователь выбирает ConfigMap в выпадающем списке (например, my-config).
    2. Рядом с выпадающим списком появляется кнопка предпросмотра.
    3. При нажатии кнопки предпросмотра выбранный ConfigMap запрашивается через Kubernetes API.
    4. Сырой YAML-контент отображается в панели предпросмотра с подсветкой синтаксиса.

    Примеры использования

    Настройка динамических форм в Task

    Пример: предоставление выпадающего списка для выбора namespaces для параметра image в Task.

    Эффект: когда пользователи оркестрируют Pipeline или TaskRun через UI, параметр namespace этого Task поддерживает выбор namespaces из выпадающего списка.

    apiVersion: tekton.dev/v1
    kind: Task
    metadata:
      name: demo-task
      namespace: <your namespace>
      annotations:
        style.tekton.dev/descriptors: |
          - path: params.namespace
            x-descriptors:
              - urn:alm:descriptor:label:en:namespace
              - urn:alm:descriptor:label:zh:namespace(zh)
              - urn:alm:descriptor:com.tectonic.ui:select
              - urn:alm:descriptor:expression:props.options:api:/kubernetes/${context.cluster}/api/v1/namespaces
              - urn:alm:descriptor:expression:props.options:path:items
              - urn:alm:descriptor:expression:props.options:label:path:metadata.name
              - urn:alm:descriptor:expression:props.options:value:path:metadata.name
              - urn:alm:descriptor:com.tectonic.ui:validation:required
    spec:
      params:
        - name: namespace
          type: string
      steps:
        - name: demo
          image: ubuntu
          script: |
            #!/bin/sh
            pwd

    Настройка динамических форм в Pipeline

    Пример: предоставление выпадающего списка для выбора namespaces для параметра target-namespace в Pipeline.

    Эффект: когда пользователи запускают Pipeline через UI или должны связать этот pipeline с другими ресурсами (Trigger, TriggerTemplate) и настроить параметры выполнения, параметр target-namespace поддерживает выбор namespaces из выпадающего списка.

    apiVersion: tekton.dev/v1
    kind: Pipeline
    metadata:
      annotations:
        style.tekton.dev/descriptors: |
          - path: params.target-namespace
            x-descriptors:
              - urn:alm:descriptor:label:en:target-namespace
              - urn:alm:descriptor:label:zh:target-namespace(zh)
              - urn:alm:descriptor:com.tectonic.ui:select
              - urn:alm:descriptor:expression:props.options:api:/kubernetes/${context.cluster}/api/v1/namespaces
              - urn:alm:descriptor:expression:props.options:label:path:metadata.name
              - urn:alm:descriptor:expression:props.options:value:path:metadata.name
              - urn:alm:descriptor:expression:props.options:path:items
              - urn:alm:descriptor:com.tectonic.ui:validation:required
      name: demo-pipelines
      namespace: <your namespace>
    spec:
      params:
        - name: target-namespace
          type: string
      tasks:
        - name: kubectl
          taskRef:
            resolver: hub
            params:
              - name: kind
                value: task
              - name: catalog
                value: catalog
              - name: name
                value: kubectl
              - name: version
                value: "0.1"

    Устранение неполадок

    • Форма не отображается или конфигурация не вступает в силу: проверьте, корректен ли YAML-формат style.tekton.dev/descriptors, убедитесь, что path задан как params.parameter-name, и проверьте, что каждый descriptor начинается с - urn:alm:descriptor:
    • Динамические варианты не загружаются: подтвердите, что путь API указан верно, проверьте, есть ли у текущего пользователя права на доступ к указанному ресурсу API, и убедитесь, что конфигурации path, label и value указывают на поля, которые существуют в возвращаемых данных
    • Значение по умолчанию не применяется: убедитесь, что для фиксированного значения по умолчанию используется формат expression:props.default:value, а для значения по умолчанию на основе выражения используется === вместо =, проверьте, правильно ли написаны переменные (option, index, length, context) в выражении
    • Context variables не разрешаются: проверьте правильность имен переменных (например, context.namespace, а не context.namespaces), убедитесь, что переменные используются в descriptors, которые поддерживают expressions, и проверьте, нет ли ошибок в синтаксисе JavaScript expression