mirror of
https://github.com/ansible-collections/community.general.git
synced 2024-09-14 20:13:21 +02:00
added option to share projects with a group
This commit is contained in:
parent
37c8560542
commit
a243ecce27
2 changed files with 262 additions and 101 deletions
|
@ -0,0 +1,2 @@
|
|||
minor_changes:
|
||||
- gitlab_project_members - add ``gitlab_group`` option to share and unshare project with groups (https://github.com/ansible-collections/community.general/pull/8676).
|
|
@ -42,7 +42,7 @@ options:
|
|||
gitlab_user:
|
||||
description:
|
||||
- A username or a list of usernames to add to/remove from the GitLab project.
|
||||
- Mutually exclusive with O(gitlab_users_access).
|
||||
- Mutually exclusive with O(gitlab_users_access) and O(gitlab_group).
|
||||
type: list
|
||||
elements: str
|
||||
access_level:
|
||||
|
@ -55,7 +55,7 @@ options:
|
|||
description:
|
||||
- Provide a list of user to access level mappings.
|
||||
- Every dictionary in this list specifies a user (by username) and the access level the user should have.
|
||||
- Mutually exclusive with O(gitlab_user) and O(access_level).
|
||||
- Mutually exclusive with O(gitlab_user), O(access_level), and O(gitlab_group).
|
||||
- Use together with O(purge_users) to remove all users not specified here from the project.
|
||||
type: list
|
||||
elements: dict
|
||||
|
@ -89,6 +89,27 @@ options:
|
|||
elements: str
|
||||
choices: ['guest', 'reporter', 'developer', 'maintainer']
|
||||
version_added: 3.7.0
|
||||
gitlab_group:
|
||||
description:
|
||||
- A list of IDs or the full paths of the groups to share/unshare the project with.
|
||||
- Every dictionary in this list specifies a group (by ID or full path) and the access level the group should have.
|
||||
- Mutually exclusive with O(gitlab_user), O(access_level) and O(gitlab_users_access).
|
||||
type: list
|
||||
elements: dict
|
||||
version_added: 9.3.0
|
||||
suboptions:
|
||||
name:
|
||||
description: ID or the full path of the group to share/unshare the project with.
|
||||
type: str
|
||||
required: true
|
||||
group_access_level:
|
||||
description:
|
||||
- The access level for the group.
|
||||
- Required if O(state=present), group state is set to present.
|
||||
type: str
|
||||
choices: ['guest', 'reporter', 'developer', 'maintainer']
|
||||
required: false
|
||||
|
||||
'''
|
||||
|
||||
EXAMPLES = r'''
|
||||
|
@ -154,6 +175,27 @@ EXAMPLES = r'''
|
|||
- name: user2
|
||||
access_level: maintainer
|
||||
state: absent
|
||||
|
||||
- name: Share a project with a list of Groups with Dedicated Access Levels to A GitLab project
|
||||
community.general.gitlab_project_members:
|
||||
api_url: 'https://gitlab.example.com'
|
||||
api_token: 'Your-Private-Token'
|
||||
project: projectname
|
||||
gitlab_group:
|
||||
- name: group1
|
||||
group_access_level: developer
|
||||
- name: group2
|
||||
group_access_level: maintainer
|
||||
state: present
|
||||
|
||||
- name: Unshare a project with a group
|
||||
community.general.gitlab_project_members:
|
||||
api_url: 'https://gitlab.example.com'
|
||||
api_token: 'Your-Private-Token'
|
||||
project: projectname
|
||||
gitlab_group:
|
||||
- name: group1
|
||||
state: absent
|
||||
'''
|
||||
|
||||
RETURN = r''' # '''
|
||||
|
@ -190,6 +232,11 @@ class GitLabProjectMembers(object):
|
|||
project = self._gitlab.projects.get(gitlab_project_id)
|
||||
return project.members.list(all=True)
|
||||
|
||||
# get all groups in a project
|
||||
def get_groups_in_a_project(self, gitlab_project_id):
|
||||
project = self._gitlab.projects.get(gitlab_project_id)
|
||||
return [group['group_id'] for group in project.shared_with_groups]
|
||||
|
||||
# get single member in a project by user name
|
||||
def get_member_in_a_project(self, gitlab_project_id, gitlab_user_id):
|
||||
member = None
|
||||
|
@ -208,6 +255,13 @@ class GitLabProjectMembers(object):
|
|||
return True
|
||||
return False
|
||||
|
||||
# check if the group is in the project
|
||||
def is_group_in_project(self, groups, group_id):
|
||||
for gid in groups:
|
||||
if gid == group_id:
|
||||
return True
|
||||
return False
|
||||
|
||||
# add user to a project
|
||||
def add_member_to_project(self, gitlab_user_id, gitlab_project_id, access_level):
|
||||
project = self._gitlab.projects.get(gitlab_project_id)
|
||||
|
@ -232,6 +286,23 @@ class GitLabProjectMembers(object):
|
|||
member.access_level = access_level
|
||||
member.save()
|
||||
|
||||
def get_group_id(self, group_name):
|
||||
try:
|
||||
group_exists = self._gitlab.groups.get(group_name)
|
||||
return group_exists.id
|
||||
except gitlab.exceptions.GitlabGetError as e:
|
||||
return None
|
||||
|
||||
# share project with a group
|
||||
def share_project_with_group(self, gitlab_project_id, group_id, access_level):
|
||||
project = self._gitlab.projects.get(gitlab_project_id)
|
||||
project.share(group_id, access_level)
|
||||
|
||||
# unshare project with a group
|
||||
def unshare_project_with_group(self, gitlab_project_id, group_id):
|
||||
project = self._gitlab.projects.get(gitlab_project_id)
|
||||
project.unshare(group_id)
|
||||
|
||||
|
||||
def main():
|
||||
argument_spec = basic_auth_argument_spec()
|
||||
|
@ -252,6 +323,15 @@ def main():
|
|||
'guest', 'reporter', 'developer', 'maintainer'], required=True),
|
||||
)
|
||||
),
|
||||
gitlab_group=dict(
|
||||
type='list',
|
||||
elements='dict',
|
||||
options=dict(
|
||||
name=dict(type='str', required=True),
|
||||
group_access_level=dict(type='str', choices=[
|
||||
'guest', 'reporter', 'developer', 'maintainer'], required=False),
|
||||
)
|
||||
),
|
||||
))
|
||||
|
||||
module = AnsibleModule(
|
||||
|
@ -262,8 +342,8 @@ def main():
|
|||
['api_username', 'api_job_token'],
|
||||
['api_token', 'api_oauth_token'],
|
||||
['api_token', 'api_job_token'],
|
||||
['gitlab_user', 'gitlab_users_access'],
|
||||
['access_level', 'gitlab_users_access'],
|
||||
['gitlab_user', 'gitlab_users_access', 'gitlab_group'],
|
||||
['access_level', 'gitlab_users_access', 'gitlab_group'],
|
||||
],
|
||||
required_together=[
|
||||
['api_username', 'api_password'],
|
||||
|
@ -271,10 +351,10 @@ def main():
|
|||
],
|
||||
required_one_of=[
|
||||
['api_username', 'api_token', 'api_oauth_token', 'api_job_token'],
|
||||
['gitlab_user', 'gitlab_users_access'],
|
||||
['gitlab_user', 'gitlab_users_access', 'gitlab_group'],
|
||||
],
|
||||
required_if=[
|
||||
['state', 'present', ['access_level', 'gitlab_users_access'], True],
|
||||
['state', 'present', ['access_level', 'gitlab_users_access', 'gitlab_group'], True],
|
||||
],
|
||||
supports_check_mode=True,
|
||||
)
|
||||
|
@ -293,6 +373,9 @@ def main():
|
|||
state = module.params['state']
|
||||
access_level = module.params['access_level']
|
||||
purge_users = module.params['purge_users']
|
||||
gitlab_users_access = []
|
||||
# initializing for the main loop
|
||||
gitlab_groups = []
|
||||
|
||||
if purge_users:
|
||||
purge_users = [access_level_int[level] for level in purge_users]
|
||||
|
@ -306,8 +389,8 @@ def main():
|
|||
module.fail_json(msg="project '%s' not found." % gitlab_project)
|
||||
|
||||
members = []
|
||||
groups = []
|
||||
if module.params['gitlab_user'] is not None:
|
||||
gitlab_users_access = []
|
||||
gitlab_users = module.params['gitlab_user']
|
||||
for gl_user in gitlab_users:
|
||||
gitlab_users_access.append(
|
||||
|
@ -316,8 +399,13 @@ def main():
|
|||
gitlab_users_access = module.params['gitlab_users_access']
|
||||
for user_level in gitlab_users_access:
|
||||
user_level['access_level'] = access_level_int[user_level['access_level']]
|
||||
elif module.params['gitlab_group'] is not None:
|
||||
gitlab_groups = module.params['gitlab_group']
|
||||
groups = project.get_groups_in_a_project(gitlab_project_id)
|
||||
|
||||
if len(gitlab_users_access) == 1 and not purge_users:
|
||||
if gitlab_groups:
|
||||
pass
|
||||
elif len(gitlab_users_access) == 1 and not purge_users:
|
||||
# only single user given
|
||||
members = [project.get_member_in_a_project(
|
||||
gitlab_project_id, project.get_user_id(gitlab_users_access[0]['name']))]
|
||||
|
@ -327,14 +415,16 @@ def main():
|
|||
# list of users given
|
||||
members = project.get_members_in_a_project(gitlab_project_id)
|
||||
else:
|
||||
module.exit_json(changed='OK', result="Nothing to do, please give at least one user or set purge_users true.",
|
||||
module.exit_json(changed='OK', result="Nothing to do, please give at least one user or group or set purge_users true.",
|
||||
result_data=[])
|
||||
|
||||
changed = False
|
||||
error = False
|
||||
changed_users = []
|
||||
changed_groups = []
|
||||
changed_data = []
|
||||
|
||||
if gitlab_users_access:
|
||||
for gitlab_user in gitlab_users_access:
|
||||
gitlab_user_id = project.get_user_id(gitlab_user['name'])
|
||||
|
||||
|
@ -441,6 +531,75 @@ def main():
|
|||
msg='FAILED: At least one given user/permission could not be set', result_data=changed_data)
|
||||
|
||||
module.exit_json(changed=changed, msg='Successfully set memberships', result="\n".join(changed_users), result_data=changed_data)
|
||||
elif gitlab_groups:
|
||||
# group logic goes here
|
||||
for gitlab_group in gitlab_groups:
|
||||
group_id = project.get_group_id(gitlab_group['name'])
|
||||
|
||||
# group doesn't exist
|
||||
if not group_id:
|
||||
if state == 'absent':
|
||||
changed_groups.append("group '%s' not found, and thus also not part of the project" % gitlab_group['name'])
|
||||
changed_data.append({'gitlab_group': gitlab_group['name'], 'result': 'OK',
|
||||
'msg': "group '%s' not found, and thus also not part of the project" % gitlab_group['name']})
|
||||
else:
|
||||
error = True
|
||||
changed_groups.append("group '%s' not found." % gitlab_group['name'])
|
||||
changed_data.append({'gitlab_group': gitlab_group['name'], 'result': 'FAILED',
|
||||
'msg': "group '%s' not found." % gitlab_group['name']})
|
||||
continue
|
||||
is_group_in_project = project.is_group_in_project(groups, group_id)
|
||||
|
||||
# check if the group is in the project
|
||||
if not is_group_in_project:
|
||||
if state == 'present':
|
||||
# share project with the group
|
||||
try:
|
||||
if not module.check_mode:
|
||||
project.share_project_with_group(gitlab_project_id, group_id, access_level_int[gitlab_group['group_access_level']])
|
||||
changed = True
|
||||
changed_groups.append("Successfully shared project with group '%s'" % gitlab_group['name'])
|
||||
changed_data.append({'gitlab_group': gitlab_group['name'], 'result': 'CHANGED',
|
||||
'msg': "Successfully shared project with group '%s'" % gitlab_group['name']})
|
||||
except (gitlab.exceptions.GitlabCreateError) as e:
|
||||
error = False
|
||||
changed_groups.append("Failed to share project with group '%s'" % gitlab_group['name'])
|
||||
changed_data.append({'gitlab_group': gitlab_group['name'], 'result': 'OK',
|
||||
'msg': "Failed to share project with group '%s': %s. No change to report." % (gitlab_group['name'], e)})
|
||||
# state as absent
|
||||
else:
|
||||
changed_groups.append("Group, '%s', is not in the project. No change to report" % gitlab_group['name'])
|
||||
changed_data.append({'gitlab_group': gitlab_group['name'], 'result': 'OK',
|
||||
'msg': "Group, '%s', is not in the project. No change to report" % gitlab_group['name']})
|
||||
# in case that a group is in the project
|
||||
else:
|
||||
if state == 'present':
|
||||
# i have not seen a way to get/update the access level for a group in a project, we are skipping this
|
||||
changed_groups.append("Group, '%s', is already in the project. No change to report" % gitlab_group['name'])
|
||||
changed_data.append({'gitlab_group': gitlab_group['name'], 'result': 'OK',
|
||||
'msg': "Group, '%s', is already in the project. No change to report" % gitlab_group['name']})
|
||||
else:
|
||||
# unshare the project with the group
|
||||
try:
|
||||
if not module.check_mode:
|
||||
project.unshare_project_with_group(gitlab_project_id, group_id)
|
||||
changed = True
|
||||
changed_groups.append("Successfully unshared project with group, '%s'" % gitlab_group['name'])
|
||||
changed_data.append({'gitlab_group': gitlab_group['name'], 'result': 'CHANGED',
|
||||
'msg': "Successfully unshared project with group, '%s'" % gitlab_group['name']})
|
||||
except (gitlab.exceptions.GitlabDeleteError) as e:
|
||||
error = True
|
||||
changed_groups.append("Failed to unshare project with group, '%s'" % gitlab_group['name'])
|
||||
changed_data.append({'gitlab_group': gitlab_group['name'], 'result': 'FAILED',
|
||||
'msg': "Failed to unshare project with group, '%s': %s" % (gitlab_group['name'], e)})
|
||||
if len(gitlab_groups) == 1 and error:
|
||||
# if single group given and an error occurred return error for list errors will be per group
|
||||
module.fail_json(msg="FAILED: '%s '" % changed_groups[0], result_data=changed_data)
|
||||
elif error:
|
||||
module.fail_json(
|
||||
msg='FAILED: At least one given group could not be set', result_data=changed_data)
|
||||
|
||||
module.exit_json(changed=changed, msg='Successfully set memberships', result="\n".join(changed_groups), result_data=changed_data)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
|
Loading…
Reference in a new issue