mirror of
https://github.com/ansible-collections/community.general.git
synced 2024-09-14 20:13:21 +02:00
xml module: Make user interface much more restricted (#28657)
So the xml module has a lot of parameters that combined together do specific things. however it does not really describe which parameters are required together, or which ones are required. This PR fixes that situation and makes it impossible to provide confussing parameters combinations. Also, `pretty_print` was used as a flag to modify the output, but also as an action to reformat the file (without other change). This is problematic the way it was designed. This fixes that too. This fixes #28194
This commit is contained in:
parent
75293d83ca
commit
11c9756d9c
1 changed files with 43 additions and 21 deletions
|
@ -224,13 +224,13 @@ xmlstring:
|
||||||
returned: when parameter 'xmlstring' is set
|
returned: when parameter 'xmlstring' is set
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
import copy
|
||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
import traceback
|
import traceback
|
||||||
|
|
||||||
from collections import MutableMapping
|
from collections import MutableMapping
|
||||||
import copy
|
|
||||||
from distutils.version import LooseVersion
|
from distutils.version import LooseVersion
|
||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
|
|
||||||
|
@ -675,11 +675,11 @@ def main():
|
||||||
argument_spec=dict(
|
argument_spec=dict(
|
||||||
path=dict(type='path', aliases=['dest', 'file']),
|
path=dict(type='path', aliases=['dest', 'file']),
|
||||||
xmlstring=dict(type='str'),
|
xmlstring=dict(type='str'),
|
||||||
xpath=dict(type='str', default='/'),
|
xpath=dict(type='str'),
|
||||||
namespaces=dict(type='dict', default={}),
|
namespaces=dict(type='dict', default={}),
|
||||||
state=dict(type='str', default='present', choices=['absent', 'present'], aliases=['ensure']),
|
state=dict(type='str', default='present', choices=['absent', 'present'], aliases=['ensure']),
|
||||||
value=dict(),
|
value=dict(type='raw'),
|
||||||
attribute=dict(),
|
attribute=dict(type='raw'),
|
||||||
add_children=dict(type='list'),
|
add_children=dict(type='list'),
|
||||||
set_children=dict(type='list'),
|
set_children=dict(type='list'),
|
||||||
count=dict(type='bool', default=False),
|
count=dict(type='bool', default=False),
|
||||||
|
@ -690,15 +690,27 @@ def main():
|
||||||
backup=dict(type='bool', default=False),
|
backup=dict(type='bool', default=False),
|
||||||
),
|
),
|
||||||
supports_check_mode=True,
|
supports_check_mode=True,
|
||||||
mutually_exclusive=[
|
# TODO: Implement this as soon as #28662 (required_by functionality) is merged
|
||||||
['value', 'set_children'],
|
# required_by=dict(
|
||||||
['value', 'add_children'],
|
# add_children=['xpath'],
|
||||||
['set_children', 'add_children'],
|
# attribute=['value'],
|
||||||
|
# set_children=['xpath'],
|
||||||
|
# value=['xpath'],
|
||||||
|
# ),
|
||||||
|
required_if=[
|
||||||
|
['content', 'attribute', ['xpath']],
|
||||||
|
['content', 'text', ['xpath']],
|
||||||
|
['count', True, ['xpath']],
|
||||||
|
['print_match', True, ['xpath']],
|
||||||
|
],
|
||||||
|
required_one_of=[
|
||||||
['path', 'xmlstring'],
|
['path', 'xmlstring'],
|
||||||
['content', 'set_children'],
|
['add_children', 'content', 'count', 'pretty_print', 'print_match', 'set_children', 'value'],
|
||||||
['content', 'add_children'],
|
],
|
||||||
['content', 'value'],
|
mutually_exclusive=[
|
||||||
]
|
['add_children', 'content', 'count', 'print_match', 'set_children', 'value'],
|
||||||
|
['path', 'xmlstring'],
|
||||||
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
xml_file = module.params['path']
|
xml_file = module.params['path']
|
||||||
|
@ -734,7 +746,7 @@ def main():
|
||||||
module.fail_json(msg="The target XML source '%s' does not exist." % xml_file)
|
module.fail_json(msg="The target XML source '%s' does not exist." % xml_file)
|
||||||
|
|
||||||
# Parse and evaluate xpath expression
|
# Parse and evaluate xpath expression
|
||||||
if xpath:
|
if xpath is not None:
|
||||||
try:
|
try:
|
||||||
etree.XPath(xpath)
|
etree.XPath(xpath)
|
||||||
except etree.XPathSyntaxError as e:
|
except etree.XPathSyntaxError as e:
|
||||||
|
@ -755,24 +767,25 @@ def main():
|
||||||
|
|
||||||
if print_match:
|
if print_match:
|
||||||
do_print_match(module, doc, xpath, namespaces)
|
do_print_match(module, doc, xpath, namespaces)
|
||||||
|
# exit
|
||||||
|
|
||||||
if count:
|
if count:
|
||||||
count_nodes(module, doc, xpath, namespaces)
|
count_nodes(module, doc, xpath, namespaces)
|
||||||
|
# exit
|
||||||
|
|
||||||
if content == 'attribute':
|
if content == 'attribute':
|
||||||
get_element_attr(module, doc, xpath, namespaces)
|
get_element_attr(module, doc, xpath, namespaces)
|
||||||
|
# exit
|
||||||
elif content == 'text':
|
elif content == 'text':
|
||||||
get_element_text(module, doc, xpath, namespaces)
|
get_element_text(module, doc, xpath, namespaces)
|
||||||
|
# exit
|
||||||
# module.fail_json(msg="OK. Well, etree parsed the xml file...")
|
|
||||||
|
|
||||||
# module.exit_json(what_did={"foo": "bar"}, changed=True)
|
|
||||||
|
|
||||||
# File exists:
|
# File exists:
|
||||||
if state == 'absent':
|
if state == 'absent':
|
||||||
# - absent: delete xpath target
|
# - absent: delete xpath target
|
||||||
delete_xpath_target(module, doc, xpath, namespaces)
|
delete_xpath_target(module, doc, xpath, namespaces)
|
||||||
# Exit
|
# exit
|
||||||
|
|
||||||
# - present: carry on
|
# - present: carry on
|
||||||
|
|
||||||
# children && value both set?: should have already aborted by now
|
# children && value both set?: should have already aborted by now
|
||||||
|
@ -781,23 +794,32 @@ def main():
|
||||||
# set_children set?
|
# set_children set?
|
||||||
if set_children:
|
if set_children:
|
||||||
set_target_children(module, doc, xpath, namespaces, set_children, input_type)
|
set_target_children(module, doc, xpath, namespaces, set_children, input_type)
|
||||||
|
# exit
|
||||||
|
|
||||||
# add_children set?
|
# add_children set?
|
||||||
if add_children:
|
if add_children:
|
||||||
add_target_children(module, doc, xpath, namespaces, add_children, input_type)
|
add_target_children(module, doc, xpath, namespaces, add_children, input_type)
|
||||||
|
# exit
|
||||||
|
|
||||||
# No?: Carry on
|
# No?: Carry on
|
||||||
|
|
||||||
# Is the xpath target an attribute selector?
|
# Is the xpath target an attribute selector?
|
||||||
if value is not None:
|
if value is not None:
|
||||||
set_target(module, doc, xpath, namespaces, attribute, value)
|
set_target(module, doc, xpath, namespaces, attribute, value)
|
||||||
|
# exit
|
||||||
|
|
||||||
# Format the xml only?
|
# If an xpath was provided, we need to do something with the data
|
||||||
if pretty_print:
|
if xpath is not None:
|
||||||
pretty(module, doc)
|
|
||||||
|
|
||||||
ensure_xpath_exists(module, doc, xpath, namespaces)
|
ensure_xpath_exists(module, doc, xpath, namespaces)
|
||||||
# module.fail_json(msg="don't know what to do")
|
# exit
|
||||||
|
|
||||||
|
# Otherwise only reformat the xml data?
|
||||||
|
if pretty_print:
|
||||||
|
xpath = '/'
|
||||||
|
pretty(module, doc)
|
||||||
|
# exit
|
||||||
|
|
||||||
|
module.fail_json(msg="Don't know what to do")
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
|
Loading…
Reference in a new issue