2016-10-04 54 views
0

我需要修改文件中的一行。只有問題,該線出現多次,但在不同的範圍。像在從WSO2組態手冊這個例子:用Ansible修改示波器中的一行

<KeyStore> 
    <Location>${carbon.home}/resources/security/wso2carbon.jks</Location> 
    <Type>JKS</Type> 
    <Password>wso2carbon</Password> 
    <KeyAlias>wso2carbon</KeyAlias> 
    <KeyPassword>wso2carbon</KeyPassword> 
</KeyStore> 

<TrustStore> 
    <!-- trust-store file location --> 
    <Location>${carbon.home}/repository/resources/security/client-truststore.jks</Location> 
    <!-- trust-store type (JKS/PKCS12 etc.) --> 
    <Type>JKS</Type> 
    <!-- trust-store password --> 
    <Password>wso2carbon</Password> 
</TrustStore> 

我需要例如修改<Password>條目與一個值在<Keystore>範圍,並與不同的第二值在<TrustStore>範圍,以有不同的密碼。 lineinfile模塊可以這樣做嗎?或者還有其他方法嗎?

PS。 使用模板不是我正在尋找的解決方案,因爲我想用它來修改已存在的服務器並且不會丟失任何本地修改。

回答

0

你不能用lineinfile來做到這一點,因爲它分開處理文件的每一行 - 所以沒有其他行可能的上下文。
正則表達式lineinfile不是多行。

您可以使用replace - 它使用多行正則表達式。
例如:

- replace: 
    backup: yes 
    dest: config.xml 
    regexp: '(<{{ item.scope }}>[\S\s]*<Password>)(?!{{ item.password }}<).*(</Password>[\S\s]*</{{ item.scope }}>)' 
    replace: '\1{{ item.password }}\2' 
    with_items: 
    - scope: KeyStore 
     password: foo 
    - scope: TrustStore 
     password: bar 

請記住,這個解決方案是不防彈 - 範圍的名稱和密碼,不應該有任何XML特殊字符或正則表達式序列。我也無法確定它是如何處理具有相同作用域名稱的嵌套XML塊的。
但一般情況下,它應該沒問題。
甚至有一種嘗試是冪等的 - 如果密碼相同,它將不會與塊匹配。

+0

謝謝,您的解決方案完美工作。該模塊的工作原理和您提出的解決方案是完美的,但我不確定負面預測分組(最後的'<'使我感到困惑)。這裏我嘗試過的這一行也起作用,我可以理解''' - name:替換模塊的測試 replace:dest =/tmp/carbon.xml regexp ='(\ s * )((?:\ n。 *)*)()(。*)()((?:\ n。*)*)()'替換='\ 1 \ 2 \ 3ThePassWord \ 5 \ 6 \ 7'backup = yes' '。我會upvote你的答案,但我沒有足夠的聲譽。 –

+0

使用'password <'的負向前視意味着跳過已設置密碼的塊(沒有它,您的任務將始終返回已更改的狀態),並且添加了<<'以避免當密碼爲'foobar'時您想將其設置爲'foo' - 在這種情況下,前面沒有'<'將匹配'foobar'的一部分,並且密碼不會被改變。 –

0

Ansible lineinfileregex參數可以匹配多行。除了那個正則表達式會很長並且很難理解和維護之外,沒有任何問題。

正如你試圖操縱XMLansible-xml模塊可能是一個很好的選擇來解決這個問題。