Skip to content

Commit

Permalink
Merge pull request #1064 from python-gitlab/feat/project-remote-mirrors
Browse files Browse the repository at this point in the history
feat(api): add support for remote mirrors API (#1056)
  • Loading branch information
max-wittig committed Apr 7, 2020
2 parents c161852 + 4cfaa2f commit 3396aa5
Show file tree
Hide file tree
Showing 5 changed files with 159 additions and 0 deletions.
1 change: 1 addition & 0 deletions docs/api-objects.rst
Expand Up @@ -37,6 +37,7 @@ API examples
gl_objects/projects
gl_objects/protected_branches
gl_objects/runners
gl_objects/remote_mirrors
gl_objects/repositories
gl_objects/repository_tags
gl_objects/search
Expand Down
34 changes: 34 additions & 0 deletions docs/gl_objects/remote_mirrors.rst
@@ -0,0 +1,34 @@
##########
Project Remote Mirrors
##########

Remote Mirrors allow you to set up push mirroring for a project.

References
==========

* v4 API:

+ :class:`gitlab.v4.objects.ProjectRemoteMirror`
+ :class:`gitlab.v4.objects.ProjectRemoteMirrorManager`
+ :attr:`gitlab.v4.objects.Project.remote_mirrors`

* GitLab API: https://docs.gitlab.com/ce/api/remote_mirrors.html

Examples
--------

Get the list of a project's remote mirrors::

mirrors = project.remote_mirrors.list()

Create (and enable) a remote mirror for a project::

mirror = project.wikis.create({'url': 'https://gitlab.com/example.git',
'enabled': True})

Update an existing remote mirror's attributes::

mirror.enabled = False
mirror.only_protected_branches = True
mirror.save()
94 changes: 94 additions & 0 deletions gitlab/tests/objects/test_projects.py
Expand Up @@ -90,6 +90,77 @@ def resp_import_github(url, request):
return response(200, content, headers, None, 25, request)


@urlmatch(
scheme="http",
netloc="localhost",
path="/api/v4/projects/1/remote_mirrors",
method="get",
)
def resp_get_remote_mirrors(url, request):
"""Mock for Project Remote Mirrors GET response."""
content = """[
{
"enabled": true,
"id": 101486,
"last_error": null,
"last_successful_update_at": "2020-01-06T17:32:02.823Z",
"last_update_at": "2020-01-06T17:32:02.823Z",
"last_update_started_at": "2020-01-06T17:31:55.864Z",
"only_protected_branches": true,
"update_status": "finished",
"url": "https://*****:*****@gitlab.com/gitlab-org/security/gitlab.git"
}
]"""
content = content.encode("utf-8")
return response(200, content, headers, None, 5, request)


@urlmatch(
scheme="http",
netloc="localhost",
path="/api/v4/projects/1/remote_mirrors",
method="post",
)
def resp_create_remote_mirror(url, request):
"""Mock for Project Remote Mirrors POST response."""
content = """{
"enabled": false,
"id": 101486,
"last_error": null,
"last_successful_update_at": null,
"last_update_at": null,
"last_update_started_at": null,
"only_protected_branches": false,
"update_status": "none",
"url": "https://*****:*****@example.com/gitlab/example.git"
}"""
content = content.encode("utf-8")
return response(200, content, headers, None, 5, request)


@urlmatch(
scheme="http",
netloc="localhost",
path="/api/v4/projects/1/remote_mirrors/1",
method="put",
)
def resp_update_remote_mirror(url, request):
"""Mock for Project Remote Mirrors PUT response."""
content = """{
"enabled": false,
"id": 101486,
"last_error": null,
"last_successful_update_at": "2020-01-06T17:32:02.823Z",
"last_update_at": "2020-01-06T17:32:02.823Z",
"last_update_started_at": "2020-01-06T17:31:55.864Z",
"only_protected_branches": true,
"update_status": "finished",
"url": "https://*****:*****@gitlab.com/gitlab-org/security/gitlab.git"
}"""
content = content.encode("utf-8")
return response(200, content, headers, None, 5, request)


class TestProject(unittest.TestCase):
"""Base class for GitLab Project tests."""

Expand Down Expand Up @@ -262,3 +333,26 @@ def test_import_github(self):
self.assertEqual(ret["name"], name)
self.assertEqual(ret["full_path"], "/".join((base_path, name)))
self.assertTrue(ret["full_name"].endswith(name))


class TestProjectRemoteMirrors(TestProject):
@with_httmock(resp_get_remote_mirrors)
def test_list_project_remote_mirrors(self):
mirrors = self.project.remote_mirrors.list()
self.assertIsInstance(mirrors, list)
self.assertIsInstance(mirrors[0], ProjectRemoteMirror)
self.assertTrue(mirrors[0].enabled)

@with_httmock(resp_create_remote_mirror)
def test_create_project_remote_mirror(self):
mirror = self.project.remote_mirrors.create({"url": "https://example.com"})
self.assertIsInstance(mirror, ProjectRemoteMirror)
self.assertEqual(mirror.update_status, "none")

@with_httmock(resp_create_remote_mirror, resp_update_remote_mirror)
def test_update_project_remote_mirror(self):
mirror = self.project.remote_mirrors.create({"url": "https://example.com"})
mirror.only_protected_branches = True
mirror.save()
self.assertEqual(mirror.update_status, "finished")
self.assertTrue(mirror.only_protected_branches)
13 changes: 13 additions & 0 deletions gitlab/v4/objects.py
Expand Up @@ -1745,6 +1745,18 @@ def delete_in_bulk(self, name_regex=".*", **kwargs):
self.gitlab.http_delete(self.path, query_data=data, **kwargs)


class ProjectRemoteMirror(SaveMixin, RESTObject):
pass


class ProjectRemoteMirrorManager(ListMixin, CreateMixin, UpdateMixin, RESTManager):
_path = "/projects/%(project_id)s/remote_mirrors"
_obj_cls = ProjectRemoteMirror
_from_parent_attrs = {"project_id": "id"}
_create_attrs = (("url",), ("enabled", "only_protected_branches"))
_update_attrs = (tuple(), ("enabled", "only_protected_branches"))


class ProjectBoardList(SaveMixin, ObjectDeleteMixin, RESTObject):
pass

Expand Down Expand Up @@ -4246,6 +4258,7 @@ class Project(SaveMixin, ObjectDeleteMixin, RESTObject):
("pipelineschedules", "ProjectPipelineScheduleManager"),
("pushrules", "ProjectPushRulesManager"),
("releases", "ProjectReleaseManager"),
("remote_mirrors", "ProjectRemoteMirrorManager"),
("repositories", "ProjectRegistryRepositoryManager"),
("runners", "ProjectRunnerManager"),
("services", "ProjectServiceManager"),
Expand Down
17 changes: 17 additions & 0 deletions tools/python_test_v4.py
Expand Up @@ -1047,6 +1047,23 @@
assert len(release_test_project.releases.list()) == 0
release_test_project.delete()

# project remote mirrors
mirror_url = "http://gitlab.test/root/mirror.git"

# create remote mirror
mirror = admin_project.remote_mirrors.create({"url": mirror_url})
assert mirror.url == mirror_url

# update remote mirror
mirror.enabled = True
mirror.save()

# list remote mirrors
mirror = admin_project.remote_mirrors.list()[0]
assert isinstance(mirror, gitlab.v4.objects.ProjectRemoteMirror)
assert mirror.url == mirror_url
assert mirror.enabled is True

# status
message = "Test"
emoji = "thumbsup"
Expand Down

0 comments on commit 3396aa5

Please sign in to comment.