forked from ComplianceAsCode/content
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request ComplianceAsCode#12014 from mildas/ansible_shell_diff
Github Action Ansible `shell` module changes check
- Loading branch information
Showing
2 changed files
with
93 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
#!/usr/bin/python3 | ||
|
||
import yaml | ||
import argparse | ||
import subprocess | ||
from pathlib import Path | ||
|
||
|
||
def parse_args(): | ||
parser = argparse.ArgumentParser( | ||
description="Check for changes in 'shell' module usage in two datastreams" | ||
) | ||
parser.add_argument('old', metavar='OLD_DS_PATH', help="Path to old datastream") | ||
parser.add_argument('new', metavar='NEW_DS_PATH', help="Path to new datastream") | ||
return parser.parse_args() | ||
|
||
|
||
def get_shell_tasks(tasks): | ||
""" | ||
Find all shell/command module tasks. | ||
Module can be as FQCN or just short name. | ||
Both forms, free form and 'cmd:' parameter, are supported. | ||
""" | ||
shell_tasks = [] | ||
for task in tasks: | ||
for task_name in ['shell', 'ansible.builtin.shell', 'command', 'ansible.builtin.command']: | ||
if task_name in task: | ||
if type(task[task_name]) is dict and 'cmd' in task[task_name]: | ||
shell_tasks.append(task[task_name]['cmd']) | ||
else: | ||
shell_tasks.append(task[task_name]) | ||
# Search also blocks | ||
if 'block' in task: | ||
tasks = get_shell_tasks(task['block']) | ||
if tasks: | ||
shell_tasks.extend(tasks) | ||
return shell_tasks | ||
|
||
|
||
if __name__ == '__main__': | ||
args = parse_args() | ||
# Generate old and new playbooks for all rules in datastream | ||
cmd = ['oscap', 'xccdf', 'generate', 'fix', '--profile', '(all)', '--fix-type', 'ansible'] | ||
subprocess.run(cmd + ['--output', 'old.yml', args.old], check=True) | ||
subprocess.run(cmd + ['--output', 'new.yml', args.new], check=True) | ||
|
||
with open('old.yml', 'r') as old_yaml, open('new.yml', 'r') as new_yaml: | ||
old_playbook = yaml.safe_load(old_yaml) | ||
new_playbook = yaml.safe_load(new_yaml) | ||
# Get only shell commands | ||
old_shell_modules = get_shell_tasks(old_playbook[0]['tasks']) | ||
new_shell_modules = get_shell_tasks(new_playbook[0]['tasks']) | ||
|
||
diff = set(new_shell_modules) - set(old_shell_modules) | ||
if diff: | ||
print(f"Changes in Ansible shell module have been found:") | ||
print("\n".join(diff)) | ||
|
||
Path.unlink('old.yml') | ||
Path.unlink('new.yml') | ||
exit(0) |