Skip to content

Commit 9fea55a

Browse files
committed
Adding json type files to crawl_n_mask
We're adding json type files to crawl_n_mask. It checks the extension and return the value of the masked key different between yaml and json formats.
1 parent 221015d commit 9fea55a

File tree

2 files changed

+39
-39
lines changed

2 files changed

+39
-39
lines changed

plugins/modules/crawl_n_mask.py

Lines changed: 24 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,6 @@ def crawl(module, path) -> bool:
191191
# Check if any parent directory (not the root) is excluded
192192
if any(part in EXCLUDED_DIRS for part in rel_path.split(os.sep)):
193193
continue
194-
195194
for f in files:
196195
if not re.search(excluded_file_ext_regex, f):
197196
if mask(module, os.path.join(root, f)):
@@ -206,7 +205,15 @@ def _get_masked_string(value):
206205
return value[:2] + MASK_STR + value[-2:]
207206

208207

209-
def partial_mask(value):
208+
def format_masked(prefix, value, suffix, extension):
209+
return (
210+
f"{prefix}'{value}'{suffix}"
211+
if extension == "yaml"
212+
else f'{prefix}"{value}"{suffix}'
213+
)
214+
215+
216+
def partial_mask(value, extension):
210217
"""
211218
Check length of the string. If it is too long, take 2 chars
212219
from beginning, then add mask string and add 2 chars from the
@@ -215,22 +222,21 @@ def partial_mask(value):
215222
"""
216223
if not value.strip():
217224
return
218-
219-
if "'" in value:
220-
parsed_value = value.split("'")
225+
if "'" in value or extension == "json":
226+
parsed_value = value.split('"') if extension == "json" else value.split("'")
221227
if len(parsed_value) > 2 and parsed_value[1] != "":
222228
prefix = parsed_value[0]
223229
value = _get_masked_string(parsed_value[1])
224230
suffix = parsed_value[2]
225-
return f"{prefix}'{value}'{suffix}"
231+
return format_masked(prefix, value, suffix, extension)
226232
else:
227233
match = re.match(r"^(\s*)(.*?)(\n?)$", value)
228234
if match:
229235
parts = list(match.groups())
230236
prefix = parts[0]
231237
value = _get_masked_string(parts[1])
232238
suffix = parts[2]
233-
return f"{prefix}'{value}'{suffix}"
239+
return format_masked(prefix, value, suffix, extension)
234240

235241

236242
def mask(module, path: str) -> bool:
@@ -240,16 +246,17 @@ def mask(module, path: str) -> bool:
240246
respective masking methods for that file.
241247
"""
242248
changed = False
243-
if (
249+
if path.endswith("json"):
250+
changed = mask_file(module, path, "json")
251+
elif (
244252
path.endswith((tuple(["yaml", "yml"])))
245253
or os.path.basename(path).split(".")[0] in ALLOWED_YAML_FILES
246254
):
247-
extension = "yaml"
248-
changed = mask_file(module, path, extension)
255+
changed = mask_file(module, path, "yaml")
249256
return changed
250257

251258

252-
def mask_yaml(infile, outfile, changed) -> bool:
259+
def mask_by_extension(infile, outfile, changed, extension) -> bool:
253260
"""
254261
Read the file, search for colon (':'), take value and
255262
mask sensitive data
@@ -259,12 +266,12 @@ def mask_yaml(infile, outfile, changed) -> bool:
259266
if ":" not in line:
260267
outfile.write(line)
261268
continue
262-
263269
key, sep, value = line.partition(":")
270+
comparable_key = key.strip().replace('"', "")
264271
masked_value = value
265272
for word in PROTECT_KEYS:
266-
if key.strip() == word:
267-
masked = partial_mask(value)
273+
if comparable_key == word.strip():
274+
masked = partial_mask(value, extension)
268275
if not masked:
269276
continue
270277
masked_value = masked_value.replace(value, masked)
@@ -293,10 +300,9 @@ def mask_file(module, path, extension) -> bool:
293300
try:
294301
with file_path.open("r", encoding="utf-8") as infile:
295302
with temp_path.open("w", encoding="utf-8") as outfile:
296-
if extension == "yaml":
297-
changed = mask_yaml(infile, outfile, changed)
298-
replace_file(temp_path, file_path, changed)
299-
return changed
303+
changed = mask_by_extension(infile, outfile, changed, extension)
304+
replace_file(temp_path, file_path, changed)
305+
return changed
300306
except Exception as e:
301307
print(f"An unexpected error occurred on masking file {file_path}: {e}")
302308

tests/unit/modules/test_crawl_n_mask.py

Lines changed: 15 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -41,25 +41,19 @@ def test_crawl_false(self, test_dir, expected_files):
4141
changed = cnm.crawl(module, test_dir)
4242
assert not changed
4343

44-
def test_partial_mask_scenario_1(self):
45-
example_value = " 'test1234'\n"
46-
expected_value = " 'te**********34'\n"
47-
test_value = cnm.partial_mask(example_value)
48-
assert expected_value == test_value
49-
50-
def test_partial_mask_scenario_2(self):
51-
example_value = " osp_ci_framework_keytab\n"
52-
expected_value = " 'os**********ab'\n"
53-
test_value = cnm.partial_mask(example_value)
54-
assert expected_value == test_value
55-
56-
def test_partial_mask_scenario_3(self):
57-
example_value = " ''\n"
58-
test_value = cnm.partial_mask(example_value)
59-
assert test_value is None
60-
61-
def test_partial_mask_scenario_4(self):
62-
example_value = "tet"
63-
expected_value = "'te**********'"
64-
test_value = cnm.partial_mask(example_value)
44+
@pytest.mark.parametrize(
45+
"file_format, example_value, expected_value",
46+
[
47+
("yaml", " 'test1234'\n", " 'te**********34'\n"),
48+
("yaml", " osp_ci_framework_keytab\n", " 'os**********ab'\n"),
49+
("yaml", " ''\n", None),
50+
("yaml", "tet", "'te**********'"),
51+
("json", " \"test1234\",\n", " \"te**********34\",\n"),
52+
("json", " \"osp_ci_framework_keytab\",\n", ' \"os**********ab\",\n'),
53+
("json", " ''\n", None),
54+
("json", "\"tet\"", '\"te**********\"'),
55+
],
56+
)
57+
def test_partial_mask(self, file_format, example_value, expected_value):
58+
test_value = cnm.partial_mask(example_value, file_format)
6559
assert expected_value == test_value

0 commit comments

Comments
 (0)