Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Webhook update w token #3

Closed
wants to merge 20 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
a5e2b6f
test: fix project transfer test failures (#663)
amimas Jan 2, 2024
7e56a63
chore(deps-dev): bump cryptography from 41.0.5 to 41.0.7 (#651)
dependabot[bot] Jan 2, 2024
f337293
chore(deps-dev): bump mypy from 1.7.1 to 1.8.0 (#659)
dependabot[bot] Jan 2, 2024
fcb8574
chore(deps-dev): bump coverage from 7.3.2 to 7.4.0 (#661)
dependabot[bot] Jan 3, 2024
d309d28
chore(deps): bump python-gitlab from 4.2.0 to 4.3.0 (#660)
dependabot[bot] Jan 3, 2024
b5513de
refactor: migrate `hooks` configuration feature to use python-gitlab …
TigreModerata Jan 4, 2024
bc6ce91
refactor: migrate `tags` processor to use python-gitlab API (#642)
lhokktyn Jan 6, 2024
96f6cc5
chore(deps): bump types-requests from 2.31.0.10 to 2.31.0.20240106 (#…
dependabot[bot] Jan 9, 2024
6d01221
chore(deps-dev): bump pytest from 7.4.3 to 7.4.4 (#665)
dependabot[bot] Jan 9, 2024
aa53356
feat: add `enforce` support for project hooks/webhooks configuration …
TigreModerata Jan 11, 2024
96d6a9a
chore(deps): bump jinja2 from 3.1.2 to 3.1.3 (#667)
dependabot[bot] Jan 12, 2024
57979d7
chore(deps): bump python-gitlab from 4.3.0 to 4.4.0 (#668)
dependabot[bot] Jan 16, 2024
326b012
chore(deps): bump markupsafe from 2.1.3 to 2.1.4 (#672)
dependabot[bot] Feb 1, 2024
f5f48ce
chore: formatting updates via latest version of black formatter (#681)
amimas Feb 10, 2024
5831d17
chore(deps): bump markupsafe from 2.1.4 to 2.1.5 (#679)
dependabot[bot] Feb 10, 2024
f82046f
chore(deps-dev): bump coverage from 7.4.0 to 7.4.1 (#675)
dependabot[bot] Feb 10, 2024
3b6a6f0
chore(deps): bump types-requests from 2.31.0.20240106 to 2.31.0.20240…
dependabot[bot] Feb 10, 2024
be144ff
chore(deps-dev): bump cryptography from 41.0.7 to 42.0.2 (#677)
dependabot[bot] Feb 10, 2024
8bd5862
chore(deps): bump yamlpath from 3.8.1 to 3.8.2 (#683)
dependabot[bot] Feb 12, 2024
c9dd134
Delete docs/reference/webhooks.md
TigreModerata Feb 26, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 0 additions & 20 deletions docs/reference/webhooks.md

This file was deleted.

18 changes: 9 additions & 9 deletions gitlabform/configuration/transform.py
Original file line number Diff line number Diff line change
Expand Up @@ -225,9 +225,9 @@ def _do_transform(self, configuration: Configuration):
for node_coordinate in processor.get_nodes(path, mustexist=True):
try:
access_level_string = str(node_coordinate.node)
node_coordinate.parent[
node_coordinate.parentref
] = AccessLevel.get_value(access_level_string)
node_coordinate.parent[node_coordinate.parentref] = (
AccessLevel.get_value(access_level_string)
)
except KeyError:
fatal(
f"Configuration string '{access_level_string}' is not one of the valid access levels:"
Expand Down Expand Up @@ -255,9 +255,9 @@ def _do_transform(self, configuration: Configuration):
if node_coordinate.parentref == "access_level":
try:
access_level_string = str(node_coordinate.node)
node_coordinate.parent[
node_coordinate.parentref
] = AccessLevel.get_value(access_level_string)
node_coordinate.parent[node_coordinate.parentref] = (
AccessLevel.get_value(access_level_string)
)
except KeyError:
fatal(
f"Configuration string '{access_level_string}' is not one of the valid access levels:"
Expand Down Expand Up @@ -313,9 +313,9 @@ def _do_transform(self, configuration: Configuration) -> None:

if old_syntax["approvals"]:
# add the settings, if there are left any after removing 'approvals_before_merge'
where_to_add_new_syntax[
"merge_requests_approvals"
] = old_syntax["approvals"]
where_to_add_new_syntax["merge_requests_approvals"] = (
old_syntax["approvals"]
)

# approval rules
if (
Expand Down
2 changes: 0 additions & 2 deletions gitlabform/gitlab/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
from gitlabform.gitlab.resource_groups import GitLabResourceGroups
from gitlabform.gitlab.schedules import GitLabPipelineSchedules
from gitlabform.gitlab.integrations import GitLabIntegrations
from gitlabform.gitlab.tags import GitLabTags
from gitlabform.gitlab.users import GitLabUsers
from gitlab import Gitlab

Expand Down Expand Up @@ -60,7 +59,6 @@ class GitLab(
GitLabRepositories,
GitLabResourceGroups,
GitLabIntegrations,
GitLabTags,
GitLabGroupLDAPLinks,
GitLabGroupBadges,
GitLabGroupVariables,
Expand Down
35 changes: 0 additions & 35 deletions gitlabform/gitlab/projects.py
Original file line number Diff line number Diff line change
Expand Up @@ -177,41 +177,6 @@ def post_project_push_rules(self, project_and_group_name: str, push_rules):
"projects/%s/push_rule", pid, "POST", push_rules, expected_codes=201
)

def get_hook_id(self, project_and_group_name, url):
hooks = self._make_requests_to_api(
"projects/%s/hooks", project_and_group_name, "GET"
)
for hook in hooks:
if hook["url"] == url:
return hook["id"]
return None

def delete_hook(self, project_and_group_name, hook_id):
self._make_requests_to_api(
"projects/%s/hooks/%s",
(project_and_group_name, hook_id),
"DELETE",
expected_codes=[200, 204],
)

def put_hook(self, project_and_group_name, hook_id, url, data):
data_required = {"url": url}
data = {**data, **data_required}
self._make_requests_to_api(
"projects/%s/hooks/%s", (project_and_group_name, hook_id), "PUT", data
)

def post_hook(self, project_and_group_name, url, data):
data_required = {"url": url}
data = {**data, **data_required}
self._make_requests_to_api(
"projects/%s/hooks",
project_and_group_name,
"POST",
data,
expected_codes=201,
)

def get_groups_from_project(self, project_and_group_name):
# couldn't find an API call that was giving me directly
# the shared groups, so I'm using directly the GET /projects/:id call
Expand Down
45 changes: 0 additions & 45 deletions gitlabform/gitlab/tags.py

This file was deleted.

6 changes: 3 additions & 3 deletions gitlabform/processors/group/group_members_processor.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,9 @@ def _process_groups(

groups_before_by_group_path = dict()
for share_details in groups_before:
groups_before_by_group_path[
share_details["group_full_path"]
] = share_details
groups_before_by_group_path[share_details["group_full_path"]] = (
share_details
)

for share_with_group_path in groups_to_set_by_group_path:
group_access_to_set = groups_to_set_by_group_path[share_with_group_path][
Expand Down
57 changes: 46 additions & 11 deletions gitlabform/processors/project/hooks_processor.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
from logging import debug
from typing import Dict, Any, List

from gitlab.base import RESTObject, RESTObjectList
from gitlab.v4.objects import Project

from gitlabform.gitlab import GitLab
from gitlabform.processors.abstract_processor import AbstractProcessor
Expand All @@ -9,23 +13,54 @@ def __init__(self, gitlab: GitLab):
super().__init__("hooks", gitlab)

def _process_configuration(self, project_and_group: str, configuration: dict):
for hook in sorted(configuration["hooks"]):
debug("Processing hooks...")
project: Project = self.gl.projects.get(project_and_group)
hooks_list: RESTObjectList | List[RESTObject] = project.hooks.list()
config_hooks: tuple[str, ...] = tuple(
x for x in sorted(configuration["hooks"]) if x != "enforce"
)

for hook in config_hooks:
gitlab_hook: RESTObject | None = next(
(h for h in hooks_list if h.url == hook), None
)
hook_id = gitlab_hook.id if gitlab_hook else None
if configuration.get("hooks|" + hook + "|delete"):
hook_id = self.gitlab.get_hook_id(project_and_group, hook)
if hook_id:
debug("Deleting hook '%s'", hook)
self.gitlab.delete_hook(project_and_group, hook_id)
project.hooks.delete(hook_id)
else:
debug("Not deleting hook '%s', because it doesn't exist", hook)
else:
hook_id = self.gitlab.get_hook_id(project_and_group, hook)
if hook_id:
debug("Changing existing hook '%s'", hook)
self.gitlab.put_hook(
project_and_group, hook_id, hook, configuration["hooks"][hook]
hook_config = {"url": hook}
hook_config.update(configuration["hooks"][hook])
gl_hook_dict = gitlab_hook.asdict() if gitlab_hook else {}
diffs = (
map(
lambda k: hook_config[k] != gl_hook_dict[k],
hook_config.keys(),
)
else:
if gl_hook_dict
else iter(())
)
if not hook_id:
debug("Creating hook '%s'", hook)
self.gitlab.post_hook(
project_and_group, hook, configuration["hooks"][hook]
created_hook: RESTObject = project.hooks.create(hook_config)
debug("Created hook '%s'", created_hook)
elif hook_id and any(diffs):
debug("Changing existing hook '%s'", hook)
changed_hook: Dict[str, Any] = project.hooks.update(
hook_id, hook_config
)
debug("Changed hook to '%s'", changed_hook)
elif hook_id and not any(diffs):
debug(f"Hook {hook} remains unchanged")

if configuration.get("hooks|enforce"):
for gh in hooks_list:
if gh.url not in config_hooks:
debug(
"Deleting hook '%s' currently setup in the project but it is not in the configuration and enforce is enabled",
gh.url,
)
project.hooks.delete(gh.id)
50 changes: 37 additions & 13 deletions gitlabform/processors/project/tags_processor.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

from gitlabform.constants import EXIT_PROCESSING_ERROR
from gitlabform.gitlab import GitLab
from gitlabform.gitlab.core import NotFoundException
from gitlab import GitlabDeleteError, GitlabGetError
from gitlabform.processors.abstract_processor import AbstractProcessor


Expand All @@ -12,7 +12,17 @@ def __init__(self, gitlab: GitLab, strict: bool):
super().__init__("tags", gitlab)
self.strict = strict

def _get_user_by_username(self, username):
user = self.gl.users.list(username=username)
if len(user) == 0:
raise GitlabGetError(
"No users found when searching for username '%s'" % username, 404
)
return user[0]

def _process_configuration(self, project_and_group: str, configuration: dict):
project = self.gl.projects.get(id=project_and_group, lazy=True)

for tag in sorted(configuration["tags"]):
try:
if configuration["tags"][tag]["protected"]:
Expand All @@ -33,13 +43,13 @@ def _process_configuration(self, project_and_group: str, configuration: dict):
elif "user_id" in config:
user_ids.add(config["user_id"])
elif "user" in config:
user_ids.add(self.gitlab._get_user_id(config["user"]))
gitlab_user = self._get_user_by_username(config["user"])
user_ids.add(gitlab_user.get_id())
elif "group_id" in config:
group_ids.add(config["group_id"])
elif "group" in config:
group_ids.add(
self.gitlab._get_group_id(config["group"])
)
gitlab_group = self.gl.groups.get(config["group"])
group_ids.add(gitlab_group.get_id())

for val in access_levels:
allowed_to_create.append({"access_level": val})
Expand All @@ -55,24 +65,38 @@ def _process_configuration(self, project_and_group: str, configuration: dict):
if "create_access_level" in configuration["tags"][tag]
else None
)

debug("Setting tag '%s' as *protected*", tag)
try:
# try to unprotect first
self.gitlab.unprotect_tag(project_and_group, tag)
except NotFoundException:
project.protectedtags.delete(tag)
except GitlabDeleteError:
pass
self.gitlab.protect_tag(
project_and_group, tag, allowed_to_create, create_access_level
)

data = {}
data["name"] = tag
if allowed_to_create is not None:
data["allowed_to_create"] = allowed_to_create
if create_access_level is not None:
data["create_access_level"] = create_access_level
project.protectedtags.create(data)
else:
debug("Setting tag '%s' as *unprotected*", tag)
self.gitlab.unprotect_tag(project_and_group, tag)
except NotFoundException:
message = f"Tag '{tag}' not found when trying to set it as protected/unprotected!"
project.protectedtags.delete(tag)
except GitlabDeleteError:
message = f"Tag '{tag}' not found when trying to unprotect it!"
if self.strict:
fatal(
message,
exit_code=EXIT_PROCESSING_ERROR,
)
else:
warning(message)
except GitlabGetError as e:
if self.strict:
fatal(
e,
exit_code=EXIT_PROCESSING_ERROR,
)
else:
warning(message)
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,6 @@ def __init__(self, gitlab: GitLab):
required_to_create_or_update=And(Key("name"), Key("deploy_access_levels")),
)

self.custom_diff_analyzers[
"deploy_access_levels"
] = self.recursive_diff_analyzer
self.custom_diff_analyzers["deploy_access_levels"] = (
self.recursive_diff_analyzer
)
6 changes: 3 additions & 3 deletions gitlabform/processors/util/difference_logger.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,9 @@ def log_diff(
if hide_entries:
changes = list(
map(
lambda i: [i[0], hide(i[1]), hide(i[2])]
if i[0] in hide_entries
else i,
lambda i: (
[i[0], hide(i[1]), hide(i[2])] if i[0] in hide_entries else i
),
changes,
)
)
Expand Down
Loading
Loading