suite-py 1.41.9__py3-none-any.whl → 1.42.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- suite_py/__version__.py +1 -1
- suite_py/cli.py +36 -210
- suite_py/commands/check.py +0 -18
- suite_py/commands/merge_pr.py +1 -12
- suite_py/commands/open_pr.py +1 -6
- suite_py/commands/release.py +2 -248
- suite_py/lib/config.py +0 -1
- suite_py/lib/handler/captainhook_handler.py +0 -7
- suite_py/lib/handler/okta_handler.py +8 -4
- suite_py/lib/metrics.py +1 -1
- suite_py/lib/oauth.py +7 -3
- suite_py/lib/tokens.py +3 -7
- {suite_py-1.41.9.dist-info → suite_py-1.42.0.dist-info}/METADATA +4 -4
- {suite_py-1.41.9.dist-info → suite_py-1.42.0.dist-info}/RECORD +16 -26
- suite_py/commands/aggregator.py +0 -159
- suite_py/commands/batch_job.py +0 -215
- suite_py/commands/deploy.py +0 -207
- suite_py/commands/docker.py +0 -91
- suite_py/commands/generator.py +0 -238
- suite_py/commands/id.py +0 -60
- suite_py/commands/ip.py +0 -68
- suite_py/commands/secret.py +0 -204
- suite_py/lib/handler/drone_handler.py +0 -252
- suite_py/lib/handler/vault_handler.py +0 -28
- {suite_py-1.41.9.dist-info → suite_py-1.42.0.dist-info}/WHEEL +0 -0
- {suite_py-1.41.9.dist-info → suite_py-1.42.0.dist-info}/entry_points.txt +0 -0
|
@@ -1,252 +0,0 @@
|
|
|
1
|
-
# -*- encoding: utf-8 -*-
|
|
2
|
-
import os
|
|
3
|
-
import subprocess
|
|
4
|
-
import sys
|
|
5
|
-
import time
|
|
6
|
-
from distutils.version import StrictVersion # pylint: disable=W0402
|
|
7
|
-
from subprocess import CalledProcessError
|
|
8
|
-
|
|
9
|
-
import requests
|
|
10
|
-
import yaml
|
|
11
|
-
from halo import Halo
|
|
12
|
-
|
|
13
|
-
from suite_py.lib import logger
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
class DroneHandler:
|
|
17
|
-
def __init__(self, config, tokens, repo=None):
|
|
18
|
-
self._token = tokens.drone
|
|
19
|
-
self._config = config
|
|
20
|
-
os.environ["DRONE_TOKEN"] = self._token
|
|
21
|
-
self._baseurl = os.environ.get("DRONE_SERVER", "https://drone-1.prima.it")
|
|
22
|
-
self._repo = repo
|
|
23
|
-
if repo:
|
|
24
|
-
self._path = os.path.join(config.user["projects_home"], repo)
|
|
25
|
-
|
|
26
|
-
def get_last_build_url(self, prefix=None):
|
|
27
|
-
with Halo(text="Contacting drone...", spinner="dots", color="magenta"):
|
|
28
|
-
# necessario per far comparire la build che abbiamo appena pushato
|
|
29
|
-
time.sleep(2)
|
|
30
|
-
try:
|
|
31
|
-
# pylint: disable-next=missing-timeout
|
|
32
|
-
builds = requests.get(
|
|
33
|
-
f"{self._baseurl}/api/repos/primait/{self._repo}/builds",
|
|
34
|
-
headers={"Authorization": f"Bearer {self._token}"},
|
|
35
|
-
).json()
|
|
36
|
-
|
|
37
|
-
if prefix:
|
|
38
|
-
builds = [b for b in builds if b["target"].startswith(prefix)]
|
|
39
|
-
|
|
40
|
-
return f"{self._baseurl}/primait/{self._repo}/{builds[0]['number']}"
|
|
41
|
-
except Exception:
|
|
42
|
-
return ""
|
|
43
|
-
|
|
44
|
-
def get_pr_build_number(self, commit_sha):
|
|
45
|
-
with Halo(text="Contacting drone...", spinner="dots", color="magenta"):
|
|
46
|
-
tries = 10
|
|
47
|
-
while tries > 0:
|
|
48
|
-
tries -= 1
|
|
49
|
-
try:
|
|
50
|
-
# pylint: disable-next=missing-timeout
|
|
51
|
-
builds = requests.get(
|
|
52
|
-
f"{self._baseurl}/api/repos/primait/{self._repo}/builds?per_page=100",
|
|
53
|
-
headers={"Authorization": f"Bearer {self._token}"},
|
|
54
|
-
).json()
|
|
55
|
-
builds = [b for b in builds if b["after"] == commit_sha]
|
|
56
|
-
return builds[0]["number"]
|
|
57
|
-
except Exception:
|
|
58
|
-
time.sleep(1)
|
|
59
|
-
|
|
60
|
-
return None
|
|
61
|
-
|
|
62
|
-
def get_user(self):
|
|
63
|
-
try:
|
|
64
|
-
# pylint: disable-next=missing-timeout
|
|
65
|
-
user = requests.get(
|
|
66
|
-
f"{self._baseurl}/api/user",
|
|
67
|
-
headers={"Authorization": f"Bearer {self._token}"},
|
|
68
|
-
).json()
|
|
69
|
-
return user
|
|
70
|
-
except Exception:
|
|
71
|
-
return None
|
|
72
|
-
|
|
73
|
-
def get_repo_build(self, repo, build_number):
|
|
74
|
-
# pylint: disable-next=missing-timeout
|
|
75
|
-
build = requests.get(
|
|
76
|
-
f"{self._baseurl}/api/repos/primait/{repo}/builds/{build_number}",
|
|
77
|
-
headers={"Authorization": f"Bearer {self._token}"},
|
|
78
|
-
).json()
|
|
79
|
-
|
|
80
|
-
return build
|
|
81
|
-
|
|
82
|
-
def get_build_url(self, build_number):
|
|
83
|
-
if build_number:
|
|
84
|
-
return f"{self._baseurl}/primait/{self._repo}/{build_number}"
|
|
85
|
-
return None
|
|
86
|
-
|
|
87
|
-
def get_repo_build_url(self, repo, build_number):
|
|
88
|
-
if build_number:
|
|
89
|
-
return f"{self._baseurl}/primait/{repo}/{build_number}"
|
|
90
|
-
return None
|
|
91
|
-
|
|
92
|
-
def get_build_and_pipeline_url(self, repo, build_number, pipeline_number):
|
|
93
|
-
if build_number:
|
|
94
|
-
return f"{self._baseurl}/primait/{repo}/{build_number}/{pipeline_number}"
|
|
95
|
-
return None
|
|
96
|
-
|
|
97
|
-
def get_tags_from_builds(self):
|
|
98
|
-
tags = []
|
|
99
|
-
# pylint: disable-next=missing-timeout
|
|
100
|
-
builds = requests.get(
|
|
101
|
-
f"{self._baseurl}/api/repos/primait/{self._repo}/builds?per_page=100",
|
|
102
|
-
headers={"Authorization": f"Bearer {self._token}"},
|
|
103
|
-
).json()
|
|
104
|
-
|
|
105
|
-
for build in builds:
|
|
106
|
-
if build["event"] == "tag":
|
|
107
|
-
tags.append(build["ref"].replace("refs/tags/", ""))
|
|
108
|
-
|
|
109
|
-
tags = list(dict.fromkeys(tags))
|
|
110
|
-
tags.sort(key=StrictVersion, reverse=True)
|
|
111
|
-
return tags
|
|
112
|
-
|
|
113
|
-
def get_builds_from_tag(self, tag):
|
|
114
|
-
try:
|
|
115
|
-
# pylint: disable-next=missing-timeout
|
|
116
|
-
builds = requests.get(
|
|
117
|
-
f"{self._baseurl}/api/repos/primait/{self._repo}/builds?per_page=100&tag={tag}",
|
|
118
|
-
headers={"Authorization": f"Bearer {self._token}"},
|
|
119
|
-
).json()
|
|
120
|
-
|
|
121
|
-
except Exception:
|
|
122
|
-
builds = []
|
|
123
|
-
|
|
124
|
-
if isinstance(builds, dict) and builds.get("message") == "Unauthorized":
|
|
125
|
-
raise Exception("Drone API Error: Unauthorized - run suite-py check")
|
|
126
|
-
|
|
127
|
-
return builds
|
|
128
|
-
|
|
129
|
-
def get_builds_from_branch(self, branch):
|
|
130
|
-
try:
|
|
131
|
-
# pylint: disable-next=missing-timeout
|
|
132
|
-
builds = requests.get(
|
|
133
|
-
f"{self._baseurl}/api/repos/primait/{self._repo}/builds?branch={branch}&per_page=100",
|
|
134
|
-
headers={"Authorization": f"Bearer {self._token}"},
|
|
135
|
-
).json()
|
|
136
|
-
|
|
137
|
-
return [b for b in builds if b["event"] == "push"]
|
|
138
|
-
except Exception:
|
|
139
|
-
return []
|
|
140
|
-
|
|
141
|
-
def get_build_number_from_tag(self, tag):
|
|
142
|
-
attempts = 0
|
|
143
|
-
while attempts < 3:
|
|
144
|
-
|
|
145
|
-
try:
|
|
146
|
-
# pylint: disable-next=missing-timeout
|
|
147
|
-
builds = requests.get(
|
|
148
|
-
f"{self._baseurl}/api/repos/primait/{self._repo}/builds?per_page=100&tag={tag}",
|
|
149
|
-
headers={"Authorization": f"Bearer {self._token}"},
|
|
150
|
-
).json()
|
|
151
|
-
|
|
152
|
-
for build in builds:
|
|
153
|
-
if build["event"] == "tag":
|
|
154
|
-
return build["number"]
|
|
155
|
-
except Exception:
|
|
156
|
-
pass
|
|
157
|
-
|
|
158
|
-
time.sleep(2)
|
|
159
|
-
attempts += 1
|
|
160
|
-
|
|
161
|
-
return None
|
|
162
|
-
|
|
163
|
-
def promote(self, build, target, querystring):
|
|
164
|
-
try:
|
|
165
|
-
# pylint: disable-next=missing-timeout
|
|
166
|
-
return requests.post(
|
|
167
|
-
f"{self._baseurl}/api/repos/primait/{self._repo}/builds/{build}/promote?target={target}&{querystring}",
|
|
168
|
-
headers={"Authorization": f"Bearer {self._token}"},
|
|
169
|
-
).json()
|
|
170
|
-
except Exception as e:
|
|
171
|
-
logger.error(f"Unable to trigger drone build, exiting with error: {e}")
|
|
172
|
-
sys.exit(-1)
|
|
173
|
-
|
|
174
|
-
def promote_staging(self, build, target, querystring):
|
|
175
|
-
return self.promote(build, target, querystring)
|
|
176
|
-
|
|
177
|
-
def promote_production(self, tag, target, querystring):
|
|
178
|
-
build = self.get_build_number_from_tag(tag)
|
|
179
|
-
if build:
|
|
180
|
-
return self.promote(build, target, querystring)
|
|
181
|
-
|
|
182
|
-
logger.error(
|
|
183
|
-
f"Unable to retrieve drone build for repo {self._repo} with tag {tag}"
|
|
184
|
-
)
|
|
185
|
-
sys.exit(-1)
|
|
186
|
-
|
|
187
|
-
def launch_build(self, build):
|
|
188
|
-
# pylint: disable-next=missing-timeout
|
|
189
|
-
return requests.post(
|
|
190
|
-
f"{self._baseurl}/api/repos/primait/{self._repo}/builds/{build}",
|
|
191
|
-
headers={"Authorization": f"Bearer {self._token}"},
|
|
192
|
-
).json()
|
|
193
|
-
|
|
194
|
-
def prestart_success(self, build_number):
|
|
195
|
-
with Halo(text="Contacting drone...", spinner="dots", color="magenta"):
|
|
196
|
-
tries = 10
|
|
197
|
-
while build_number and tries > 0:
|
|
198
|
-
tries -= 1
|
|
199
|
-
# pylint: disable-next=missing-timeout
|
|
200
|
-
build_status = requests.get(
|
|
201
|
-
f"{self._baseurl}/api/repos/primait/{self._repo}/builds/{build_number}",
|
|
202
|
-
headers={"Authorization": f"Bearer {self._token}"},
|
|
203
|
-
).json()
|
|
204
|
-
|
|
205
|
-
steps = build_status["stages"][0]["steps"]
|
|
206
|
-
|
|
207
|
-
for step in steps:
|
|
208
|
-
if step["name"] == "pre-start":
|
|
209
|
-
if step["status"] == "success":
|
|
210
|
-
return True
|
|
211
|
-
break
|
|
212
|
-
time.sleep(3)
|
|
213
|
-
return False
|
|
214
|
-
|
|
215
|
-
def fmt(self):
|
|
216
|
-
try:
|
|
217
|
-
subprocess.run(
|
|
218
|
-
["drone", "fmt", "--save", ".drone.yml"], cwd=self._path, check=True
|
|
219
|
-
)
|
|
220
|
-
except CalledProcessError as e:
|
|
221
|
-
logger.error(f"{self._repo}: unable to format the .drone.yml {e}")
|
|
222
|
-
sys.exit(-1)
|
|
223
|
-
|
|
224
|
-
def validate(self):
|
|
225
|
-
try:
|
|
226
|
-
subprocess.run(
|
|
227
|
-
["drone", "lint", "--trusted", ".drone.yml"], cwd=self._path, check=True
|
|
228
|
-
)
|
|
229
|
-
except CalledProcessError as e:
|
|
230
|
-
logger.error(f"{self._path}: the .drone.yml is not valid {e}")
|
|
231
|
-
sys.exit(-1)
|
|
232
|
-
|
|
233
|
-
def sign(self):
|
|
234
|
-
try:
|
|
235
|
-
subprocess.run(
|
|
236
|
-
["drone", "sign", f"primait/{self._repo}", "--save"],
|
|
237
|
-
cwd=self._path,
|
|
238
|
-
check=True,
|
|
239
|
-
)
|
|
240
|
-
except CalledProcessError as e:
|
|
241
|
-
logger.error(f"{self._repo}: unable to sign the .drone.yml {e}")
|
|
242
|
-
sys.exit(-1)
|
|
243
|
-
|
|
244
|
-
def parse_yaml(self):
|
|
245
|
-
repo_path = os.path.join(self._config.user["projects_home"], self._repo)
|
|
246
|
-
yaml_path = os.path.join(repo_path, ".drone.yml")
|
|
247
|
-
try:
|
|
248
|
-
return yaml.load_all(
|
|
249
|
-
open(yaml_path, "r", encoding="utf-8"), Loader=yaml.FullLoader
|
|
250
|
-
)
|
|
251
|
-
except FileNotFoundError:
|
|
252
|
-
return None
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
# -*- encoding: utf-8 -*-
|
|
2
|
-
import os
|
|
3
|
-
import subprocess
|
|
4
|
-
import sys
|
|
5
|
-
from subprocess import CalledProcessError
|
|
6
|
-
|
|
7
|
-
from suite_py.lib import logger
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
class VaultHandler:
|
|
11
|
-
def __init__(self, repo, config):
|
|
12
|
-
self._repo = repo
|
|
13
|
-
self._projects_home = config.user["projects_home"]
|
|
14
|
-
self._path = os.path.join(self._projects_home, repo)
|
|
15
|
-
|
|
16
|
-
def exec(self, profile, command, additional_args=""):
|
|
17
|
-
try:
|
|
18
|
-
c = subprocess.Popen( # pylint: disable=consider-using-with
|
|
19
|
-
f"aws-vault exec {profile} {additional_args} -- {command}",
|
|
20
|
-
stdout=subprocess.PIPE,
|
|
21
|
-
shell=True,
|
|
22
|
-
cwd=self._path,
|
|
23
|
-
) # .stdout.read()
|
|
24
|
-
c.wait()
|
|
25
|
-
return c
|
|
26
|
-
except CalledProcessError as e:
|
|
27
|
-
logger.error(f"Error during command execution: {e}")
|
|
28
|
-
sys.exit(-1)
|
|
File without changes
|
|
File without changes
|