summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMax Wittig <max.wittig@siemens.com>2020-04-07 10:39:46 +0200
committerGitHub <noreply@github.com>2020-04-07 10:39:46 +0200
commit5979750fcc953148fcca910c04258f56c3027bce (patch)
tree08ee6b2556dce3a53248895d040a580c8770b1b1
parent3396aa51e055b7e7d3bceddc1b91deed17323f3a (diff)
parent01de524ce39a67b549b3157bf4de827dd0568d6b (diff)
downloadgitlab-5979750fcc953148fcca910c04258f56c3027bce.tar.gz
Merge pull request #1052 from machine424/deploy-tokens-support
feat(api): add support for Gitlab Deploy Token API
-rw-r--r--docs/cli.rst13
-rw-r--r--docs/gl_objects/deploy_tokens.rst137
-rw-r--r--gitlab/__init__.py1
-rw-r--r--gitlab/tests/test_gitlab.py34
-rw-r--r--gitlab/v4/objects.py39
-rwxr-xr-xtools/cli_test_v4.sh88
-rw-r--r--tools/python_test_v4.py50
7 files changed, 354 insertions, 8 deletions
diff --git a/docs/cli.rst b/docs/cli.rst
index b4a6c5e..b5c8e52 100644
--- a/docs/cli.rst
+++ b/docs/cli.rst
@@ -207,6 +207,19 @@ Get a specific user by id:
$ gitlab user get --id 3
+Create a deploy token for a project:
+
+.. code-block:: console
+
+ $ gitlab -v project-deploy-token create --project-id 2 \
+ --name bar --username root --expires-at "2021-09-09" --scopes "read_repository"
+
+List deploy tokens for a group:
+
+.. code-block:: console
+
+ $ gitlab -v group-deploy-token list --group-id 3
+
Get a list of snippets for this project:
.. code-block:: console
diff --git a/docs/gl_objects/deploy_tokens.rst b/docs/gl_objects/deploy_tokens.rst
new file mode 100644
index 0000000..404bf09
--- /dev/null
+++ b/docs/gl_objects/deploy_tokens.rst
@@ -0,0 +1,137 @@
+#######
+Deploy tokens
+#######
+
+Deploy tokens allow read-only access to your repository and registry images
+without having a user and a password.
+
+Deploy tokens
+=============
+
+This endpoint requires admin access.
+
+Reference
+---------
+
+* v4 API:
+
+ + :class:`gitlab.v4.objects.DeployToken`
+ + :class:`gitlab.v4.objects.DeployTokenManager`
+ + :attr:`gitlab.Gitlab.deploytokens`
+
+* GitLab API: https://docs.gitlab.com/ce/api/deploy_tokens.html
+
+Examples
+--------
+
+Use the ``list()`` method to list all deploy tokens across the GitLab instance.
+
+::
+
+ # List deploy tokens
+ deploy_tokens = gl.deploytokens.list()
+
+Project deploy tokens
+=====================
+
+This endpoint requires project maintainer access or higher.
+
+Reference
+---------
+
+* v4 API:
+
+ + :class:`gitlab.v4.objects.ProjectDeployToken`
+ + :class:`gitlab.v4.objects.ProjectDeployTokenManager`
+ + :attr:`gitlab.v4.objects.Project.deploytokens`
+
+* GitLab API: https://docs.gitlab.com/ce/api/deploy_tokens.html#project-deploy-tokens
+
+Examples
+--------
+
+List the deploy tokens for a project::
+
+ deploy_tokens = project.deploytokens.list()
+
+Create a new deploy token to access registry images of a project:
+
+In addition to required parameters ``name`` and ``scopes``, this method accepts
+the following parameters:
+
+* ``expires_at`` Expiration date of the deploy token. Does not expire if no value is provided.
+* ``username`` Username for deploy token. Default is ``gitlab+deploy-token-{n}``
+
+
+::
+
+ deploy_token = project.deploytokens.create({'name': 'token1', 'scopes': ['read_registry'], 'username':'', 'expires_at':''})
+ # show its id
+ print(deploy_token.id)
+ # show the token value. Make sure you save it, you won't be able to access it again.
+ print(deploy_token.token)
+
+.. warning::
+
+ With GitLab 12.9, even though ``username`` and ``expires_at`` are not required, they always have to be passed to the API.
+ You can set them to empty strings, see: https://gitlab.com/gitlab-org/gitlab/-/issues/211878.
+ Also, the ``username``'s value is ignored by the API and will be overriden with ``gitlab+deploy-token-{n}``,
+ see: https://gitlab.com/gitlab-org/gitlab/-/issues/211963
+ These issues were fixed in GitLab 12.10.
+
+Remove a deploy token from the project::
+
+ deploy_token.delete()
+ # or
+ project.deploytokens.delete(deploy_token.id)
+
+
+Group deploy tokens
+===================
+
+Reference
+---------
+
+* v4 API:
+
+ + :class:`gitlab.v4.objects.GroupDeployToken`
+ + :class:`gitlab.v4.objects.GroupDeployTokenManager`
+ + :attr:`gitlab.v4.objects.Group.deploytokens`
+
+* GitLab API: https://docs.gitlab.com/ce/api/deploy_tokens.html#group-deploy-tokens
+
+Examples
+--------
+
+List the deploy tokens for a group::
+
+ deploy_tokens = group.deploytokens.list()
+
+Create a new deploy token to access all repositories of all projects in a group:
+
+In addition to required parameters ``name`` and ``scopes``, this method accepts
+the following parameters:
+
+* ``expires_at`` Expiration date of the deploy token. Does not expire if no value is provided.
+* ``username`` Username for deploy token. Default is ``gitlab+deploy-token-{n}``
+
+::
+
+ deploy_token = group.deploytokens.create({'name': 'token1', 'scopes': ['read_repository'], 'username':'', 'expires_at':''})
+ # show its id
+ print(deploy_token.id)
+
+.. warning::
+
+ With GitLab 12.9, even though ``username`` and ``expires_at`` are not required, they always have to be passed to the API.
+ You can set them to empty strings, see: https://gitlab.com/gitlab-org/gitlab/-/issues/211878.
+ Also, the ``username``'s value is ignored by the API and will be overriden with ``gitlab+deploy-token-{n}``,
+ see: https://gitlab.com/gitlab-org/gitlab/-/issues/211963
+ These issues were fixed in GitLab 12.10.
+
+Remove a deploy token from the group::
+
+ deploy_token.delete()
+ # or
+ group.deploytokens.delete(deploy_token.id)
+
diff --git a/gitlab/__init__.py b/gitlab/__init__.py
index a12ffb9..94e80f8 100644
--- a/gitlab/__init__.py
+++ b/gitlab/__init__.py
@@ -119,6 +119,7 @@ class Gitlab(object):
self.broadcastmessages = objects.BroadcastMessageManager(self)
self.deploykeys = objects.DeployKeyManager(self)
+ self.deploytokens = objects.DeployTokenManager(self)
self.geonodes = objects.GeoNodeManager(self)
self.gitlabciymls = objects.GitlabciymlManager(self)
self.gitignores = objects.GitignoreManager(self)
diff --git a/gitlab/tests/test_gitlab.py b/gitlab/tests/test_gitlab.py
index 8261cc6..6fc551c 100644
--- a/gitlab/tests/test_gitlab.py
+++ b/gitlab/tests/test_gitlab.py
@@ -903,6 +903,40 @@ class TestGitlab(unittest.TestCase):
self.assertEqual(application.redirect_uri, "http://localhost:8080")
self.assertEqual(application.scopes, ["api", "email"])
+ def test_deploy_tokens(self):
+ @urlmatch(
+ scheme="http",
+ netloc="localhost",
+ path="/api/v4/projects/1/deploy_tokens",
+ method="post",
+ )
+ def resp_deploy_token_create(url, request):
+ headers = {"content-type": "application/json"}
+ content = """{
+ "id": 1,
+ "name": "test_deploy_token",
+ "username": "custom-user",
+ "expires_at": "2022-01-01T00:00:00.000Z",
+ "token": "jMRvtPNxrn3crTAGukpZ",
+ "scopes": [ "read_repository" ]}"""
+ content = content.encode("utf-8")
+ return response(200, content, headers, None, 5, request)
+
+ with HTTMock(resp_deploy_token_create):
+ deploy_token = self.gl.projects.get(1, lazy=True).deploytokens.create(
+ {
+ "name": "test_deploy_token",
+ "expires_at": "2022-01-01T00:00:00.000Z",
+ "username": "custom-user",
+ "scopes": ["read_repository"],
+ }
+ )
+ self.assertIsInstance(deploy_token, ProjectDeployToken)
+ self.assertEqual(deploy_token.id, 1),
+ self.assertEqual(deploy_token.expires_at, "2022-01-01T00:00:00.000Z"),
+ self.assertEqual(deploy_token.username, "custom-user")
+ self.assertEqual(deploy_token.scopes, ["read_repository"])
+
def _default_config(self):
fd, temp_path = tempfile.mkstemp()
os.write(fd, valid_config)
diff --git a/gitlab/v4/objects.py b/gitlab/v4/objects.py
index 25d890e..0d745b4 100644
--- a/gitlab/v4/objects.py
+++ b/gitlab/v4/objects.py
@@ -695,6 +695,43 @@ class DeployKeyManager(ListMixin, RESTManager):
_obj_cls = DeployKey
+class DeployToken(ObjectDeleteMixin, RESTObject):
+ pass
+
+
+class DeployTokenManager(ListMixin, RESTManager):
+ _path = "/deploy_tokens"
+ _obj_cls = DeployToken
+
+
+class ProjectDeployToken(ObjectDeleteMixin, RESTObject):
+ pass
+
+
+class ProjectDeployTokenManager(ListMixin, CreateMixin, DeleteMixin, RESTManager):
+ _path = "/projects/%(project_id)s/deploy_tokens"
+ _from_parent_attrs = {"project_id": "id"}
+ _obj_cls = ProjectDeployToken
+ _create_attrs = (
+ ("name", "scopes",),
+ ("expires_at", "username",),
+ )
+
+
+class GroupDeployToken(ObjectDeleteMixin, RESTObject):
+ pass
+
+
+class GroupDeployTokenManager(ListMixin, CreateMixin, DeleteMixin, RESTManager):
+ _path = "/groups/%(group_id)s/deploy_tokens"
+ _from_parent_attrs = {"group_id": "id"}
+ _obj_cls = GroupDeployToken
+ _create_attrs = (
+ ("name", "scopes",),
+ ("expires_at", "username",),
+ )
+
+
class NotificationSettings(SaveMixin, RESTObject):
_id_attr = None
@@ -1323,6 +1360,7 @@ class Group(SaveMixin, ObjectDeleteMixin, RESTObject):
("subgroups", "GroupSubgroupManager"),
("variables", "GroupVariableManager"),
("clusters", "GroupClusterManager"),
+ ("deploytokens", "GroupDeployTokenManager"),
)
@cli.register_custom_action("Group", ("to_project_id",))
@@ -4271,6 +4309,7 @@ class Project(SaveMixin, ObjectDeleteMixin, RESTObject):
("clusters", "ProjectClusterManager"),
("additionalstatistics", "ProjectAdditionalStatisticsManager"),
("issuesstatistics", "ProjectIssuesStatisticsManager"),
+ ("deploytokens", "ProjectDeployTokenManager"),
)
@cli.register_custom_action("Project", ("submodule", "branch", "commit_sha"))
diff --git a/tools/cli_test_v4.sh b/tools/cli_test_v4.sh
index b916705..395289a 100755
--- a/tools/cli_test_v4.sh
+++ b/tools/cli_test_v4.sh
@@ -195,14 +195,6 @@ testcase "project upload" '
--filename '$(basename $0)' --filepath '$0' >/dev/null 2>&1
'
-testcase "project deletion" '
- GITLAB project delete --id "$PROJECT_ID"
-'
-
-testcase "group deletion" '
- OUTPUT=$(try GITLAB group delete --id $GROUP_ID)
-'
-
testcase "application settings get" '
GITLAB application-settings get >/dev/null 2>&1
'
@@ -222,3 +214,83 @@ testcase "values from files" '
echo $OUTPUT | grep -q "Multi line"
'
+# Test deploy tokens
+CREATE_PROJECT_DEPLOY_TOKEN_OUTPUT=$(GITLAB -v project-deploy-token create --project-id $PROJECT_ID \
+ --name foo --username root --expires-at "2021-09-09" --scopes "read_registry")
+CREATED_DEPLOY_TOKEN_ID=$(echo "$CREATE_PROJECT_DEPLOY_TOKEN_OUTPUT" | grep ^id: | cut -d" " -f2)
+testcase "create project deploy token" '
+ echo $CREATE_PROJECT_DEPLOY_TOKEN_OUTPUT | grep -q "name: foo"
+'
+testcase "create project deploy token" '
+ echo $CREATE_PROJECT_DEPLOY_TOKEN_OUTPUT | grep -q "expires-at: 2021-09-09T00:00:00.000Z"
+'
+testcase "create project deploy token" '
+ echo $CREATE_PROJECT_DEPLOY_TOKEN_OUTPUT | grep "scopes: " | grep -q "read_registry"
+'
+# Uncomment once https://gitlab.com/gitlab-org/gitlab/-/issues/211963 is fixed
+#testcase "create project deploy token" '
+# echo $CREATE_PROJECT_DEPLOY_TOKEN_OUTPUT | grep -q "username: root"
+#'
+
+# Remove once https://gitlab.com/gitlab-org/gitlab/-/issues/211963 is fixed
+testcase "create project deploy token" '
+ echo $CREATE_PROJECT_DEPLOY_TOKEN_OUTPUT | grep -q "gitlab+deploy-token"
+'
+
+LIST_DEPLOY_TOKEN_OUTPUT=$(GITLAB -v deploy-token list)
+testcase "list all deploy tokens" '
+ echo $LIST_DEPLOY_TOKEN_OUTPUT | grep -q "name: foo"
+'
+testcase "list all deploy tokens" '
+ echo $LIST_DEPLOY_TOKEN_OUTPUT | grep -q "id: $CREATED_DEPLOY_TOKEN_ID"
+'
+testcase "list all deploy tokens" '
+ echo $LIST_DEPLOY_TOKEN_OUTPUT | grep -q "expires-at: 2021-09-09T00:00:00.000Z"
+'
+testcase "list all deploy tokens" '
+ echo $LIST_DEPLOY_TOKEN_OUTPUT | grep "scopes: " | grep -q "read_registry"
+'
+
+testcase "list project deploy tokens" '
+ OUTPUT=$(GITLAB -v project-deploy-token list --project-id $PROJECT_ID)
+ echo $OUTPUT | grep -q "id: $CREATED_DEPLOY_TOKEN_ID"
+'
+testcase "delete project deploy token" '
+ GITLAB -v project-deploy-token delete --project-id $PROJECT_ID --id $CREATED_DEPLOY_TOKEN_ID
+ LIST_PROJECT_DEPLOY_TOKEN_OUTPUT=$(GITLAB -v project-deploy-token list --project-id $PROJECT_ID)
+ echo $LIST_PROJECT_DEPLOY_TOKEN_OUTPUT | grep -qv "id: $CREATED_DEPLOY_TOKEN_ID"
+'
+# Uncomment once https://gitlab.com/gitlab-org/gitlab/-/issues/212523 is fixed
+#testcase "delete project deploy token" '
+# LIST_DEPLOY_TOKEN_OUTPUT=$(GITLAB -v deploy-token list)
+# echo $LIST_DEPLOY_TOKEN_OUTPUT | grep -qv "id: $CREATED_DEPLOY_TOKEN_ID"
+#'
+
+CREATE_GROUP_DEPLOY_TOKEN_OUTPUT=$(GITLAB -v group-deploy-token create --group-id $GROUP_ID \
+ --name bar --username root --expires-at "2021-09-09" --scopes "read_repository")
+CREATED_DEPLOY_TOKEN_ID=$(echo "$CREATE_GROUP_DEPLOY_TOKEN_OUTPUT" | grep ^id: | cut -d" " -f2)
+testcase "create group deploy token" '
+ echo $CREATE_GROUP_DEPLOY_TOKEN_OUTPUT | grep -q "name: bar"
+'
+testcase "list group deploy tokens" '
+ OUTPUT=$(GITLAB -v group-deploy-token list --group-id $GROUP_ID)
+ echo $OUTPUT | grep -q "id: $CREATED_DEPLOY_TOKEN_ID"
+'
+testcase "delete group deploy token" '
+ GITLAB -v group-deploy-token delete --group-id $GROUP_ID --id $CREATED_DEPLOY_TOKEN_ID
+ LIST_GROUP_DEPLOY_TOKEN_OUTPUT=$(GITLAB -v group-deploy-token list --group-id $GROUP_ID)
+ echo $LIST_GROUP_DEPLOY_TOKEN_OUTPUT | grep -qv "id: $CREATED_DEPLOY_TOKEN_ID"
+'
+# Uncomment once https://gitlab.com/gitlab-org/gitlab/-/issues/212523 is fixed
+#testcase "delete group deploy token" '
+# LIST_DEPLOY_TOKEN_OUTPUT=$(GITLAB -v deploy-token list)
+# echo $LIST_DEPLOY_TOKEN_OUTPUT | grep -qv "id: $CREATED_DEPLOY_TOKEN_ID"
+#'
+
+testcase "project deletion" '
+ GITLAB project delete --id "$PROJECT_ID"
+'
+
+testcase "group deletion" '
+ OUTPUT=$(try GITLAB group delete --id $GROUP_ID)
+'
diff --git a/tools/python_test_v4.py b/tools/python_test_v4.py
index 649f413..7145bc1 100644
--- a/tools/python_test_v4.py
+++ b/tools/python_test_v4.py
@@ -652,6 +652,56 @@ assert len(sudo_project.keys.list()) == 1
sudo_project.keys.delete(deploy_key.id)
assert len(sudo_project.keys.list()) == 0
+# deploy tokens
+deploy_token = admin_project.deploytokens.create(
+ {
+ "name": "foo",
+ "username": "bar",
+ "expires_at": "2022-01-01",
+ "scopes": ["read_registry"],
+ }
+)
+assert len(admin_project.deploytokens.list()) == 1
+assert gl.deploytokens.list() == admin_project.deploytokens.list()
+
+assert admin_project.deploytokens.list()[0].name == "foo"
+assert admin_project.deploytokens.list()[0].expires_at == "2022-01-01T00:00:00.000Z"
+assert admin_project.deploytokens.list()[0].scopes == ["read_registry"]
+# Uncomment once https://gitlab.com/gitlab-org/gitlab/-/issues/211963 is fixed
+# assert admin_project.deploytokens.list()[0].username == "bar"
+deploy_token.delete()
+assert len(admin_project.deploytokens.list()) == 0
+# Uncomment once https://gitlab.com/gitlab-org/gitlab/-/issues/212523 is fixed
+# assert len(gl.deploytokens.list()) == 0
+
+
+deploy_token_group = gl.groups.create(
+ {"name": "deploy_token_group", "path": "deploy_token_group"}
+)
+
+# Uncomment once https://gitlab.com/gitlab-org/gitlab/-/issues/211878 is fixed
+# deploy_token = group_deploy_token.deploytokens.create(
+# {
+# "name": "foo",
+# "scopes": ["read_registry"],
+# }
+# )
+
+# Remove once https://gitlab.com/gitlab-org/gitlab/-/issues/211878 is fixed
+deploy_token = deploy_token_group.deploytokens.create(
+ {"name": "foo", "username": "", "expires_at": "", "scopes": ["read_repository"],}
+)
+
+assert len(deploy_token_group.deploytokens.list()) == 1
+# Uncomment once https://gitlab.com/gitlab-org/gitlab/-/issues/212523 is fixed
+# assert gl.deploytokens.list() == deploy_token_group.deploytokens.list()
+deploy_token.delete()
+assert len(deploy_token_group.deploytokens.list()) == 0
+# Uncomment once https://gitlab.com/gitlab-org/gitlab/-/issues/212523 is fixed
+# assert len(gl.deploytokens.list()) == 0
+
+deploy_token_group.delete()
+
# labels
# label1 = admin_project.labels.create({"name": "label1", "color": "#778899"})
# label1 = admin_project.labels.list()[0]