2017-10-10 86 views
0

编辑10OCT2017感谢@techraf使用jinja2模板 我有一个令人发狂的令人担忧的任务(顺便说一句,我只有1天Ansible的经验,所以我可能在我的测试/思维方式中出错) 。我试图将一个对象转换成不同的对象。我原来的目标是这样的:在Ansible中操作对象

[ 
{"allowed":[{"IPProtocol":"tcp","ports":["1234-1235"]},{"IPProtocol":"udp","ports":["1238-1239"]}], 
"description":"hello1", 
"name":"hello1", 
"sourceRanges":["128.0.0.0/16","192.0.0.0/16"]}, 
{"allowed":[{"IPProtocol":"tcp","ports":["2345-2346"]},{"IPProtocol":"udp","ports":["4567-4578"]}], 
"description":"hello2", 
"name":"hello2", 
"sourceRanges":["128.0.0.0/16","192.0.0.0/16"]} 
] 

,我想将其改造成:

[ 
{"allowed":"tcp:1234-1235,udp:1238-1239", 
"description":"hello1", 
"name":"hello1", 
"sourceRanges":"128.0.0.0/16,192.0.0.0/16"}, 
{"allowed":"tcp:2345-2346,udp:4567-4578", 
"description":"hello2", 
"name":"hello2", 
"sourceRanges":"128.0.0.0/16,192.0.0.0/16"} 
] 

余米压扁协议/端口和sourcerange。

我尝试使用Jinja2的模板具有以下ansible剧本:

#ansible-playbook issue.yml -i 'local,' --connection=local 
- hosts: 
    - local tasks: 
    - name: setVar 
    set_fact: 
     aOriginal='[{"allowed":[{"IPProtocol":"tcp","ports":["1234-1235"]},{"IPProtocol":"udp","ports":["1238-1239"]}],"description":"hello1","name":"hello1","sourceRanges":["128.0.0.0/16","192.0.0.0/16"]},{"allowed":[{"IPProtocol":"tcp","ports":["2345-2346"]},{"IPProtocol":"udp","ports":["4567-4578"]}],"description":"hello2","name":"hello2","sourceRanges":["128.0.0.0/16","192.0.0.0/16"]}]' 
    - debug: 
     var: aOriginal 
    - name: Populate SubnetIds 
    set_fact: 
     test3: "{{ lookup('template', 'subnet2.j2') }}" 
    vars: 
     rules: "{{ aOriginal }}" 
    - debug: 
     var: test3 
    - name: Create rules 
    shell: gclofud compute firewall-rules create {{ item.name }} --allow {{ item.altIpProtos }} --description {{ item.description }} --source-ranges {{ item.flatSrcRanges }} 
    with_items: "{{ test1 }}" 

与我的模板文件(同一文件夹 - 与文件名 “subnet2.j2”):

