如何使用 XML 模块在 Ansible 中删除 XML 文件中的某些节点?

问题描述 投票:0回答:3

我尝试从

activemq.xml
配置文件中删除一些节点。在这个文件中,我想删除除
tcp
之外的所有连接。

<beans
  xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
  http://activemq.apache.org/schema/core http://activemq.apache.org/schema/core/activemq-core.xsd">
...
   <broker xmlns="http://activemq.apache.org/schema/core" brokerName="localhost" dataDirectory="${activemq.data}">
   ...
        <transportConnectors>
            <!-- DOS protection, limit concurrent connections to 1000 and frame size to 100MB -->
            <transportConnector name="openwire" uri="tcp://0.0.0.0:61616?maximumConnections=1000&amp;wireFormat.maxFrameSize=104857600"/>
            <transportConnector name="amqp" uri="amqp://0.0.0.0:5672?maximumConnections=1000&amp;wireFormat.maxFrameSize=104857600"/>
            <transportConnector name="stomp" uri="stomp://0.0.0.0:61613?maximumConnections=1000&amp;wireFormat.maxFrameSize=104857600"/>
            <transportConnector name="mqtt" uri="mqtt://0.0.0.0:1883?maximumConnections=1000&amp;wireFormat.maxFrameSize=104857600"/>
            <transportConnector name="ws" uri="ws://0.0.0.0:61614?maximumConnections=1000&amp;wireFormat.maxFrameSize=104857600"/>
        </transportConnectors>
...
    </broker>
</beans>

我使用 Ansible

community.general.xml
模块

- name: Désactiver les autres protocoles de publication de message
  xml:
    path: /mypath/activemq-modif.xml
    xpath: "/ns:beans/broker:broker/broker:transportConnectors/broker:transportConnector[@name!='openwire']/*"
    state: absent
    namespaces:
      ns: http://www.springframework.org/schema/beans
      broker: http://activemq.apache.org/schema/core

当我运行剧本时,没有错误,但文件没有改变。

如果我按照模块文档示例中的说明删除

