Skip to content

Commit

Permalink
Merge pull request #36 from RedHatProductSecurity/staging
Browse files Browse the repository at this point in the history
Merge staging to main
  • Loading branch information
Alex Flom authored Aug 25, 2023
2 parents 99998cd + 69a31e5 commit 1d24f1d
Show file tree
Hide file tree
Showing 11 changed files with 517 additions and 304 deletions.
9 changes: 5 additions & 4 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# kics-scan disable=fd54f200-402c-4333-a5a4-36ef6709af2f,b03a748a-542d-44f4-bb86-9199ab4fd2d5
FROM python:3.8.1-slim as python-base
FROM python:3.9-slim as python-base

ENV PYTHONUNBUFFERED=1 \
# prevents python creating .pyc files
Expand Down Expand Up @@ -33,10 +33,11 @@ FROM python-base as dependencies
RUN apt-get update \
&& apt-get install --no-install-recommends -y \
# deps for building python deps
build-essential
build-essential \
git

# install poetry - respects $POETRY_VERSION & $POETRY_HOME
RUN python3.8 -m pip install --no-cache-dir --upgrade pip \
RUN python3.9 -m pip install --no-cache-dir --upgrade pip \
&& pip install --no-cache-dir poetry=="$POETRY_VERSION"

# Cache runtime deps
Expand All @@ -59,5 +60,5 @@ COPY ./entrypoint.sh /

RUN chmod +x /entrypoint.sh

ENTRYPOINT ["python3.8", "-m" , "trestlebot"]
ENTRYPOINT ["python3.9", "-m" , "trestlebot"]

2 changes: 1 addition & 1 deletion entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ else
fi

# Initialize the command variable
command="python3.8 -m trestlebot \
command="python3.9 -m trestlebot \
--markdown-path=\"${INPUT_MARKDOWN_PATH}\" \
--oscal-model=\"${INPUT_OSCAL_MODEL}\" \
--ssp-index-path=\"${INPUT_SSP_INDEX_PATH}\" \
Expand Down
543 changes: 273 additions & 270 deletions poetry.lock

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ trestle-bot = "trestlebot.cli:run"
[tool.poetry.dependencies]
python = '^3.8.1'
gitpython = "^3.1.31"
compliance-trestle = "^2.2.1"
compliance-trestle = {git = "https://github.com/RedHatProductSecurity/compliance-trestle.git", rev = "bb19091d08025f630379da59cba42b64e4701839"}
github3-py = "^4.0.1"
python-gitlab = "^3.15.0"

Expand Down
14 changes: 12 additions & 2 deletions tests/testutils.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@
from trestle.oscal import component as comp
from trestle.oscal import profile as prof

from trestlebot.const import COMPDEF_KEY_NAME, LEVERAGED_SSP_KEY_NAME, PROFILE_KEY_NAME


JSON_TEST_DATA_PATH = pathlib.Path("tests/data/json/").resolve()

Expand Down Expand Up @@ -78,6 +80,7 @@ def setup_for_ssp(
yaml_header=None,
allowed_sections=None,
force_overwrite=None,
leveraged_ssp="",
)

