Coverage for src/gitlabracadabra/gitlab/pygitlab.py: 66%

70 statements  

« prev     ^ index     » next       coverage.py v7.6.12, created at 2025-03-10 17:02 +0100

1# 

2# Copyright (C) 2019-2025 Mathieu Parent <math.parent@gmail.com> 

3# 

4# This program is free software: you can redistribute it and/or modify 

5# it under the terms of the GNU Lesser General Public License as published by 

6# the Free Software Foundation, either version 3 of the License, or 

7# (at your option) any later version. 

8# 

9# This program is distributed in the hope that it will be useful, 

10# but WITHOUT ANY WARRANTY; without even the implied warranty of 

11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 

12# GNU Lesser General Public License for more details. 

13# 

14# You should have received a copy of the GNU Lesser General Public License 

15# along with this program. If not, see <http://www.gnu.org/licenses/>. 

16 

17 

18from __future__ import annotations 

19 

20from os import getenv 

21from typing import TYPE_CHECKING 

22 

23from gitlab import Gitlab 

24from requests.auth import HTTPBasicAuth 

25 

26from gitlabracadabra import __version__ as gitlabracadabra_version 

27from gitlabracadabra.auth_info import AuthInfo 

28from gitlabracadabra.gitlab.deploy_key_cache import DeployKeyCache 

29from gitlabracadabra.gitlab.group_cache import GroupCache 

30from gitlabracadabra.gitlab.user_cache import UserCache 

31 

32if TYPE_CHECKING: 32 ↛ 33line 32 didn't jump to line 33 because the condition on line 32 was never true

33 from requests import Session 

34 

35 from gitlabracadabra.containers.authenticated_session import AuthenticatedSession 

36 

37 

38class PyGitlab: 

39 """Python-Gitlab wrapper.""" 

40 

41 def __init__( 

42 self, 

43 gitlab_id: str | None, 

44 config_files: list[str] | None, 

45 *, 

46 debug: bool, 

47 auth: bool = True, 

48 ) -> None: 

49 """Initialize a Python-Gitlab wrapper. 

50 

51 Args: 

52 gitlab_id: Section in python-gitlab config files. 

53 config_files: None or list of configuration files. 

54 debug: True to enable debugging. 

55 auth: True to authenticate on creation. 

56 """ 

57 self._gitlab_id = gitlab_id 

58 self._config_files = config_files 

59 self._debug = debug 

60 options: dict[str, str | None] = { 

61 "server_url": getenv("GITLAB_URL"), 

62 "private_token": getenv("GITLAB_PRIVATE_TOKEN"), 

63 "oauth_token": getenv("GITLAB_OAUTH_TOKEN"), 

64 } 

65 try: 

66 self._gl = Gitlab.merge_config(options, self.gitlab_id, self._config_files) 

67 except AttributeError: 

68 self._gl = Gitlab.from_config(self.gitlab_id, self._config_files) 

69 if self.gitlab_tls_verify != "": 69 ↛ 70line 69 didn't jump to line 70 because the condition on line 69 was never true

70 self._gl.ssl_verify = self.gitlab_tls_verify 

71 self._gl.headers["User-Agent"] = f"gitlabracadabra/{gitlabracadabra_version}" 

72 if auth and (self.pygitlab.private_token or self.pygitlab.oauth_token): 

73 self.pygitlab.auth() 

74 if self._debug: 74 ↛ 75line 74 didn't jump to line 75 because the condition on line 74 was never true

75 self.pygitlab.enable_debug() 

76 

77 self.group_cache = GroupCache(self) 

78 self.user_cache = UserCache(self) 

79 self.deploy_key_cache = DeployKeyCache(self) 

80 

81 @property 

82 def gitlab_id(self) -> str | None: 

83 """Get Gitlab id (section in python-gitlab config files). 

84 

85 Returns: 

86 A string. 

87 """ 

88 return self._gitlab_id 

89 

90 @property 

91 def pygitlab(self) -> Gitlab: 

92 """Get python-gitlab object. 

93 

94 Returns: 

95 A gitlab.Gitlab object. 

96 """ 

97 return self._gl 

98 

99 @property 

100 def registry_auth_info(self) -> AuthInfo: 

101 """Get Registry Authentication information. 

102 

103 Returns: 

104 A dict, with 'headers' and 'auth' to pass to requests. 

105 

106 Raises: 

107 ValueError: No auth info. 

108 """ 

109 if self.pygitlab.private_token: 109 ↛ 111line 109 didn't jump to line 111 because the condition on line 109 was always true

110 return AuthInfo(auth=HTTPBasicAuth("personal-access-token", self.pygitlab.private_token)) 

111 if self.pygitlab.oauth_token: 

112 return AuthInfo(auth=HTTPBasicAuth("oauth2", self.pygitlab.oauth_token)) 

113 if self.pygitlab.job_token: 

114 return AuthInfo(auth=HTTPBasicAuth("gitlab-ci-token", self.pygitlab.job_token)) 

115 if self.pygitlab.http_username and self.pygitlab.http_password: 

116 return AuthInfo(auth=HTTPBasicAuth(self.pygitlab.http_username, self.pygitlab.http_password)) 

117 msg = "No auth info" 

118 raise ValueError(msg) 

119 

120 def registry_session_callback(self, session: AuthenticatedSession) -> None: 

121 """Apply options to registry session. 

122 

123 Args: 

124 session: requests Session 

125 """ 

126 session.verify = self._gl.ssl_verify 

127 session.auth_info = self.registry_auth_info 

128 

129 def session_callback(self, session: Session) -> None: 

130 """Apply options to requests session. 

131 

132 Args: 

133 session: requests Session 

134 """ 

135 session.verify = self._gl.ssl_verify 

136 registry_auth_info = self.registry_auth_info 

137 session.auth = registry_auth_info.auth 

138 if registry_auth_info.headers is not None: 138 ↛ 139line 138 didn't jump to line 139 because the condition on line 138 was never true

139 for header_name, header_value in registry_auth_info.headers.items(): 

140 session.headers[header_name] = header_value 

141 

142 @property 

143 def api_url(self) -> str: 

144 """Get API URL. 

145 

146 Returns: 

147 API URL. 

148 """ 

149 return self.pygitlab.api_url 

150 

151 @property 

152 def gitlab_tls_verify(self) -> bool | str: 

153 """Get TLS verify. 

154 

155 Returns: 

156 Boolean to enable or disable, string for CA path, empty string to keep default. 

157 """ 

158 gitlab_tls_verify = getenv("GITLAB_TLS_VERIFY", "") 

159 if gitlab_tls_verify in {"true", "false"}: 159 ↛ 160line 159 didn't jump to line 160 because the condition on line 159 was never true

160 return gitlab_tls_verify == "true" 

161 return gitlab_tls_verify