summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNejc Habjan <hab.nejc@gmail.com>2020-04-07 00:55:33 +0200
committerNejc Habjan <hab.nejc@gmail.com>2020-04-07 00:55:33 +0200
commit4cfaa2fd44b64459f6fc268a91d4469284c0e768 (patch)
treec89e1641af92580c6e7435dd3847b58e7b9ce19e
parentc161852b5a976d11f682c5af00ff3f4e8daa26ef (diff)
downloadgitlab-feat/project-remote-mirrors.tar.gz
feat(api): add support for remote mirrors API (#1056)feat/project-remote-mirrors
-rw-r--r--docs/api-objects.rst1
-rw-r--r--docs/gl_objects/remote_mirrors.rst34
-rw-r--r--gitlab/tests/objects/test_projects.py94
-rw-r--r--gitlab/v4/objects.py13
-rw-r--r--tools/python_test_v4.py17
5 files changed, 159 insertions, 0 deletions
diff --git a/docs/api-objects.rst b/docs/api-objects.rst
index 32f0d0c..32852f8 100644
--- a/docs/api-objects.rst
+++ b/docs/api-objects.rst
@@ -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
diff --git a/docs/gl_objects/remote_mirrors.rst b/docs/gl_objects/remote_mirrors.rst
new file mode 100644
index 0000000..ea4f72c
--- /dev/null
+++ b/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()
diff --git a/gitlab/tests/objects/test_projects.py b/gitlab/tests/objects/test_projects.py
index 1c2347a..48347f9 100644
--- a/gitlab/tests/objects/test_projects.py
+++ b/gitlab/tests/objects/test_projects.py
@@ -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."""
@@ -262,3 +333,26 @@ class TestProjectImport(TestProject):
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)
diff --git a/gitlab/v4/objects.py b/gitlab/v4/objects.py
index 9855196..25d890e 100644
--- a/gitlab/v4/objects.py
+++ b/gitlab/v4/objects.py
@@ -1745,6 +1745,18 @@ class ProjectRegistryTagManager(DeleteMixin, RetrieveMixin, RESTManager):
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
@@ -4246,6 +4258,7 @@ class Project(SaveMixin, ObjectDeleteMixin, RESTObject):
("pipelineschedules", "ProjectPipelineScheduleManager"),
("pushrules", "ProjectPushRulesManager"),
("releases", "ProjectReleaseManager"),
+ ("remote_mirrors", "ProjectRemoteMirrorManager"),
("repositories", "ProjectRegistryRepositoryManager"),
("runners", "ProjectRunnerManager"),
("services", "ProjectServiceManager"),
diff --git a/tools/python_test_v4.py b/tools/python_test_v4.py
index 076329b..649f413 100644
--- a/tools/python_test_v4.py
+++ b/tools/python_test_v4.py
@@ -1047,6 +1047,23 @@ release_test_project.releases.delete(release_tag_name)
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"