return args
Expand Down Expand Up @@ -161,12 +164,19 @@ def setup_for_compdef(


def write_index_json(
file_path: str, ssp_name: str, profile: str, component_definitions: List[str]
file_path: str,
ssp_name: str,
profile: str,
component_definitions: List[str],
leveraged_ssp: str = "",
) -> None:
"""Write out ssp index JSON for tests"""
data = {
ssp_name: {"profile": profile, "component_definitions": component_definitions}
ssp_name: {PROFILE_KEY_NAME: profile, COMPDEF_KEY_NAME: component_definitions}
}

if leveraged_ssp:
data[ssp_name][LEVERAGED_SSP_KEY_NAME] = leveraged_ssp

with open(file_path, "w") as file:
json.dump(data, file, indent=4)
69 changes: 69 additions & 0 deletions tests/trestlebot/tasks/authored/test_ssp.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
test_comp = "test_comp"
test_ssp_output = "test-ssp"
markdown_dir = "md_ssp"
leveraged_ssp = "leveraged_ssp"


def test_assemble(tmp_trestle_dir: str) -> None:
Expand Down Expand Up @@ -145,3 +146,71 @@ def test_get_profile_by_ssp(tmp_trestle_dir: str) -> None:
ssp_index: SSPIndex = SSPIndex(ssp_index_path)

assert ssp_index.get_profile_by_ssp(test_ssp_output) == test_prof


def test_get_leveraged_ssp(tmp_trestle_dir: str) -> None:
"""Test to get leveraged ssp from index"""
ssp_index_path = os.path.join(tmp_trestle_dir, "ssp-index.json")
testutils.write_index_json(
ssp_index_path, test_ssp_output, test_prof, [test_comp], leveraged_ssp
)
ssp_index: SSPIndex = SSPIndex(ssp_index_path)

assert ssp_index.get_leveraged_by_ssp(test_ssp_output) == leveraged_ssp


def test_add_ssp_to_index(tmp_trestle_dir: str) -> None:
"""Test adding an ssp to an index"""
ssp_index_path = os.path.join(tmp_trestle_dir, "ssp-index.json")
testutils.write_index_json(ssp_index_path, test_ssp_output, test_prof, [test_comp])
ssp_index: SSPIndex = SSPIndex(ssp_index_path)

ssp_index.add_new_ssp("new_ssp", "test_prof", ["my_comp"])

assert ssp_index.get_profile_by_ssp("new_ssp") == "test_prof"
assert "my_comp" in ssp_index.get_comps_by_ssp("new_ssp")
assert ssp_index.get_leveraged_by_ssp("new_ssp") is None

ssp_index.add_new_ssp("another_new_ssp", "test_prof", ["my_comp"], "test_leveraged")

assert ssp_index.get_profile_by_ssp("another_new_ssp") == "test_prof"
assert "my_comp" in ssp_index.get_comps_by_ssp("another_new_ssp")
assert ssp_index.get_leveraged_by_ssp("another_new_ssp") == "test_leveraged"

# Test adding to an empty ssp index

ssp_index_path = os.path.join(tmp_trestle_dir, "another-ssp-index.json")
ssp_index = SSPIndex(ssp_index_path)

ssp_index.add_new_ssp("another_new_ssp", "test_prof", ["my_comp"], "test_leveraged")

assert ssp_index.get_profile_by_ssp("another_new_ssp") == "test_prof"
assert "my_comp" in ssp_index.get_comps_by_ssp("another_new_ssp")
assert ssp_index.get_leveraged_by_ssp("another_new_ssp") == "test_leveraged"


def test_write_new_ssp_index(tmp_trestle_dir: str) -> None:
"""Test writing out a new ssp index"""
ssp_index_path = os.path.join(tmp_trestle_dir, "ssp-index.json")
testutils.write_index_json(ssp_index_path, test_ssp_output, test_prof, [test_comp])
ssp_index: SSPIndex = SSPIndex(ssp_index_path)

ssp_index.add_new_ssp("new_ssp", "test_prof", ["my_comp"])
ssp_index.add_new_ssp("another_new_ssp", "test_prof", ["my_comp"], "test_leveraged")

ssp_index.write_out()

# Reread the ssp index from JSON
ssp_index = SSPIndex(ssp_index_path)

assert ssp_index.get_profile_by_ssp(test_ssp_output) == test_prof
assert test_comp in ssp_index.get_comps_by_ssp(test_ssp_output)
assert ssp_index.get_leveraged_by_ssp(test_ssp_output) is None

assert ssp_index.get_profile_by_ssp("new_ssp") == "test_prof"
assert "my_comp" in ssp_index.get_comps_by_ssp("new_ssp")
assert ssp_index.get_leveraged_by_ssp("new_ssp") is None

assert ssp_index.get_profile_by_ssp("another_new_ssp") == "test_prof"
assert "my_comp" in ssp_index.get_comps_by_ssp("another_new_ssp")
assert ssp_index.get_leveraged_by_ssp("another_new_ssp") == "test_leveraged"
21 changes: 20 additions & 1 deletion tests/trestlebot/test_gitlab.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
[
"https://gitlab.com/owner/repo",
"https://gitlab.com/owner/repo.git",
"https://test:[email protected]/owner/repo.git",
"gitlab.com/owner/repo.git",
],
)
Expand All @@ -55,7 +56,7 @@ def test_parse_repository(repo_url: str) -> None:
],
)
def test_parse_repository_with_server_url(repo_url: str) -> None:
"""Test an invalid url input"""
"""Test with a custom server url"""
gl = GitLab("fake", "https://mygitlab.com")