/*
,则会出现错误

fatal: [localhost]: FAILED! => {"changed": false, "msg": "Couldn't delete xpath target: /ns:beans/broker:broker/broker:transportConnectors/broker:transportConnector[@name!='openwire'] (module 'lxml.etree' has no attribute '_ElementStringResult')"}

如何删除(或评论)除

transportConnector
之外的所有
openwire
节点?

ansible-playbook [core 2.15.13]
  config file = None
  configured module search path = ['/root/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/local/lib/python3.9/site-packages/ansible
  ansible collection location = /root/.ansible/collections:/usr/share/ansible/collections
  executable location = /usr/local/bin/ansible-playbook
  python version = 3.9.18 (main, Oct  4 2024, 00:00:00) [GCC 11.4.1 20231218 (Red Hat 11.4.1-3)] (/usr/bin/python3)
  jinja version = 3.1.4
  libyaml = True

Package             Version
------------------- --------
ansible             8.7.0
lxml                5.3.0
xml ansible lxml
3个回答
2
投票

好的,我已经检查了模块代码

xml.py
。在第 435 行,一条评论提到了

lxml
5.1.1 删除了
etree._ElementStringResult
,所以我们不能再简单地假设它在那里

如果我将

lxml
降级到5.1.0,脚本就可以并且文档按照我的意愿进行更改!

似乎 Ansible

xml
模块 在 5.1.0 版本之后无法再正确使用
lxml
。所以我为此在 Github 上打开了一个问题。

谢谢。


1
投票

这是基于 XSLT 的解决方案,它利用所谓的“身份转换”模式。

输入XML

<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://activemq.apache.org/schema/core http://activemq.apache.org/schema/core/activemq-core.xsd">... <broker xmlns="http://activemq.apache.org/schema/core" brokerName="localhost" dataDirectory="${activemq.data}"> <transportConnectors> <!-- DOS protection, limit concurrent connections to 1000 and frame size to 100MB --> <transportConnector name="openwire" uri="tcp://0.0.0.0:61616?maximumConnections=1000&amp;wireFormat.maxFrameSize=104857600"/> <transportConnector name="amqp" uri="amqp://0.0.0.0:5672?maximumConnections=1000&amp;wireFormat.maxFrameSize=104857600"/> <transportConnector name="stomp" uri="stomp://0.0.0.0:61613?maximumConnections=1000&amp;wireFormat.maxFrameSize=104857600"/> <transportConnector name="mqtt" uri="mqtt://0.0.0.0:1883?maximumConnections=1000&amp;wireFormat.maxFrameSize=104857600"/> <transportConnector name="ws" uri="ws://0.0.0.0:61614?maximumConnections=1000&amp;wireFormat.maxFrameSize=104857600"/> </transportConnectors> </broker> </beans>

XSLT

<?xml version="1.0"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ns2="http://activemq.apache.org/schema/core"> <xsl:output omit-xml-declaration="yes" indent="yes"/> <xsl:strip-space elements="*"/> <!--Identity transform--> <xsl:template match="node()|@*"> <xsl:copy> <xsl:apply-templates select="node()|@*"/> </xsl:copy> </xsl:template> <xsl:template match="ns2:transportConnector[not(starts-with(@uri,'tcp:'))]"/> </xsl:stylesheet>

输出XML

<beans xmlns="http://www.springframework.org/schema/beans" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://activemq.apache.org/schema/core http://activemq.apache.org/schema/core/activemq-core.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <broker xmlns="http://activemq.apache.org/schema/core" dataDirectory="${activemq.data}" brokerName="localhost"> <transportConnectors> <!-- DOS protection, limit concurrent connections to 1000 and frame size to 100MB --> <transportConnector name="openwire" uri="tcp://0.0.0.0:61616?maximumConnections=1000&amp;wireFormat.maxFrameSize=104857600"/> </transportConnectors> </broker> </beans>



0
投票
如何在 Ansible 中过滤 XML 属性?

如何用 Ansible 替换 XML 元素的文本?,一个带有 activemq.xml

 的最小示例
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://activemq.apache.org/schema/core http://activemq.apache.org/schema/core/activemq-core.xsd"> <broker xmlns="http://activemq.apache.org/schema/core" brokerName="localhost" dataDirectory="${activemq.data}"> <transportConnectors> <!-- DOS protection, limit concurrent connections to 1000 and frame size to 100MB --> <transportConnector name="openwire" uri="tcp://0.0.0.0:61616?maximumConnections=1000&amp;wireFormat.maxFrameSize=104857600"/> <transportConnector name="amqp" uri="amqp://0.0.0.0:5672?maximumConnections=1000&amp;wireFormat.maxFrameSize=104857600"/> <transportConnector name="stomp" uri="stomp://0.0.0.0:61613?maximumConnections=1000&amp;wireFormat.maxFrameSize=104857600"/> <transportConnector name="mqtt" uri="mqtt://0.0.0.0:1883?maximumConnections=1000&amp;wireFormat.maxFrameSize=104857600"/> <transportConnector name="ws" uri="ws://0.0.0.0:61614?maximumConnections=1000&amp;wireFormat.maxFrameSize=104857600"/> </transportConnectors> </broker> </beans>

和剧本
xml.yml

---
- hosts: localhost
  become: false
  gather_facts: false

  vars:

    XML: "{{ lookup('file', 'activemq.xml') }}"

  tasks:

  - name: Convert XML to YML
    set_fact:
      YML: "{{ XML | ansible.utils.from_xml }}"

  - name: Show content
    debug:
      msg: "{{ YML }}"

  # Drop all transportConnector except the first in list

  - name: Update path
    ansible.utils.update_fact:
      updates:
        - path: "YML.beans.broker.transportConnectors.transportConnector"
          value: "{{ YML.beans.broker.transportConnectors.transportConnector[0] }}"
    register: updated

  - name: Show updated content
    debug:
      msg: "{{ updated.YML | ansible.utils.to_xml }}"

  - name: Write out XML file
    copy:
      dest: updated.activemq.xml
      content: "{{ updated.YML | ansible.utils.to_xml }}"

将生成一个 
updated.activemq.xml

文件

<?xml version="1.0" encoding="utf-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd       http://activemq.apache.org/schema/core http://activemq.apache.org/schema/core/activemq-core.xsd">
        <broker xmlns="http://activemq.apache.org/schema/core" brokerName="localhost" dataDirectory="${activemq.data}">
                <transportConnectors>
                        <transportConnector name="openwire" uri="tcp://0.0.0.0:61616?maximumConnections=1000&amp;wireFormat.maxFrameSize=104857600"></transportConnector>
                </transportConnectors>
        </broker>
</beans>

这是因为

xml模块

需要

在执行此模块的主机上。

lxml >= 2.3.0



并且依赖于它,而

from_xml 过滤器

 则不依赖于它。
如果您喜欢

从列表中选择一个特定的项目值

,例如按名称 - name: Show 'openwire' from transportConnectors debug: msg: "{{ YML.beans.broker.transportConnectors.transportConnector | selectattr('@name', '==', 'openwire') }}"

更新可以通过
完成

# Drop all transportConnector except with name 'openwire' - name: Update path ansible.utils.update_fact: updates: - path: "YML.beans.broker.transportConnectors.transportConnector" value: "{{ YML.beans.broker.transportConnectors.transportConnector | selectattr('@name', '==', 'openwire') }}" register: updated

	
© www.soinside.com 2019 - 2024. All rights reserved.