qontract-reconcile 0.10.1rc536__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: qontract-reconcile
3
- Version: 0.10.1rc536
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
@@ -1,5 +1,5 @@
1
1
  reconcile/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
- reconcile/acs_policies.py,sha256=Mop44Z5T0DxXghme13ZVvy1hr5KphZKzc_ZevxAJBQ0,8784
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
@@ -375,7 +375,7 @@ reconcile/templates/jira-checkpoint-missinginfo.j2,sha256=c_Vvg-lEENsB3tgxm9B6Y9
375
375
  reconcile/test/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
376
376
  reconcile/test/conftest.py,sha256=rQousYrxUz-EwAIbsYO6bIwR1B4CrOz9y_zaUVo2lfI,4466
377
377
  reconcile/test/fixtures.py,sha256=9SDWAUlSd1rCx7z3GhULHcpr-I6FyCsXxaFAZIqYQsQ,591
378
- reconcile/test/test_acs_policies.py,sha256=2hioxQ1AlbtW-jerw9YiQ8aIb0YjFpzDFs1j6pvn-Nc,15133
378
+ reconcile/test/test_acs_policies.py,sha256=hMnCX9KdLRKb53gYXK4JUR5yJwhczJRyyUPywDeLeLg,15716
379
379
  reconcile/test/test_acs_rbac.py,sha256=lvNd8GY0-GHzcOdOn13QWdrqbBXXKzNT7EEDHNH7cjM,28272
380
380
  reconcile/test/test_aggregated_list.py,sha256=iiWitQuNYC58aimWaiBoE4NROHjr1NCgQ91MnHEG_Ro,6412
381
381
  reconcile/test/test_amtool.py,sha256=vxRhGieeydMBOb9UI2ziMHjJa8puMeGNsUhGhy-yMnk,1032
@@ -590,7 +590,7 @@ reconcile/utils/vaultsecretref.py,sha256=3Ed2uBy36TzSvL0B-l4FoWQqB2SbBKDKEuUPIO6
590
590
  reconcile/utils/vcs.py,sha256=o1r0n_IrU2El75CED_6sjR2GZGM-exuWsj5F7jONaMU,6779
591
591
  reconcile/utils/acs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
592
592
  reconcile/utils/acs/base.py,sha256=Qih-xZ3RBJZEE291iHHlv7lUY6ShcAvSj1PA3_aTTnM,2276
593
- reconcile/utils/acs/policies.py,sha256=utDmFKb6pbBN3W6JFxRrlr9yFwL3aQurGDywaFGM6w0,5196
593
+ reconcile/utils/acs/policies.py,sha256=_jAz6cv8KRYtDsXjGoJgNbD8_9PUa5LSwwVlpK4A_cQ,5505
594
594
  reconcile/utils/acs/rbac.py,sha256=ugsLM9Pb7FbUbdq85E3VzXGMaB9ZovXob7tdWCxwqZ8,8808
595
595
  reconcile/utils/cloud_resource_best_practice/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
596
596
  reconcile/utils/cloud_resource_best_practice/aws_rds.py,sha256=EvE6XKLsrZ531MJptKqPht2lOETrOjySTHXk6CzMgo0,2279
@@ -668,8 +668,8 @@ tools/test/test_app_interface_metrics_exporter.py,sha256=SX7qL3D1SIRKFo95FoQztvf
668
668
  tools/test/test_qontract_cli.py,sha256=d18KrdhtUGqoC7_kWZU128U0-VJEj-0rjFkLVufcI6I,2755
669
669
  tools/test/test_sd_app_sre_alert_report.py,sha256=v363r9zM7__0kR5K6mvJoGFcM9BvE33fWAayrqkpojA,2116
670
670
  tools/test/test_sre_checkpoints.py,sha256=SKqPPTl9ua0RFdSSofnoQX-JZE6dFLO3LRhfQzqtfh8,2607
671
- qontract_reconcile-0.10.1rc536.dist-info/METADATA,sha256=BZPcvTsEmz0tR4NJmj-JZM7l_J2qAMSglos5FuteOCo,2349
672
- qontract_reconcile-0.10.1rc536.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
673
- qontract_reconcile-0.10.1rc536.dist-info/entry_points.txt,sha256=rTjAv28I_CHLM8ID3OPqMI_suoQ9s7tFbim4aYjn9kk,376
674
- qontract_reconcile-0.10.1rc536.dist-info/top_level.txt,sha256=l5ISPoXzt0SdR4jVdkfa7RPSKNc8zAHYWAnR-Dw8Ey8,24
675
- qontract_reconcile-0.10.1rc536.dist-info/RECORD,,
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, gql_policy: AcsPolicyV1, notifier_name_to_id: dict[str, str]
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(cluster=ns.cluster.name, namespace=ns.name)
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, query_func: Callable, notifiers: list[AcsPolicyApi.NotifierIdentifiers]
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
- desired = self.get_desired_state(gqlapi.query, notifiers)
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
@@ -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="app-sre-stage"),
45
- ClusterV1(name="app-sre-prod"),
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="app-sre-prod", namespace=""),
95
- Scope(cluster="app-sre-stage", namespace=""),
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="app-sre-prod", namespace="app-interface-production"),
110
- Scope(cluster="app-sre-stage", namespace="app-interface-stage"),
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": "app-sre-stage", "namespace": "", "label": None},
179
- {"cluster": "app-sre-prod", "namespace": "", "label": None},
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": "app-sre-stage",
223
+ "cluster": CLUSTER_ID_ONE,
220
224
  "namespace": "app-interface-stage",
221
225
  "label": None,
222
226
  },
223
227
  {
224
- "cluster": "app-sre-prod",
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, notifiers=api_response_list_notifiers
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
 
@@ -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
+ ]