owner, repo_name = gl.parse_repository(repo_url)
Expand All @@ -64,6 +65,24 @@ def test_parse_repository_with_server_url(repo_url: str) -> None:
assert repo_name == "repo"


@pytest.mark.parametrize(
"repo_url",
[
"https://mygitlab.com/group/owner/repo",
"https://mygitlab.com/group/owner/repo.git",
"mygitlab.com/group/owner/repo.git",
],
)
def test_parse_repository_with_group(repo_url: str) -> None:
"""Test with nested namespaces"""
gl = GitLab("fake", "https://mygitlab.com")

owner, repo_name = gl.parse_repository(repo_url)

assert owner == "group/owner"
assert repo_name == "repo"


def test_parse_repository_integration(tmp_repo: Tuple[str, Repo]) -> None:
"""Tests integration with git remote get-url"""
repo_path, repo = tmp_repo
Expand Down
14 changes: 11 additions & 3 deletions trestlebot/bot.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,17 @@ def run(
commit_sha: str = ""
pr_number: int = 0

# Create Git Repo
repo = Repo(working_dir)

branch_names: List[str] = [b.name for b in repo.branches] # type: ignore
if branch in branch_names:
logger.debug(f"Local branch {branch} found")
repo.git.checkout(branch)
else:
logger.debug(f"Local branch {branch} created")
repo.git.checkout("-b", branch)

# Execute bot pre-tasks before committing repository updates
if pre_tasks is not None:
for task in pre_tasks:
Expand All @@ -128,9 +139,6 @@ def run(
except TaskException as e:
raise RepoException(f"Bot pre-tasks failed: {e}")

# Create Git Repo
repo = Repo(working_dir)

# Check if there are any unstaged files
if repo.is_dirty(untracked_files=True):
if check_only:
Expand Down
7 changes: 7 additions & 0 deletions trestlebot/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,10 @@
# Common exit codes
SUCCESS_EXIT_CODE = 0
ERROR_EXIT_CODE = 1


# SSP Index Fields

PROFILE_KEY_NAME = "profile"
COMPDEF_KEY_NAME = "component_definitions"
LEVERAGED_SSP_KEY_NAME = "leveraged_ssp"
12 changes: 8 additions & 4 deletions trestlebot/gitlab.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ def __init__(self, api_token: str, server_url: str = "https://gitlab.com"):
self._gitlab_client = gitlab.Gitlab(server_url, private_token=api_token)

stripped_url = re.sub(r"^(https?://)?", "", server_url)
self.pattern = r"^(?:https?://)?{0}/([^/]+)/([^/.]+)".format(
self.pattern = r"^(?:https?://)?{0}(/.+)/([^/.]+)(\.git)?$".format(
re.escape(stripped_url)
)

Expand All @@ -46,12 +46,16 @@ def parse_repository(self, repo_url: str) -> Tuple[str, str]:
Returns:
Owner and project name in a tuple, respectively
"""
match = re.match(self.pattern, repo_url)

# Strip out any basic auth
stripped_url = re.sub(r"https?://.*?@", "https://", repo_url)

match = re.match(self.pattern, stripped_url)

if not match:
raise GitProviderException(f"{repo_url} is an invalid repo URL")
raise GitProviderException(f"{stripped_url} is an invalid repo URL")

owner = match.group(1)
owner = match.group(1)[1:] # Removing the leading slash
repo = match.group(2)
return (owner, repo)

Expand Down
Loading

0 comments on commit 1d24f1d

Please sign in to comment.