Skip to content

Commit ce8567d

Browse files
author
ayoub mrini
committed
feat(api): add support for Gitlab Deploy Token API
1 parent 4ffaf1d commit ce8567d

File tree

6 files changed

+209
-1
lines changed

6 files changed

+209
-1
lines changed

docs/gl_objects/deploy_tokens.rst

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
#######
2+
Deploy tokens
3+
#######
4+
5+
Deploy tokens allow read-only access to your repository and registry images
6+
without having a user and a password.
7+
8+
Deploy tokens can be managed by maintainers only.
9+
10+
Deploy tokens
11+
=============
12+
13+
Reference
14+
---------
15+
16+
* v4 API:
17+
18+
+ :class:`gitlab.v4.objects.DeployToken`
19+
+ :class:`gitlab.v4.objects.DeployTokenManager`
20+
+ :attr:`gitlab.Gitlab.deploytokens`
21+
22+
* GitLab API: https://docs.gitlab.com/ce/api/deploy_tokens.html
23+
24+
Examples
25+
--------
26+
27+
Use the ``list()`` method to list all deploy tokens across the GitLab instance.
28+
29+
This requires admin access.
30+
31+
::
32+
33+
# List deploy tokens
34+
deploy_tokens = gl.deploytokens.list()
35+
36+
Project deploy tokens
37+
=====================
38+
39+
Reference
40+
---------
41+
42+
* v4 API:
43+
44+
+ :class:`gitlab.v4.objects.ProjectDeployToken`
45+
+ :class:`gitlab.v4.objects.ProjectDeployTokenManager`
46+
+ :attr:`gitlab.v4.objects.Project.deploytokens`
47+
48+
* GitLab API: https://docs.gitlab.com/ce/api/deploy_tokens.html
49+
50+
Examples
51+
--------
52+
53+
List the deploy tokens for a project::
54+
55+
deploy_tokens = project.deploytokens.list()
56+
57+
Create a new deploy token to access registry images of a project:
58+
59+
This method accepts the following none required parameters:
60+
61+
* ``name`` New deploy token’s name
62+
* ``expires_at`` Expiration date for the deploy token. Does not expire if no value is provided.
63+
* ``username`` Username for deploy token. Default is ``gitlab+deploy-token-{n}``
64+
65+
::
66+
67+
deploy_token = project.deploytokens.create({'name': 'token1', 'scopes': ['read_registry']})
68+
# show its id
69+
print(deploy_token.id)
70+
# show the token value. Make sure you save it, you won't be able to access it again.
71+
print(deploy_token.token)
72+
73+
Revoke (delete) the deploy token::
74+
75+
deploy_token.delete()
76+
# or
77+
project.deploytokens.delete(deploy_token.id)
78+
79+
80+
Group deploy tokens
81+
===================
82+
83+
Reference
84+
---------
85+
86+
* v4 API:
87+
88+
+ :class:`gitlab.v4.objects.GroupDeployToken`
89+
+ :class:`gitlab.v4.objects.GroupDeployTokenManager`
90+
+ :attr:`gitlab.v4.objects.Group.deploytokens`
91+
92+
* GitLab API: https://docs.gitlab.com/ce/api/deploy_tokens.html
93+
94+
Examples
95+
--------
96+
97+
List the deploy tokens for a group::
98+
99+
deploy_tokens = group.deploytokens.list()
100+
101+
Create a new deploy token to access all repositories of all projects in a group:
102+
103+
This method accepts the following none required parameters:
104+
105+
* ``name`` New deploy token’s name
106+
* ``expires_at`` Expiration date for the deploy token. Does not expire if no value is provided.
107+
* ``username`` Username for deploy token. Default is ``gitlab+deploy-token-{n}``
108+
109+
::
110+
111+
deploy_token = group.deploytokens.create({'name': 'token1', 'scopes': ['read_repository']})
112+
# show its id
113+
print(deploy_token.id)
114+
115+
Revoke (delete) the deploy token::
116+
117+
deploy_token.delete()
118+
# or
119+
group.deploytokens.delete(deploy_token.id)
120+

