suite-py 1.41.10__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 +6 -194
- 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.10.dist-info → suite_py-1.42.0.dist-info}/METADATA +4 -4
- {suite_py-1.41.10.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.10.dist-info → suite_py-1.42.0.dist-info}/WHEEL +0 -0
- {suite_py-1.41.10.dist-info → suite_py-1.42.0.dist-info}/entry_points.txt +0 -0
suite_py/commands/secret.py
DELETED
|
@@ -1,204 +0,0 @@
|
|
|
1
|
-
# -*- coding: utf-8 -*-
|
|
2
|
-
import json
|
|
3
|
-
import os
|
|
4
|
-
import sys
|
|
5
|
-
|
|
6
|
-
import yaml
|
|
7
|
-
|
|
8
|
-
from suite_py.lib import logger, metrics
|
|
9
|
-
from suite_py.lib.handler import prompt_utils
|
|
10
|
-
from suite_py.lib.handler.vault_handler import VaultHandler
|
|
11
|
-
|
|
12
|
-
profiles_mapping = {
|
|
13
|
-
"common": {
|
|
14
|
-
"stack_name_pattern": "{service}-platform-cluster-{env}-serviceaccount-iamrole",
|
|
15
|
-
"logical_id": "ServiceAccountIamRole",
|
|
16
|
-
"developer_role": "arn:aws:iam::595659439703:role/aws-reserved/sso.amazonaws.com/eu-west-1/AWSReservedSSO_ItalyDeveloperPlatform_cb5de4d001016cc4",
|
|
17
|
-
},
|
|
18
|
-
"it": {
|
|
19
|
-
"stack_name_pattern": "ecs-roles-{service}-{env}",
|
|
20
|
-
"logical_id": "ECSTaskRole",
|
|
21
|
-
"developer_role": "arn:aws:iam::001575623345:role/AllowNonProductionBiscuitDecryption",
|
|
22
|
-
},
|
|
23
|
-
"uk": {
|
|
24
|
-
"stack_name_pattern": "{service}-main-{env}-serviceaccount-iamrole",
|
|
25
|
-
"logical_id": "ServiceAccountIamRole",
|
|
26
|
-
"developer_role": "arn:aws:iam::815911007681:role/aws-reserved/sso.amazonaws.com/eu-west-1/AWSReservedSSO_UnitedKingdomDeveloper_f578b0b2b98ea593",
|
|
27
|
-
},
|
|
28
|
-
"es": {
|
|
29
|
-
"stack_name_pattern": "{service}-main-{env}-serviceaccount-iamrole",
|
|
30
|
-
"logical_id": "ServiceAccountIamRole",
|
|
31
|
-
"developer_role": "arn:aws:iam::199959896441:role/aws-reserved/sso.amazonaws.com/eu-west-1/AWSReservedSSO_SpainDeveloper_acf53aa98cfc0ac4",
|
|
32
|
-
},
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
class Secret:
|
|
37
|
-
def __init__(self, project, config, action, base_profile, secret_file):
|
|
38
|
-
self._project = project
|
|
39
|
-
self._config = config
|
|
40
|
-
self._path = os.path.join(config.user["projects_home"], project)
|
|
41
|
-
self._vault = VaultHandler(project, config)
|
|
42
|
-
self._action = action
|
|
43
|
-
self._base_profile = base_profile
|
|
44
|
-
self._secret_file = secret_file
|
|
45
|
-
|
|
46
|
-
@metrics.command("secret")
|
|
47
|
-
def run(self):
|
|
48
|
-
if self._base_profile is not None:
|
|
49
|
-
self._config.vault["base_secret_profile"] = self._base_profile
|
|
50
|
-
|
|
51
|
-
if not self._secret_file:
|
|
52
|
-
self._secret_file = "config/secrets.yml"
|
|
53
|
-
|
|
54
|
-
if self._action == "create":
|
|
55
|
-
self._create_new_secret()
|
|
56
|
-
return
|
|
57
|
-
|
|
58
|
-
if self._action == "grant":
|
|
59
|
-
secrets = self._get_available_secrets()
|
|
60
|
-
secret = prompt_utils.ask_choices("Select secret: ", secrets)
|
|
61
|
-
self._set_grant_on_secret(secret)
|
|
62
|
-
return
|
|
63
|
-
|
|
64
|
-
logger.error(
|
|
65
|
-
"You have to specify what to do! See available flags with suite-py secret --help"
|
|
66
|
-
)
|
|
67
|
-
|
|
68
|
-
def _create_new_secret(self):
|
|
69
|
-
secret = prompt_utils.ask_questions_input("Enter secret name: ")
|
|
70
|
-
value = prompt_utils.ask_questions_input("Enter secret value: ")
|
|
71
|
-
e = self._vault.exec(
|
|
72
|
-
self._config.vault["base_secret_profile"],
|
|
73
|
-
f"biscuit put -f {self._secret_file} -- {secret} {value}",
|
|
74
|
-
)
|
|
75
|
-
if e.returncode != 0:
|
|
76
|
-
logger.error("An error occurred.")
|
|
77
|
-
sys.exit(1)
|
|
78
|
-
|
|
79
|
-
if prompt_utils.ask_confirm(f"Do you want to grant permissions for {secret}?"):
|
|
80
|
-
self._set_grant_on_secret(secret)
|
|
81
|
-
|
|
82
|
-
def _set_grant_on_secret(self, secret_name):
|
|
83
|
-
environment = self._ask_environment()
|
|
84
|
-
profiles = self._ask_profile()
|
|
85
|
-
for profile in profiles:
|
|
86
|
-
mapping = profiles_mapping[profile]
|
|
87
|
-
stack_name = (
|
|
88
|
-
mapping["stack_name_pattern"]
|
|
89
|
-
.replace("{service}", self._project)
|
|
90
|
-
.replace("{env}", environment)
|
|
91
|
-
)
|
|
92
|
-
# Get stack resource info
|
|
93
|
-
logger.info(
|
|
94
|
-
f"Obtaining ARN for {mapping['logical_id']} from stack {stack_name}..."
|
|
95
|
-
)
|
|
96
|
-
stack_resource = self._get_stack_resource(
|
|
97
|
-
profile, stack_name, mapping["logical_id"]
|
|
98
|
-
)
|
|
99
|
-
if stack_resource is None:
|
|
100
|
-
iam_role_arn = self._manual_iam_arn()
|
|
101
|
-
else:
|
|
102
|
-
iam_role_name = stack_resource["StackResourceDetail"][
|
|
103
|
-
"PhysicalResourceId"
|
|
104
|
-
]
|
|
105
|
-
# Get IAM Role ARN
|
|
106
|
-
iam_role = self._get_iam_role(profile, iam_role_name)
|
|
107
|
-
iam_role_arn = iam_role["Role"]["Arn"]
|
|
108
|
-
if iam_role_arn is None:
|
|
109
|
-
iam_role_arn = self._manual_iam_arn()
|
|
110
|
-
logger.info(f"ARN found for profile {profile}: {iam_role_arn}")
|
|
111
|
-
|
|
112
|
-
if iam_role_arn is None:
|
|
113
|
-
continue
|
|
114
|
-
|
|
115
|
-
logger.debug(
|
|
116
|
-
f"---\nGranting permissions on {self._project}/{secret_name}\nEnvironment: {environment}\nUsing vault profile: {profile}\nIAM Role ARN: {iam_role_arn}\n---"
|
|
117
|
-
)
|
|
118
|
-
if not prompt_utils.ask_confirm("Do you want to continue?", default=True):
|
|
119
|
-
continue
|
|
120
|
-
|
|
121
|
-
# Grant decrypt permissions to task
|
|
122
|
-
logger.info("Granting permissions to task...")
|
|
123
|
-
e = self._vault.exec(
|
|
124
|
-
self._config.vault["base_secret_profile"],
|
|
125
|
-
f"biscuit kms grants create --grantee-principal {iam_role_arn} -f {self._secret_file} {secret_name}",
|
|
126
|
-
)
|
|
127
|
-
if e.returncode != 0:
|
|
128
|
-
logger.error("An error occurred.")
|
|
129
|
-
continue
|
|
130
|
-
|
|
131
|
-
# Grant decrypt permissions to developers group
|
|
132
|
-
if environment in ["staging", "qa"]:
|
|
133
|
-
logger.info("Granting permissions to devs...")
|
|
134
|
-
e = self._vault.exec(
|
|
135
|
-
self._config.vault["base_secret_profile"],
|
|
136
|
-
f"biscuit kms grants create --grantee-principal {mapping['developer_role']} -f {self._secret_file} {secret_name}",
|
|
137
|
-
)
|
|
138
|
-
if e.returncode != 0:
|
|
139
|
-
logger.error("An error occurred.")
|
|
140
|
-
continue
|
|
141
|
-
|
|
142
|
-
logger.info("Ta-da! Permissions granted.")
|
|
143
|
-
|
|
144
|
-
def _get_available_secrets(self):
|
|
145
|
-
try:
|
|
146
|
-
secrets = []
|
|
147
|
-
with open(f"{self._path}/{self._secret_file}", encoding="utf-8") as s:
|
|
148
|
-
yaml_secrets = yaml.load(s, Loader=yaml.FullLoader)
|
|
149
|
-
secrets = [
|
|
150
|
-
key for key, values in yaml_secrets.items() if key != "_keys"
|
|
151
|
-
]
|
|
152
|
-
|
|
153
|
-
return secrets
|
|
154
|
-
except FileNotFoundError:
|
|
155
|
-
logger.error(f"Can't load secrets from {self._secret_file}.")
|
|
156
|
-
sys.exit(1)
|
|
157
|
-
|
|
158
|
-
def _get_stack_resource(self, profile, stack_name, logical_id):
|
|
159
|
-
e = self._vault.exec(
|
|
160
|
-
profile,
|
|
161
|
-
f"aws cloudformation describe-stack-resource --stack-name {stack_name} --logical-resource-id {logical_id}",
|
|
162
|
-
)
|
|
163
|
-
command_result = e.stdout.read()
|
|
164
|
-
if e.returncode != 0:
|
|
165
|
-
logger.warning("An error occurred trying to obtain stack. Skipping...")
|
|
166
|
-
return None
|
|
167
|
-
stack_info = command_result.decode("utf8").replace("'", '"')
|
|
168
|
-
data = json.loads(stack_info)
|
|
169
|
-
return data
|
|
170
|
-
|
|
171
|
-
def _get_iam_role(self, profile, iam_role_name):
|
|
172
|
-
e = self._vault.exec(
|
|
173
|
-
profile,
|
|
174
|
-
f"aws iam get-role --role-name {iam_role_name}",
|
|
175
|
-
additional_args="--no-session",
|
|
176
|
-
)
|
|
177
|
-
command_result = e.stdout.read()
|
|
178
|
-
if e.returncode != 0:
|
|
179
|
-
logger.warning(
|
|
180
|
-
"An error occurred trying to obtain IAM Role details. Skipping..."
|
|
181
|
-
)
|
|
182
|
-
return None
|
|
183
|
-
stack_info = command_result.decode("utf8").replace("'", '"')
|
|
184
|
-
data = json.loads(stack_info)
|
|
185
|
-
return data
|
|
186
|
-
|
|
187
|
-
def _manual_iam_arn(self):
|
|
188
|
-
arn = prompt_utils.ask_questions_input(
|
|
189
|
-
"No associated IAM Role ARN found. Insert it manually or leave blank to skip",
|
|
190
|
-
default_text="",
|
|
191
|
-
)
|
|
192
|
-
if arn == "":
|
|
193
|
-
return None
|
|
194
|
-
return arn
|
|
195
|
-
|
|
196
|
-
def _ask_environment(self):
|
|
197
|
-
return prompt_utils.ask_choices(
|
|
198
|
-
"Select an environment:", ["production", "staging", "qa"]
|
|
199
|
-
)
|
|
200
|
-
|
|
201
|
-
def _ask_profile(self):
|
|
202
|
-
return prompt_utils.ask_multiple_choices(
|
|
203
|
-
"Select vault profile(s):", self._config.vault["profiles"]
|
|
204
|
-
)
|
|
@@ -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
|