【问题标题】:Is it possible to use abstraction in a YAML file?是否可以在 YAML 文件中使用抽象?
【发布时间】:2019-04-25 05:10:15
【问题描述】:

是否可以使用argumentsabstraction尽量减少 YAML 文件中的重复代码

我正在编写一个触发部署的 YAML 文件,并且在部署之前和之后我想调用一个松弛通道来指示部署正在开始和结束,以及它是否失败。

这是我写的,但感觉太冗长了

example_deploy:
    - call: notify
    in:
      msgText: "Deployment starting for environment *${environment}*"
    - try:
      - ${oneops.environmentCommitAndDeploy(environment = 'production', platform = '${platform}', deployAllPlatforms = false )}
      error:
    - log: "Error trying to deploy: ${lastError.cause}"
    - call: notify
      in:
        msgText: " :fire: Deployment failed for environment *${environment}* http://concord.com/#/process/${txId}/log"
    - exit
  - call: notify
    in:
      msgText: " :party: Deployment succeeded for environment *${environment}* http://concord.com/#/process/${txId}/log"
  notify:
  - task: slack
    in:
      channelId: ${alerts}
      username: ${slackname}
      iconEmoji: ${slackEmojiLooper}
      text: "${msgText}"

现在,如果我想拥有example_deploy_2 并做同样类型的事情,我是否必须重写所有代码?或者有没有办法拥有一个“函数”或抽象 YAML 的重复部分

更新 我已经使用call 来抽象对 slack 的调用,但现在我想知道是否可以对 slack 进行通用调用并动态更新消息 - 因为现在我正在重复传递给块的参数我定义为called

的代码

示例

  example_deploy:
    - call: slack_start_deploy
    - try:
      - ${transitionVariableUpdate(platform = '${platform}', environment = '${environment}', component = '${component_ear}' variables = { appVersion = '${BRANCH_NAME}-${BUILD_NUMBER}' })}
      - ${environmentCommitAndDeploy(environment = 'qa', platform = '${platform}', deployAllPlatforms = false )}
      error:
    - log: "Error trying to deploy: ${lastError.cause}"
    - call: slack_deploy_error
    - exit
  - call: slack_deploy_success

  slack_start_deploy:
  - slack.postMessage:
      text: "${entryPoint} Deployment starting for environment *${environment}*"
      channelId: ${alerts}
      username: ${slackname}
      iconEmoji: ${slackEmojiConcord}

  slack_deploy_error:
  - slack.postMessage:
      text: " :fire: ${entryPoint} Deployment failed for environment *${environment}* http://concord.com/#/process/${txId}/log"
      channelId: ${alerts}
      username: ${slackname}
      iconEmoji: ${slackEmojiConcord}

  slack_deploy_success:
  - slack.postMessage:
      text: " :party: Deployment succeeded for environment *${environment}* http://concord.com/#/process/${txId}/log"
      channelId: ${alerts}
      username: ${slackname}
      iconEmoji: ${slackEmojiConcord}

【问题讨论】:

  • 您的示例无效 YAML error: 是一个映射键,其缩进与前面的序列项一样多,- call: 是一个序列项,其缩进量与 exampel_deplay: 键一样多。你不能在 YAML 中混合这样的集合
  • @anthon 省去我的详细信息 - 我对更大的图景感兴趣。

标签: yaml abstraction


【解决方案1】:

YAML 规范中唯一允许 尽量减少重复是使用 anchor 在节点上和 使用别名引用该节点。这适用于两个叶节点 (即任何类型的标量值)和集合节点 (映射,序列)。锚定集合的别名基本上 “替换”集合下方的整个子树。

除此之外,映射中还有merge key << 由大多数 YAML 加载器实现(通常在构建阶段), 您可以在其中有一个或多个映射提供键值对 具有合并键的映射中未指定的键 (直接或通过较早处理的合并)。

除此之外,任何使用 YAML 加载器的程序都可以扩展加载器 (通常是它的构造机制,但这可以更早完成 在加载过程中)他们认为合适,但这样的机制是 不被视为 YAML 的一部分。

可以在您的 YAML 上部署合并机制以减少行数。如果你的例子 改为example.yaml

example_deploy:
  - call: slack_start_deploy
  - try:
    - ${transitionVariableUpdate(platform = '${platform}', environment = '${environment}', component = '${component_ear}' variables = { appVersion = '${BRANCH_NAME}-${BUILD_NUMBER}' })}
    - ${environmentCommitAndDeploy(environment = 'qa', platform = '${platform}', deployAllPlatforms = false )}
error:
  - log: "Error trying to deploy: ${lastError.cause}"
  - call: slack_deploy_error
  - exit
  - call: slack_deploy_success

slack_start_deploy:
- slack.postMessage: &pm
    text: "${entryPoint} Deployment starting for environment *${environment}*"
    channelId: ${alerts}
    username: ${slackname}
    iconEmoji: ${slackEmojiConcord}

slack_deploy_error:
- slack.postMessage:
    text: " :fire: ${entryPoint} Deployment failed for environment *${environment}* http://concord.com/#/process/${txId}/log"
    <<: *pm

slack_deploy_success:
- slack.postMessage:
    text: " :party: Deployment succeeded for environment *${environment}* http://concord.com/#/process/${txId}/log"
    <<: *pm

(请注意,我更改了您的 error:- call: ... 行的缩进,如您的 文件是无效的 YAML)

在上面,&amp;pm 是具有四个键的映射节点的锚点。 *pms 是别名 使用此映射,每次使用 text 的原始值。

以下 Python 程序通过加载,然后转储显示合并键如何扩展为 加载过程中您的原件。

import sys
from pathlib import Path
import ruamel.yaml

example = Path('example.yaml')

yaml = ruamel.yaml.YAML(typ='safe')
yaml.default_flow_style = False
data = yaml.load(example)
yaml.dump(data, sys.stdout)

给出:

error:
- log: 'Error trying to deploy: ${lastError.cause}'
- call: slack_deploy_error
- exit
- call: slack_deploy_success
example_deploy:
- call: slack_start_deploy
- try:
  - ${transitionVariableUpdate(platform = '${platform}', environment = '${environment}',
    component = '${component_ear}' variables = { appVersion = '${BRANCH_NAME}-${BUILD_NUMBER}'
    })}
  - ${environmentCommitAndDeploy(environment = 'qa', platform = '${platform}', deployAllPlatforms
    = false )}
slack_deploy_error:
- slack.postMessage:
    channelId: ${alerts}
    iconEmoji: ${slackEmojiConcord}
    text: ' :fire: ${entryPoint} Deployment failed for environment *${environment}*
      http://concord.com/#/process/${txId}/log'
    username: ${slackname}
slack_deploy_success:
- slack.postMessage:
    channelId: ${alerts}
    iconEmoji: ${slackEmojiConcord}
    text: ' :party: Deployment succeeded for environment *${environment}* http://concord.com/#/process/${txId}/log'
    username: ${slackname}
slack_start_deploy:
- slack.postMessage:
    channelId: ${alerts}
    iconEmoji: ${slackEmojiConcord}
    text: ${entryPoint} Deployment starting for environment *${environment}*
    username: ${slackname}

【讨论】:

    猜你喜欢
    • 2020-02-28
    • 1970-01-01
    • 2012-11-18
    • 1970-01-01
    • 2017-02-06
    • 2013-04-21
    • 1970-01-01
    • 2014-08-30
    相关资源
    最近更新 更多