mirror of
https://github.com/ansible-collections/community.general.git
synced 2026-06-11 02:25:36 +00:00
new module: gitlab_project_approvals configures GitLab project approval rules (#12096)
* Add gitlab_project_approvals module * Update BOTMETA info * Add lisence info to tests
This commit is contained in:
parent
8468fea3b0
commit
e41e76fdf5
4 changed files with 292 additions and 0 deletions
2
.github/BOTMETA.yml
vendored
2
.github/BOTMETA.yml
vendored
|
|
@ -674,6 +674,8 @@ files:
|
|||
maintainers: pixslx
|
||||
$modules/gitlab_project_access_token.py:
|
||||
maintainers: pixslx
|
||||
$modules/gitlab_project_approvals.py:
|
||||
maintainers: masa-orca
|
||||
$modules/grove.py:
|
||||
maintainers: zimbatm
|
||||
$modules/gunicorn.py:
|
||||
|
|
|
|||
208
plugins/modules/gitlab_project_approvals.py
Normal file
208
plugins/modules/gitlab_project_approvals.py
Normal file
|
|
@ -0,0 +1,208 @@
|
|||
#!/usr/bin/python
|
||||
|
||||
# Copyright (c) 2026, Masaru Onodera (@masa-orca)
|
||||
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
DOCUMENTATION = r"""
|
||||
module: gitlab_project_approvals
|
||||
short_description: Manage project-level merge request approvals settings on GitLab Server
|
||||
version_added: 13.1.0
|
||||
description:
|
||||
- This module allows to manage project-level merge request approval configurations.
|
||||
author:
|
||||
- "Masaru Onodera (@masa-orca)"
|
||||
requirements:
|
||||
- python-gitlab python module
|
||||
extends_documentation_fragment:
|
||||
- community.general._auth_basic
|
||||
- community.general._gitlab
|
||||
- community.general._attributes
|
||||
|
||||
attributes:
|
||||
check_mode:
|
||||
support: full
|
||||
diff_mode:
|
||||
support: none
|
||||
|
||||
options:
|
||||
project:
|
||||
description:
|
||||
- The name or full path of the GitLab project.
|
||||
required: true
|
||||
type: str
|
||||
|
||||
approvals_before_merge:
|
||||
description:
|
||||
- The number of approvals required before a merge request can be merged.
|
||||
- Deprecated in GitLab 12.3.
|
||||
type: int
|
||||
|
||||
reset_approvals_on_push:
|
||||
description:
|
||||
- Reset approvals on new commit.
|
||||
type: bool
|
||||
|
||||
disable_overriding_approvers_per_merge_request:
|
||||
description:
|
||||
- Disable overriding approvers per merge request.
|
||||
type: bool
|
||||
|
||||
merge_requests_author_approval:
|
||||
description:
|
||||
- Allow authors to self-approve merge requests.
|
||||
type: bool
|
||||
|
||||
merge_requests_disable_committers_approval:
|
||||
description:
|
||||
- Prevent committers from approving merge requests.
|
||||
type: bool
|
||||
|
||||
selective_code_owner_removals:
|
||||
description:
|
||||
- Reset approvals from Code Owners if their files are changed.
|
||||
type: bool
|
||||
|
||||
require_password_to_approve:
|
||||
description:
|
||||
- Require password reauthentication to approve a merge request.
|
||||
- Deprecated in GitLab 16.9.
|
||||
type: bool
|
||||
|
||||
require_reauthentication_to_approve:
|
||||
description:
|
||||
- Require user reauthentication to approve a merge request.
|
||||
type: bool
|
||||
"""
|
||||
|
||||
EXAMPLES = r"""
|
||||
- name: Configure GitLab Project approval settings
|
||||
community.general.gitlab_project_approvals:
|
||||
api_url: https://gitlab.example.com/
|
||||
api_token: "{{ api_token }}"
|
||||
project: my_group/my_project
|
||||
reset_approvals_on_push: true
|
||||
merge_requests_author_approval: false
|
||||
merge_requests_disable_committers_approval: true
|
||||
"""
|
||||
|
||||
RETURN = r"""
|
||||
project_approvals:
|
||||
description: The updated GitLab project approval settings.
|
||||
returned: always
|
||||
type: dict
|
||||
sample:
|
||||
approvals_before_merge: 2
|
||||
reset_approvals_on_push: true
|
||||
disable_overriding_approvers_per_merge_request: false
|
||||
merge_requests_author_approval: false
|
||||
merge_requests_disable_committers_approval: true
|
||||
"""
|
||||
|
||||
|
||||
from ansible.module_utils.api import basic_auth_argument_spec
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
|
||||
from ansible_collections.community.general.plugins.module_utils._gitlab import (
|
||||
auth_argument_spec,
|
||||
find_project,
|
||||
gitlab_authentication,
|
||||
)
|
||||
|
||||
|
||||
class GitlabProjectApprovals:
|
||||
def __init__(self, module, gitlab_instance):
|
||||
self._module = module
|
||||
self._gitlab = gitlab_instance
|
||||
self.project = self.get_project(module.params["project"])
|
||||
|
||||
def get_project(self, project_name):
|
||||
project = find_project(self._gitlab, project_name)
|
||||
if project is None:
|
||||
self._module.fail_json(msg=f"Project {project_name} not found or insufficient permissions.")
|
||||
return project
|
||||
|
||||
def update_approval_settings(self, options):
|
||||
changed = False
|
||||
try:
|
||||
approval_settings = self.project.approvals.get()
|
||||
except Exception as e:
|
||||
self._module.fail_json(msg=f"Failed to get project approval settings: {e}")
|
||||
|
||||
# Check which options differ from current settings and apply them
|
||||
for key, value in options.items():
|
||||
if value is not None:
|
||||
current_value = getattr(approval_settings, key, None)
|
||||
if current_value != value:
|
||||
setattr(approval_settings, key, value)
|
||||
changed = True
|
||||
|
||||
if changed:
|
||||
if not self._module.check_mode:
|
||||
try:
|
||||
approval_settings.save()
|
||||
except Exception as e:
|
||||
self._module.fail_json(msg=f"Failed to update project approval settings: {e}")
|
||||
|
||||
return changed, approval_settings.attributes
|
||||
|
||||
|
||||
def main():
|
||||
argument_spec = basic_auth_argument_spec()
|
||||
argument_spec.update(auth_argument_spec())
|
||||
argument_spec.update(
|
||||
dict(
|
||||
project=dict(type="str", required=True),
|
||||
approvals_before_merge=dict(type="int"),
|
||||
reset_approvals_on_push=dict(type="bool"),
|
||||
disable_overriding_approvers_per_merge_request=dict(type="bool"),
|
||||
merge_requests_author_approval=dict(type="bool"),
|
||||
merge_requests_disable_committers_approval=dict(type="bool"),
|
||||
selective_code_owner_removals=dict(type="bool"),
|
||||
require_password_to_approve=dict(type="bool"),
|
||||
require_reauthentication_to_approve=dict(type="bool"),
|
||||
)
|
||||
)
|
||||
|
||||
module = AnsibleModule(
|
||||
argument_spec=argument_spec,
|
||||
mutually_exclusive=[
|
||||
["api_username", "api_token"],
|
||||
["api_username", "api_oauth_token"],
|
||||
["api_username", "api_job_token"],
|
||||
["api_token", "api_oauth_token"],
|
||||
["api_token", "api_job_token"],
|
||||
],
|
||||
required_together=[
|
||||
["api_username", "api_password"],
|
||||
],
|
||||
required_one_of=[["api_username", "api_token", "api_oauth_token", "api_job_token"]],
|
||||
supports_check_mode=True,
|
||||
)
|
||||
|
||||
gitlab_instance = gitlab_authentication(module)
|
||||
|
||||
gitlab_project_approvals = GitlabProjectApprovals(module, gitlab_instance)
|
||||
|
||||
options = {
|
||||
"approvals_before_merge": module.params["approvals_before_merge"],
|
||||
"reset_approvals_on_push": module.params["reset_approvals_on_push"],
|
||||
"disable_overriding_approvers_per_merge_request": module.params[
|
||||
"disable_overriding_approvers_per_merge_request"
|
||||
],
|
||||
"merge_requests_author_approval": module.params["merge_requests_author_approval"],
|
||||
"merge_requests_disable_committers_approval": module.params["merge_requests_disable_committers_approval"],
|
||||
"selective_code_owner_removals": module.params["selective_code_owner_removals"],
|
||||
"require_password_to_approve": module.params["require_password_to_approve"],
|
||||
"require_reauthentication_to_approve": module.params["require_reauthentication_to_approve"],
|
||||
}
|
||||
|
||||
changed, approval_attrs = gitlab_project_approvals.update_approval_settings(options)
|
||||
|
||||
module.exit_json(changed=changed, project_approvals=approval_attrs)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
---
|
||||
# Copyright (c) Ansible Project
|
||||
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
gitlab_api_token: glpat-XXXXXXXXXXXXXXXXXXXX
|
||||
gitlab_api_url: https://gitlab.com
|
||||
gitlab_project_name: ansible_test_project
|
||||
|
|
@ -0,0 +1,74 @@
|
|||
---
|
||||
####################################################################
|
||||
# WARNING: These are designed specifically for Ansible tests #
|
||||
# and should not be used as examples of how to write Ansible roles #
|
||||
####################################################################
|
||||
|
||||
# Copyright (c) Ansible Project
|
||||
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
- name: Install required libs
|
||||
pip:
|
||||
name: python-gitlab
|
||||
state: present
|
||||
|
||||
- name: Set project approval settings
|
||||
gitlab_project_approvals:
|
||||
api_url: "{{ gitlab_api_url }}"
|
||||
validate_certs: false
|
||||
api_token: "{{ gitlab_api_token }}"
|
||||
project: "{{ gitlab_project_name }}"
|
||||
approvals_before_merge: 2
|
||||
reset_approvals_on_push: false
|
||||
disable_overriding_approvers_per_merge_request: true
|
||||
merge_requests_author_approval: true
|
||||
merge_requests_disable_committers_approval: true
|
||||
selective_code_owner_removals: true
|
||||
require_password_to_approve: true
|
||||
require_reauthentication_to_approve: true
|
||||
register: approval_result
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- approval_result is changed
|
||||
|
||||
- name: Re-run project approval for idempotency
|
||||
gitlab_project_approvals:
|
||||
api_url: "{{ gitlab_api_url }}"
|
||||
validate_certs: false
|
||||
api_token: "{{ gitlab_api_token }}"
|
||||
project: "{{ gitlab_project_name }}"
|
||||
approvals_before_merge: 2
|
||||
reset_approvals_on_push: false
|
||||
disable_overriding_approvers_per_merge_request: true
|
||||
merge_requests_author_approval: true
|
||||
merge_requests_disable_committers_approval: true
|
||||
selective_code_owner_removals: true
|
||||
require_password_to_approve: true
|
||||
require_reauthentication_to_approve: true
|
||||
register: approval_result_idem
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- approval_result_idem is not changed
|
||||
|
||||
- name: Reset project approval settings
|
||||
gitlab_project_approvals:
|
||||
api_url: "{{ gitlab_api_url }}"
|
||||
validate_certs: false
|
||||
api_token: "{{ gitlab_api_token }}"
|
||||
project: "{{ gitlab_project_name }}"
|
||||
approvals_before_merge: 0
|
||||
reset_approvals_on_push: true
|
||||
disable_overriding_approvers_per_merge_request: false
|
||||
merge_requests_author_approval: false
|
||||
merge_requests_disable_committers_approval: false
|
||||
selective_code_owner_removals: false
|
||||
require_password_to_approve: false
|
||||
require_reauthentication_to_approve: false
|
||||
register: approval_result
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- approval_result is changed
|
||||
Loading…
Add table
Add a link
Reference in a new issue