qontract-reconcile 0.10.2.dev60__py3-none-any.whl → 0.10.2.dev61__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.
- {qontract_reconcile-0.10.2.dev60.dist-info → qontract_reconcile-0.10.2.dev61.dist-info}/METADATA +1 -1
- {qontract_reconcile-0.10.2.dev60.dist-info → qontract_reconcile-0.10.2.dev61.dist-info}/RECORD +9 -9
- reconcile/change_owners/change_log_tracking.py +15 -25
- reconcile/utils/output.py +3 -6
- tools/app_interface_reporter.py +44 -70
- tools/cli_commands/gpg_encrypt.py +2 -2
- tools/qontract_cli.py +291 -230
- {qontract_reconcile-0.10.2.dev60.dist-info → qontract_reconcile-0.10.2.dev61.dist-info}/WHEEL +0 -0
- {qontract_reconcile-0.10.2.dev60.dist-info → qontract_reconcile-0.10.2.dev61.dist-info}/entry_points.txt +0 -0
{qontract_reconcile-0.10.2.dev60.dist-info → qontract_reconcile-0.10.2.dev61.dist-info}/METADATA
RENAMED
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: qontract-reconcile
|
3
|
-
Version: 0.10.2.
|
3
|
+
Version: 0.10.2.dev61
|
4
4
|
Summary: Collection of tools to reconcile services with their desired state as defined in the app-interface DB.
|
5
5
|
Project-URL: homepage, https://github.com/app-sre/qontract-reconcile
|
6
6
|
Project-URL: repository, https://github.com/app-sre/qontract-reconcile
|
{qontract_reconcile-0.10.2.dev60.dist-info → qontract_reconcile-0.10.2.dev61.dist-info}/RECORD
RENAMED
@@ -164,7 +164,7 @@ reconcile/change_owners/README.md,sha256=NEXVw4SioTWTGo9elSQUjqY10RIUoisl4zkzEBv
|
|
164
164
|
reconcile/change_owners/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
165
165
|
reconcile/change_owners/approver.py,sha256=Z3_11vnK2WNOxjEEXVDh0224-_-qbt9d6mBeVE-7fsc,2259
|
166
166
|
reconcile/change_owners/bundle.py,sha256=h30fU-JmLH5a-rCAovpzTeTkkkgZztsZ5A2raee0YuU,5355
|
167
|
-
reconcile/change_owners/change_log_tracking.py,sha256=
|
167
|
+
reconcile/change_owners/change_log_tracking.py,sha256=6MXABuPbLQwLeFZE_J2SS9Sx23fAVAtPRWKSBxjQrSo,8850
|
168
168
|
reconcile/change_owners/change_owners.py,sha256=7tESnSX2-psNGPIF63OeK5f-m3iqwanaGjt03FIjWXU,17111
|
169
169
|
reconcile/change_owners/change_types.py,sha256=5eSvS2_npUriq9RN4LdAWdYUiNzF91K1pDUEVYDIQ4k,32023
|
170
170
|
reconcile/change_owners/changes.py,sha256=YTqwUYutQ6JVSSYmC2Ph5ROCiVix42Vnzy47-i57z4Q,18119
|
@@ -615,7 +615,7 @@ reconcile/utils/oc_map.py,sha256=ougQ-Wlsa8ymoE_lPQ7g2LlpsUOsHVeRCLYW_6fjeWU,897
|
|
615
615
|
reconcile/utils/ocm_base_client.py,sha256=t5kxhklEqOpenXPkXiwQIk8d3D7hIUndBm5qGusS0bc,6681
|
616
616
|
reconcile/utils/openshift_resource.py,sha256=DI-e04f4NqEUFJ_9HzjY-QMhFt7o2XVauM09mzMC5Vs,24716
|
617
617
|
reconcile/utils/openssl.py,sha256=QVvhzhpChq_4Daf_5wE1qeZJr4thg3DDjJPn4bOPD4E,365
|
618
|
-
reconcile/utils/output.py,sha256=
|
618
|
+
reconcile/utils/output.py,sha256=dj3tE_sj3x8ssnAV6hCGmsRI9ttqUUFsIH1r7RujNA8,2038
|
619
619
|
reconcile/utils/pagerduty_api.py,sha256=_24i9S_4X7nlvHb-7clXRE0p1BG4ODjOzKxWO-F9WgI,7627
|
620
620
|
reconcile/utils/parse_dhms_duration.py,sha256=TONpLnec5gHeF7k815YNJpQyDjXhkxZIcv9s8ffbTSY,1840
|
621
621
|
reconcile/utils/password_validator.py,sha256=XwuWg-8CPlcuG7dl_oQ1G1h2gSVSnfMym_VkuprpWVg,2183
|
@@ -745,18 +745,18 @@ reconcile/utils/unleash/client.py,sha256=YrJnauxjcy1ml7W2AHg7dzIH_fVK_GugoRu7IFm
|
|
745
745
|
reconcile/utils/unleash/server.py,sha256=907gDh9Ee8UxLqusnfpzE-7LUnttB38D4xhVJ0vMf_M,4439
|
746
746
|
tools/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
747
747
|
tools/app_interface_metrics_exporter.py,sha256=f1qwTmQfEcs98uBVRyBa0k7GQXdiSwd7w1hDVjhdGcQ,2303
|
748
|
-
tools/app_interface_reporter.py,sha256=
|
748
|
+
tools/app_interface_reporter.py,sha256=0_oq1-mL0UOh1x5G8CoKaEVJqK-XTKE7PX7IbRTovBc,17224
|
749
749
|
tools/app_sre_tekton_access_reporter.py,sha256=o9prLUgQpwO3msRWc2as1xT1y9OB3znkpgvLr0Ys8_M,3146
|
750
750
|
tools/app_sre_tekton_access_revalidation.py,sha256=66nHEaY-bIqxIhpcmwN8AvQZu6ZXenfkg4Fut0pVZRM,2726
|
751
751
|
tools/glitchtip_access_reporter.py,sha256=o01A6b88t3Wie6tj_tJWWVo2J01LxQ_a9giGm4UzEaU,2901
|
752
752
|
tools/glitchtip_access_revalidation.py,sha256=8kbBJk04mkq28kWoRDDkfCGIF3GRg3pJrFAh1sW0dbk,2821
|
753
|
-
tools/qontract_cli.py,sha256=
|
753
|
+
tools/qontract_cli.py,sha256=HAN-3m8udB8Ea1B4fIpmJoJjLWQERDhIF-9LU9XBCnQ,152477
|
754
754
|
tools/sd_app_sre_alert_report.py,sha256=jQpJdXVID68bSNtJNOGDh0-ei1CfEUS4Itr4MAaBNFA,5062
|
755
755
|
tools/template_validation.py,sha256=qpKYaTgk0GOPGa2Ct5_5sKdwIHtCAKIBGzsMPuJU5fw,3371
|
756
756
|
tools/cli_commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
757
757
|
tools/cli_commands/container_images_report.py,sha256=8fG9XU-eEhJ7hKCdQzBcdPpvIJR-8WGkHOgFEulpfYQ,5213
|
758
758
|
tools/cli_commands/erv2.py,sha256=VxUlNXllo947UwmtvS-42IeI9x_t_X3MHrrSI3K_GRo,23274
|
759
|
-
tools/cli_commands/gpg_encrypt.py,sha256=
|
759
|
+
tools/cli_commands/gpg_encrypt.py,sha256=JWwds_Qg7KhSJMIGUh8TfI5-Jf17iUtmaEi4kWJxfVE,4907
|
760
760
|
tools/cli_commands/systems_and_tools.py,sha256=EMHOF1AtUDaoSk0bbjl6oUKYAz4rTZjIBaF-6E6GspM,16816
|
761
761
|
tools/cli_commands/cost_report/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
762
762
|
tools/cli_commands/cost_report/aws.py,sha256=JtwDfhaYLfa4Uz1LR6OfSBh_3nBlb90kQq6i3MV_ims,4563
|
@@ -777,7 +777,7 @@ tools/saas_promotion_state/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJ
|
|
777
777
|
tools/saas_promotion_state/saas_promotion_state.py,sha256=UfwwRLS5Ya4_Nh1w5n1dvoYtchQvYE9yj1VANt2IKqI,3925
|
778
778
|
tools/sre_checkpoints/__init__.py,sha256=CDaDaywJnmRCLyl_NCcvxi-Zc0hTi_3OdwKiFOyS39I,145
|
779
779
|
tools/sre_checkpoints/util.py,sha256=zEDbGr18ZeHNQwW8pUsr2JRjuXIPz--WAGJxZo9sv_Y,894
|
780
|
-
qontract_reconcile-0.10.2.
|
781
|
-
qontract_reconcile-0.10.2.
|
782
|
-
qontract_reconcile-0.10.2.
|
783
|
-
qontract_reconcile-0.10.2.
|
780
|
+
qontract_reconcile-0.10.2.dev61.dist-info/METADATA,sha256=QOFjMzvg2cy2BeJ5BHN3OPgfQe1IaDis_HcAfm-G0_Y,24665
|
781
|
+
qontract_reconcile-0.10.2.dev61.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
782
|
+
qontract_reconcile-0.10.2.dev61.dist-info/entry_points.txt,sha256=5i9l54La3vQrDLAdwDKQWC0iG4sV9RRfOb1BpvzOWLc,698
|
783
|
+
qontract_reconcile-0.10.2.dev61.dist-info/RECORD,,
|
@@ -1,7 +1,8 @@
|
|
1
1
|
import logging
|
2
2
|
from collections import defaultdict
|
3
3
|
from collections.abc import Callable
|
4
|
-
|
4
|
+
|
5
|
+
from pydantic import BaseModel
|
5
6
|
|
6
7
|
from reconcile.change_owners.bundle import (
|
7
8
|
NoOpFileDiffResolver,
|
@@ -33,19 +34,17 @@ QONTRACT_INTEGRATION = "change-log-tracking"
|
|
33
34
|
BUNDLE_DIFFS_OBJ = "bundle-diffs.json"
|
34
35
|
|
35
36
|
|
36
|
-
|
37
|
-
class ChangeLogItem:
|
37
|
+
class ChangeLogItem(BaseModel):
|
38
38
|
commit: str
|
39
39
|
merged_at: str
|
40
|
-
change_types: list[str] =
|
40
|
+
change_types: list[str] = []
|
41
41
|
error: bool = False
|
42
|
-
apps: list[str] =
|
42
|
+
apps: list[str] = []
|
43
43
|
description: str = ""
|
44
44
|
|
45
45
|
|
46
|
-
|
47
|
-
|
48
|
-
items: list[ChangeLogItem] = field(default_factory=list)
|
46
|
+
class ChangeLog(BaseModel):
|
47
|
+
items: list[ChangeLogItem] = []
|
49
48
|
|
50
49
|
@property
|
51
50
|
def apps(self) -> set[str]:
|
@@ -89,28 +88,19 @@ class ChangeLogIntegration(QontractReconcileIntegration[ChangeLogIntegrationPara
|
|
89
88
|
app = ns.app.name
|
90
89
|
app_names_by_cluster_name[cluster].add(app)
|
91
90
|
jenkins_configs = get_jenkins_configs()
|
91
|
+
integration_state = init_state(integration=self.name)
|
92
|
+
gl = init_gitlab(self.params.gitlab_project_id)
|
93
|
+
diff_state = init_state(integration=self.name)
|
94
|
+
diff_state.state_path = "bundle-archive/diff"
|
92
95
|
|
93
|
-
integration_state = init_state(
|
94
|
-
integration=self.name,
|
95
|
-
)
|
96
96
|
if defer:
|
97
97
|
defer(integration_state.cleanup)
|
98
|
-
diff_state = init_state(
|
99
|
-
integration=self.name,
|
100
|
-
)
|
101
|
-
if defer:
|
102
98
|
defer(diff_state.cleanup)
|
103
|
-
|
99
|
+
defer(gl.cleanup)
|
104
100
|
|
105
101
|
if not self.params.process_existing:
|
106
102
|
existing_change_log = ChangeLog(**integration_state.get(BUNDLE_DIFFS_OBJ))
|
107
|
-
|
108
|
-
ChangeLogItem(**i) # type: ignore[arg-type]
|
109
|
-
for i in existing_change_log.items
|
110
|
-
]
|
111
|
-
gl = init_gitlab(self.params.gitlab_project_id)
|
112
|
-
if defer:
|
113
|
-
defer(gl.cleanup)
|
103
|
+
|
114
104
|
change_log = ChangeLog()
|
115
105
|
for item in diff_state.ls():
|
116
106
|
key = item.lstrip("/")
|
@@ -119,7 +109,7 @@ class ChangeLogIntegration(QontractReconcileIntegration[ChangeLogIntegrationPara
|
|
119
109
|
continue
|
120
110
|
if not self.params.process_existing:
|
121
111
|
existing_change_log_item = next(
|
122
|
-
(i for i in
|
112
|
+
(i for i in existing_change_log.items if i.commit == commit), None
|
123
113
|
)
|
124
114
|
if existing_change_log_item:
|
125
115
|
logging.debug(f"Found existing commit {commit}")
|
@@ -233,4 +223,4 @@ class ChangeLogIntegration(QontractReconcileIntegration[ChangeLogIntegrationPara
|
|
233
223
|
change_log.items, key=lambda i: i.merged_at, reverse=True
|
234
224
|
)
|
235
225
|
if not dry_run:
|
236
|
-
integration_state.add(BUNDLE_DIFFS_OBJ,
|
226
|
+
integration_state.add(BUNDLE_DIFFS_OBJ, change_log.dict(), force=True)
|
reconcile/utils/output.py
CHANGED
@@ -1,9 +1,6 @@
|
|
1
1
|
import json
|
2
2
|
import re
|
3
|
-
from collections.abc import
|
4
|
-
Iterable,
|
5
|
-
Mapping,
|
6
|
-
)
|
3
|
+
from collections.abc import Iterable, Mapping
|
7
4
|
|
8
5
|
import yaml
|
9
6
|
from tabulate import tabulate
|
@@ -11,11 +8,11 @@ from tabulate import tabulate
|
|
11
8
|
|
12
9
|
def print_output(
|
13
10
|
options: Mapping[str, str | bool],
|
14
|
-
content:
|
11
|
+
content: Iterable[dict],
|
15
12
|
columns: Iterable[str] = (),
|
16
13
|
) -> str | None:
|
17
14
|
if options["sort"]:
|
18
|
-
content
|
15
|
+
content = sorted(content, key=lambda c: tuple(c.values()))
|
19
16
|
if options.get("to_string"):
|
20
17
|
for c in content:
|
21
18
|
for k, v in c.items():
|
tools/app_interface_reporter.py
CHANGED
@@ -2,6 +2,7 @@ import contextlib
|
|
2
2
|
import logging
|
3
3
|
import os
|
4
4
|
import textwrap
|
5
|
+
from collections.abc import Mapping, MutableMapping
|
5
6
|
from datetime import (
|
6
7
|
UTC,
|
7
8
|
datetime,
|
@@ -38,50 +39,14 @@ DASHDOTDB_SECRET = os.environ.get(
|
|
38
39
|
)
|
39
40
|
|
40
41
|
|
41
|
-
def promql(url, query, auth=None):
|
42
|
-
"""
|
43
|
-
Run an instant-query on the prometheus instance.
|
44
|
-
|
45
|
-
The returned structure is documented here:
|
46
|
-
https://prometheus.io/docs/prometheus/latest/querying/api/#instant-queries
|
47
|
-
|
48
|
-
:param url: base prometheus url (not the API endpoint).
|
49
|
-
:type url: string
|
50
|
-
:param query: this is a second value
|
51
|
-
:type query: string
|
52
|
-
:param auth: auth object
|
53
|
-
:type auth: requests.auth
|
54
|
-
:return: structure with the metrics
|
55
|
-
:rtype: dictionary
|
56
|
-
"""
|
57
|
-
|
58
|
-
url = os.path.join(url, "api/v1/query")
|
59
|
-
|
60
|
-
if auth is None:
|
61
|
-
auth = {}
|
62
|
-
|
63
|
-
params = {"query": query}
|
64
|
-
|
65
|
-
response = requests.get(url, params=params, auth=auth, timeout=60)
|
66
|
-
|
67
|
-
response.raise_for_status()
|
68
|
-
response = response.json()
|
69
|
-
|
70
|
-
# TODO ensure len response == 1
|
71
|
-
return response["data"]["result"]
|
72
|
-
|
73
|
-
|
74
42
|
class Report:
|
75
|
-
def __init__(self, app, date):
|
43
|
+
def __init__(self, app: Mapping, date: datetime) -> None:
|
76
44
|
settings = queries.get_app_interface_settings()
|
77
45
|
self.secret_reader = SecretReader(settings=settings)
|
78
|
-
# standard date format
|
79
|
-
if hasattr(date, "strftime"):
|
80
|
-
date = date.strftime("%Y-%m-%d")
|
81
|
-
|
82
46
|
self.app = app
|
83
|
-
|
84
|
-
self.
|
47
|
+
# standard date format
|
48
|
+
self.date = date.strftime("%Y-%m-%d")
|
49
|
+
self.report_sections: dict = {}
|
85
50
|
|
86
51
|
# promotions
|
87
52
|
self.add_report_section("promotions", self.app.get("promotions"))
|
@@ -108,10 +73,10 @@ class Report:
|
|
108
73
|
)
|
109
74
|
|
110
75
|
@property
|
111
|
-
def path(self):
|
112
|
-
return "data/reports/{
|
76
|
+
def path(self) -> str:
|
77
|
+
return f"data/reports/{self.app['name']}/{self.date}.yml"
|
113
78
|
|
114
|
-
def content(self):
|
79
|
+
def content(self) -> dict:
|
115
80
|
return {
|
116
81
|
"$schema": "/app-sre/report-1.yml",
|
117
82
|
"labels": {"app": self.app["name"]},
|
@@ -122,21 +87,20 @@ class Report:
|
|
122
87
|
"content": yaml.safe_dump(self.report_sections, sort_keys=False),
|
123
88
|
}
|
124
89
|
|
125
|
-
def to_yaml(self):
|
90
|
+
def to_yaml(self) -> str:
|
126
91
|
return yaml.safe_dump(self.content(), sort_keys=False)
|
127
92
|
|
128
|
-
def to_message(self):
|
93
|
+
def to_message(self) -> dict:
|
129
94
|
return {"file_path": self.path, "content": self.to_yaml()}
|
130
95
|
|
131
|
-
def add_report_section(self, header, content):
|
132
|
-
|
133
|
-
content = None
|
134
|
-
|
135
|
-
self.report_sections[header] = content
|
96
|
+
def add_report_section(self, header: str, content: list[dict] | None) -> None:
|
97
|
+
self.report_sections[header] = content or None
|
136
98
|
|
137
99
|
@staticmethod
|
138
|
-
def get_vulnerability_content(
|
139
|
-
|
100
|
+
def get_vulnerability_content(
|
101
|
+
container_vulnerabilities: Mapping | None,
|
102
|
+
) -> list[dict]:
|
103
|
+
parsed_metrics: list[dict] = []
|
140
104
|
if not container_vulnerabilities:
|
141
105
|
return parsed_metrics
|
142
106
|
|
@@ -150,8 +114,8 @@ class Report:
|
|
150
114
|
return parsed_metrics
|
151
115
|
|
152
116
|
@staticmethod
|
153
|
-
def get_post_deploy_jobs_content(post_deploy_jobs):
|
154
|
-
results = []
|
117
|
+
def get_post_deploy_jobs_content(post_deploy_jobs: Mapping | None) -> list[dict]:
|
118
|
+
results: list[dict] = []
|
155
119
|
if not post_deploy_jobs:
|
156
120
|
return results
|
157
121
|
|
@@ -165,8 +129,8 @@ class Report:
|
|
165
129
|
return results
|
166
130
|
|
167
131
|
@staticmethod
|
168
|
-
def get_validations_content(deployment_validations):
|
169
|
-
parsed_metrics = []
|
132
|
+
def get_validations_content(deployment_validations: Mapping | None) -> list[dict]:
|
133
|
+
parsed_metrics: list[dict] = []
|
170
134
|
if not deployment_validations:
|
171
135
|
return parsed_metrics
|
172
136
|
|
@@ -180,8 +144,8 @@ class Report:
|
|
180
144
|
return parsed_metrics
|
181
145
|
|
182
146
|
@staticmethod
|
183
|
-
def get_slo_content(service_slo):
|
184
|
-
parsed_metrics = []
|
147
|
+
def get_slo_content(service_slo: Mapping | None) -> list[dict]:
|
148
|
+
parsed_metrics: list[dict] = []
|
185
149
|
if not service_slo:
|
186
150
|
return parsed_metrics
|
187
151
|
|
@@ -200,7 +164,7 @@ class Report:
|
|
200
164
|
return parsed_metrics
|
201
165
|
|
202
166
|
@staticmethod
|
203
|
-
def get_activity_content(activity):
|
167
|
+
def get_activity_content(activity: Mapping) -> list[dict]:
|
204
168
|
if not activity:
|
205
169
|
return []
|
206
170
|
|
@@ -214,7 +178,9 @@ class Report:
|
|
214
178
|
]
|
215
179
|
|
216
180
|
|
217
|
-
def get_apps_data(
|
181
|
+
def get_apps_data(
|
182
|
+
date: datetime, month_delta: int = 1, thread_pool_size: int = 10
|
183
|
+
) -> list[dict]:
|
218
184
|
settings = queries.get_app_interface_settings()
|
219
185
|
secret_reader = SecretReader(settings)
|
220
186
|
|
@@ -297,9 +263,9 @@ def get_apps_data(date, month_delta=1, thread_pool_size=10):
|
|
297
263
|
if namespace["app"]["name"] != app["name"]:
|
298
264
|
continue
|
299
265
|
app_namespaces.append(namespace)
|
300
|
-
vuln_mx = {}
|
301
|
-
validt_mx = {}
|
302
|
-
slo_mx = {}
|
266
|
+
vuln_mx: dict = {}
|
267
|
+
validt_mx: dict = {}
|
268
|
+
slo_mx: dict = {}
|
303
269
|
for family in text_string_to_metric_families(vuln_metrics):
|
304
270
|
for sample in family.samples:
|
305
271
|
if sample.name == "imagemanifestvuln_total":
|
@@ -375,7 +341,7 @@ def get_apps_data(date, month_delta=1, thread_pool_size=10):
|
|
375
341
|
return apps
|
376
342
|
|
377
343
|
|
378
|
-
def get_build_history(job):
|
344
|
+
def get_build_history(job: MutableMapping) -> MutableMapping:
|
379
345
|
try:
|
380
346
|
logging.info(f"getting build history for {job['name']}")
|
381
347
|
job["build_history"] = job["jenkins"].get_build_history(
|
@@ -386,7 +352,9 @@ def get_build_history(job):
|
|
386
352
|
return job
|
387
353
|
|
388
354
|
|
389
|
-
def get_build_history_pool(
|
355
|
+
def get_build_history_pool(
|
356
|
+
jenkins_map: Mapping, jobs: Mapping, timestamp_limit: int, thread_pool_size: int
|
357
|
+
) -> dict:
|
390
358
|
history_to_get = []
|
391
359
|
for instance, _jobs in jobs.items():
|
392
360
|
jenkins = jenkins_map[instance]
|
@@ -411,7 +379,7 @@ def get_build_history_pool(jenkins_map, jobs, timestamp_limit, thread_pool_size)
|
|
411
379
|
return history
|
412
380
|
|
413
381
|
|
414
|
-
def get_repo_url(job):
|
382
|
+
def get_repo_url(job: Mapping) -> str:
|
415
383
|
repo_url_raw = job["properties"][0]["github"]["url"]
|
416
384
|
return repo_url_raw.strip("/").replace(".git", "")
|
417
385
|
|
@@ -424,8 +392,13 @@ def get_repo_url(job):
|
|
424
392
|
@gitlab_project_id
|
425
393
|
@click.option("--reports-path", help="path to write reports")
|
426
394
|
def main(
|
427
|
-
configfile
|
428
|
-
|
395
|
+
configfile: str,
|
396
|
+
dry_run: bool,
|
397
|
+
log_level: str,
|
398
|
+
gitlab_project_id: str,
|
399
|
+
reports_path: str,
|
400
|
+
thread_pool_size: int,
|
401
|
+
) -> None:
|
429
402
|
init_env(log_level=log_level, config_file=configfile)
|
430
403
|
|
431
404
|
now = datetime.now()
|
@@ -476,8 +449,9 @@ def main(
|
|
476
449
|
gitlab_project_id=gitlab_project_id, sqs_or_gitlab="gitlab"
|
477
450
|
) as mr_cli:
|
478
451
|
result = mr.submit(cli=mr_cli)
|
479
|
-
|
452
|
+
if result:
|
453
|
+
logging.info(["created_mr", result.web_url])
|
480
454
|
|
481
455
|
|
482
456
|
if __name__ == "__main__":
|
483
|
-
main()
|
457
|
+
main()
|
@@ -132,7 +132,7 @@ class GPGEncryptCommand:
|
|
132
132
|
|
133
133
|
return user["public_gpg_key"]
|
134
134
|
|
135
|
-
def _output(self, content: str):
|
135
|
+
def _output(self, content: str) -> None:
|
136
136
|
output = self._command_data.output
|
137
137
|
if not output:
|
138
138
|
print(content)
|
@@ -140,7 +140,7 @@ class GPGEncryptCommand:
|
|
140
140
|
with open(output, "w", encoding="locale") as f:
|
141
141
|
f.write(content)
|
142
142
|
|
143
|
-
def execute(self):
|
143
|
+
def execute(self) -> None:
|
144
144
|
secret = self._fetch_secret()
|
145
145
|
gpg_key = self._get_gpg_key()
|
146
146
|
encrypted_content = gpg.gpg_encrypt(
|