高级输入配置
高级输入设置可让您为执行自助操作的用户创建更多可定制的体验。 具体方法是创建自适应输入,根据实体、用户和其他输入的相关数据进行更改。
常见被用于情况
- 过滤下拉输入中的可用选项。
- 在输入之间创建依赖关系,允许用户根据另一个输入的值选择一个值。
- 根据登录的用户属性(如团队、电子邮件、角色)或正在执行操作的实体(仅限第 2 天或删除操作)定义动态默认值。
Usage
目前仅支持以 JSON 模式定义高级输入。
创建动作后,第二步是定义输入。 至少定义一个输入后,表单底部会出现 "高级配置 "部分。 单击 "编辑 JSON",然后添加 JSON 格式的配置。
编写配置模式
Port 提供了一个 jqQuery
属性,可用于从实体、登录用户或当前操作的表单输入中提取数据。 它还可用于执行数据操作。
例如,下面的 jqQuery
检查另一个属性(language
)的值,并据此确定 SDK
属性的可能值:
{
"properties": {
"language": {
"type": "string",
"enum": ["javascript", "python"]
},
"SDK": {
"type": "string",
"enum": {
"jqQuery": "if .form.language == \"javascript\" then [\"Node 16\", \"Node 18\"] else [\"Python 3.8\"] end"
}
}
}
}
使用 "jqQuery "对象可以访问的属性
- form
- entity
- user
当前操作表单中的输入值。
Usage:
{
"jqQuery": ".form.input1"
}
可用的 form
对象(每个输入都是动作userInputs
对象中的一个键) :
{
"input1": "...",
"input2": "...",
"input3": "..."
}
执行操作的 "实体 "的属性。 实体数据仅在 "第 2 天 "和 "删除 "操作中可用。
Usage:
{
"jqQuery": ".entity.properties.property1"
}
可用的 "实体 "对象:
{
"identifier": "...",
"title": "...",
"blueprint": "...",
"team": ["..."],
"properties": {
"property1": "...",
"property2": "...",
"property3": "..."
},
"relations": {
"relation1": "...",
"relation2": "...",
"relationMany": ["...", "..."]
},
"createdAt": "...",
"createdBy": "...",
"updatedAt": "...",
"updatedBy": "...",
"scorecards": {
"ResourceQuota": {
"rules": [
{
"identifier": "...",
"status": "...",
"level": "..."
},
{
"identifier": "...",
"status": "...",
"level": "..."
}
],
"level": "..."
},
"Ownership": {
"rules": [
{
"identifier": "...",
"status": "...",
"level": "..."
},
{
"identifier": "...",
"status": "...",
"level": "..."
}
],
"level": "..."
}
}
}
执行操作的用户的属性。
Usage:
{
"jqQuery": ".user.email"
}
可用的 logging 用户对象:
{
"picture": "...",
"userId": "...",
"email": "...",
"name": "...",
"mainRole": "...",
"roles": [
{
"name": "..."
}
],
"teams": [
{
"name": "...",
"provider": "..."
},
{
"name": "...",
"provider": "..."
}
]
}
jqQuery 表达式支持的键:
Key | Description |
---|---|
enum | any enum of a property |
default | the default value of any property |
required | the properties which will be required in the form |
value | the value inside a "dataset" rule |
visible | the condition to display any property in the form |
其他可用房产
您可以使用这些附加属性创建更复杂的输入:
- visible
- dependsOn
- dataset
可见 "属性用于动态隐藏/显示表单中的输入。 可见 "值可以设置为一个布尔值("true "值总是显示,"false "值总是隐藏),也可以设置为一个评估为布尔值的 "jqQuery"。
在本例中,"runArguments "属性配置为 "visible",因此只有在 "language "输入框中选择匹配值时,它们才会显示在表单中:
- API
- Terraform
- Pulumi
{
"properties": {
"language": {
"type": "string",
"enum": ["javascript", "python"]
},
"pythonRunArguments": {
"type": "string",
"visible": {
"jqQuery": ".form.language == \"python\""
}
},
"nodeRunArguments": {
"type": "string",
"visible": {
"jqQuery": ".form.language == \"javascript\""
}
}
}
}
resource "port_action" myAction {
# ...action configuration
{
user_properties = {
string_props = {
language = {
enum = ["javascript", "python"]
}
pythonRunArguments = {
visible_jq_query = ".form.language == \"python\""
}
nodeRunArguments = {
visible_jq_query = ".form.language == \"javascript\""
}
}
}
}
}
action = Action(
# ...action properties
user_properties={
"string_props": {
"language": {
"enums": ["python", "javascript"],
},
"pythonRunArguments": {"visible_jq_query": '.form.language == "python"'},
"nodeRunArguments": {"visible_jq_query": '.form.language == "javascript"'},
},
}
)
依赖于 "属性被用来创建输入之间的依赖关系。 如果输入 X 依赖于输入 Y,则输入 X 将被禁用,直到输入 Y 填满为止。 在下面的示例中,"SDK "输入依赖于 "语言 "输入:
- API
- Terraform
- Pulumi
{
"properties": {
"language": {
"type": "string",
"enum": ["javascript", "python"]
},
"SDK": {
"type": "string",
"dependsOn": ["language"]
}
}
}
resource "port_action" myAction {
# ...action configuration
{
user_properties = {
string_props = {
language = {
enum = ["javascript", "python"]
}
SDK = {
depends_on: ["language"]
}
}
}
}
}
action = Action(
# ...action properties
user_properties={
"string_props": {
"language": {
"enums": ["python", "javascript"],
},
"SDK": {
"depends_ons": ["language"]
},
},
}
)
数据集 "属性用于过滤entity 输入中显示的选项。它由两个属性组成:
Combinator
- 在数据集的规则之间应用的逻辑运算。Read more.Rules
-rules 的数组,只有通过这些规则的实体才会显示在表单中。请注意,数据集中的value
键可以是常量(字符串、数字等)或 "jqQuery "对象。
- api
- terraform
- pulumi
{
"namespace": {
"type": "string",
"format": "entity",
"blueprint": "namespace",
"dataset": {
"combinator": "and",
"rules": [
{
"property": "$team",
"operator": "containsAny",
"value": "value here. this can also be a 'jqQuery' object"
}
]
}
}
}
resource "port_action" "myAction" {
# ...action properties
user_properties = {
string_props = {
"namespace" = {
format = "entity"
blueprint = "namespace"
dataset = {
combinator = "and"
rules = [
{
property = "$team"
operator = "containsAny"
value = "value here. this can also be a 'jqQuery' object"
}
]
}
}
}
}
}
action = Action(
# ...action properties
user_properties={
"string_props": {
"namespace": {
"format": "entity",
"blueprint": "namespace",
"dataset": {
"combinator": "and",
"rules": [
{
"property": "$team",
"operator": "containsAny",
"value": "value here. this can also be a 'jqQuery' object"
}
]
}
}
}
}
)
模式示例
在两个表单输入之间创建依赖关系
此示例中,"language "输入和 "SDK "输入之间存在依赖关系,"SDK "输入的可用选项是根据所选语言定义的(参见 "jqQuery "键)。
- API
- Terraform
- Pulumi
{
"properties": {
"language": {
"type": "string",
"enum": ["javascript", "python"]
},
"SDK": {
"type": "string",
"enum": {
"jqQuery": "if .form.language == \"javascript\" then [\"Node 16\", \"Node 18\"] else [\"Python 3.8\"] end"
},
"dependsOn": ["language"]
}
}
}
resource "port_action" myAction {
# ...action configuration
{
user_properties = {
string_props = {
language = {
enum = ["javascript", "python"]
}
SDK = {
enum_jq_query = "if .form.language == \"javascript\" then [\"Node 16\", \"Node 18\"] else [\"Python 3.8\"] end"
depends_on: ["language"]
}
}
}
}
}
action = Action(
# ...action properties
user_properties={
"string_props": {
"language": {
"enums": ["python", "javascript"],
},
"SDK": {
"enum_jq_query": "if .form.language == \"javascript\" then [\"Node 16\", \"Node 18\"] else [\"Python 3.8\"] end"
"depends_ons": ["language"]
},
},
}
)
###根据执行用户的角色隐藏属性
在此示例中,"visible "会检查执行用户是否具有 "admin "角色,如果不具有该角色,则会隐藏高级选项。 默认值仍会被填写并发送到后端:
- API
- Terraform
- Pulumi
{
"properties": {
"simpleOption": {
"type": "string",
"enum": ["option1", "option2"]
},
"advancedOption": {
"type": "string",
"default": "default advanced value",
"visible": {
"jqQuery": ".user.roles | any(.name == \"Admin\")"
}
}
}
}
resource "port_action" myAction {
# ...action configuration
{
user_properties = {
string_props = {
simpleOption = {
enum = ["option1", "option2"]
}
advancedOption = {
visible_jq_query = ".user.roles | any(.name == \"Admin\")"
}
}
}
}
}
action = Action(
"pulumi-resource-name",
identifier="action-identifier",
title="Action Title",
blueprint="myBlueprint",
user_properties={
"string_props": {
"simpleOption": {
"enums": ["option1", "option2"]
},
"advancedOption": {"visible_jq_query": ".user.roles | any(.name == \"Admin\")"}
},
},
trigger="DAY-2",
webhook_method={"url": "https://myserver.com"},
)
非管理员用户的运行表单显示如下: !What Non-Admins See
管理员用户的表单显示如下: !What Admins See
###根据属性过滤下拉菜单中的可用选项
此示例包含一个过滤器,只显示related to 在 Cluster
输入中所选集群的 namespace:
- API
- Terraform
- Pulumi
{
"env": {
"type": "string",
"format": "entity",
"blueprint": "environment",
"dataset": {
"combinator": "and",
"rules": [
{
"property": "type",
"operator": "!=",
"value": "production"
}
]
}
}
}
resource "port_action" myAction {
# ...action configuration
{
user_properties = {
string_props = {
env = {
format : "entity",
blueprint : "environment"
dataset = {
combinator = "and"
rules = [
{
property = "type"
operator = "!="
value = {
jq_query = "'production'"
}
}
]
}
}
}
}
}
}
action = Action(
# ...action properties
user_properties={
"string_props": {
"env": {
"format": "entity",
"blueprint": "environment",
"dataset": {
"combinator": "and",
"rules": [
{
"property": "type",
"operator": "!=",
"value": "production"
}
]
}
}
}
}
)
☝ 只有类型不是 "生产 "的环境才会出现在下拉菜单中。 ☝
###根据之前的输入过滤下拉菜单中的可用选项
此示例包含一个过滤器,只显示related to 在 Cluster
输入中所选集群的 namespace:
- API
- Terraform
- Pulumi
{
"Cluster": {
"type": "string",
"format": "entity",
"blueprint": "Cluster",
"title": "Cluster",
"description": "The cluster to create the namespace in"
},
"namespace": {
"type": "string",
"format": "entity",
"blueprint": "namespace",
"dependsOn": ["Cluster"],
"dataset": {
"combinator": "and",
"rules": [
{
"blueprint": "Cluster",
"operator": "relatedTo",
"value": {
"jqQuery": ".form.Cluster.identifier"
}
}
]
},
"title": "namespace",
"description": "The namespace to create the cluster in"
}
}
resource "port_action" myAction {
# ...action configuration
{
user_properties = {
string_props = {
cluster = {
format = "entity",
blueprint = "Cluster",
title = "Cluster",
description = "The cluster to create the namespace in"
}
namespace = {
title : "namespace",
description : "The namespace to create the cluster in"
format = "entity",
blueprint = "namespace",
depends_on = ["Cluster"],
dataset = {
combinator = "and"
rules = [
{
blueprint = "Cluster"
operator = "relatedTo"
value = {
jq_query = ".form.Cluster.identifier"
}
}
]
}
}
}
}
}
}
action = Action(
# ...action properties
user_properties={
"string_props": {
"Cluster": {
"format": "entity",
"blueprint": "Cluster",
"title": "Cluster",
"description": "The cluster to create the namespace in"
},
"namespace": {
"format": "entity",
"blueprint": "namespace",
"dataset": {
"combinator": "and",
"rules": [
{
"blueprint": "Cluster",
"operator": "relatedTo",
"value": {
"jq_query": ".form.Cluster.identifier"
}
}
]
}
}
}
}
)
point_up: 用户需要选择一个集群,然后`namespace'输入列表将填充与所选集群相关的 namespace 实体:
###根据执行操作的用户属性过滤下拉菜单的可用选项
此示例包含一个过滤器,只显示属于用户团队的 namespace(注意规则对象中的值键):
- API
- Terraform
- Pulumi
{
"namespace": {
"type": "string",
"format": "entity",
"blueprint": "namespace",
"dataset": {
"combinator": "and",
"rules": [
{
"property": "$team",
"operator": "containsAny",
"value": {
"jqQuery": "[.user.teams[].name]"
}
}
]
}
}
}
resource "port_action" myAction {
# ...action configuration
{
user_properties = {
string_props = {
namespace = {
format : "entity",
blueprint : "namespace"
dataset = {
combinator = "and"
rules = [
{
property = "$team",
operator = "containsAny",
value = {
jq_query = "[.user.teams[].name]"
}
}
]
}
}
}
}
}
}
action = Action(
# ...action properties
user_properties={
"string_props": {
"namespace": {
"format": "entity",
"blueprint": "namespace",
"dataset": {
"combinator": "and",
"rules": [
{
"property": "$team",
"operator": "containsAny",
"value": {
"jq_query": "[.user.teams[].name]"
}
}
]
}
}
}
}
)
☝ 这些是唯一与登录用户的团队相关联的 namespace:
###根据执行操作的实体属性过滤下拉菜单的可用选项
此示例包含一个过滤器,只显示与执行操作的实体具有相似标记的 namespace:
- API
- Terraform
- Pulumi
{
"namespace": {
"type": "string",
"format": "entity",
"blueprint": "namespace",
"dataset": {
"combinator": "and",
"rules": [
{
"property": "tags",
"operator": "containsAny",
"value": {
"jqQuery": "[.entity.properties.tags[]]"
}
}
]
}
}
}
resource "port_action" myAction {
# ...action configuration
{
user_properties = {
string_props = {
namespace = {
format = "entity",
blueprint = "namespace",
dataset = {
combinator = "and"
rules = [
{
property = "tags"
operator = "containsAny"
value = {
jq_query = "[.entity.properties.tags[]]"
}
}
]
}
}
}
}
}
}
action = Action(
# ...action properties
user_properties = {
"string_props": {
"namespace": {
"format": "entity",
"blueprint": "namespace",
"dataset": {
"combinator": "and",
"rules": [
{
"property": "tags",
"operator": "containsAny",
"value": {
"jq_query": "[.entity.properties.tags[]]"
}
}
]
}
}
}
}
)
使用 jqQuery 设置默认值
此示例包含一个数组输入,其默认值将等于执行操作的实体的标记:
- API
- Terraform
- Pulumi
{
"some_input": {
"type": "array",
"default": {
"jqQuery": ".entity.properties.tags"
}
}
}
resource "port_action" myAction {
# ...action configuration
{
user_properties = {
array_props = {
some_input = {
default_jq_query = ".entity.properties.tags"
}
}
}
}
}
action = Action(
# ...action properties
user_properties={
"array_props": {
"some_input": {
"default_jq_query": ".entity.properties.tags"
}
},
},
trigger="DAY-2", # CREATE, DAY-2, DELETE
)
☝ 命名空间标记已插入表单中。 ☝
使用 jqQuery 设置所需输入内容
此示例包含两个用户输入: 一个始终为必填项,另一个根据实体属性为必填项。
- API
- Terraform
- Pulumi
{
"properties": {
"alwaysRequiredInput": {
"type": "string"
},
"inputRequiredBasedOnData": {
"type": "string"
}
},
"required": {
"jqQuery": "if .entity.properties.conditionBooleanProperty then [\"alwaysRequiredInput\", \"inputRequiredBasedOnData\"] else [\"alwaysRequiredInput\"] end"
}
}
resource "port_action" myAction {
# ...action configuration
{
user_properties = {
string_props = {
alwaysRequiredInput = {}
inputRequiredBasedOnData = {}
}
}
required_jq_query = "if .entity.properties.conditionBooleanProperty then [\"alwaysRequiredInput\", \"inputRequiredBasedOnData\"] else [\"alwaysRequiredInput\"] end"
}
}
action = Action(
"budding-action",
identifier="budding-action",
title="A Budding Act",
# ...more action properties
user_properties={
"string_props": {
"alwaysRequiredInput": {},
"inputRequiredBasedOnData": {}
},
},
required_jq_query='if .entity.properties.conditionBooleanProperty then ["alwaysRequiredInput", "inputRequiredBasedOnData"] else ["alwaysRequiredInput"] end',
trigger="DAY-2", # CREATE, DAY-2, DELETE
)
pulumi.export("name", action.title)
完整示例
在这个示例中,我们将创建一个操作,让用户选择一个集群和该 集群中的一个命名空间。 用户还可以选择一个已在集群中运行的服务。 然后,该操作将把选定的服务部署到集群中选定的命名空间。 用户只能选择与他的团队相关联的服务。
Port 中的现有模型:
动作配置:
- API
- Terraform
- Pulumi
{
"identifier": "createRunningService",
"title": "Deploy running service to a cluster",
"icon": "Cluster",
"userInputs": {
"properties": {
"Cluster": {
"type": "string",
"format": "entity",
"blueprint": "Cluster",
"title": "Cluster",
"description": "The cluster to create the namespace in"
},
"namespace": {
"type": "string",
"format": "entity",
"blueprint": "namespace",
"dependsOn": ["Cluster"],
"dataset": {
"combinator": "and",
"rules": [
{
"blueprint": "Cluster",
"operator": "relatedTo",
"value": {
"jqQuery": ".form.Cluster.identifier"
}
}
]
},
"title": "namespace",
"description": "The namespace to create the cluster in"
},
"service": {
"type": "string",
"format": "entity",
"blueprint": "Service",
"dataset": {
"combinator": "and",
"rules": [
{
"blueprint": "$team",
"operator": "containsAny",
"value": {
"jqQuery": "[.user.teams[].name]"
}
}
]
},
"title": "Service"
}
},
"required": ["Cluster", "namespace", "service"]
},
"invocationMethod": {
"type": "WEBHOOK",
"url": "https://example.com"
},
"trigger": "CREATE",
"description": "This will deploy a running service to a cluster"
}
resource "port_action" "createRunningService" {
title = "Create Running Service"
blueprint = "abc"
identifier = "createRunningService"
trigger = "CREATE"
description = "This will deploy a running service to a cluster"
webhook_method = {
url = "https://example.com"
}
user_properties = {
string_props = {
cluster = {
format = "entity",
blueprint = "Cluster",
title = "Cluster"
description = "The cluster to create the namespace in"
required = true
}
namespace = {
title = "Namespace"
format = "entity",
blueprint = "namespace",
description = "The namespace to create the cluster in"
required = true
depends_on = ["cluster"]
dataset = {
combinator = "and"
rules = [
{
blueprint = "Cluster"
operator = "relatedTo"
value = {
jq_query = ".form.Cluster.identifier"
}
}
]
}
}
service = {
title = "Service"
blueprint = "Service",
required = true
dataset = {
combinator = "and"
rules = [
{
blueprint = "$team"
operator = "containsAny"
value = {
jq_query = "[.user.teams[].name]"
}
}
]
}
}
}
}
}
- Python
- Javascript
action = Action(
"create-running-service",
identifier="createRunningService",
title="Deploy running service to a cluster",
icon="Cluster",
user_properties={
"string_props": {
"Cluster": {
"format": "entity",
"blueprint": "Cluster",
"required": True,
"title": "Cluster",
"description": "The cluster to create the namespace in"
},
"namespace": {
"format": "entity",
"blueprint": "namespace",
"required": True,
"depends_ons": ["Cluster"],
"dataset": {
"combinator": "and",
"rules": [
{
"blueprint": "Cluster",
"operator": "relatedTo",
"value": {
"jq_query": ".form.Cluster.identifier"
}
}
],
},
"title": "namespace",
"description": "The namespace to create the cluster in"
},
"service": {
"format": "entity",
"blueprint": "Service",
"required": True,
"dataset": {
"combinator": "and",
"rules": [
{
"blueprint": "$team",
"operator": "containsAny",
"value": {
"jq_query": "[.user.teams[].name]"
}
}
]
},
"title": "Service"
}
},
},
trigger="CREATE",
description="This will deploy a running service to a cluster"
webhook_method={"url": "https://example.com"},
)
pulumi.export("name", action.title)
"use strict";
const pulumi = require("@pulumi/pulumi");
const port = require("@port-labs/port");
const entity = new Action("create-running-service", {
identifier: "createRunningService",
title: "Deploy running service to a cluster",
icon: "Cluster",
userProperties: {
stringProps: {
"Cluster": {
"format": "entity",
"blueprint": "Cluster",
"required": true,
"title": "Cluster",
"description": "The cluster to create the namespace in"
},
"namespace": {
"format": "entity",
"blueprint": "namespace",
"required": true,
"dependsOns": ["Cluster"],
"dataset": {
"combinator": "and",
"rules": [
{
"blueprint": "Cluster",
"operator": "relatedTo",
"value": {
"jqQuery": ".form.Cluster.identifier"
}
}
],
},
},
"service": {
"format": "entity",
"blueprint": "Service",
"required": true,
"dataset": {
"combinator": "and",
"rules": [
{
"blueprint": "$team",
"operator": "containsAny",
"value": {
"jqQuery": "[.user.teams[].name]"
}
}
]
},
"title": "Service"
}
}
},
trigger: "CREATE",
description: "This will deploy a running service to a cluster"
webhookMethod: {
"url": "https://example.com"
},
});
exports.title = entity.title;