nephilimrising
nephilimrising

Reputation: 133

How to replace specific word in Ansible with regex_replace

I have a string to replace that looks like this:

{
        "_expandable": {
            "ancestors": "",
            "children": "/rest/api/content/164794022/child",
            "container": "/rest/api/space/AT",
            "descendants": "/rest/api/content/164794022/descendant",
            "history": "/rest/api/content/164794022/history",
            "metadata": "",
            "operations": "",
            "restrictions": "/rest/api/content/164794022/restriction/byOperation",
            "space": "/rest/api/space/AT",
            "version": ""
        },
        "_links": {
            "base": "https://***/confluence",
            "collection": "/rest/api/content",
            "context": "/confluence",
            "edit": "/pages/resumedraft.action?draftId=164794022&draftShareId=e44b5ec9-f1a1-463e-aa40-6667c6022ec8",
            "self": "https://***/confluence/rest/api/content/164794022",
            "tinyui": "/x/po7SCQ",
            "webui": "/display/AT/Jira+Dev"
        },
        "body": {
            "_expandable": {
                "anonymous_export_view": "",
                "editor": "",
                "export_view": "",
                "styled_view": "",
                "view": ""
            },
            "storage": {
                "_expandable": {
                    "content": "/rest/api/content/164794022"
                },
                "representation": "storage",
 **here**====>      "value": "<p class=\"auto-cursor-target\"><br /></p><ac:structured-macro ac:name=\"details\" ac:schema-version=\"1\" ac:macro-id=\"6f61e6bd-3edc-4e93-a9b7-2f15cd5fc33c\"><ac:parameter ac:name=\"id\">1</ac:parameter><ac:rich-text-body><p class=\"auto-cursor-target\"><br /></p><table class=\"wrapped\"><colgroup><col /><col /></colgroup><tbody><tr><th colspan=\"1\">Hostname</th><td colspan=\"1\">jira-dev</td></tr><tr><th>IP</th><td>192.168.182.231</td></tr><tr><th colspan=\"1\">Static/Dynamic IP?</th><td colspan=\"1\"><div class=\"content-wrapper\"><p>Static</p></div></td></tr><tr><th>Server</th><td>Hosted by IT Team</td></tr><tr><th colspan=\"1\"><p>Installed Product</p></th><td colspan=\"1\">Jira Software + Service Management</td></tr><tr><th colspan=\"1\"><p>Necessity</p></th><td colspan=\"1\"><div class=\"content-wrapper\"><p>Normal</p></div></td></tr><tr><th>OS</th><td>Ubuntu 20.04</td></tr><tr><th>Monitoring</th><td>No</td></tr><tr><th>Backup</th><td>No</td></tr><tr><th colspan=\"1\">Installed Product URL</th><td colspan=\"1\"><a href=\"http://jira-dev:8080\">http://jira-dev:8080</a></td></tr><tr><th colspan=\"1\">Using SSO</th><td colspan=\"1\">No</td></tr><tr><th colspan=\"1\">Product credentials</th><td colspan=\"1\"><div class=\"content-wrapper\"><p class=\"auto-cursor-target\"><br /></p><ac:structured-macro ac:name=\"secure\" ac:schema-version=\"1\" ac:macro-id=\"baba2872-b3b8-45e2-a5b4-fe7384f862d2\"><ac:parameter ac:name=\"title\">Product credentials</ac:parameter><ac:rich-text-body><span class=\"sec-icon-lock icon16\">&nbsp;</span><pre class=\"secret\">-----BEGIN PGP MESSAGE-----\nVersion: BCPG v1.59\n\nhQEMAxOSOe32i2V3Agf/SGkioVaXxO/pLAdaT6K7+tNBzVdCgmdYz8rIPF2C+fw9\nY8W+3++H8IyWMVDmSlAV6zENi/YnV9roOJC/ndSHEHEiBAtfHQUjT62cRQM7b3fo\nwOKhDETne4q42bFEJbfo9TJ+eYhOTJ4GduRJz1yNetgWpAbiVg3rXj7Aox9xeWIe\nHK1rGm5ZzIElXLI9VpjNvKG0aqVQS4QefcuKi6/xVnZuFkdA3IGE2yPWJizPAjyt\nlkD7iRi1Ol46b0xPDVsDfpiwQAdpwM2NmOJwbT6mRBqx0gXeKOXIUOUwDdC6biVJ\nLuau6FDgdQru+oVsXnTD2dM+M7yyhJaMtttUJch9btLCEAHlw2panHKUC6iUxbjZ\nLA8c9z3RgSq01G/gxFMvO3hSs6ih13SAdsCz18MIFdaTDU4+6cMR9hSsgF+8qxtY\nl1JEziDFpqQgZZoDv7afZn3+3IdMQ7mwQgqVu+xsckTe66hO8DlRuslyXiU39Mct\nJuUziC3OGD74x2ZhiFXxLgn4XI77TnEc5qUh6imK4xli6Pyz1Jy4RbgzdNunBN2P\n9qMxNO9fgdx5vfVxmGGaGIbvZ3a3dsSr0vi92xUmV1kd7oaUCuNe2Tw55Eb52fsA\nUQQ1WM/NZi31/cWAPyhLx8cTByMc/RjHg+h0UIlo50CBTNUOPE0QgdAXXZzZ17t5\nsvNdEBswMCHmcMIrCEGa0kWvykgK0D7kvmu+U5yzMM9482K2rws+1Q8e5UHyJ55e\nKn4cUR5yjnBXGZwerSBrIKhUcpGFPCDgctFpV6U8KxrY/lDV7k8TtsV9f71i3o51\noEvV/v9ufoWsFsp5qJRSwY/qkfYAOr8pw5mHFN3pC2MOOkkj1xDOkEwr4/J1wDaI\n8VAGONGizwDnNvYD58LpaAYnQWkdI2WEVLpkKQWgGolJSuDkmpY2wWiSxcAFI31X\nQY1e3nFzXQPcB6MkCW0P1buMUrJnQaVFQmtPf4A/yhmdK15jHfPLbUyIB1j6ewIm\njEDfo276k+nAdskmUNo+0KekJta8RHCS9tR5H4qr4LLiUOmhPYTN7MyDC+aCXX+N\nLtNpnMCQVHVxWTuCCqhmlI1VIOjUOJjAvNKX1+DAhSOquo2FXPeo0nS/MYFeRu/c\npmu5WUR5DI2kZb/psp1Lj+awRvoOy3EV5Tv9a7MfrebvjnV021+JbK2uQVViFtvg\nGAKu8dPDUW0u0jxLWeFxm/RXzcStyS2+CQQ3UY1gdqvenzZbH0PKq0vHmShy/J3b\nK4kT09FF/Wcc3j6f4pSwR1B23p9fNE17iUvcNoU9c+tD3g==\n=Qwvl\n-----END PGP MESSAGE-----\n</pre>Secured content</ac:rich-text-body></ac:structured-macro><p class=\"auto-cursor-target\"><br /></p></div></td></tr><tr><th colspan=\"1\">Host credentials</th><td colspan=\"1\"><div class=\"content-wrapper\"><p class=\"auto-cursor-target\"><br /></p><ac:structured-macro ac:name=\"secure\" ac:schema-version=\"1\" ac:macro-id=\"fbc7388c-0965-4b10-8acc-0d1233ca3ef4\"><ac:parameter ac:name=\"title\">Host credentials</ac:parameter><ac:rich-text-body><span class=\"sec-icon-lock icon16\">&nbsp;</span><pre class=\"secret\">-----BEGIN PGP MESSAGE-----\nVersion: OpenPGP.js v4.10.10\nComment: https://openpgpjs.org\n\nwcBMAxOSOe32i2V3Agf+IKFt2bSmyFl4Sk3YtTf1cXu+Xv9yZ0c/iP4RJ9ll\n5P9LM8DKPtBL+othBMLEUigNEgjXOrANp11W/endk1Ulst4UkTyttQQx5JZ2\nyNI2Q0M5uUfj/2tlCq9TTO1eXb/bffM+cKzk0D68UWC+EBvXpRp5sbKVz1Ya\nJj7nYItETTuWPUjF0uEaYVlbmsdfe3dvVy63EPw5GZdVobwv++93ZIEEhKmS\nvc+d+iw9L+Ov16kXCQaHNXzyiwtvp5nIIMYORp3IaRrbzmBqiV07RjIZrvNR\nyozEGcNWdSW7egC1k+JEF+qi2kLASglKLWFWmHn/cMpetULl8Z9c3VFZpnu7\nENLBVwFQ2f3uaF+A6t19Zi5CKptV+f1qtYekyZZok61TBkldQD4AL2UEBDB0\nMpUfEEdy4vgYqNjGWGOpX2QbWjXZDhxPAQgNr6XxxcJ7L1gzHLZT45MjFzB9\nBBhtX/qvczL1uWNHwYErUZGbwX6pwfyfbTUDX57bDbOYUG0A+nZjWIRJt5tA\nFPWiM0vicufuMACUYG00n3+C2Eu/DPIcRaHRhnz1aEDOQ4dX19ZpUCY0hWeZ\ndnhtLEYOXxTy6bgsHoBIHxac+DQ9a/0iFSNIErXfIq7yrABPEfn04Kc3tkXJ\nK+RAFQ7aJ93LjkfYMqxjLVp1lAZ05dealMLHStkvisPI3Y0qDGwPKmg9kkMD\nBnF5OuU6L/RXzei9eUHU4O2HOJtf5ClTZ7vHBXyBzoZ1JOUu2axAaOJq7Y8h\nm7L1vYJngepSMrh4xLzQXuoegM049NNSIsumioCyF4VBvtopATta1cG/U2dF\n/lahHpm0l3FtdWodNCag2Ejsr61+H5gIHinqPZC96MUmdbOOzWnHXlXjAAO/\nzkXNDAAJss+WolNuF+o8yUd9w9woYIuqzrXOOMhEM1pAxAiBhOjeXI3lQXa6\nf0pr/txZXy+qrvuQlcaF5EyWc4GrLTnuceBWAhHIrsaEhLQVf5RtJDrvgdyR\nJLw4+79Hzt+/R6gRP6Pat1bN9e734/w09gpdvnolzWxTzpn7Wuje4uX4w+M=\n=CiIl\n-----END PGP MESSAGE-----\n</pre>Secured content</ac:rich-text-body></ac:structured-macro><p class=\"auto-cursor-target\"><br /></p></div></td></tr><tr><th colspan=\"1\">Status</th><td colspan=\"1\"><div class=\"content-wrapper\"><p><ac:structured-macro ac:name=\"status\" ac:schema-version=\"1\" ac:macro-id=\"50e10a44-3a60-4c7c-aa16-8a7577487768\"><ac:parameter ac:name=\"colour\">Red</ac:parameter><ac:parameter ac:name=\"title\">PING</ac:parameter><ac:parameter ac:name=\"\" /></ac:structured-macro><span> </span><ac:structured-macro ac:name=\"status\" ac:schema-version=\"1\" ac:macro-id=\"1e1a2aa2-80ee-49e9-8f4c-5c5335ac3f52\"><ac:parameter ac:name=\"colour\">Green</ac:parameter><ac:parameter ac:name=\"title\">ssh</ac:parameter><ac:parameter ac:name=\"\" /></ac:structured-macro><span> </span><ac:structured-macro ac:name=\"status\" ac:schema-version=\"1\" ac:macro-id=\"68710b0e-2f40-4156-ac81-15f1c3c1d025\"><ac:parameter ac:name=\"colour\">Green</ac:parameter><ac:parameter ac:name=\"title\">HTTP</ac:parameter><ac:parameter ac:name=\"\" /></ac:structured-macro></p></div></td></tr></tbody></table><p class=\"auto-cursor-target\"><br /></p></ac:rich-text-body></ac:structured-macro><p><br /></p><p><br /></p><p><br /></p><p><br /></p><p><br /></p><p><br /></p>"
            }
        },
        "extensions": {
            "position": "none"
        },
        "id": "164794022",
        "status": "current",
        "title": "Jira Dev",
        "type": "page"
    }
}

