Skip to content

Commit

Permalink
Dev: crmshmod: Improve parse logic for corner cases
Browse files Browse the repository at this point in the history
* Parse multi interface/node as list in the dict
* When there is no space between words in corosync.conf, like "totem{" or "ring0_addr:10.10.10.121",
  corosync still works, but our parse results are wrong
  • Loading branch information
liangxin1300 committed Mar 14, 2021
1 parent 2bcc2e7 commit 3c4aa36
Showing 1 changed file with 38 additions and 9 deletions.
47 changes: 38 additions & 9 deletions salt/states/crmshmod.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@

# Import python libs
from __future__ import absolute_import, unicode_literals, print_function
import re


# Import salt libs
Expand Down Expand Up @@ -298,11 +299,23 @@ def cluster_configured(
return ret


def _convert2dict(file_content_lines):
def _find_dup_items(fstream):
"""
Find duplicated section name set
"""
sec_list = re.findall("(\w+)\s*{", fstream)
return set([x for x in sec_list if sec_list.count(x) > 1])


DUMMY_SEC_NAME_TEMPL = "__{}_list"


def _convert2dict(file_content_lines, dup_sec_set=()):
"""
Convert the corosync configuration file to a dictionary
"""
corodict = {}
sub_dict = {}
index = 0

for i, line in enumerate(file_content_lines):
Expand All @@ -313,19 +326,27 @@ def _convert2dict(file_content_lines):
if index > i:
continue

line_items = stripped_line.split()
if '{' in stripped_line:
corodict[line_items[0]], new_index = _convert2dict(file_content_lines[i+1:])
sub_dict, new_index = _convert2dict(file_content_lines[i+1:], dup_sec_set)
sec_name = re.sub("\s*{", "", stripped_line)
if sec_name in dup_sec_set:
dummpy_sec_name = DUMMY_SEC_NAME_TEMPL.format(sec_name)
if dummpy_sec_name not in corodict:
corodict[dummpy_sec_name] = []
corodict[dummpy_sec_name].append({sec_name: sub_dict})
else:
corodict[sec_name] = sub_dict
index = i + new_index
elif line_items[0][-1] == ':':
corodict[line_items[0][:-1]] = line_items[-1]
elif ':' in stripped_line:
key, *values = stripped_line.split(':')
corodict[key] = ':'.join(values).strip()
elif '}' in stripped_line:
return corodict, i+2

return corodict, index


def _mergedicts(main_dict, changes_dict, applied_changes, initial_path=''):
def _mergedicts(main_dict, changes_dict, applied_changes, initial_path='', index=0):
"""
Merge the 2 dictionaries. We cannot use update as it changes all the children of an entry
"""
Expand All @@ -336,10 +357,13 @@ def _mergedicts(main_dict, changes_dict, applied_changes, initial_path=''):
applied_changes[current_path] = value
main_dict[key] = value
elif key in main_dict.keys():
modified_dict, new_changes = _mergedicts(main_dict[key], value, applied_changes, current_path)
modified_dict, new_changes = _mergedicts(main_dict[key], value, applied_changes, current_path, index)
main_dict[key] = modified_dict
applied_changes.update(new_changes)

elif DUMMY_SEC_NAME_TEMPL.format(key) in main_dict.keys():
modified_dict, new_changes = _mergedicts(main_dict[DUMMY_SEC_NAME_TEMPL.format(key)][index][key], value, applied_changes, current_path, index)
main_dict[DUMMY_SEC_NAME_TEMPL.format(key)][index][key] = modified_dict
applied_changes.update(new_changes)
else: # Entry not found in current main dictionary, so we can update all
main_dict[key] = changes_dict[key]
applied_changes[current_path] = value
Expand All @@ -359,6 +383,9 @@ def _convert2corosync(corodict, indentation=''):
output += _convert2corosync(value, indentation)
indentation = indentation[:-1]
output += '{}}}\n'.format(indentation)
elif isinstance(value, list):
for item in value:
output += _convert2corosync(item, indentation)
else:
output += '{}{}: {}\n'.format(indentation, key, value)
return output
Expand All @@ -385,7 +412,9 @@ def corosync_updated(
'comment': ''}

with salt_utils.files.fopen(name, 'r') as file_content:
corodict, _ = _convert2dict(file_content.read().splitlines())
fstream = file_content.read()
dup_sec_set = _find_dup_items(fstream)
corodict, _ = _convert2dict(fstream.splitlines(), dup_sec_set)
new_conf_dict, changes = _mergedicts(corodict, data, {})

if not changes:
Expand Down

0 comments on commit 3c4aa36

Please sign in to comment.