Как настроить динамические формы
Обзор функции
Функция конфигурации динамических форм позволяет декларативно настраивать удобный интерактивный интерфейс для таких ресурсов, как 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, связанные с Pipeline/Task
Обычно эти переменные используются вместе с 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')
Валидация формы
Поддерживается настройка различных правил валидации, несколько правил можно применять одновременно.
Проверка обязательности
- 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:
-
Пользователь одновременно видит два отдельных поля множественного выбора: "Deployments" и "StatefulSets".
-
Поле Deployments получает данные из Deployment API, а StatefulSets — из StatefulSet API.
-
Когда пользователь выбирает 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:
- Пользователь выбирает ConfigMap в выпадающем списке (например,
my-config).
- Рядом с выпадающим списком появляется кнопка предпросмотра.
- При нажатии кнопки предпросмотра выбранный ConfigMap запрашивается через Kubernetes API.
- Сырой 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