diff --git a/CMakeLists.txt b/CMakeLists.txt index 23395480075..788d0e45dc3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -158,6 +158,7 @@ find_python_module(openpyxl) find_python_module(pandas) find_python_module(pcre2) find_python_module(cmakelint) +find_python_module(github) # sphinx documentation requirements find_python_module(sphinx) @@ -268,6 +269,7 @@ message(STATUS "python pcre2 module (optional): ${PY_PCRE2}") message(STATUS "python lxml module (optional): ${PY_LXML}") message(STATUS "python prometheus-client module (optional): ${PY_PROMETHEUS_CLIENT}") message(STATUS "python compliance-trestle module (optional): ${PY_TRESTLE}") +message(STATUS "python github (PyGitHub) module (optional): ${PY_GITHUB}") message(STATUS " ") message(STATUS "Build options:") diff --git a/docs/manual/developer/05_tools_and_utilities.md b/docs/manual/developer/05_tools_and_utilities.md index a2ea6289567..1bcc8220659 100644 --- a/docs/manual/developer/05_tools_and_utilities.md +++ b/docs/manual/developer/05_tools_and_utilities.md @@ -704,3 +704,15 @@ $ ./build_product ocp4 $ ./utils/rule_dir_json.py $ ./utils/oscal/build_cd_from_policy.py -o build/ocp4.json -p fedramp_rev4_high -pr ocp4 -c nist_ocp4:high ``` + +### `utils/ansible_playbook_to_role.py` – Generates Ansible Roles and pushes them to Github + +This script converts the Ansible playbooks created by the build system and converts them to Ansible roles and can upload them to GitHub. + + +An example of how to execute the script to generate roles locally: + +```bash +$ ./build_product rhel9 +$ ./utils/ansible_playbook_to_role.py --dry-run output +``` diff --git a/test-requirements.txt b/test-requirements.txt index d40f61590c0..0ffd58563c6 100644 --- a/test-requirements.txt +++ b/test-requirements.txt @@ -6,3 +6,4 @@ lxml lxml-stubs requests compliance-trestle==2.4.0 +PyGitHub diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 5bde9bbbc8e..b074241aaea 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -350,3 +350,19 @@ if(PYTHON_VERSION_MAJOR GREATER 2 AND PYTHON_VERSION_MINOR GREATER 6) set_tests_properties("utils-import_disa_stig_sanity" PROPERTIES LABELS quick) ) endif() + + +if(PYTHON_VERSION_MAJOR GREATER 2 AND PY_GITHUB) + add_test( + NAME "utils-ansible-playbook-to-role-help" + COMMAND env "PYTHONPATH=$ENV{PYTHONPATH}" "${PYTHON_EXECUTABLE}" "${CMAKE_SOURCE_DIR}/utils/ansible_playbook_to_role.py" "--help" + ) + set_tests_properties("utils-ansible-playbook-to-role-help" PROPERTIES LABELS quick) + if(SSG_PRODUCT_RHEL9) + file(MAKE_DIRECTORY "${CMAKE_BINARY_DIR}/roles") + add_test( + NAME "utils-ansible-playbook-to-role-rhel9" + COMMAND env "PYTHONPATH=$ENV{PYTHONPATH}" "${PYTHON_EXECUTABLE}" "${CMAKE_SOURCE_DIR}/utils/ansible_playbook_to_role.py" "--dry-run" "${CMAKE_BINARY_DIR}/roles" "--product" "rhel9" "--build-playbooks-dir" "${CMAKE_BINARY_DIR}/ansible" + ) + endif() +endif() diff --git a/utils/ansible_playbook_to_role.py b/utils/ansible_playbook_to_role.py index c8d3c19e16d..e9a7a961861 100755 --- a/utils/ansible_playbook_to_role.py +++ b/utils/ansible_playbook_to_role.py @@ -1,5 +1,4 @@ #!/usr/bin/python3 -# -*- coding: utf-8 -*- from __future__ import print_function @@ -15,17 +14,25 @@ import yaml import collections + +SSG_ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), "..")) +PLAYBOOK_ROOT = os.path.join(SSG_ROOT, "build", "ansible") + try: from github import Github, InputGitAuthor, UnknownObjectException except ImportError: - sys.stderr.write("Please install PyGithub, on Fedora it's in the " - "python-PyGithub package.\n") - sys.exit(1) + print("Please install PyGithub, on Fedora it's in the python-PyGithub package.", + file=sys.stderr) + raise SystemExit(1) -import ssg.ansible -import ssg.yaml -from ssg.utils import mkdir_p +try: + import ssg.ansible + import ssg.yaml + from ssg.utils import mkdir_p +except ImportError: + print("Unable to find the ssg module. Please run 'source .pyenv'", file=sys.stderr) + raise SystemExit(1) def memoize(f): @@ -486,17 +493,18 @@ def parse_args(): parser = argparse.ArgumentParser( description='Generates Ansible Roles and pushes them to Github') parser.add_argument( - "--build-playbooks-dir", required=True, + "--build-playbooks-dir", help="Path to directory containing the generated Ansible Playbooks. " - "Most likely this is going to be ./build/ansible", - dest="build_playbooks_dir") + "Most likely this is going to be ./build/ansible. Defaults to {}".format(PLAYBOOK_ROOT), + dest="build_playbooks_dir", default=PLAYBOOK_ROOT) parser.add_argument( "--dry-run", "-d", dest="dry_run", - help="Do not push Ansible Roles to the Github, store them only to local directory" + help="Do not push Ansible Roles to Github, store them only to the given local directory." ) parser.add_argument( "--organization", "-o", default=ORGANIZATION_NAME, - help="Name of the Github organization") + help="Name of the Github organization to publish roles to. " + "Defaults to {}.".format(ORGANIZATION_NAME)) parser.add_argument( "--profile", "-p", default=[], action="append", metavar="PROFILE", choices=PROFILE_ALLOWLIST, @@ -507,7 +515,7 @@ def parse_args(): help="What products to upload, if not specified, upload all that are applicable.") parser.add_argument( "--tag-release", "-n", default=False, action="store_true", - help="Tag a new release in GitHub") + help="Tag a new release in GitHub. Defaults to False.") parser.add_argument( "--token", "-t", dest="token", help="GitHub token used for organization authorization") @@ -598,7 +606,7 @@ def main(): elif repo.name not in potential_roles: print("Repo '%s' is not managed by this script. " "It may need to be deleted, please verify and do that " - "manually!" % repo.name) + "manually!" % repo.name, file=sys.stderr) if __name__ == "__main__":