summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAbhishek Singh <abhiandthetruth@gmail.com>2022-11-01 15:10:04 +0530
committerGitHub <noreply@github.com>2022-11-01 10:40:04 +0100
commite5dc72de9b3cdf0a7944ee0961fbdc6784c7f315 (patch)
tree324550c485d554c5b41f234bc4ea811ac8f445e4
parent31ec1469211875a9c2b16b4d891a8b7fe1043af1 (diff)
downloadgitlab-e5dc72de9b3cdf0a7944ee0961fbdc6784c7f315.tar.gz
feat(api): add support for remote project import (#2348)
-rw-r--r--docs/gl_objects/projects.rst9
-rw-r--r--gitlab/v4/objects/projects.py45
-rw-r--r--tests/functional/api/test_import_export.py14
-rw-r--r--tests/unit/objects/test_project_import_export.py31
4 files changed, 99 insertions, 0 deletions
diff --git a/docs/gl_objects/projects.rst b/docs/gl_objects/projects.rst
index e96f14c..231aa50 100644
--- a/docs/gl_objects/projects.rst
+++ b/docs/gl_objects/projects.rst
@@ -342,6 +342,15 @@ Import the project into a namespace and override parameters::
override_params={'visibility': 'private'},
)
+Import the project using file stored on a remote URL::
+
+ output = gl.projects.remote_import(
+ url="https://whatever.com/url/file.tar.gz",
+ path="my_new_remote_project",
+ name="My New Remote Project",
+ namespace="my-group",
+ override_params={'visibility': 'private'},
+ )
Project custom attributes
=========================
diff --git a/gitlab/v4/objects/projects.py b/gitlab/v4/objects/projects.py
index 36e61f6..446e4f5 100644
--- a/gitlab/v4/objects/projects.py
+++ b/gitlab/v4/objects/projects.py
@@ -822,6 +822,8 @@ class ProjectManager(CRUDMixin, RESTManager):
Args:
file: Data or file object containing the project
path: Name and path for the new project
+ name: The name of the project to import. If not provided,
+ defaults to the path of the project.
namespace: The ID or path of the namespace that the project
will be imported to
overwrite: If True overwrite an existing project with the
@@ -849,6 +851,49 @@ class ProjectManager(CRUDMixin, RESTManager):
"/projects/import", post_data=data, files=files, **kwargs
)
+ def remote_import(
+ self,
+ url: str,
+ path: str,
+ name: Optional[str] = None,
+ namespace: Optional[str] = None,
+ overwrite: bool = False,
+ override_params: Optional[Dict[str, Any]] = None,
+ **kwargs: Any,
+ ) -> Union[Dict[str, Any], requests.Response]:
+ """Import a project from an archive file stored on a remote URL.
+
+ Args:
+ url: URL for the file containing the project data to import
+ path: Name and path for the new project
+ name: The name of the project to import. If not provided,
+ defaults to the path of the project.
+ namespace: The ID or path of the namespace that the project
+ will be imported to
+ overwrite: If True overwrite an existing project with the
+ same path
+ override_params: Set the specific settings for the project
+ **kwargs: Extra options to send to the server (e.g. sudo)
+
+ Raises:
+ GitlabAuthenticationError: If authentication is not correct
+ GitlabListError: If the server failed to perform the request
+
+ Returns:
+ A representation of the import status.
+ """
+ data = {"path": path, "overwrite": str(overwrite), "url": url}
+ if override_params:
+ for k, v in override_params.items():
+ data[f"override_params[{k}]"] = v
+ if name is not None:
+ data["name"] = name
+ if namespace:
+ data["namespace"] = namespace
+ return self.gitlab.http_post(
+ "/projects/remote-import", post_data=data, **kwargs
+ )
+
def import_bitbucket_server(
self,
bitbucket_server_url: str,
diff --git a/tests/functional/api/test_import_export.py b/tests/functional/api/test_import_export.py
index 32b85c6..83cccc6 100644
--- a/tests/functional/api/test_import_export.py
+++ b/tests/functional/api/test_import_export.py
@@ -1,5 +1,7 @@
import time
+import pytest
+
import gitlab
@@ -64,3 +66,15 @@ def test_project_import_export(gl, project, temp_dir):
count += 1
if count == 15:
raise Exception("Project import taking too much time")
+
+
+def test_project_remote_import(gl):
+ with pytest.raises(gitlab.exceptions.GitlabHttpError) as err_info:
+ gl.projects.remote_import(
+ "ftp://whatever.com/url", "remote-project", "remote-project", "root"
+ )
+ assert err_info.value.response_code == 400
+ assert (
+ "File url is blocked: Only allowed schemes are https"
+ in err_info.value.error_message
+ )
diff --git a/tests/unit/objects/test_project_import_export.py b/tests/unit/objects/test_project_import_export.py
index 450acc0..72321ec 100644
--- a/tests/unit/objects/test_project_import_export.py
+++ b/tests/unit/objects/test_project_import_export.py
@@ -30,6 +30,30 @@ def resp_import_project():
@pytest.fixture
+def resp_remote_import():
+ content = {
+ "id": 1,
+ "description": None,
+ "name": "remote-project",
+ "name_with_namespace": "Administrator / remote-project",
+ "path": "remote-project",
+ "path_with_namespace": "root/remote-project",
+ "created_at": "2018-02-13T09:05:58.023Z",
+ "import_status": "scheduled",
+ }
+
+ with responses.RequestsMock() as rsps:
+ rsps.add(
+ method=responses.POST,
+ url="http://localhost/api/v4/projects/remote-import",
+ json=content,
+ content_type="application/json",
+ status=200,
+ )
+ yield rsps
+
+
+@pytest.fixture
def resp_import_status():
content = {
"id": 1,
@@ -99,6 +123,13 @@ def test_import_project(gl, resp_import_project):
assert project_import["import_status"] == "scheduled"
+def test_remote_import(gl, resp_remote_import):
+ project_import = gl.projects.remote_import(
+ "https://whatever.com/url", "remote-project", "remote-project", "root"
+ )
+ assert project_import["import_status"] == "scheduled"
+
+
def test_import_project_with_override_params(gl, resp_import_project):
project_import = gl.projects.import_project(
"file", "api-project", override_params={"visibility": "private"}