-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathmanager.py
104 lines (89 loc) · 3.91 KB
/
manager.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
from dictdiffer import DictDiffer
from gitlab import Gitlab, GitlabGetError
from typing import Dict, Iterable, Union
from gitlabbuildvariables.common import GitLabConfig
SSL_VERIFY = False
_VARIABLE_KEY_PROPERTY = "key"
_VARIABLE_VALUE_PROPERTY = "value"
if not SSL_VERIFY:
try:
import requests
from requests.packages.urllib3.exceptions import InsecureRequestWarning
# Silence insecure messages
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
except ImportError:
pass
class ProjectVariablesManager:
"""
Manages the build variables used by a project.
"""
def __init__(self, gitlab_config: GitLabConfig, project: str):
"""
Constructor.
:param gitlab_config: configuration to access GitLab
:param project: the project of interest (preferably namespaced, e.g. "hgi/my-project")
"""
self._connector = Gitlab(gitlab_config.location, gitlab_config.token, ssl_verify=SSL_VERIFY)
self._connector.auth()
try:
self._project = self._connector.projects.get(project)
except GitlabGetError as e:
if "Project Not Found" in e.error_message:
raise ValueError("Project '%s' not found. Valid projects are: %s"
% (project,
[project.path_with_namespace for project in self._connector.projects.list()]))
def get(self) -> Dict[str, str]:
"""
Gets the build variables for the project.
:return: the build variables
"""
variables = self._project.variables.list(all=True)
return {variable.key: variable.value for variable in variables}
def clear(self):
"""
Clears all of the build variables.
"""
for variable in self._project.variables.list(all=True):
variable.delete()
def remove(self, variables: Union[Iterable[str], Dict[str, str]]=None):
"""
Removes the given variables. Will only remove a key if it has the given value if the value has been defined.
:param variables: the variables to remove
"""
keys = list(variables.keys()) if isinstance(variables, Dict) else variables # type: Iterable[str]
for key in keys:
variable = self._project.variables.get(key)
if isinstance(variables, Dict):
if variables[key] != variable.value:
continue
variable.delete()
def set(self, variables: Dict[str, str]):
"""
Sets the build variables (i.e. removes old ones, adds new ones)
:param variables: the build variables to set
"""
current_variables = self.get()
difference = DictDiffer(variables, current_variables)
removed_keys = difference.removed()
self.remove(removed_keys)
changed_keys = difference.added() | difference.changed()
changed = {key: variables[key] for key in changed_keys}
self.add(changed, overwrite=True)
def add(self, variables: Dict[str, str], overwrite: bool=False):
"""
Adds the given build variables to those that already exist.
:param variables: the build variables to add
:param overwrite: whether the old variable should be overwritten in the case of a redefinition
"""
preset_variables = self._project.variables.list()
preset_variable_keys = [variable.key for variable in preset_variables]
for key, value in variables.items():
if key in preset_variable_keys:
if overwrite:
variable = preset_variables[preset_variable_keys.index(key)]
variable.value = value
variable.save()
else:
variable = self._project.variables.create({
_VARIABLE_KEY_PROPERTY: key, _VARIABLE_VALUE_PROPERTY: value})
variable.save()