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:
parent
3f2213791a
commit
340ff8586d
1008 changed files with 61301 additions and 58309 deletions
|
|
@ -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()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue