2017-10-10 97 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 }}"