1. 授权认证
  2. 获取用户个人信息
  3. 项目协同
  4. 代码托管
  5. 持续集成
  6. 制品仓库
  7. 测试管理
  8. 文档管理
  1. 项目协同
  2. 代码仓库
  3. DevOps 实践之旅
  4. 一分钟开始持续集成之旅
  5. 持续部署
  6. 制品库

使用 CODING 持续部署的强大表达式

简介

管道表达式是一种动态的表达式,可以在阶段内引用系统内已存在的任意值。即只要存在此变量,就能够被阶段引用。

目前,管道表达式可以使用在两个地方:

  • 阶段内执行选项条件表达式表单,用来判断当前阶段满足表达式才能执行。
  • 部署的 manifest 内,可以使用表达式。

语法

由美元符号 ${} 组成,即 ${},括号内书写在部署阶段内置的变量名,但不能被嵌套使用。例如这样是不合法的:${ expression1 ${expression2} }

高级用法

管道表达式内允许用户执行 JAVA 代码,可以定义更加复杂的逻辑,出于安全考虑,只有以下 JAVA 类可以被调用:

  • Boolean
  • Byte
  • ChronoUnit
  • Date
  • DayOfWeek
  • Double
  • Instant
  • Integer
  • LocalDate
  • LocalDateTime
  • Long
  • Math
  • Random
  • SimpleDateFormat
  • String
  • URLEncoder
  • UUID

例如,你希望在条件表达式内获取到当前日期,可以这样写:

${new java.text.SimpleDateFormat("MM-dd-yyyy").format(new java.util.Date())}

表达式比较

可以用关系运算符来做比较,例如:

${instance["size"] > 400}
${parameters["runCanary"] == "true"}

特别注意,比较的时候需要两者数据结构一致才可以,例如 ${parameters["runCanary"] 可能为 String ,那么必须将其转换为 Boolean 类型,否则比较不生效。可以用内置的辅助函数来做数据转换:

${#toBoolean(parameters["runCanary"]) == true}。

除此之外,还有以下内置数据转换辅助函数:

  • #toBoolean(String)
  • #toFloat(String)
  • #toInt(String)

其他辅助函数

常用
  • #fromUrl(String)

    • 请求 URL 返回字符串,用来获取网页信息。
  • #jsonFromUrl(String)

    • 请求 URL 的内容,并将 JSON 转换为 map 或 list。
  • #yamlFromUrl(String)

    • 请求 URL 的内容,并将 yaml 转换为 map。
  • #judgment(String)

    • 获取“人工确认”阶段用户选择的值。
  • #stage(String)

    • 通过名称获取 stage ,区分大小写,可以获取到该 stage 的配置信息。
  • #triggerResolvedArtifact(String)

    • 在触发器中查找已解析的制品,如果有多个,只返回一个。例如:

      ${#triggerResolvedArtifact("my-image")["reference"]}

      可能会返回

      gcr.io/spinnaker-marketplace/orca@sha256:b48dbe7d7cb580db8512e4687d31f3710185b08afcf3cb53c0203025f93f9091

  • #triggerResolvedArtifactByType(String)

    • 在执行触发器中按其类型查找制品,如果有多个,只返回 1 个。例如,

      ${#triggerResolvedArtifactByType("docker/image")["reference"]}

      可能会返回

      gcr.io/spinnaker-marketplace/orca@sha256:b48dbe7d7cb580db8512e4687d31f3710185b08afcf3cb53c0203025f93f9091

不常用

  • #alphanumerical(String)

    • 返回传入字符串的字母数字值。也就是说,去除了除 AZ 和 0-9 之外的所有字符的输入字符串。
  • #deployedServerGroups(String)

    • 将部署阶段的名称作为参数,并返回由指定阶段创建的服务器组。
  • #readJson(String)

    • 将 JSON 字符串转换为 Map,然后可以进一步处理。
  • #readYaml(String)

    • 将 YAML 字符串转换为 Map,然后可以对其进行进一步处理。
  • #deployedServerGroups(String)

    • 将部署阶段的名称作为参数,并返回由指定阶段创建的服务器组。
  • #manifestLabelValue(stageName, manifestKind, labelKey)

    • 返回带有类型 labelKey 的 Kubernetes 部署或 ReplicaSet 清单中的键的标签的值,该清单 manifestKind 通过类型 deployManifest 和名称的阶段进行部署 stageName。
  • #propertiesFromUrl(String)

    • 在给定的 URL 上检索 Java 属性文件的内容,并将其转换为映射。
  • #stageByRefId(String)

    • 通过 refId 获取 stage ,区分大小写,可以获取到该 stage 的配置信息。
  • #currentStage(String)

    • 返回当前阶段。
  • #stageExists(String)

    • 检查给定阶段是否存在,可以用名称或者 ID。
  • #pipelineId(String)

    • 返回管道 ID ,例如

      ${#pipelineId("Deploy to prod")}

      可能会返回

      9b2395dc-7a2b-4845-b623-838bd74d059b

  • #toJson(String)

    • 将任意 JSON 对象转换为 JSON 字符串。

获取任意的变量

通过查看已执行完成的部署流程 “Source”,可以看到部署流程使用的所有变量:

这些变量,都可以通过辅助函数来获取。

也可以用过滤符号 .? 来做数据筛选,例如:

${execution["stages"].?[type == "bake"][0]}

将返回管道中第一个 bake 阶段。

数学运算

可以在管道表达式中使用数学运算符号,例如 ${trigger["buildInfo"]["number"] * 2} ,需要注意的是,变量需要使用辅助函数转化为 IntFloat 之后,才能进行数学运算。

常用示例

部署的 manifest 使用条件表达式

例如指定 Pod 部署权重为上一个人工确认阶段输入的值,另外一个 Pod 权重则由数学表达式计算,两者权重合计 100。

apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
  name: k8s-flask-pro
  namespace: pro
spec:
  entryPoints:
    - web
  routes:
    - kind: Rule
      match: Host(`pro.coding`)
      services:
        - name: k8s-flask
          namespace: pro
          port: 8080
          weight: '${100 - #toInt(#judgment("生产环境 - 灰度比例"))}'
        - name: k8s-flask-canary
          namespace: pro
          port: 8080
          weight: '${#toInt(#judgment("生产环境 - 灰度比例"))}'

动态跳过阶段

如果希望实现这种动态交叉的阶段,根据人工确认阶段输入的值动态选择部署路径:

可以在 A/B 测试阶段的 条件表达式 表单内输入:

${♯judgment("是否灰度并进行 A/B 测试") == '是,进行 A/B 测试'}

意味着是否灰度并进行 A/B 测试的人工确认阶段选择了是,进行 A/B 测试后,A/B 测试阶段会被执行。如果选择了其他的值,则会进入到 是否进入自动化灰度阶段。

限制 latest 版本制品的部署,防止提单误操作

例如,要限制部署 latest 版本的 docker 镜像部署,可以取当前阶段所需制品的已绑定制品版本是否为 latest:

${trigger["expectedArtifacts"][2]["boundArtifact"]["version"]  != 'latest'}

意味着第三个制品是我们配置的 docker 类型的启动所需制品,注意索引从第 0 个开始。

上一篇CODING CD 主机组部署实践
最近更新
感谢反馈有用
感谢反馈没用

在阅读中是否遇到以下问题?

您希望我们如何改进?