一尘不染

在ansible中修改json的最佳方法

json

我有一个变量(通过set_fact)包含一个json字符串:

{
  "PolicyVersion": {
    "CreateDate": "2017-08-07T02:48:05Z",
    "Document": {
      "Statement": [
        {
          "Action": "sts:AssumeRole",
          "Effect": "Allow",
          "Resource": [
            "arn:aws:iam::123456789123:role/Root_Update_svcacct",
            "arn:aws:iam::123456789123:role/Root_Delete_svcacct",
            "arn:aws:iam::123456789123:role/Root_Create_svcacct",
            "arn:aws:iam::123456789123:role/Root_Full_svcacct",
            "arn:aws:iam::987654321987:role/Member1_Create_svcacct",
            "arn:aws:iam::987654321987:role/Member1_Update_svcacct",
            "arn:aws:iam::987654321987:role/Member1_Delete_svcacct",
            "arn:aws:iam::987654321987:role/Member1_Full_svcacct"
          ]
        }
      ],
      "Version": "2012-10-17"
    },
    "IsDefaultVersion": true,
    "VersionId": "v2"
  }
}

在“资源”数组中插入更多元素的最佳方法是什么?

"arn:aws:iam::001122334455:role/Member1_Create_svcacct",
"arn:aws:iam::001122334455:role/Member1_Update_svcacct",
"arn:aws:iam::001122334455:role/Member1_Delete_svcacct",
"arn:aws:iam::001122334455:role/Member1_Full_svcacct"

我正在探索将变量转储到文件中,并使用外部shell工具插入所需的块,这似乎并不好。


阅读 569

收藏
2020-07-27

共1个答案

一尘不染

我不知道 最好的
方法,但是一种选择是编写一个简单的库模块来为您处理更新的机制。您可以使用该jsonpointer模块来查找要修改的数据,然后将修改后的对象返回到ansible。起点可能看起来像:

#!/usr/bin/python

from ansible.module_utils.basic import AnsibleModule

import json

try:
    import jsonpointer
except ImportError:
    jsonpointer = None


def main():
    module = AnsibleModule(
        argument_spec=dict(
            data=dict(required=True, type='dict'),
            pointer=dict(required=True),
            action=dict(required=True,
                        choices=['append', 'extend', 'update']),
            update=dict(type='dict'),
            extend=dict(type='list'),
            append=dict(),
        ),
        supports_check_mode=True,
    )

    if jsonpointer is None:
        module.fail_json(msg='jsonpointer module is not available')

    action = module.params['action']
    data = module.params['data']
    pointer = module.params['pointer']

    if isinstance(data, str):
        data = json.loads(str)

    try:
        res = jsonpointer.resolve_pointer(data, pointer)
    except jsonpointer.JsonPointerException as err:
        module.fail_json(msg=str(err))

    if action == 'append':
        res.append(module.params['append'])
    if action == 'extend':
        res.extend(module.params['extend'])
    elif action == 'update':
        res.update(module.params['update'])

    module.exit_json(changed=True,
                     result=data)


if __name__ == '__main__':
    main()

如果将其放入例如中,则library/json_modify.py可以在像这样的剧本中使用它:

- hosts: localhost
  gather_facts: false
  vars:
    myvar: {
        "PolicyVersion": {
          "CreateDate": "2017-08-07T02:48:05Z",
          "Document": {
            "Statement": [
              {
                "Action": "sts:AssumeRole",
                "Effect": "Allow",
                "Resource": [
                  "arn:aws:iam::123456789123:role/Root_Update_svcacct",
                  "arn:aws:iam::123456789123:role/Root_Delete_svcacct",
                  "arn:aws:iam::123456789123:role/Root_Create_svcacct",
                  "arn:aws:iam::123456789123:role/Root_Full_svcacct",
                  "arn:aws:iam::987654321987:role/Member1_Create_svcacct",
                  "arn:aws:iam::987654321987:role/Member1_Update_svcacct",
                  "arn:aws:iam::987654321987:role/Member1_Delete_svcacct",
                  "arn:aws:iam::987654321987:role/Member1_Full_svcacct"
                ]
              }
            ],
            "Version": "2012-10-17"
          },
          "IsDefaultVersion": true,
          "VersionId": "v2"
        }
      }
  tasks:
    - json_modify:
        data: "{{ myvar }}"
        pointer: "/PolicyVersion/Document/Statement/0/Resource"
        action: extend
        extend:
          - "arn:aws:iam::001122334455:role/Member1_Create_svcacct"
          - "arn:aws:iam::001122334455:role/Member1_Update_svcacct"
          - "arn:aws:iam::001122334455:role/Member1_Delete_svcacct"
          - "arn:aws:iam::001122334455:role/Member1_Full_svcacct"
      register: result

    - debug:
        var: result.result

运行该手册和建议的模块的结果是:

TASK [debug] *******************************************************************
ok: [localhost] => {
    "result.result": {
        "PolicyVersion": {
            "CreateDate": "2017-08-07T02:48:05Z", 
            "Document": {
                "Statement": [
                    {
                        "Action": "sts:AssumeRole", 
                        "Effect": "Allow", 
                        "Resource": [
                            "arn:aws:iam::123456789123:role/Root_Update_svcacct", 
                            "arn:aws:iam::123456789123:role/Root_Delete_svcacct", 
                            "arn:aws:iam::123456789123:role/Root_Create_svcacct", 
                            "arn:aws:iam::123456789123:role/Root_Full_svcacct", 
                            "arn:aws:iam::987654321987:role/Member1_Create_svcacct", 
                            "arn:aws:iam::987654321987:role/Member1_Update_svcacct", 
                            "arn:aws:iam::987654321987:role/Member1_Delete_svcacct", 
                            "arn:aws:iam::987654321987:role/Member1_Full_svcacct", 
                            "arn:aws:iam::001122334455:role/Member1_Create_svcacct", 
                            "arn:aws:iam::001122334455:role/Member1_Update_svcacct", 
                            "arn:aws:iam::001122334455:role/Member1_Delete_svcacct", 
                            "arn:aws:iam::001122334455:role/Member1_Full_svcacct"
                        ]
                    }
                ], 
                "Version": "2012-10-17"
            }, 
            "IsDefaultVersion": true, 
            "VersionId": "v2"
        }
    }
}
2020-07-27