mirror of
https://github.com/ansible-collections/community.general.git
synced 2024-09-14 20:13:21 +02:00
[PR #3935/f3be0076 backport][stable-6] Add Gitlab group runners support (#6234)
Add Gitlab group runners support (#3935)
(cherry picked from commit f3be0076af
)
Co-authored-by: Léo GATELLIER <26511053+lgatellier@users.noreply.github.com>
This commit is contained in:
parent
493fa405e2
commit
16a18d1456
4 changed files with 124 additions and 7 deletions
2
changelogs/fragments/3935-add-gitlab-group-runner.yml
Normal file
2
changelogs/fragments/3935-add-gitlab-group-runner.yml
Normal file
|
@ -0,0 +1,2 @@
|
|||
minor_changes:
|
||||
- 'gitlab_runner - allow to register group runner (https://github.com/ansible-collections/community.general/pull/3935).'
|
|
@ -44,10 +44,17 @@ attributes:
|
|||
support: none
|
||||
|
||||
options:
|
||||
group:
|
||||
description:
|
||||
- ID or full path of the group in the form group/subgroup.
|
||||
- Mutually exclusive with I(owned) and I(project).
|
||||
type: str
|
||||
version_added: '6.5.0'
|
||||
project:
|
||||
description:
|
||||
- ID or full path of the project in the form of group/name.
|
||||
- Mutually exclusive with I(owned) since community.general 4.5.0.
|
||||
- Mutually exclusive with I(group).
|
||||
type: str
|
||||
version_added: '3.7.0'
|
||||
description:
|
||||
|
@ -73,6 +80,7 @@ options:
|
|||
description:
|
||||
- Searches only runners available to the user when searching for existing, when false admin token required.
|
||||
- Mutually exclusive with I(project) since community.general 4.5.0.
|
||||
- Mutually exclusive with I(group).
|
||||
default: false
|
||||
type: bool
|
||||
version_added: 2.0.0
|
||||
|
@ -209,21 +217,23 @@ except NameError:
|
|||
|
||||
|
||||
class GitLabRunner(object):
|
||||
def __init__(self, module, gitlab_instance, project=None):
|
||||
def __init__(self, module, gitlab_instance, group=None, project=None):
|
||||
self._module = module
|
||||
self._gitlab = gitlab_instance
|
||||
self.runner_object = None
|
||||
|
||||
# Whether to operate on GitLab-instance-wide or project-wide runners
|
||||
# See https://gitlab.com/gitlab-org/gitlab-ce/issues/60774
|
||||
# for group runner token access
|
||||
if project:
|
||||
self._runners_endpoint = project.runners.list
|
||||
elif group:
|
||||
self._runners_endpoint = group.runners.list
|
||||
elif module.params['owned']:
|
||||
self._runners_endpoint = gitlab_instance.runners.list
|
||||
else:
|
||||
self._runners_endpoint = gitlab_instance.runners.all
|
||||
|
||||
self.runner_object = None
|
||||
|
||||
def create_or_update_runner(self, description, options):
|
||||
changed = False
|
||||
|
||||
|
@ -360,6 +370,7 @@ def main():
|
|||
maximum_timeout=dict(type='int', default=3600),
|
||||
registration_token=dict(type='str', no_log=True),
|
||||
project=dict(type='str'),
|
||||
group=dict(type='str'),
|
||||
state=dict(type='str', default="present", choices=["absent", "present"]),
|
||||
))
|
||||
|
||||
|
@ -372,6 +383,8 @@ def main():
|
|||
['api_token', 'api_oauth_token'],
|
||||
['api_token', 'api_job_token'],
|
||||
['project', 'owned'],
|
||||
['group', 'owned'],
|
||||
['project', 'group'],
|
||||
],
|
||||
required_together=[
|
||||
['api_username', 'api_password'],
|
||||
|
@ -396,6 +409,7 @@ def main():
|
|||
maximum_timeout = module.params['maximum_timeout']
|
||||
registration_token = module.params['registration_token']
|
||||
project = module.params['project']
|
||||
group = module.params['group']
|
||||
|
||||
if access_level is None:
|
||||
message = "The option 'access_level' is unspecified, so 'ref_protected' is assumed. "\
|
||||
|
@ -408,13 +422,20 @@ def main():
|
|||
|
||||
gitlab_instance = gitlab_authentication(module)
|
||||
gitlab_project = None
|
||||
gitlab_group = None
|
||||
|
||||
if project:
|
||||
try:
|
||||
gitlab_project = gitlab_instance.projects.get(project)
|
||||
except gitlab.exceptions.GitlabGetError as e:
|
||||
module.fail_json(msg='No such a project %s' % project, exception=to_native(e))
|
||||
elif group:
|
||||
try:
|
||||
gitlab_group = gitlab_instance.groups.get(group)
|
||||
except gitlab.exceptions.GitlabGetError as e:
|
||||
module.fail_json(msg='No such a group %s' % group, exception=to_native(e))
|
||||
|
||||
gitlab_runner = GitLabRunner(module, gitlab_instance, gitlab_project)
|
||||
gitlab_runner = GitLabRunner(module, gitlab_instance, gitlab_group, gitlab_project)
|
||||
runner_exists = gitlab_runner.exists_runner(runner_description)
|
||||
|
||||
if state == 'absent':
|
||||
|
|
|
@ -213,6 +213,31 @@ def resp_get_group(url, request):
|
|||
return response(200, content, headers, None, 5, request)
|
||||
|
||||
|
||||
@urlmatch(scheme="http", netloc="localhost", path="/api/v4/groups/foo-bar", method="get")
|
||||
def resp_get_group_by_name(url, request):
|
||||
headers = {'content-type': 'application/json'}
|
||||
content = ('{"id": 1, "name": "Foobar Group", "path": "foo-bar",'
|
||||
'"description": "An interesting group", "visibility": "public",'
|
||||
'"lfs_enabled": true, "avatar_url": "http://localhost:3000/uploads/group/avatar/1/foo.jpg",'
|
||||
'"web_url": "http://localhost:3000/groups/foo-bar", "request_access_enabled": false,'
|
||||
'"full_name": "Foobar Group", "full_path": "foo-bar",'
|
||||
'"project_creation_level": "maintainer", "subgroup_creation_level": "maintainer",'
|
||||
'"require_two_factor_authentication": true,'
|
||||
'"file_template_project_id": 1, "parent_id": null, "projects": [{"id": 1,"description": null, "default_branch": "master",'
|
||||
'"ssh_url_to_repo": "git@example.com:diaspora/diaspora-client.git",'
|
||||
'"http_url_to_repo": "http://example.com/diaspora/diaspora-client.git",'
|
||||
'"web_url": "http://example.com/diaspora/diaspora-client",'
|
||||
'"readme_url": "http://example.com/diaspora/diaspora-client/blob/master/README.md",'
|
||||
'"tag_list": ["example","disapora client"],"name": "Diaspora Client",'
|
||||
'"name_with_namespace": "Diaspora / Diaspora Client","path": "diaspora-client",'
|
||||
'"path_with_namespace": "diaspora/diaspora-client","created_at": "2013-09-30T13:46:02Z",'
|
||||
'"last_activity_at": "2013-09-30T13:46:02Z","forks_count": 0,'
|
||||
'"avatar_url": "http://example.com/uploads/project/avatar/4/uploads/avatar.png",'
|
||||
'"star_count": 0}]}')
|
||||
content = content.encode("utf-8")
|
||||
return response(200, content, headers, None, 5, request)
|
||||
|
||||
|
||||
@urlmatch(scheme="http", netloc="localhost", path="/api/v4/groups/1", method="get")
|
||||
def resp_get_missing_group(url, request):
|
||||
headers = {'content-type': 'application/json'}
|
||||
|
@ -600,6 +625,40 @@ def resp_find_runners_list(url, request):
|
|||
return response(200, content, headers, None, 5, request)
|
||||
|
||||
|
||||
@urlmatch(scheme="http", netloc="localhost", path=r'/api/v4/projects/1/runners$', method="get")
|
||||
def resp_find_project_runners(url, request):
|
||||
headers = {'content-type': 'application/json',
|
||||
"X-Page": 1,
|
||||
"X-Next-Page": 2,
|
||||
"X-Per-Page": 1,
|
||||
"X-Total-Pages": 1,
|
||||
"X-Total": 2}
|
||||
content = ('[{"active": true,"description": "test-1-20220210","id": 1,'
|
||||
'"is_shared": false,"ip_address": "127.0.0.1","name": null,'
|
||||
'"online": true,"status": "online"},{"active": true,'
|
||||
'"description": "test-2-20220210","id": 2,"ip_address": "127.0.0.1",'
|
||||
'"is_shared": false,"name": null,"online": false,"status": "offline"}]')
|
||||
content = content.encode("utf-8")
|
||||
return response(200, content, headers, None, 5, request)
|
||||
|
||||
|
||||
@urlmatch(scheme="http", netloc="localhost", path=r'/api/v4/groups/1/runners$', method="get")
|
||||
def resp_find_group_runners(url, request):
|
||||
headers = {'content-type': 'application/json',
|
||||
"X-Page": 1,
|
||||
"X-Next-Page": 2,
|
||||
"X-Per-Page": 1,
|
||||
"X-Total-Pages": 1,
|
||||
"X-Total": 2}
|
||||
content = ('[{"active": true,"description": "test-3-20220210","id": 1,'
|
||||
'"is_shared": false,"ip_address": "127.0.0.1","name": null,'
|
||||
'"online": true,"status": "online"},{"active": true,'
|
||||
'"description": "test-4-20220210","id": 2,"ip_address": "127.0.0.1",'
|
||||
'"is_shared": false,"name": null,"online": false,"status": "offline"}]')
|
||||
content = content.encode("utf-8")
|
||||
return response(200, content, headers, None, 5, request)
|
||||
|
||||
|
||||
@urlmatch(scheme="http", netloc="localhost", path=r'/api/v4/runners/1$', method="put")
|
||||
def resp_update_runner(url, request):
|
||||
headers = {'content-type': 'application/json',
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
from __future__ import (absolute_import, division, print_function)
|
||||
|
||||
import gitlab
|
||||
__metaclass__ = type
|
||||
|
||||
import pytest
|
||||
|
@ -23,9 +25,11 @@ try:
|
|||
from .gitlab import (FakeAnsibleModule,
|
||||
GitlabModuleTestCase,
|
||||
python_version_match_requirement,
|
||||
resp_find_runners_all,
|
||||
resp_find_runners_list, resp_get_runner,
|
||||
resp_create_runner, resp_delete_runner)
|
||||
resp_find_runners_all, resp_find_runners_list,
|
||||
resp_find_project_runners, resp_find_group_runners,
|
||||
resp_get_runner,
|
||||
resp_create_runner, resp_delete_runner,
|
||||
resp_get_project_by_name, resp_get_group_by_name)
|
||||
|
||||
# GitLab module requirements
|
||||
if python_version_match_requirement():
|
||||
|
@ -76,6 +80,37 @@ class TestGitlabRunner(GitlabModuleTestCase):
|
|||
|
||||
self.assertEqual(rvalue, False)
|
||||
|
||||
@with_httmock(resp_find_project_runners)
|
||||
@with_httmock(resp_get_runner)
|
||||
@with_httmock(resp_get_project_by_name)
|
||||
def test_project_runner_exist(self):
|
||||
gitlab_project = self.gitlab_instance.projects.get('foo-bar/diaspora-client')
|
||||
module_util = GitLabRunner(module=FakeAnsibleModule(), gitlab_instance=self.gitlab_instance, project=gitlab_project)
|
||||
|
||||
rvalue = module_util.exists_runner("test-1-20220210")
|
||||
|
||||
self.assertEqual(rvalue, True)
|
||||
|
||||
rvalue = module_util.exists_runner("test-3-00000000")
|
||||
|
||||
self.assertEqual(rvalue, False)
|
||||
|
||||
@with_httmock(resp_find_group_runners)
|
||||
@with_httmock(resp_get_group_by_name)
|
||||
@with_httmock(resp_get_runner)
|
||||
@pytest.mark.skipif(gitlab.__version__ < "2.3.0", reason="require python-gitlab >= 2.3.0")
|
||||
def test_group_runner_exist(self):
|
||||
gitlab_group = self.gitlab_instance.groups.get('foo-bar')
|
||||
module_util = GitLabRunner(module=FakeAnsibleModule(), gitlab_instance=self.gitlab_instance, group=gitlab_group)
|
||||
|
||||
rvalue = module_util.exists_runner("test-3-20220210")
|
||||
|
||||
self.assertEqual(rvalue, True)
|
||||
|
||||
rvalue = module_util.exists_runner("test-3-00000000")
|
||||
|
||||
self.assertEqual(rvalue, False)
|
||||
|
||||
@with_httmock(resp_create_runner)
|
||||
def test_create_runner(self):
|
||||
runner = self.module_util_all.create_runner({"token": "token", "description": "test-1-20150125"})
|
||||
|
|
Loading…
Reference in a new issue