[ { {% for s in rules %}name:{{s.name}},description:{{s.description}},allowed:{% for aOneAllowedProtoPort in s.allowed %}{{aOneAllowedProtoPort.IPProtocol}}:{% for aOneAllowedPort in aOneAllowedProtoPort.ports %}{{aOneAllowedPort}}{% endfor %}{% if not loop.last %},{% endif %}{% endfor %},sourceRanges:"{% for aOneAllowedSource in s.sourceRanges %}{{aOneAllowedSource}}{% if not loop.last %},{% endif %}{% endfor %}{% endfor %} } ] 

正如你所看到的与test3结果如下:

ok: [local] => { 
    "test3": "[\"name\":hello1,description:hello1,allowed:tcp:1234-1235,udp:1238-1239,sourceRanges:128.0.0.0/16,192.0.0.0/16\"name\":hello2,description:hello2,allowed:tcp:2345-2346,udp:4567-4578,sourceRanges:128.0.0.0/16,192.0.0.0/16]\n" 
} 

我设法组合在一起protocole /端口和范围列表尽管如此,模板的输出似乎被解释为一个字符串和音符作为一个对象。我尝试过几次测试(把“字符串绕得无法帮助,因为它们有可靠的前缀),我不知道发生了什么。

我不知道是否有某个特定的事情需要将模板的结果转换为对象。 。还在研究,并会与我的进步更新问题THX @techraf

最后更新我做了这里是ansible剧本(内Jinja2的模板):

#ansible-playbook issue.yml -i 'local,' --connection=local 
- hosts: 
    - local 
    tasks: 
    - name: setVar 
    set_fact: 
     aOriginal='[{"allowed":[{"IPProtocol":"tcp","ports":["1234-1235"]},{"IPProtocol":"udp","ports":["1238-1239"]}],"description":"hello1","name":"hello1","sourceRanges":["128.0.0.0/16","192.0.0.0/16"]},{"allowed":[{"IPProtocol":"tcp","ports":["2345-2346"]},{"IPProtocol":"udp","ports":["4567-4578"]}],"description":"hello2","name":"hello2","sourceRanges":["128.0.0.0/16","192.0.0.0/16"]}]' 
    - debug: 
     var: aOriginal 
    - name: Populate SubnetIds 
    set_fact: 
     test3='[ {% for s in rules %} {"name":"{{s.name}}","description":"{{s.description}}","allowed":"{% for aOneAllowedProtoPort in s.allowed %}{{aOneAllowedProtoPort.IPProtocol}}:{% for aOneAllowedPort in aOneAllowedProtoPort.ports %}{{aOneAllowedPort}}{% endfor %}{% if not loop.last %},{% endif %}{% endfor %}","sourceRanges":"{% for aOneAllowedSource in s.sourceRanges %}{{aOneAllowedSource}}{% if not loop.last %},{% endif %}{% endfor %}"}{% if not loop.last %},{% endif %} {% endfor %} ]' 
    vars: 
     rules: "{{ aOriginal }}" 
    - debug: 
     var: test3 
    - name: Create rules 
    shell: gclofud compute firewall-rules create {{ item.name }} --allow {{ item.altIpProtos }} --description {{ item.description }} --source-ranges {{ item.flatSrcRanges }} 
    with_items: "{{ test3 }}" 
+0

看起来像一个单一的Jinja2模板与for循环三个或四个要求 - 任务比富有挑战性的比较费力。有人在这里为你写这篇文章可能需要一些时间。看到这个想法https://stackoverflow.com/q/40034175/2947502 – techraf

+0

根据您的反馈意见编辑问题到目前为止取得的进展。 THX的模板暗示。 –

+0

它正在工作。 Thx @techraf提供有关模板的提示。我将发布最终解决方案作为答案。可悲的是,我不能接受techraf的评论,即使它帮助我如此: –

回答

0

我找到了解决办法谢谢to @techraf about jinja2 template。

我为这里只是分享的情况下,它帮助别人,将来的结果:

#ansible-playbook issue.yml -i 'local,' --connection=local 
- hosts: 
    - local 
    tasks: 
    - name: setVar 
    set_fact: 
     aOriginal='[{"allowed":[{"IPProtocol":"tcp","ports":["1234-1235"]},{"IPProtocol":"udp","ports":["1238-1239"]}],"description":"hello1","name":"hello1","sourceRanges":["128.0.0.0/16","192.0.0.0/16"]},{"allowed":[{"IPProtocol":"tcp","ports":["2345-2346"]},{"IPProtocol":"udp","ports":["4567-4578"]}],"description":"hello2","name":"hello2","sourceRanges":["128.0.0.0/16","192.0.0.0/16"]}]' 
    - debug: 
     var: aOriginal 
    - name: Populate SubnetIds 
    set_fact: 
     test3='[ {% for s in rules %} {"name":"{{s.name}}","description":"{{s.description}}","allowed":"{% for aOneAllowedProtoPort in s.allowed %}{{aOneAllowedProtoPort.IPProtocol}}:{% for aOneAllowedPort in aOneAllowedProtoPort.ports %}{{aOneAllowedPort}}{% endfor %}{% if not loop.last %},{% endif %}{% endfor %}","sourceRanges":"{% for aOneAllowedSource in s.sourceRanges %}{{aOneAllowedSource}}{% if not loop.last %},{% endif %}{% endfor %}"}{% if not loop.last %},{% endif %} {% endfor %} ]' 
    vars: 
     rules: "{{ aOriginal }}" 
    - debug: 
     var: test3 
    - name: Create rules 
    shell: gclofud compute firewall-rules create {{ item.name }} --allow {{ item.altIpProtos }} --description {{ item.description }} --source-ranges {{ item.flatSrcRanges }} 
    with_items: "{{ test3 }}"