首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何从词典列表中找出词典

如何从词典列表中找出词典
EN

Stack Overflow用户
提问于 2021-04-27 04:37:50
回答 1查看 1.3K关注 0票数 1
代码语言:javascript
复制
$ more defaults/mail.yaml

---
envs:
  - dev:
      acr-names:
        - intake.azurecr.io
        - dit.azurecr.io
        - dev.azurecr.io
      subscription-id: xxx

  - uat:
      acr-names:
        - stagreg.azurecr.io
      subscription-id: yyy

  - prod:
      acr-names:
        - prodreg.azurecr.io
      subscription-id: zzz

我想要写一个ansible play,在azure https://learn.microsoft.com/en-us/azure/container-registry/container-registry-import-images#import-from-a-registry-in-a-different-subscription中复制注册表之间的图像。

这个剧本应该接受两个参数。source_image和target_image,所以游戏将把图像从源导入到目的地

代表:

target_image=stagreg.azurecr.io/stage-repo:latest :v1.0.0.0

ansible- ansible-playbook同步-docker-Image.yml -e -e源_image=id.azure.io/repo1:v1.0.0.0-e-e

2个问题:

  1. 在这里如何找出source_image或target_image在ansible剧本中属于哪个env(dev、uat或prod),基于env,我想选择订阅id。因此,从上面的示例中,我希望创建两个名为source_subscription和target_subscription的变量,并分别将它们分配给dev和uat订阅。

YAML中的

  1. ,是否可以访问基于键的字典列表中的变量,例如像envsdev

之类的

谢谢

EN

回答 1

Stack Overflow用户

发布于 2021-04-29 13:16:54

首先--如果可能的话--当您只有这三个阶段时,不要使用envs中的dict项列表。我认为它们已经命名了,所以请使用:

代码语言:javascript
复制
envs:
  dev:
    acr-names:
      - ...
    subscription-id: xxx
  uat:
    acr-names:
      - ...
    subscription-id: yyy
  prod:
    acr-names:
      - ...
    subscription-id: zzz

这将使通过envs.devenvs.uat等方式访问各个阶段变得更容易。因此,您只需要在envs.dev.acr-names上迭代(可能使用_而不是-,否则以后会遇到麻烦)。在迭代过程中,您可以使用when条件对照源检查该项:

代码语言:javascript
复制
- name: "Facts"
  set_fact:
    envs:
      dev:
        acr_names:
          - intake.azurecr.io
          - dit.azurecr.io
          - dev.azurecr.io
        subscription_id: xxx
      uat:
        acr_names:
          - stagreg.azurecr.io
        subscription_id: yyy
      prod:
        acr_names:
          - prodreg.azurecr.io
        subscription_id: zzz
    source_image: "dit.azurecr.io/repo1:v1.0.0.0"
    target_image: "stagreg.azurecr.io/stage-repo:latest"

- name: "Identify source subscription"
  set_fact:
    source_subscription: "{{ envs.dev.subscription_id }}"
  when:
    - "item in source_image"
    - "source_subscription is undefined"
  loop: "{{ envs.dev.acr_names }}"

如果无法更改dict (因为您有“多”),则需要迭代envs中的项。如果可能,不要创建“随机”键,而是使用“名称”d项。所以这样的结构会更好

代码语言:javascript
复制
envs:
  - name: dev
    acr_names:
      - ...
    subscription_id: xxx
  - name: uat
    acr_names:
      - ...
    subscription_id: yyy
  ...

因此,您遍历envs中的项,然后遍历item.acr_names以找到您的系统。这更复杂,因为您遍历一个列表,然后遍历该列表中的项。我认为,这是不可能的,只要一项任务。但是,对于给定的结构,问题在于-- source_target中的字符串与acr_names中的字符串不完全相同。因此,删除斜杠后的任何内容,然后可以使用不同的方法搜索列表中的字符串。

代码语言:javascript
复制
- name: "Identify source subscription"
  set_fact:
    source_subscription: "{{ env.subscription_id }}"
  when:
    - "source_image.split('/')[0] in env.acr_names"
    - "source_subscription is undefined"
  loop: "{{ envs }}"
  loop_control:
    loop_var: env

您还可以在第一个示例中使用split过滤器,而无需遍历envs.dev等。

代码语言:javascript
复制
- name: "Show result"
  set_fact:
    source_subscription: "{{ envs.dev.subscription_id }}"
  when:
    - "source_image.split('/')[0] in envs.dev.acr_names"

如果确实需要使用给定的结构,则需要在envs上进行迭代。它以一个随机键作为根元素来表示字典。这使得事情变得非常复杂。在这种情况下,您需要循环它,包含一个带有item.keyanditem.value.acr_namesanditem.value.subscription_id`的单独任务文件,在任务列表中,您需要过滤器lookup('dict',env) to get a special dict and you can access lookup('dict',env) to get a special dict and you can access来访问dict中的值。我不建议你这么做。

代码语言:javascript
复制
- name: "Identify source subscription"
  include_tasks: find_env.yml
  loop: "{{ envs }}"
  loop_control:
    loop_var: env

find_env.yml包含:

代码语言:javascript
复制
- name: "Show result"
  set_fact:
    source_subscription: "{{ env[item.key].subscription_id }}"
  when:
    - "source_image.split('/')[0] in env[item.key].acr_names"
    - "source_subscription is undefined"
  loop: "{{ env | dict2items }}"

所有这些都必须对源和目标执行两次。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67277045

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档