gitlab/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@ def __init__(
119119

120120
self.broadcastmessages = objects.BroadcastMessageManager(self)
121121
self.deploykeys = objects.DeployKeyManager(self)
122+
self.deploytokens = objects.DeployTokenManager(self)
122123
self.geonodes = objects.GeoNodeManager(self)
123124
self.gitlabciymls = objects.GitlabciymlManager(self)
124125
self.gitignores = objects.GitignoreManager(self)

gitlab/tests/test_gitlab.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -964,6 +964,40 @@ def resp_application_create(url, request):
964964
self.assertEqual(application.redirect_uri, "http://localhost:8080")
965965
self.assertEqual(application.scopes, ["api", "email"])
966966

967+
def test_deploy_tokens(self):
968+
@urlmatch(
969+
scheme="http",
970+
netloc="localhost",
971+
path="/api/v4/projects/1/deploy_tokens",
972+
method="post",
973+
)
974+
def resp_deploy_token_create(url, request):
975+
headers = {"content-type": "application/json"}
976+
content = """{
977+
"id": 1,
978+
"name": "test_deploy_token",
979+
"username": "custom-user",
980+
"expires_at": "2022-01-01T00:00:00.000Z",
981+
"token": "jMRvtPNxrn3crTAGukpZ",
982+
"scopes": [ "read_repository" ]}"""
983+
content = content.encode("utf-8")
984+
return response(200, content, headers, None, 5, request)
985+
986+
with HTTMock(resp_deploy_token_create):
987+
deploy_token = self.gl.projects.get(1, lazy=True).deploytokens.create(
988+
{
989+
"name": "test_deploy_token",
990+
"expires_at": "2022-01-01T00:00:00.000Z",
991+
"username": "custom-user",
992+
"scopes": ["read_repository"],
993+
}
994+
)
995+
self.assertIsInstance(deploy_token, ProjectDeployToken)
996+
self.assertEqual(deploy_token.id, 1),
997+
self.assertEqual(deploy_token.expires_at, "2022-01-01T00:00:00.000Z"),
998+
self.assertEqual(deploy_token.username, "custom-user")
999+
self.assertEqual(deploy_token.scopes, ["read_repository"])
1000+
9671001
def _default_config(self):
9681002
fd, temp_path = tempfile.mkstemp()
9691003
os.write(fd, valid_config)

gitlab/v4/objects.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -695,6 +695,43 @@ class DeployKeyManager(ListMixin, RESTManager):
695695
_obj_cls = DeployKey
696696

697697

698+
class DeployToken(ObjectDeleteMixin, RESTObject):
699+
pass
700+
701+
702+
class DeployTokenManager(ListMixin, RESTManager):
703+
_path = "/deploy_tokens"
704+
_obj_cls = DeployToken
705+
706+
707+
class ProjectDeployToken(ObjectDeleteMixin, RESTObject):
708+
pass
709+
710+
711+
class ProjectDeployTokenManager(ListMixin, CreateMixin, DeleteMixin, RESTManager):
712+
_path = "/projects/%(project_id)s/deploy_tokens"
713+
_from_parent_attrs = {"project_id": "id"}
714+
_obj_cls = ProjectDeployToken
715+
_create_attrs = (
716+
("name", "expires_at", "username", "scopes",),
717+
tuple(),
718+
)
719+
720+
721+
class GroupDeployToken(ObjectDeleteMixin, RESTObject):
722+
pass
723+
724+
725+
class GroupDeployTokenManager(ListMixin, CreateMixin, DeleteMixin, RESTManager):
726+
_path = "/groups/%(group_id)s/deploy_tokens"
727+
_from_parent_attrs = {"group_id": "id"}
728+
_obj_cls = GroupDeployToken
729+
_create_attrs = (
730+
("name", "expires_at", "username", "scopes",),
731+
tuple(),
732+
)
733+
734+
698735
class NotificationSettings(SaveMixin, RESTObject):
699736
_id_attr = None
700737

@@ -1301,6 +1338,7 @@ class Group(SaveMixin, ObjectDeleteMixin, RESTObject):
13011338
("subgroups", "GroupSubgroupManager"),
13021339
("variables", "GroupVariableManager"),
13031340
("clusters", "GroupClusterManager"),
1341+
("deploytokens", "GroupDeployTokenManager"),
13041342
)
13051343

13061344
@cli.register_custom_action("Group", ("to_project_id",))
@@ -4194,6 +4232,7 @@ class Project(SaveMixin, ObjectDeleteMixin, RESTObject):
41944232
("clusters", "ProjectClusterManager"),
41954233
("additionalstatistics", "ProjectAdditionalStatisticsManager"),
41964234
("issuesstatistics", "ProjectIssuesStatisticsManager"),
4235+
("deploytokens", "ProjectDeployTokenManager"),
41974236
)
41984237

41994238
@cli.register_custom_action("Project", ("submodule", "branch", "commit_sha"))

tools/build_test_env.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ NOVENV=
3030
PY_VER=3
3131
API_VER=4
3232
GITLAB_IMAGE="gitlab/gitlab-ce"
33-
GITLAB_TAG="latest"
33+
GITLAB_TAG="nightly"
3434
while getopts :knp:a: opt "$@"; do
3535
case $opt in
3636
k) REUSE_CONTAINER=1;;

tools/python_test_v4.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -617,6 +617,20 @@
617617
sudo_project.keys.delete(deploy_key.id)
618618
assert len(sudo_project.keys.list()) == 0
619619

620+
# deploy tokens
621+
deploy_token = admin_project.deploytokens.create(
622+
{"name": "foo",
623+
"username": "bar",
624+
"expires_at": "2021-09-09",
625+
"scopes": ["read_registry"]
626+
}
627+
)
628+
assert len(admin_project.deploytokens.list()) == 1
629+
assert gl.deploytokens.list() == admin_project.deploytokens.list()
630+
631+
deploy_token.delete()
632+
assert len(admin_project.deploytokens.list()) == 0
633+
620634
# labels
621635
# label1 = admin_project.labels.create({"name": "label1", "color": "#778899"})
622636
# label1 = admin_project.labels.list()[0]

0 commit comments

Comments
 (0)