qontract-reconcile 0.10.1rc535__py3-none-any.whl → 0.10.1rc537__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.1rc535.dist-info → qontract_reconcile-0.10.1rc537.dist-info}/METADATA +1 -1
- {qontract_reconcile-0.10.1rc535.dist-info → qontract_reconcile-0.10.1rc537.dist-info}/RECORD +13 -12
- reconcile/acs_policies.py +16 -6
- reconcile/saas_auto_promotions_manager/merge_request_manager/merge_request_manager_v2.py +24 -1
- reconcile/saas_auto_promotions_manager/merge_request_manager/metrics.py +40 -0
- reconcile/saas_auto_promotions_manager/merge_request_manager/reconciler.py +10 -7
- reconcile/test/saas_auto_promotions_manager/merge_request_manager/merge_request_manager/test_merge_request_manager.py +3 -2
- reconcile/test/saas_auto_promotions_manager/merge_request_manager/merge_request_manager/test_reconciler.py +8 -10
- reconcile/test/test_acs_policies.py +26 -11
- reconcile/utils/acs/policies.py +10 -0
- {qontract_reconcile-0.10.1rc535.dist-info → qontract_reconcile-0.10.1rc537.dist-info}/WHEEL +0 -0
- {qontract_reconcile-0.10.1rc535.dist-info → qontract_reconcile-0.10.1rc537.dist-info}/entry_points.txt +0 -0
- {qontract_reconcile-0.10.1rc535.dist-info → qontract_reconcile-0.10.1rc537.dist-info}/top_level.txt +0 -0
{qontract_reconcile-0.10.1rc535.dist-info → qontract_reconcile-0.10.1rc537.dist-info}/METADATA
RENAMED
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: qontract-reconcile
|
3
|
-
Version: 0.10.
|
3
|
+
Version: 0.10.1rc537
|
4
4
|
Summary: Collection of tools to reconcile services with their desired state as defined in the app-interface DB.
|
5
5
|
Home-page: https://github.com/app-sre/qontract-reconcile
|
6
6
|
Author: Red Hat App-SRE Team
|
{qontract_reconcile-0.10.1rc535.dist-info → qontract_reconcile-0.10.1rc537.dist-info}/RECORD
RENAMED
@@ -1,5 +1,5 @@
|
|
1
1
|
reconcile/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
2
|
-
reconcile/acs_policies.py,sha256=
|
2
|
+
reconcile/acs_policies.py,sha256=e_kVyP4rGm3fJzq10Anr8scZoPenlmTcoS5REK0d2T0,9144
|
3
3
|
reconcile/acs_rbac.py,sha256=YoKu5wTRTtb3EGT0PV3r279LDgvw2ECb-0_0j4suScg,23032
|
4
4
|
reconcile/aws_ami_share.py,sha256=eeu0TI3M5yyUaozyAq_aW3tir-9be4YFguOXvIvKHSo,3757
|
5
5
|
reconcile/aws_ecr_image_pull_secrets.py,sha256=TGEc_0nv8oxV2HqA8VdcM4HHP-B1YqmNOOU6FPwVFTY,2328
|
@@ -350,9 +350,10 @@ reconcile/saas_auto_promotions_manager/publisher.py,sha256=4_M9Oykhj-kEZPUn05E2D
|
|
350
350
|
reconcile/saas_auto_promotions_manager/subscriber.py,sha256=cLhPlkT71J2LIice3SLmH1WpsqzV46gd0peMxrnqyRw,7452
|
351
351
|
reconcile/saas_auto_promotions_manager/merge_request_manager/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
352
352
|
reconcile/saas_auto_promotions_manager/merge_request_manager/merge_request.py,sha256=BeAJWLow7b4HQyZ9zz398sQkPeIz8chpMkCts2NU27c,1282
|
353
|
-
reconcile/saas_auto_promotions_manager/merge_request_manager/merge_request_manager_v2.py,sha256=
|
353
|
+
reconcile/saas_auto_promotions_manager/merge_request_manager/merge_request_manager_v2.py,sha256=mU6csC1-2WjEHhYNCeEDDmN63QQIprp0zkqQ5UH5xNM,6817
|
354
|
+
reconcile/saas_auto_promotions_manager/merge_request_manager/metrics.py,sha256=mI9yYwCiNePmtox16yKH1mU5ijsMeQYjQBgRiZq101A,878
|
354
355
|
reconcile/saas_auto_promotions_manager/merge_request_manager/mr_parser.py,sha256=x8Gg-YjEFWEeDPJH3Y8SrfcJbwhLuAqCz4kIhfEyaaA,7060
|
355
|
-
reconcile/saas_auto_promotions_manager/merge_request_manager/reconciler.py,sha256=
|
356
|
+
reconcile/saas_auto_promotions_manager/merge_request_manager/reconciler.py,sha256=nst5ZynEQs9Hy9Z2DAjN8_ALIS_5XnrbJh7KG4YVRrE,7789
|
356
357
|
reconcile/saas_auto_promotions_manager/merge_request_manager/renderer.py,sha256=huslpgeXNf_VmEVmWHIYYSwEcT67zsbuubYMk2P9ezc,6959
|
357
358
|
reconcile/saas_auto_promotions_manager/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
358
359
|
reconcile/saas_auto_promotions_manager/utils/saas_files_inventory.py,sha256=mihuWynroB1Cea1Lsvf6V8Nb8PGiBdcLC0uhCX_52Y0,6966
|
@@ -374,7 +375,7 @@ reconcile/templates/jira-checkpoint-missinginfo.j2,sha256=c_Vvg-lEENsB3tgxm9B6Y9
|
|
374
375
|
reconcile/test/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
375
376
|
reconcile/test/conftest.py,sha256=rQousYrxUz-EwAIbsYO6bIwR1B4CrOz9y_zaUVo2lfI,4466
|
376
377
|
reconcile/test/fixtures.py,sha256=9SDWAUlSd1rCx7z3GhULHcpr-I6FyCsXxaFAZIqYQsQ,591
|
377
|
-
reconcile/test/test_acs_policies.py,sha256=
|
378
|
+
reconcile/test/test_acs_policies.py,sha256=hMnCX9KdLRKb53gYXK4JUR5yJwhczJRyyUPywDeLeLg,15716
|
378
379
|
reconcile/test/test_acs_rbac.py,sha256=lvNd8GY0-GHzcOdOn13QWdrqbBXXKzNT7EEDHNH7cjM,28272
|
379
380
|
reconcile/test/test_aggregated_list.py,sha256=iiWitQuNYC58aimWaiBoE4NROHjr1NCgQ91MnHEG_Ro,6412
|
380
381
|
reconcile/test/test_amtool.py,sha256=vxRhGieeydMBOb9UI2ziMHjJa8puMeGNsUhGhy-yMnk,1032
|
@@ -458,9 +459,9 @@ reconcile/test/saas_auto_promotions_manager/merge_request_manager/__init__.py,sh
|
|
458
459
|
reconcile/test/saas_auto_promotions_manager/merge_request_manager/merge_request_manager/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
459
460
|
reconcile/test/saas_auto_promotions_manager/merge_request_manager/merge_request_manager/conftest.py,sha256=7O3lbk1EmEtUofqGncfiwMYvDPXrkQNPB59zlQ_zXkM,4588
|
460
461
|
reconcile/test/saas_auto_promotions_manager/merge_request_manager/merge_request_manager/data_keys.py,sha256=Z1IV51OUuzhd-3S8W-k7ixC-fkaglCokn0eakK0Z73s,606
|
461
|
-
reconcile/test/saas_auto_promotions_manager/merge_request_manager/merge_request_manager/test_merge_request_manager.py,sha256=
|
462
|
+
reconcile/test/saas_auto_promotions_manager/merge_request_manager/merge_request_manager/test_merge_request_manager.py,sha256=h8lnorFPZIxTtbaaXGLoiEsBbB4Qj-Mg9BKV62ZqEBQ,2389
|
462
463
|
reconcile/test/saas_auto_promotions_manager/merge_request_manager/merge_request_manager/test_mr_parser.py,sha256=dcGHzxuafKSxmswSO1qF2WlKaqsmEvtERC6Lb8kDAN0,10019
|
463
|
-
reconcile/test/saas_auto_promotions_manager/merge_request_manager/merge_request_manager/test_reconciler.py,sha256=
|
464
|
+
reconcile/test/saas_auto_promotions_manager/merge_request_manager/merge_request_manager/test_reconciler.py,sha256=_bzfJzjFJgubu--7wyXIiusUrdbmLtFbHmkbat4SX_M,17828
|
464
465
|
reconcile/test/saas_auto_promotions_manager/merge_request_manager/renderer/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
465
466
|
reconcile/test/saas_auto_promotions_manager/merge_request_manager/renderer/conftest.py,sha256=2rCSstewp4LPoEJHm5N7dGJexEtY8ndLHvoGZYjmpsc,1678
|
466
467
|
reconcile/test/saas_auto_promotions_manager/merge_request_manager/renderer/data_keys.py,sha256=beHYQ9kgDLeBZgC2FvxQA3tHx1PO-RAMN8_kVcSdikI,90
|
@@ -589,7 +590,7 @@ reconcile/utils/vaultsecretref.py,sha256=3Ed2uBy36TzSvL0B-l4FoWQqB2SbBKDKEuUPIO6
|
|
589
590
|
reconcile/utils/vcs.py,sha256=o1r0n_IrU2El75CED_6sjR2GZGM-exuWsj5F7jONaMU,6779
|
590
591
|
reconcile/utils/acs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
591
592
|
reconcile/utils/acs/base.py,sha256=Qih-xZ3RBJZEE291iHHlv7lUY6ShcAvSj1PA3_aTTnM,2276
|
592
|
-
reconcile/utils/acs/policies.py,sha256=
|
593
|
+
reconcile/utils/acs/policies.py,sha256=_jAz6cv8KRYtDsXjGoJgNbD8_9PUa5LSwwVlpK4A_cQ,5505
|
593
594
|
reconcile/utils/acs/rbac.py,sha256=ugsLM9Pb7FbUbdq85E3VzXGMaB9ZovXob7tdWCxwqZ8,8808
|
594
595
|
reconcile/utils/cloud_resource_best_practice/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
595
596
|
reconcile/utils/cloud_resource_best_practice/aws_rds.py,sha256=EvE6XKLsrZ531MJptKqPht2lOETrOjySTHXk6CzMgo0,2279
|
@@ -667,8 +668,8 @@ tools/test/test_app_interface_metrics_exporter.py,sha256=SX7qL3D1SIRKFo95FoQztvf
|
|
667
668
|
tools/test/test_qontract_cli.py,sha256=d18KrdhtUGqoC7_kWZU128U0-VJEj-0rjFkLVufcI6I,2755
|
668
669
|
tools/test/test_sd_app_sre_alert_report.py,sha256=v363r9zM7__0kR5K6mvJoGFcM9BvE33fWAayrqkpojA,2116
|
669
670
|
tools/test/test_sre_checkpoints.py,sha256=SKqPPTl9ua0RFdSSofnoQX-JZE6dFLO3LRhfQzqtfh8,2607
|
670
|
-
qontract_reconcile-0.10.
|
671
|
-
qontract_reconcile-0.10.
|
672
|
-
qontract_reconcile-0.10.
|
673
|
-
qontract_reconcile-0.10.
|
674
|
-
qontract_reconcile-0.10.
|
671
|
+
qontract_reconcile-0.10.1rc537.dist-info/METADATA,sha256=dGXxQQQzpUMW_Kyo_ktrTXrUVvKSJ9GMS7SG5jKdMoo,2349
|
672
|
+
qontract_reconcile-0.10.1rc537.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
|
673
|
+
qontract_reconcile-0.10.1rc537.dist-info/entry_points.txt,sha256=rTjAv28I_CHLM8ID3OPqMI_suoQ9s7tFbim4aYjn9kk,376
|
674
|
+
qontract_reconcile-0.10.1rc537.dist-info/top_level.txt,sha256=l5ISPoXzt0SdR4jVdkfa7RPSKNc8zAHYWAnR-Dw8Ey8,24
|
675
|
+
qontract_reconcile-0.10.1rc537.dist-info/RECORD,,
|
reconcile/acs_policies.py
CHANGED
@@ -58,7 +58,10 @@ class AcsPoliciesIntegration(QontractReconcileIntegration[NoParams]):
|
|
58
58
|
return self.qontract_integration.replace("_", "-")
|
59
59
|
|
60
60
|
def _build_policy(
|
61
|
-
self,
|
61
|
+
self,
|
62
|
+
gql_policy: AcsPolicyV1,
|
63
|
+
notifier_name_to_id: dict[str, str],
|
64
|
+
cluster_name_to_id: dict[str, str],
|
62
65
|
) -> Policy:
|
63
66
|
conditions = [
|
64
67
|
pc for c in gql_policy.conditions if (pc := self._build_policy_condition(c))
|
@@ -72,7 +75,7 @@ class AcsPoliciesIntegration(QontractReconcileIntegration[NoParams]):
|
|
72
75
|
severity=f"{gql_policy.severity.upper()}_SEVERITY", # align with acs api severity value format
|
73
76
|
scope=sorted(
|
74
77
|
[
|
75
|
-
Scope(cluster=cs.name, namespace="")
|
78
|
+
Scope(cluster=cluster_name_to_id[cs.name], namespace="")
|
76
79
|
for cs in cast(
|
77
80
|
gql_acs_policies.AcsPolicyScopeClusterV1,
|
78
81
|
gql_policy.scope,
|
@@ -83,7 +86,9 @@ class AcsPoliciesIntegration(QontractReconcileIntegration[NoParams]):
|
|
83
86
|
if gql_policy.scope.level == "cluster"
|
84
87
|
else sorted(
|
85
88
|
[
|
86
|
-
Scope(
|
89
|
+
Scope(
|
90
|
+
cluster=cluster_name_to_id[ns.cluster.name], namespace=ns.name
|
91
|
+
)
|
87
92
|
for ns in cast(
|
88
93
|
gql_acs_policies.AcsPolicyScopeNamespaceV1,
|
89
94
|
gql_policy.scope,
|
@@ -158,7 +163,10 @@ class AcsPoliciesIntegration(QontractReconcileIntegration[NoParams]):
|
|
158
163
|
return None
|
159
164
|
|
160
165
|
def get_desired_state(
|
161
|
-
self,
|
166
|
+
self,
|
167
|
+
query_func: Callable,
|
168
|
+
notifiers: list[AcsPolicyApi.NotifierIdentifiers],
|
169
|
+
clusters: list[AcsPolicyApi.ClusterIdentifiers],
|
162
170
|
) -> list[Policy]:
|
163
171
|
"""
|
164
172
|
Get desired ACS security policies and convert to acs api policy object format
|
@@ -167,8 +175,9 @@ class AcsPoliciesIntegration(QontractReconcileIntegration[NoParams]):
|
|
167
175
|
:return: list of utils.acs.policies.Policy derived from acs-policy-1 definitions
|
168
176
|
"""
|
169
177
|
notifier_name_to_id = {n.name: n.id for n in notifiers}
|
178
|
+
cluster_name_to_id = {c.name: c.id for c in clusters}
|
170
179
|
return [
|
171
|
-
self._build_policy(gql_policy, notifier_name_to_id)
|
180
|
+
self._build_policy(gql_policy, notifier_name_to_id, cluster_name_to_id)
|
172
181
|
for gql_policy in gql_acs_policies.query(query_func=query_func).acs_policies
|
173
182
|
or []
|
174
183
|
]
|
@@ -225,7 +234,8 @@ class AcsPoliciesIntegration(QontractReconcileIntegration[NoParams]):
|
|
225
234
|
instance={"url": instance.url, "token": token[instance.credentials.field]}
|
226
235
|
) as acs_api:
|
227
236
|
notifiers = acs_api.list_notifiers()
|
228
|
-
|
237
|
+
clusters = acs_api.list_clusters()
|
238
|
+
desired = self.get_desired_state(gqlapi.query, notifiers, clusters)
|
229
239
|
current = acs_api.get_custom_policies()
|
230
240
|
self.reconcile(
|
231
241
|
desired=desired, current=current, acs=acs_api, dry_run=dry_run
|
@@ -7,6 +7,15 @@ from gitlab.exceptions import GitlabGetError
|
|
7
7
|
from reconcile.saas_auto_promotions_manager.merge_request_manager.merge_request import (
|
8
8
|
SAPMMR,
|
9
9
|
)
|
10
|
+
from reconcile.saas_auto_promotions_manager.merge_request_manager.metrics import (
|
11
|
+
SAPMClosedMRsCounter as MRClosedCounter,
|
12
|
+
)
|
13
|
+
from reconcile.saas_auto_promotions_manager.merge_request_manager.metrics import (
|
14
|
+
SAPMOpenedMRsCounter as MROpenedCounter,
|
15
|
+
)
|
16
|
+
from reconcile.saas_auto_promotions_manager.merge_request_manager.metrics import (
|
17
|
+
SAPMParallelOpenMRsGauge as ParallelOpenMRGauge,
|
18
|
+
)
|
10
19
|
from reconcile.saas_auto_promotions_manager.merge_request_manager.mr_parser import (
|
11
20
|
MRParser,
|
12
21
|
)
|
@@ -19,6 +28,7 @@ from reconcile.saas_auto_promotions_manager.merge_request_manager.renderer impor
|
|
19
28
|
Renderer,
|
20
29
|
)
|
21
30
|
from reconcile.saas_auto_promotions_manager.subscriber import Subscriber
|
31
|
+
from reconcile.utils import metrics
|
22
32
|
from reconcile.utils.mr.labels import AUTO_MERGE
|
23
33
|
from reconcile.utils.vcs import VCS
|
24
34
|
|
@@ -138,19 +148,32 @@ class MergeRequestManagerV2:
|
|
138
148
|
|
139
149
|
def reconcile(self, subscribers: Iterable[Subscriber]) -> None:
|
140
150
|
current_state = self._mr_parser.retrieve_open_mrs(label=SAPM_LABEL)
|
151
|
+
metrics.set_gauge(ParallelOpenMRGauge(), len(current_state))
|
152
|
+
|
141
153
|
desired_state = self._aggregate_desired_state(subscribers=subscribers)
|
154
|
+
|
142
155
|
diff = self._reconciler.reconcile(
|
143
156
|
batch_limit=BATCH_SIZE_LIMIT,
|
144
157
|
desired_promotions=desired_state,
|
145
158
|
open_mrs=current_state,
|
146
159
|
)
|
147
160
|
for deletion in diff.deletions:
|
161
|
+
metrics.inc_counter(
|
162
|
+
MRClosedCounter(
|
163
|
+
reason=deletion.reason.name,
|
164
|
+
),
|
165
|
+
)
|
148
166
|
self._vcs.close_app_interface_mr(
|
149
167
|
mr=deletion.mr.raw,
|
150
|
-
comment=deletion.reason,
|
168
|
+
comment=deletion.reason.value,
|
151
169
|
)
|
152
170
|
|
153
171
|
for addition in diff.additions:
|
172
|
+
metrics.inc_counter(
|
173
|
+
MROpenedCounter(
|
174
|
+
is_batchable=addition.batchable,
|
175
|
+
),
|
176
|
+
)
|
154
177
|
self._render_mr(addition=addition)
|
155
178
|
|
156
179
|
for rendered_mr in self._sapm_mrs:
|
@@ -0,0 +1,40 @@
|
|
1
|
+
from pydantic import BaseModel
|
2
|
+
|
3
|
+
from reconcile.utils.metrics import (
|
4
|
+
CounterMetric,
|
5
|
+
GaugeMetric,
|
6
|
+
)
|
7
|
+
|
8
|
+
|
9
|
+
class SAPMBaseMetric(BaseModel):
|
10
|
+
"Base class for SAPM MR metrics"
|
11
|
+
|
12
|
+
integration: str = "saas_auto_promotions_manager"
|
13
|
+
|
14
|
+
|
15
|
+
class SAPMOpenedMRsCounter(SAPMBaseMetric, CounterMetric):
|
16
|
+
"Counter for the number of opened auto-promotion MRs"
|
17
|
+
|
18
|
+
is_batchable: bool
|
19
|
+
|
20
|
+
@classmethod
|
21
|
+
def name(cls) -> str:
|
22
|
+
return "sapm_opened_mrs"
|
23
|
+
|
24
|
+
|
25
|
+
class SAPMClosedMRsCounter(SAPMBaseMetric, CounterMetric):
|
26
|
+
"Counter for the number of closed auto-promotion MRs"
|
27
|
+
|
28
|
+
reason: str
|
29
|
+
|
30
|
+
@classmethod
|
31
|
+
def name(cls) -> str:
|
32
|
+
return "sapm_closed_mrs"
|
33
|
+
|
34
|
+
|
35
|
+
class SAPMParallelOpenMRsGauge(SAPMBaseMetric, GaugeMetric):
|
36
|
+
"Gauge for the number of parallel open auto-promotion MRs"
|
37
|
+
|
38
|
+
@classmethod
|
39
|
+
def name(cls) -> str:
|
40
|
+
return "sapm_parallel_open_mrs"
|
@@ -1,14 +1,17 @@
|
|
1
1
|
from collections.abc import Iterable
|
2
2
|
from dataclasses import dataclass
|
3
|
+
from enum import Enum
|
3
4
|
from typing import Optional
|
4
5
|
|
5
6
|
from reconcile.saas_auto_promotions_manager.merge_request_manager.mr_parser import (
|
6
7
|
OpenMergeRequest,
|
7
8
|
)
|
8
9
|
|
9
|
-
|
10
|
-
|
11
|
-
|
10
|
+
|
11
|
+
class Reason(Enum):
|
12
|
+
MISSING_UNBATCHING = "Closing this MR because it failed MR check and isn't marked as un-batchable yet. cc @kfischer"
|
13
|
+
OUTDATED_CONTENT = "Closing this MR because it has out-dated content."
|
14
|
+
NEW_BATCH = "Closing this MR in favor of a new batch MR."
|
12
15
|
|
13
16
|
|
14
17
|
@dataclass
|
@@ -20,7 +23,7 @@ class Promotion:
|
|
20
23
|
@dataclass
|
21
24
|
class Deletion:
|
22
25
|
mr: OpenMergeRequest
|
23
|
-
reason:
|
26
|
+
reason: Reason
|
24
27
|
|
25
28
|
|
26
29
|
@dataclass
|
@@ -70,7 +73,7 @@ class Reconciler:
|
|
70
73
|
diff.deletions.append(
|
71
74
|
Deletion(
|
72
75
|
mr=mr,
|
73
|
-
reason=
|
76
|
+
reason=Reason.MISSING_UNBATCHING,
|
74
77
|
)
|
75
78
|
)
|
76
79
|
else:
|
@@ -112,7 +115,7 @@ class Reconciler:
|
|
112
115
|
diff.deletions.append(
|
113
116
|
Deletion(
|
114
117
|
mr=mr,
|
115
|
-
reason=
|
118
|
+
reason=Reason.OUTDATED_CONTENT,
|
116
119
|
)
|
117
120
|
)
|
118
121
|
self._open_mrs = open_mrs_after_deletion
|
@@ -163,7 +166,7 @@ class Reconciler:
|
|
163
166
|
diff.deletions.append(
|
164
167
|
Deletion(
|
165
168
|
mr=batch_with_capacity,
|
166
|
-
reason=
|
169
|
+
reason=Reason.NEW_BATCH,
|
167
170
|
)
|
168
171
|
)
|
169
172
|
|
@@ -14,6 +14,7 @@ from reconcile.saas_auto_promotions_manager.merge_request_manager.reconciler imp
|
|
14
14
|
Addition,
|
15
15
|
Deletion,
|
16
16
|
Diff,
|
17
|
+
Reason,
|
17
18
|
Reconciler,
|
18
19
|
)
|
19
20
|
from reconcile.saas_auto_promotions_manager.merge_request_manager.renderer import (
|
@@ -48,7 +49,7 @@ def test_reconcile(
|
|
48
49
|
failed_mr_check=False,
|
49
50
|
is_batchable=True,
|
50
51
|
),
|
51
|
-
reason=
|
52
|
+
reason=Reason.NEW_BATCH,
|
52
53
|
)
|
53
54
|
|
54
55
|
additions = [
|
@@ -76,7 +77,7 @@ def test_reconcile(
|
|
76
77
|
|
77
78
|
assert len(manager._sapm_mrs) == len(additions)
|
78
79
|
vcs.close_app_interface_mr.assert_has_calls([
|
79
|
-
call(deletion.mr.raw, deletion.reason),
|
80
|
+
call(deletion.mr.raw, deletion.reason.value),
|
80
81
|
])
|
81
82
|
vcs.open_app_interface_merge_request.assert_has_calls([
|
82
83
|
call(mr) for mr in manager._sapm_mrs
|
@@ -8,13 +8,11 @@ from reconcile.saas_auto_promotions_manager.merge_request_manager.mr_parser impo
|
|
8
8
|
OpenMergeRequest,
|
9
9
|
)
|
10
10
|
from reconcile.saas_auto_promotions_manager.merge_request_manager.reconciler import (
|
11
|
-
MSG_MISSING_UNBATCHING,
|
12
|
-
MSG_NEW_BATCH,
|
13
|
-
MSG_OUTDATED_CONTENT,
|
14
11
|
Addition,
|
15
12
|
Deletion,
|
16
13
|
Diff,
|
17
14
|
Promotion,
|
15
|
+
Reason,
|
18
16
|
Reconciler,
|
19
17
|
)
|
20
18
|
|
@@ -110,7 +108,7 @@ def _aggregate_channels(items: Sequence[Addition | Deletion]) -> set[str]:
|
|
110
108
|
failed_mr_check=True,
|
111
109
|
is_batchable=True,
|
112
110
|
),
|
113
|
-
reason=
|
111
|
+
reason=Reason.MISSING_UNBATCHING,
|
114
112
|
),
|
115
113
|
Deletion(
|
116
114
|
mr=OpenMergeRequest(
|
@@ -120,7 +118,7 @@ def _aggregate_channels(items: Sequence[Addition | Deletion]) -> set[str]:
|
|
120
118
|
failed_mr_check=False,
|
121
119
|
is_batchable=True,
|
122
120
|
),
|
123
|
-
reason=
|
121
|
+
reason=Reason.OUTDATED_CONTENT,
|
124
122
|
),
|
125
123
|
Deletion(
|
126
124
|
mr=OpenMergeRequest(
|
@@ -130,7 +128,7 @@ def _aggregate_channels(items: Sequence[Addition | Deletion]) -> set[str]:
|
|
130
128
|
failed_mr_check=False,
|
131
129
|
is_batchable=False,
|
132
130
|
),
|
133
|
-
reason=
|
131
|
+
reason=Reason.OUTDATED_CONTENT,
|
134
132
|
),
|
135
133
|
Deletion(
|
136
134
|
mr=OpenMergeRequest(
|
@@ -140,7 +138,7 @@ def _aggregate_channels(items: Sequence[Addition | Deletion]) -> set[str]:
|
|
140
138
|
failed_mr_check=True,
|
141
139
|
is_batchable=False,
|
142
140
|
),
|
143
|
-
reason=
|
141
|
+
reason=Reason.OUTDATED_CONTENT,
|
144
142
|
),
|
145
143
|
],
|
146
144
|
additions=[],
|
@@ -181,7 +179,7 @@ def _aggregate_channels(items: Sequence[Addition | Deletion]) -> set[str]:
|
|
181
179
|
failed_mr_check=True,
|
182
180
|
is_batchable=True,
|
183
181
|
),
|
184
|
-
reason=
|
182
|
+
reason=Reason.MISSING_UNBATCHING,
|
185
183
|
)
|
186
184
|
],
|
187
185
|
additions=[
|
@@ -263,7 +261,7 @@ def _aggregate_channels(items: Sequence[Addition | Deletion]) -> set[str]:
|
|
263
261
|
failed_mr_check=False,
|
264
262
|
is_batchable=True,
|
265
263
|
),
|
266
|
-
reason=
|
264
|
+
reason=Reason.NEW_BATCH,
|
267
265
|
)
|
268
266
|
],
|
269
267
|
additions=[
|
@@ -321,7 +319,7 @@ def _aggregate_channels(items: Sequence[Addition | Deletion]) -> set[str]:
|
|
321
319
|
failed_mr_check=False,
|
322
320
|
is_batchable=True,
|
323
321
|
),
|
324
|
-
reason=
|
322
|
+
reason=Reason.NEW_BATCH,
|
325
323
|
)
|
326
324
|
],
|
327
325
|
additions=[
|
@@ -20,6 +20,10 @@ from reconcile.gql_definitions.acs.acs_policies import (
|
|
20
20
|
)
|
21
21
|
from reconcile.utils.acs.policies import AcsPolicyApi, Policy, PolicyCondition, Scope
|
22
22
|
|
23
|
+
CLUSTER_NAME_ONE = "app-sre-stage"
|
24
|
+
CLUSTER_ID_ONE = "5211d395-5cf7-4185-a1fb-d88f41bc7542"
|
25
|
+
CLUSTER_NAME_TWO = "app-sre-prod"
|
26
|
+
CLUSTER_ID_TWO = "a217cca7-d85a-4be1-9703-f58866fdbe2d"
|
23
27
|
CUSTOM_POLICY_ONE_NAME = "app-sre-clusters-fixable-cve-7-fixable"
|
24
28
|
CUSTOM_POLICY_ONE_ID = "365d4e71-3241-4448-9f3d-eb0eed1c1820"
|
25
29
|
CUSTOM_POLICY_TWO_NAME = "app-sre-namespaces-severity-critical"
|
@@ -41,8 +45,8 @@ def query_data_desired_state() -> AcsPolicyQueryData:
|
|
41
45
|
scope=AcsPolicyScopeClusterV1(
|
42
46
|
level="cluster",
|
43
47
|
clusters=[
|
44
|
-
ClusterV1(name=
|
45
|
-
ClusterV1(name=
|
48
|
+
ClusterV1(name=CLUSTER_NAME_ONE),
|
49
|
+
ClusterV1(name=CLUSTER_NAME_TWO),
|
46
50
|
],
|
47
51
|
),
|
48
52
|
conditions=[
|
@@ -91,8 +95,8 @@ def modeled_acs_policies() -> list[Policy]:
|
|
91
95
|
notifiers=[JIRA_NOTIFIER_ID],
|
92
96
|
categories=["Vulnerability Management"],
|
93
97
|
scope=[
|
94
|
-
Scope(cluster=
|
95
|
-
Scope(cluster=
|
98
|
+
Scope(cluster=CLUSTER_ID_ONE, namespace=""),
|
99
|
+
Scope(cluster=CLUSTER_ID_TWO, namespace=""),
|
96
100
|
],
|
97
101
|
conditions=[
|
98
102
|
PolicyCondition(field_name="CVSS", values=[">=7"], negate=False),
|
@@ -106,8 +110,8 @@ def modeled_acs_policies() -> list[Policy]:
|
|
106
110
|
notifiers=[],
|
107
111
|
categories=["DevOps Best Practices", "Vulnerability Management"],
|
108
112
|
scope=[
|
109
|
-
Scope(cluster=
|
110
|
-
Scope(cluster=
|
113
|
+
Scope(cluster=CLUSTER_ID_ONE, namespace="app-interface-stage"),
|
114
|
+
Scope(cluster=CLUSTER_ID_TWO, namespace="app-interface-production"),
|
111
115
|
],
|
112
116
|
conditions=[
|
113
117
|
PolicyCondition(
|
@@ -175,8 +179,8 @@ def api_response_policies_specific() -> list[Any]:
|
|
175
179
|
"eventSource": "NOT_APPLICABLE",
|
176
180
|
"exclusions": [],
|
177
181
|
"scope": [
|
178
|
-
{"cluster":
|
179
|
-
{"cluster":
|
182
|
+
{"cluster": CLUSTER_ID_ONE, "namespace": "", "label": None},
|
183
|
+
{"cluster": CLUSTER_ID_TWO, "namespace": "", "label": None},
|
180
184
|
],
|
181
185
|
"severity": "HIGH_SEVERITY",
|
182
186
|
"enforcementActions": [],
|
@@ -216,12 +220,12 @@ def api_response_policies_specific() -> list[Any]:
|
|
216
220
|
"exclusions": [],
|
217
221
|
"scope": [
|
218
222
|
{
|
219
|
-
"cluster":
|
223
|
+
"cluster": CLUSTER_ID_ONE,
|
220
224
|
"namespace": "app-interface-stage",
|
221
225
|
"label": None,
|
222
226
|
},
|
223
227
|
{
|
224
|
-
"cluster":
|
228
|
+
"cluster": CLUSTER_ID_TWO,
|
225
229
|
"namespace": "app-interface-production",
|
226
230
|
"label": None,
|
227
231
|
},
|
@@ -257,11 +261,20 @@ def api_response_list_notifiers() -> list[AcsPolicyApi.NotifierIdentifiers]:
|
|
257
261
|
]
|
258
262
|
|
259
263
|
|
264
|
+
@pytest.fixture
|
265
|
+
def api_response_list_clusters() -> list[AcsPolicyApi.ClusterIdentifiers]:
|
266
|
+
return [
|
267
|
+
AcsPolicyApi.ClusterIdentifiers(id=CLUSTER_ID_ONE, name=CLUSTER_NAME_ONE),
|
268
|
+
AcsPolicyApi.ClusterIdentifiers(id=CLUSTER_ID_TWO, name=CLUSTER_NAME_TWO),
|
269
|
+
]
|
270
|
+
|
271
|
+
|
260
272
|
def test_get_desired_state(
|
261
273
|
mocker: MockerFixture,
|
262
274
|
query_data_desired_state: AcsPolicyQueryData,
|
263
275
|
modeled_acs_policies: list[Policy],
|
264
276
|
api_response_list_notifiers: list[AcsPolicyApi.NotifierIdentifiers],
|
277
|
+
api_response_list_clusters: list[AcsPolicyApi.ClusterIdentifiers],
|
265
278
|
) -> None:
|
266
279
|
query_func = mocker.patch(
|
267
280
|
"reconcile.gql_definitions.acs.acs_policies.query", autospec=True
|
@@ -270,7 +283,9 @@ def test_get_desired_state(
|
|
270
283
|
|
271
284
|
integration = AcsPoliciesIntegration()
|
272
285
|
result = integration.get_desired_state(
|
273
|
-
query_func=query_func,
|
286
|
+
query_func=query_func,
|
287
|
+
notifiers=api_response_list_notifiers,
|
288
|
+
clusters=api_response_list_clusters,
|
274
289
|
)
|
275
290
|
assert result == modeled_acs_policies
|
276
291
|
|
reconcile/utils/acs/policies.py
CHANGED
@@ -151,3 +151,13 @@ class AcsPolicyApi(AcsBaseApi):
|
|
151
151
|
self.NotifierIdentifiers(id=c["id"], name=c["name"])
|
152
152
|
for c in self.generic_request("/v1/notifiers", "GET").json()["notifiers"]
|
153
153
|
]
|
154
|
+
|
155
|
+
class ClusterIdentifiers(BaseModel):
|
156
|
+
id: str
|
157
|
+
name: str
|
158
|
+
|
159
|
+
def list_clusters(self) -> list[ClusterIdentifiers]:
|
160
|
+
return [
|
161
|
+
self.ClusterIdentifiers(id=c["id"], name=c["name"])
|
162
|
+
for c in self.generic_request("/v1/clusters", "GET").json()["clusters"]
|
163
|
+
]
|
File without changes
|
File without changes
|
{qontract_reconcile-0.10.1rc535.dist-info → qontract_reconcile-0.10.1rc537.dist-info}/top_level.txt
RENAMED
File without changes
|