1
0
Fork 0
mirror of https://github.com/ansible-collections/community.general.git synced 2026-04-03 18:56:55 +00:00

Reformat everything.

This commit is contained in:
Felix Fontein 2025-11-01 12:08:41 +01:00
parent 3f2213791a
commit 340ff8586d
1008 changed files with 61301 additions and 58309 deletions

View file

@ -369,6 +369,7 @@ from ansible_collections.community.general.plugins.module_utils.version import L
LXML_IMP_ERR = None
try:
from lxml import etree, objectify
HAS_LXML = True
except ImportError:
LXML_IMP_ERR = traceback.format_exc()
@ -384,17 +385,17 @@ _NSIDENT = f"{_IDENT}|{_IDENT}:{_IDENT}"
_XPSTR = "('(?:.*)'|\"(?:.*)\")"
_RE_SPLITSIMPLELAST = re.compile(f"^(.*)/({_NSIDENT})$")
_RE_SPLITSIMPLELASTEQVALUE = re.compile(f'^(.*)/({_NSIDENT}' + ')/text\\(\\)=' + _XPSTR + '$')
_RE_SPLITSIMPLELASTEQVALUE = re.compile(f"^(.*)/({_NSIDENT}" + ")/text\\(\\)=" + _XPSTR + "$")
_RE_SPLITSIMPLEATTRLAST = re.compile(f"^(.*)/(@(?:{_NSIDENT}))$")
_RE_SPLITSIMPLEATTRLASTEQVALUE = re.compile(f"^(.*)/(@(?:{_NSIDENT}))={_XPSTR}$")
_RE_SPLITSUBLAST = re.compile(f'^(.*)/({_NSIDENT}' + ')\\[(.*)\\]$')
_RE_SPLITSUBLAST = re.compile(f"^(.*)/({_NSIDENT}" + ")\\[(.*)\\]$")
_RE_SPLITONLYEQVALUE = re.compile("^(.*)/text\\(\\)=" + _XPSTR + "$")
def has_changed(doc):
orig_obj = etree.tostring(objectify.fromstring(etree.tostring(orig_doc)))
obj = etree.tostring(objectify.fromstring(etree.tostring(doc)))
return (orig_obj != obj)
return orig_obj != obj
def do_print_match(module, tree, xpath, namespaces):
@ -408,14 +409,14 @@ def do_print_match(module, tree, xpath, namespaces):
def count_nodes(module, tree, xpath, namespaces):
""" Return the count of nodes matching the xpath """
"""Return the count of nodes matching the xpath"""
hits = tree.xpath(f"count(/{xpath})", namespaces=namespaces)
msg = f"found {hits} nodes"
finish(module, tree, xpath, namespaces, changed=False, msg=msg, hitcount=int(hits))
def is_node(tree, xpath, namespaces):
""" Test if a given xpath matches anything and if that match is a node.
"""Test if a given xpath matches anything and if that match is a node.
For now we just assume you're only searching for one specific thing."""
if xpath_matches(tree, xpath, namespaces):
@ -428,13 +429,13 @@ def is_node(tree, xpath, namespaces):
def is_attribute(tree, xpath, namespaces):
""" Test if a given xpath matches and that match is an attribute
"""Test if a given xpath matches and that match is an attribute
An xpath attribute search will only match one item"""
# lxml 5.1.1 removed etree._ElementStringResult, so we can no longer simply assume it is there
# (https://github.com/lxml/lxml/commit/eba79343d0e7ad1ce40169f60460cdd4caa29eb3)
ElementStringResult = getattr(etree, '_ElementStringResult', None)
ElementStringResult = getattr(etree, "_ElementStringResult", None)
if xpath_matches(tree, xpath, namespaces):
match = tree.xpath(xpath, namespaces=namespaces)
@ -446,14 +447,14 @@ def is_attribute(tree, xpath, namespaces):
def xpath_matches(tree, xpath, namespaces):
""" Test if a node exists """
"""Test if a node exists"""
if tree.xpath(xpath, namespaces=namespaces):
return True
return False
def delete_xpath_target(module, tree, xpath, namespaces):
""" Delete an attribute or element from a tree """
"""Delete an attribute or element from a tree"""
changed = False
try:
for result in tree.xpath(xpath, namespaces=namespaces):
@ -593,7 +594,9 @@ def nsnameToClark(name, namespaces):
def check_or_make_target(module, tree, xpath, namespaces):
(inner_xpath, changes) = split_xpath_last(xpath)
if (inner_xpath == xpath) or (changes is None):
module.fail_json(msg=f"Can't process Xpath {xpath} in order to spawn nodes! tree is {etree.tostring(tree, pretty_print=True)}")
module.fail_json(
msg=f"Can't process Xpath {xpath} in order to spawn nodes! tree is {etree.tostring(tree, pretty_print=True)}"
)
return False
changed = False
@ -603,8 +606,8 @@ def check_or_make_target(module, tree, xpath, namespaces):
# we test again after calling check_or_make_target
if is_node(tree, inner_xpath, namespaces) and changes:
for (eoa, eoa_value) in changes:
if eoa and eoa[0] != '@' and eoa[0] != '/':
for eoa, eoa_value in changes:
if eoa and eoa[0] != "@" and eoa[0] != "/":
# implicitly creating an element
new_kids = children_to_nodes(module, [nsnameToClark(eoa, namespaces)], "yaml")
if eoa_value:
@ -615,7 +618,7 @@ def check_or_make_target(module, tree, xpath, namespaces):
node.extend(new_kids)
changed = True
# module.fail_json(msg="now tree=%s" % etree.tostring(tree, pretty_print=True))
elif eoa and eoa[0] == '/':
elif eoa and eoa[0] == "/":
element = eoa[1:]
new_kids = children_to_nodes(module, [nsnameToClark(element, namespaces)], "yaml")
for node in tree.xpath(inner_xpath, namespaces=namespaces):
@ -634,11 +637,11 @@ def check_or_make_target(module, tree, xpath, namespaces):
node.text = eoa_value
changed = True
elif eoa and eoa[0] == '@':
elif eoa and eoa[0] == "@":
attribute = nsnameToClark(eoa[1:], namespaces)
for element in tree.xpath(inner_xpath, namespaces=namespaces):
changing = (attribute not in element.attrib or element.attrib[attribute] != eoa_value)
changing = attribute not in element.attrib or element.attrib[attribute] != eoa_value
if changing:
changed = changed or changing
@ -678,11 +681,15 @@ def set_target_inner(module, tree, xpath, namespaces, attribute, value):
# TODO: Implement a more robust check to check for child namespaces' existence
if tree.getroot().nsmap and ":" not in xpath:
missing_namespace = "XML document has namespace(s) defined, but no namespace prefix(es) used in xpath!\n"
module.fail_json(msg=f"{missing_namespace}Xpath {xpath} causes a failure: {e}\n -- tree is {etree.tostring(tree, pretty_print=True)}",
exception=traceback.format_exc())
module.fail_json(
msg=f"{missing_namespace}Xpath {xpath} causes a failure: {e}\n -- tree is {etree.tostring(tree, pretty_print=True)}",
exception=traceback.format_exc(),
)
if not is_node(tree, xpath, namespaces):
module.fail_json(msg=f"Xpath {xpath} does not reference a node! tree is {etree.tostring(tree, pretty_print=True)}")
module.fail_json(
msg=f"Xpath {xpath} does not reference a node! tree is {etree.tostring(tree, pretty_print=True)}"
)
for element in tree.xpath(xpath, namespaces=namespaces):
if not attribute:
@ -733,8 +740,8 @@ def get_element_attr(module, tree, xpath, namespaces):
def child_to_element(module, child, in_type):
if in_type == 'xml':
infile = BytesIO(to_bytes(child, errors='surrogate_or_strict'))
if in_type == "xml":
infile = BytesIO(to_bytes(child, errors="surrogate_or_strict"))
try:
parser = etree.XMLParser()
@ -742,7 +749,7 @@ def child_to_element(module, child, in_type):
return node.getroot()
except etree.XMLSyntaxError as e:
module.fail_json(msg=f"Error while parsing child element: {e}")
elif in_type == 'yaml':
elif in_type == "yaml":
if isinstance(child, str):
return etree.Element(child)
elif isinstance(child, MutableMapping):
@ -751,8 +758,8 @@ def child_to_element(module, child, in_type):
(key, value) = list(child.items())[0]
if isinstance(value, MutableMapping):
children = value.pop('_', None)
child_value = value.pop('+value', None)
children = value.pop("_", None)
child_value = value.pop("+value", None)
node = etree.Element(key, value)
@ -775,7 +782,7 @@ def child_to_element(module, child, in_type):
module.fail_json(msg=f"Invalid child input type: {in_type}. Type must be either xml or yaml.")
def children_to_nodes(module=None, children=None, type='yaml'):
def children_to_nodes(module=None, children=None, type="yaml"):
"""turn a str/hash/list of str&hash into a list of elements"""
children = [] if children is None else children
@ -783,65 +790,71 @@ def children_to_nodes(module=None, children=None, type='yaml'):
def make_pretty(module, tree):
xml_string = etree.tostring(tree, xml_declaration=True, encoding='UTF-8', pretty_print=module.params['pretty_print'])
xml_string = etree.tostring(
tree, xml_declaration=True, encoding="UTF-8", pretty_print=module.params["pretty_print"]
)
result = dict(
changed=False,
)
if module.params['path']:
xml_file = module.params['path']
with open(xml_file, 'rb') as xml_content:
if module.params["path"]:
xml_file = module.params["path"]
with open(xml_file, "rb") as xml_content:
if xml_string != xml_content.read():
result['changed'] = True
result["changed"] = True
if not module.check_mode:
if module.params['backup']:
result['backup_file'] = module.backup_local(module.params['path'])
tree.write(xml_file, xml_declaration=True, encoding='UTF-8', pretty_print=module.params['pretty_print'])
if module.params["backup"]:
result["backup_file"] = module.backup_local(module.params["path"])
tree.write(
xml_file, xml_declaration=True, encoding="UTF-8", pretty_print=module.params["pretty_print"]
)
elif module.params['xmlstring']:
result['xmlstring'] = xml_string
elif module.params["xmlstring"]:
result["xmlstring"] = xml_string
# NOTE: Modifying a string is not considered a change !
if xml_string != module.params['xmlstring']:
result['changed'] = True
if xml_string != module.params["xmlstring"]:
result["changed"] = True
module.exit_json(**result)
def finish(module, tree, xpath, namespaces, changed=False, msg='', hitcount=0, matches=tuple()):
def finish(module, tree, xpath, namespaces, changed=False, msg="", hitcount=0, matches=tuple()):
result = dict(
actions=dict(
xpath=xpath,
namespaces=namespaces,
state=module.params['state']
),
actions=dict(xpath=xpath, namespaces=namespaces, state=module.params["state"]),
changed=has_changed(tree),
)
if module.params['count'] or hitcount:
result['count'] = hitcount
if module.params["count"] or hitcount:
result["count"] = hitcount
if module.params['print_match'] or matches:
result['matches'] = matches
if module.params["print_match"] or matches:
result["matches"] = matches
if msg:
result['msg'] = msg
result["msg"] = msg
if result['changed']:
if result["changed"]:
if module._diff:
result['diff'] = dict(
before=etree.tostring(orig_doc, xml_declaration=True, encoding='UTF-8', pretty_print=True),
after=etree.tostring(tree, xml_declaration=True, encoding='UTF-8', pretty_print=True),
result["diff"] = dict(
before=etree.tostring(orig_doc, xml_declaration=True, encoding="UTF-8", pretty_print=True),
after=etree.tostring(tree, xml_declaration=True, encoding="UTF-8", pretty_print=True),
)
if module.params['path'] and not module.check_mode:
if module.params['backup']:
result['backup_file'] = module.backup_local(module.params['path'])
tree.write(module.params['path'], xml_declaration=True, encoding='UTF-8', pretty_print=module.params['pretty_print'])
if module.params["path"] and not module.check_mode:
if module.params["backup"]:
result["backup_file"] = module.backup_local(module.params["path"])
tree.write(
module.params["path"],
xml_declaration=True,
encoding="UTF-8",
pretty_print=module.params["pretty_print"],
)
if module.params['xmlstring']:
result['xmlstring'] = etree.tostring(tree, xml_declaration=True, encoding='UTF-8', pretty_print=module.params['pretty_print'])
if module.params["xmlstring"]:
result["xmlstring"] = etree.tostring(
tree, xml_declaration=True, encoding="UTF-8", pretty_print=module.params["pretty_print"]
)
module.exit_json(**result)
@ -849,84 +862,84 @@ def finish(module, tree, xpath, namespaces, changed=False, msg='', hitcount=0, m
def main():
module = AnsibleModule(
argument_spec=dict(
path=dict(type='path', aliases=['dest', 'file']),
xmlstring=dict(type='str'),
xpath=dict(type='str'),
namespaces=dict(type='dict', default={}),
state=dict(type='str', default='present', choices=['absent', 'present'], aliases=['ensure']),
value=dict(type='raw'),
attribute=dict(type='raw'),
add_children=dict(type='list', elements='raw'),
set_children=dict(type='list', elements='raw'),
count=dict(type='bool', default=False),
print_match=dict(type='bool', default=False),
pretty_print=dict(type='bool', default=False),
content=dict(type='str', choices=['attribute', 'text']),
input_type=dict(type='str', default='yaml', choices=['xml', 'yaml']),
backup=dict(type='bool', default=False),
strip_cdata_tags=dict(type='bool', default=False),
insertbefore=dict(type='bool', default=False),
insertafter=dict(type='bool', default=False),
path=dict(type="path", aliases=["dest", "file"]),
xmlstring=dict(type="str"),
xpath=dict(type="str"),
namespaces=dict(type="dict", default={}),
state=dict(type="str", default="present", choices=["absent", "present"], aliases=["ensure"]),
value=dict(type="raw"),
attribute=dict(type="raw"),
add_children=dict(type="list", elements="raw"),
set_children=dict(type="list", elements="raw"),
count=dict(type="bool", default=False),
print_match=dict(type="bool", default=False),
pretty_print=dict(type="bool", default=False),
content=dict(type="str", choices=["attribute", "text"]),
input_type=dict(type="str", default="yaml", choices=["xml", "yaml"]),
backup=dict(type="bool", default=False),
strip_cdata_tags=dict(type="bool", default=False),
insertbefore=dict(type="bool", default=False),
insertafter=dict(type="bool", default=False),
),
supports_check_mode=True,
required_by=dict(
add_children=['xpath'],
attribute=['value'],
content=['xpath'],
set_children=['xpath'],
value=['xpath'],
add_children=["xpath"],
attribute=["value"],
content=["xpath"],
set_children=["xpath"],
value=["xpath"],
),
required_if=[
['count', True, ['xpath']],
['print_match', True, ['xpath']],
['insertbefore', True, ['xpath']],
['insertafter', True, ['xpath']],
["count", True, ["xpath"]],
["print_match", True, ["xpath"]],
["insertbefore", True, ["xpath"]],
["insertafter", True, ["xpath"]],
],
required_one_of=[
['path', 'xmlstring'],
['add_children', 'content', 'count', 'pretty_print', 'print_match', 'set_children', 'value'],
["path", "xmlstring"],
["add_children", "content", "count", "pretty_print", "print_match", "set_children", "value"],
],
mutually_exclusive=[
['add_children', 'content', 'count', 'print_match', 'set_children', 'value'],
['path', 'xmlstring'],
['insertbefore', 'insertafter'],
["add_children", "content", "count", "print_match", "set_children", "value"],
["path", "xmlstring"],
["insertbefore", "insertafter"],
],
)
xml_file = module.params['path']
xml_string = module.params['xmlstring']
xpath = module.params['xpath']
namespaces = module.params['namespaces']
state = module.params['state']
value = json_dict_bytes_to_unicode(module.params['value'])
attribute = module.params['attribute']
set_children = json_dict_bytes_to_unicode(module.params['set_children'])
add_children = json_dict_bytes_to_unicode(module.params['add_children'])
pretty_print = module.params['pretty_print']
content = module.params['content']
input_type = module.params['input_type']
print_match = module.params['print_match']
count = module.params['count']
backup = module.params['backup']
strip_cdata_tags = module.params['strip_cdata_tags']
insertbefore = module.params['insertbefore']
insertafter = module.params['insertafter']
xml_file = module.params["path"]
xml_string = module.params["xmlstring"]
xpath = module.params["xpath"]
namespaces = module.params["namespaces"]
state = module.params["state"]
value = json_dict_bytes_to_unicode(module.params["value"])
attribute = module.params["attribute"]
set_children = json_dict_bytes_to_unicode(module.params["set_children"])
add_children = json_dict_bytes_to_unicode(module.params["add_children"])
pretty_print = module.params["pretty_print"]
content = module.params["content"]
input_type = module.params["input_type"]
print_match = module.params["print_match"]
count = module.params["count"]
backup = module.params["backup"]
strip_cdata_tags = module.params["strip_cdata_tags"]
insertbefore = module.params["insertbefore"]
insertafter = module.params["insertafter"]
# Check if we have lxml 2.3.0 or newer installed
if not HAS_LXML:
module.fail_json(msg=missing_required_lib("lxml"), exception=LXML_IMP_ERR)
elif LooseVersion('.'.join(to_native(f) for f in etree.LXML_VERSION)) < LooseVersion('2.3.0'):
module.fail_json(msg='The xml ansible module requires lxml 2.3.0 or newer installed on the managed machine')
elif LooseVersion('.'.join(to_native(f) for f in etree.LXML_VERSION)) < LooseVersion('3.0.0'):
module.warn('Using lxml version lower than 3.0.0 does not guarantee predictable element attribute order.')
elif LooseVersion(".".join(to_native(f) for f in etree.LXML_VERSION)) < LooseVersion("2.3.0"):
module.fail_json(msg="The xml ansible module requires lxml 2.3.0 or newer installed on the managed machine")
elif LooseVersion(".".join(to_native(f) for f in etree.LXML_VERSION)) < LooseVersion("3.0.0"):
module.warn("Using lxml version lower than 3.0.0 does not guarantee predictable element attribute order.")
infile = None
try:
# Check if the file exists
if xml_string:
infile = BytesIO(to_bytes(xml_string, errors='surrogate_or_strict'))
infile = BytesIO(to_bytes(xml_string, errors="surrogate_or_strict"))
elif os.path.isfile(xml_file):
infile = open(xml_file, 'rb')
infile = open(xml_file, "rb")
else:
module.fail_json(msg=f"The target XML source '{xml_file}' does not exist.")
@ -959,13 +972,13 @@ def main():
if count:
count_nodes(module, doc, xpath, namespaces)
if content == 'attribute':
if content == "attribute":
get_element_attr(module, doc, xpath, namespaces)
elif content == 'text':
elif content == "text":
get_element_text(module, doc, xpath, namespaces)
# File exists:
if state == 'absent':
if state == "absent":
# - absent: delete xpath target
delete_xpath_target(module, doc, xpath, namespaces)
@ -999,5 +1012,5 @@ def main():
module.fail_json(msg="Don't know what to do")
if __name__ == '__main__':
if __name__ == "__main__":
main()