i am trying to replace 3 of the properties(i will paste formatted, but they are on 1 line in the response):

<ac:parameter ac:name=\"colour\">Red</ac:parameter><ac:parameter ac:name=\"title\">ssh</ac:parameter>
<ac:parameter ac:name=\"colour\">Green</ac:parameter><ac:parameter ac:name=\"title\">http</ac:parameter>
<ac:parameter ac:name=\"colour\">Green</ac:parameter><ac:parameter ac:name=\"title\">ping</ac:parameter>

I am targeting the first one with:

    - name: replace value in body
      set_fact:
        page: "{{ page.json | regex_replace('\"colour\">(.{1,5}?)<\/ac:parameter><ac:parameter ac:name=\"title\">ssh<\/ac:parameter>', '//1') }}"

this is resulting in <ac:parameter ac:name=//1<ac:parameter ac:name=\"\" /> and the word I need to match is in capture group 1. How to make the replacement properly? I need to replace Red with a variable I have: actual_statuses[0] (0 index of list of statuses I obtain beforehand, actual value 'Green')

Upvotes: 0

Views: 327

Answers (1)

mdaniel
mdaniel

Reputation: 33231

It's hard to tell from your question whether that cited JSON is how ansible sees it, or you copied that from somewhere else and just assumed that is how ansible sees it

