表达式
样书最强大的功能之一是使用表达式。可以在各种方案中使用样书表达式来计算动态值。以下示例是将参数值与文字字符串连接的表达式。
示例:
$parameters.appname + "-mon"
此表达式检索名为 appname
的参数,并将其与字符串连接 -mon
。
注意
在样书定义中定义参数和表达式时,样书支持使用保留关键字。保留的关键字是 -
and
、false
、in
、not
、true
和or
。
支持以下类型的表达式:
算术表达式
- 添加 (+)
- Subtraction (-)
- 乘法 (*)
- 分隔 (/)
- 模数 (%)
示例:
- 添加两个数字:$parameters.a + $parameters.b
- 乘以两个数字:$parameters.a * 10
- 在一个数字除以另一个数字后查找剩余数字:
15%10
5
中的结果
字符串表达
- 连接两个字符串 (+)
示例:
连接两个字符串:str(“app-“) + $parameters.appname
列出表达式
合并两个列表 (+)
示例:
-
连接两个列表:$parameters.external-servers + $parameters.internal-servers
-
如果
$parameters.ports-1
是 [80, 81] 并且$parameters.port-2
是 [81, 82],则$parameters.ports-1 + $parameters.ports-2
显示为列表 [80、81、81、82]。
关系表达式
-
==:测试两个操作数是否相等,如果两个操作数相等则返回 true,否则返回 false。
-
!=:测试两个操作数是否不同,如果不同则返回 true,否则返回 false。
-
>:如果第一个操作数大于第二个操作数,则返回 true,否则返回 false。
-
>=:如果第一个操作数大于或等于第二个操作数,则返回 true,否则返回 false。
-
<:如果第一个操作数小于第二个操作数,则返回 true,否则返回 false。
-
<=:如果第一个操作数小于或等于第二个操作数则返回 true,否则返回 false。
示例:
- 使用平等运算符:
$parameters.name = = "abcd"
- 不等式运算符的使用:
$parameters.name != "default"
-
其他关系运算符示例
10 > 9
10 >= 10
0 < 9
10 <= 9
10 == 10
10 != 1
逻辑表达式-布尔值
-
and:逻辑的 and 运算符。如果两个操作数为 true,则结果为 true,否则为 false。
-
or:逻辑的 or 运算符。如果其中一个操作数为 true,则结果为 true,否则为 false。
-
not:一元运算符。如果操作数为 true,则结果为 false,而相反。
-
in:测试第一个参数是否是第二个参数的子字符串
-
in:测试项目是否为列表的一部分
注意
您可以键入转换表达式,其中字符串被转换为数字(使用 int() 内置函数),并将数字转换为字符串(使用 str() 内置函数)。同样,您可以转换
tcp-port
为数字(使用int()
内置函数),并可以将 IP 地址转换为字符串(使用 str () 内置函数)。在任何运算符之前和之后使用分隔符。可以使用以下分隔符:
在运算符之前:
space
、tab
、comma
、(
、)
、[
、]
在运算符之后:
space
、tab
、(
、[
例如:
abc + def
100 % 10
10 > 9
$item in $parameters.some-list
Splat 表达式
splat 表达式 [*]
提供了一种更简单的方法来从所有迭代的复杂列表中检索某个属性。现在,您可以在样书定义中包含 splat 表达式。
语法:
list[*].attribute
<!--NeedCopy-->
此表达式遍历其左侧指定的列表的所有项目,并返回其右侧指定的属性值。
当您要从列表中检索每个虚拟服务器的 IP 地址或主机名时,可以使用以下 splat 表达式:
示例 1:
$parameters.server-members[*].hostname
<!--NeedCopy-->
此表达式返回所有服务器成员的主机名列表。
示例 2:
$parameters.server-members[*].sub-domains[*].name
<!--NeedCopy-->
此表达式返回每个服务器成员的子域下所有名称的列表。
这些表达式总是返回最右边的元素类型的列表。
逐字字符串表达式
当字符串中的特殊字符必须采用文字形式时,可以使用逐字字符串。这些字符串可以包含转义字符、反斜杠、引号、括号、空格、括号等。在逐字字符串中,特殊角色的通常解释被跳过。字符串中的所有字符都以其文字形式保留。
在样书中,您可以使用逐字字符串将 NetScaler 策略表达式包含在其文本形式中。策略表达式通常包含特殊字符。如果没有逐字字符串,您必须通过将字符串分成子字符串来转义特殊字符。
要创建逐字字符串,请将字符串封装在特殊字符之间,如下所示:
~{string}~
<!--NeedCopy-->
您可以在样书表达式中使用逐字字符串。
注意请
勿在输入字符串中使用字符
}~
的序列,因为此序列表示逐字字符串的结尾。
示例:
~{HTTP.REQ.COOKIE.VALUE("jsessionid") ALT HTTP.REQ.URL.BEFORE_STR("=").AFTER_STR(";jsessionid=") ALT HTTP.REQ.URL.AFTER_STR(";jsessionid=")}~
<!--NeedCopy-->
有关详细信息,请参阅允许在样书中使用特殊字符的文字形式。
目标表达式
在样书定义中,您可以使$current-target
用 表达式来引用当前目标 NetScaler 实例。要具体引用目标 NetScaler 实例的 IP 地址,请按如下方式使用此表达式:
$current-target.ip
<!--NeedCopy-->
示例:
components:
-
name: lb-comp
type: ns::lbvserver
properties:
name: $current-target.ip + "-lbvserver"
<!--NeedCopy-->
在此示例中,名称 使lbvserver
用目标 NetScaler 实例的 IP 地址。
表达式类型验证
样书引擎现在允许在编译时进行更强的类型检查,也就是说,编写样书时使用的表达式是在导入样书本身的过程中验证的,而不是在创建配置包时进行验证。
对参数、替换、组件、组件属性、组件输出、用户定义变量(repeat-item、repeat-index、替代函数的参数)等的所有引用都经过验证,以确定它们的存在和类型。
类型检查示例:
在以下示例中, lbvserver
样书的端口属性的预期类型为 tcp-port
。在 NetScaler 控制台中,类型验证发生在编译时(导入时)。编译器发现该字符串并且 tcp-port
不兼容类型,因此,样书编译器显示错误,导入或迁移样书失败。
components:
-
name: lbvserver-comp
type: ns::lbvserver
properties:
name: mylb
ipv46: 10.102.190.15
port: str("80")
servicetype: HTTP
<!--NeedCopy-->
要成功编译此样书,请在编译器中将以下内容声明为数字:
port: 80
标记无效表达式的示例:
将样书导入到 NetScaler 控制台时,编译器会识别出无效的表达式并将其标记。因此,样书无法导入到 NetScaler 控制台。
在以下示例中,分配给 lb-sg-binding-comp
组件中 name 属性的表达式为: $components.lbvserver-comp.properties.lbvservername
。但是,组件 lbvserver-comp
中没有调用 lbvservername
的属性。
Components:
-
name: lbvserver-comp
type: ns::lbvserver
properties:
name: mylb
ipv46: 10.102.190.15
port: 80
servicetype: HTTP
-
name: sg-comp
type: ns::servicegroup
properties:
servicegroupname: mysg
servicetype: HTTP
-
name: lb-sg-binding-comp
type: ns::lbvserver_servicegroup_binding
condition: $parameters.create-binding
properties:
name: $components.lbvserver-comp.properties.lbvservername
servicegroupname: $components.sg-comp.properties.servicegroupname
<!--NeedCopy-->
数据类型的隐式类型转换
当您将样书表达式用于不同的数据类型时,样书引擎现在会隐式地将输出类型转换为适当的数据类型。数据类型的隐式类型转换支持二进制运算和值分配。
二进制运算示例:
- 添加 (+) 两个类型为
string
和number
的变量,将输出数据类型设置为string
。
$parameters.appname + '_' + $parameters.app_instance_num
- 添加 (+) 两个类型为
string
和ipaddress
的变量,将输出数据类型设置为string
。
$parameters.appname + '_' + $parameters.instance_ip
- 添加 (+) 两个类型为
ipaddress
和number
的变量,将输出数据类型设置为ipaddress
。
$parameters.instance_ip + $parameters.number
- 减去 (-) 两个类型为
ipaddress
和number
的变量,将输出数据类型设置为ipaddress
。
$parameters.instance_ip - $parameters.number
- 将 (*) 两个类型为
string
和number
的变量相乘,将输出数据类型设置为string
。
$parameters.dummy_str * $parameters.count
值赋值示例:
- 如果将变量定义为
string
数据类型,则分配的值将转换为定义的数据类型。
name: $parameters.port * 3
- 如果将变量定义为
portnumber
数据类型,则分配的值会转换为portnumber
数据类型,但有例外。
port: $index + $parameters.lower_limit
为列表建立索引
现在,可以直接为列表中的项目建立索引来访问它们:
表达式 | 说明 |
$components.test-lbs[0] |
指 thetest-lbs 组件中的第一个项目 |
$components.test-lbs[0].properties.p1 |
是指测试 lbs 组件中第一个项目的属性 p1 |
$components.lbcomps[0].outputs.servicegroups[1].properties.servicegroupname |
指 servicegroups 组件中第二个项目的属性 servicegroupname ,该属性是 lbcomps 组件第一项的输出 |
样书中的策略表达式
样书 GUI 允许您通过从列表中选择项目来构建 NetScaler 策略表达式,从而帮助您更快、更准确地创建表达式。
样书中的策略表达式允许您创建灵活且可自定义的配置。您可以根据各种参数、属性或变量指定条件。策略表达式通常用于实现 NetScaler 策略配置。
在样书 GUI 中启用策略表达式编辑器
要使 EPA 或表达式编辑器可用于某个参数,请在参数定义中指定 is_policy_expression
GUI 属性。启用(设置为 true)时,此设置允许您在为该参数输入值时调用表达式编辑器。
parameters:
-
name: expression
type: string
label: Expression
required: true
gui:
is_policy_expression: true
<!--NeedCopy-->
创建和构建策略表达式
-
导航到应用程序 > 配置 > 样本。 样书页面显示您的 NetScaler 控制台中可用的所有样书。
-
选择一本在其参数中包含策略表达式的样书。
-
单击 创建配置。在“创建配置”页面中,输入本样书中定义的所有参数的值。
-
单击“表达式”字段旁边的图标。将出现“创建表达式”页面。
-
在创建表达式中,使用直观的下拉菜单来构造您的策略表达式。单击 Submit(提交)。
如果您想创建自定义策略表达式,请单击 EPA 编辑器或表达式编辑器来生成您的表达式。在“预览表达式”中查看您的表达式,然后单击“提交”。
-
选择应在其上部署配置的目标 NetScaler 实例,然后单击“提交”。