在Ansible中操作对象
问题描述:
编辑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 }}"
答
我找到了解决办法谢谢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 }}"
看起来像一个单一的Jinja2模板与for循环三个或四个要求 - 任务比富有挑战性的比较费力。有人在这里为你写这篇文章可能需要一些时间。看到这个想法https://stackoverflow.com/q/40034175/2947502 – techraf
根据您的反馈意见编辑问题到目前为止取得的进展。 THX的模板暗示。 –
它正在工作。 Thx @techraf提供有关模板的提示。我将发布最终解决方案作为答案。可悲的是,我不能接受techraf的评论,即使它帮助我如此: –