Either way, as best I can tell you're interested in inserting actual_values[0] into the place of the capture group in your regex, which isn't how that process works. In your case, you actually want everything except the capture group carried over, which means you don't care about the capture group's value, which means you shouldn't use a capture group

You also have an unusual .{1,5}? syntax which I'm guessing you mean as "either nothing, or a string of 1 to 5 characters," which in regex is expressed as .{0,5}

For your first problem, you'll want to ensure you and ansible are working with the same understanding about that data; that's what the | type_debug filter is for, since - debug: var=page.json can be misleading with all the jinja2 and stdout callback plugins that touch that data on the way back to your terminal.

Next, and this is kind of related to that, you'll want to know if some process in ansible that has touched that data has introduced escape characters in front of those " in your body.storage.value; my code snipped below works on the assumption they are not present, because your snippet assumed they were not present, but you'll want to verify that for sure. You don't have to leave that assert: in your final playbook, but it can help you ensure you're starting from the right place because if the regex_replace doesn't find any matches, it merely doesn't do anything, which can make it seem like it is silently failing. We want loud failures.

Finally, getting to the part you care about: your process is that you have a bunch of literal text, a variable part, and a bunch of literal text. While it might not be necessary, it is clearest to send that literal text through | regex_escape to let the computer do any regex quoting for you. Then, using that same literal text, tell regex_replace to swap out the variable part with the new bookends

    # <JUST FOR YOUR DEBUGGING>
    - debug:
        msg: It seems the type of page.json is {{ page.json | type_debug }}
    - assert:
        that:
        - 0 != (page.json | regex_findall('<ac:parameter ac:name="colour">') | length)
    # </JUST FOR YOUR DEBUGGING>

    - set_fact:
        page: >-
          {{ page.json | regex_replace(
            (head | regex_escape) + ".{0,5}" + (tail | regex_escape),
            head + actual_statuses[0] + tail) }}
      vars:
        head: '<ac:parameter ac:name="colour">'
        tail: '</ac:parameter><ac:parameter ac:name="title">ssh</ac:parameter>'
        actual_statuses:
        - Alpha
        - Beta
        - Charlie

produces:

...><ac:parameter ac:name="colour">Alpha</ac:parameter><ac:parameter ac:name="title">ssh<...

which is what I think you wanted

Upvotes: 1

Related Questions