qontract-reconcile 0.10.1rc737__py3-none-any.whl → 0.10.1rc739__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.1rc737
3
+ Version: 0.10.1rc739
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,6 +1,6 @@
1
1
  reconcile/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
- reconcile/acs_notifiers.py,sha256=1UBRTGsLrMUxpgm3WGceNyCmY9MZwUht4t26eIMWOLU,5589
3
- reconcile/acs_policies.py,sha256=1iRYmMdz0YtqyQgA9O0uGQdmMKUCCe-ApRa6LIEAdps,8769
2
+ reconcile/acs_notifiers.py,sha256=YIV9TrgWjBD8nFbrBvvU8-9s-AdezY4X5t90bFROCtM,4451
3
+ reconcile/acs_policies.py,sha256=xNbhIlwE1u2URbEQcX-3C-pTu--XjrKAqGj0-Wd85dY,9152
4
4
  reconcile/acs_rbac.py,sha256=JEDevU4AdhTjMW-fAnNG3iw6Od5tYxGuYSirmu9KurI,22657
5
5
  reconcile/aws_ami_share.py,sha256=eeu0TI3M5yyUaozyAq_aW3tir-9be4YFguOXvIvKHSo,3757
6
6
  reconcile/aws_ecr_image_pull_secrets.py,sha256=TGEc_0nv8oxV2HqA8VdcM4HHP-B1YqmNOOU6FPwVFTY,2328
@@ -186,7 +186,7 @@ reconcile/glitchtip_project_dsn/integration.py,sha256=qt2a33FOUUlCyonSHm3nUb7pNX
186
186
  reconcile/gql_definitions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
187
187
  reconcile/gql_definitions/acs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
188
188
  reconcile/gql_definitions/acs/acs_instances.py,sha256=L91WW9LbhJbBSrECqShQpFtjoBOsmNIYLRpMbx1io5o,2181
189
- reconcile/gql_definitions/acs/acs_policies.py,sha256=negfb87RDVH7WT1qiouD8ywfgH4Iumsv9Q2bf9rbjcA,7089
189
+ reconcile/gql_definitions/acs/acs_policies.py,sha256=bN5i4mks10Z23KJSj7jqp966Osq2dps4d-sPH9gjxEA,7008
190
190
  reconcile/gql_definitions/acs/acs_rbac.py,sha256=cZsIlCWliPQdQHgmBsIMx54fJNOtkdRXLzmOKZmJNHk,3009
191
191
  reconcile/gql_definitions/advanced_upgrade_service/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
192
192
  reconcile/gql_definitions/advanced_upgrade_service/aus_clusters.py,sha256=zrZCHaxkffdX2bvFUt1Hd_czViI3v3FPhZz5vJQ73jI,4301
@@ -434,8 +434,8 @@ reconcile/terraform_init/merge_request_manager.py,sha256=fMcT6hbdEF3nFATJpvr8Bed
434
434
  reconcile/test/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
435
435
  reconcile/test/conftest.py,sha256=rQousYrxUz-EwAIbsYO6bIwR1B4CrOz9y_zaUVo2lfI,4466
436
436
  reconcile/test/fixtures.py,sha256=9SDWAUlSd1rCx7z3GhULHcpr-I6FyCsXxaFAZIqYQsQ,591
437
- reconcile/test/test_acs_notifiers.py,sha256=LIVXu7EBlfKh5CWgR5jcA0vJ4IhUtxkZM6-1im204rc,12865
438
- reconcile/test/test_acs_policies.py,sha256=9TPGbF4mS2B18S7ldibZrugztaTQvcrBFvzs5eXbN-E,19211
437
+ reconcile/test/test_acs_notifiers.py,sha256=xf3WL6q6V7KQdTVSx6YI-pa4yzOX3mkvIJomgPUc3Mw,12746
438
+ reconcile/test/test_acs_policies.py,sha256=8pwnXpAO-0OI-6oubjf_oPPlpZjVldeZfJJ9uhsNMWM,17579
439
439
  reconcile/test/test_acs_rbac.py,sha256=lvNd8GY0-GHzcOdOn13QWdrqbBXXKzNT7EEDHNH7cjM,28272
440
440
  reconcile/test/test_aggregated_list.py,sha256=iiWitQuNYC58aimWaiBoE4NROHjr1NCgQ91MnHEG_Ro,6412
441
441
  reconcile/test/test_amtool.py,sha256=vxRhGieeydMBOb9UI2ziMHjJa8puMeGNsUhGhy-yMnk,1032
@@ -666,7 +666,7 @@ reconcile/utils/vaultsecretref.py,sha256=3Ed2uBy36TzSvL0B-l4FoWQqB2SbBKDKEuUPIO6
666
666
  reconcile/utils/vcs.py,sha256=o1r0n_IrU2El75CED_6sjR2GZGM-exuWsj5F7jONaMU,6779
667
667
  reconcile/utils/acs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
668
668
  reconcile/utils/acs/base.py,sha256=kjcxLGIMe8oLNFOxZ_bDcClFqGCL7Auwug5is0yNGbw,2555
669
- reconcile/utils/acs/notifiers.py,sha256=LfWw9LGq7hA90A69n8Ie9f-NozvCGdYwXEXRLIc17rY,3735
669
+ reconcile/utils/acs/notifiers.py,sha256=2n5blP9N1FdGLZuy3do9bpjd8NKg88kmLNNqhAGn8w4,5013
670
670
  reconcile/utils/acs/policies.py,sha256=_jAz6cv8KRYtDsXjGoJgNbD8_9PUa5LSwwVlpK4A_cQ,5505
671
671
  reconcile/utils/acs/rbac.py,sha256=ugsLM9Pb7FbUbdq85E3VzXGMaB9ZovXob7tdWCxwqZ8,8808
672
672
  reconcile/utils/aws_api_typed/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -777,8 +777,8 @@ tools/test/test_app_interface_metrics_exporter.py,sha256=SX7qL3D1SIRKFo95FoQztvf
777
777
  tools/test/test_qontract_cli.py,sha256=w2l4BHB09k1d-BGJ1jBUNCqDv7zkqYrMHojQXg-21kQ,4155
778
778
  tools/test/test_sd_app_sre_alert_report.py,sha256=v363r9zM7__0kR5K6mvJoGFcM9BvE33fWAayrqkpojA,2116
779
779
  tools/test/test_sre_checkpoints.py,sha256=SKqPPTl9ua0RFdSSofnoQX-JZE6dFLO3LRhfQzqtfh8,2607
780
- qontract_reconcile-0.10.1rc737.dist-info/METADATA,sha256=cSDUzKY1nBbpIuGIWfYeQyeIlIvmyU8slP8iVQOiR7Q,2382
781
- qontract_reconcile-0.10.1rc737.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
782
- qontract_reconcile-0.10.1rc737.dist-info/entry_points.txt,sha256=rIxI5zWtHNlfpDeq1a7pZXAPoqf7HG32KMTN3MeWK_8,429
783
- qontract_reconcile-0.10.1rc737.dist-info/top_level.txt,sha256=l5ISPoXzt0SdR4jVdkfa7RPSKNc8zAHYWAnR-Dw8Ey8,24
784
- qontract_reconcile-0.10.1rc737.dist-info/RECORD,,
780
+ qontract_reconcile-0.10.1rc739.dist-info/METADATA,sha256=ppwPtbo2DwU3cf6Sl4VRGILrpth1zVtdcQD2eDU70zY,2382
781
+ qontract_reconcile-0.10.1rc739.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
782
+ qontract_reconcile-0.10.1rc739.dist-info/entry_points.txt,sha256=rIxI5zWtHNlfpDeq1a7pZXAPoqf7HG32KMTN3MeWK_8,429
783
+ qontract_reconcile-0.10.1rc739.dist-info/top_level.txt,sha256=l5ISPoXzt0SdR4jVdkfa7RPSKNc8zAHYWAnR-Dw8Ey8,24
784
+ qontract_reconcile-0.10.1rc739.dist-info/RECORD,,
@@ -1,5 +1,4 @@
1
1
  import logging
2
- from typing import Any
3
2
 
4
3
  import reconcile.gql_definitions.acs.acs_policies as gql_acs_policies
5
4
  from reconcile.gql_definitions.jira.jira_servers import (
@@ -13,7 +12,6 @@ from reconcile.utils.acs.notifiers import (
13
12
  AcsNotifiersApi,
14
13
  JiraCredentials,
15
14
  JiraNotifier,
16
- SeverityPriorityMapping,
17
15
  )
18
16
  from reconcile.utils.differ import diff_iterables
19
17
  from reconcile.utils.disabled_integrations import integration_is_enabled
@@ -53,43 +51,11 @@ class AcsNotifiersIntegration(QontractReconcileIntegration[NoParams]):
53
51
  }.values()
54
52
  )
55
53
 
56
- def _build_jira_notifier(
57
- self, escalation_policy: gql_acs_policies.AppEscalationPolicyV1
58
- ) -> JiraNotifier:
59
- jira_board = escalation_policy.channels.jira_board[0]
60
-
61
- custom_fields: dict[str, Any] = {}
62
- if jira_board.issue_security_id:
63
- custom_fields["security"] = {"id": jira_board.issue_security_id}
64
- if escalation_policy.channels.jira_component:
65
- custom_fields["components"] = [
66
- {"name": escalation_policy.channels.jira_component}
67
- ]
68
- if escalation_policy.channels.jira_labels:
69
- custom_fields["labels"] = escalation_policy.channels.jira_labels
70
-
71
- item = JiraNotifier(
72
- name=f"jira-{escalation_policy.name}",
73
- board=jira_board.name,
74
- url=jira_board.server.server_url,
75
- issue_type=jira_board.issue_type or "Task",
76
- severity_priority_mappings=sorted(
77
- [
78
- SeverityPriorityMapping(**vars(sp))
79
- for sp in jira_board.severity_priority_mappings.mappings
80
- ],
81
- key=lambda m: m.severity,
82
- ),
83
- custom_fields=custom_fields,
84
- )
85
-
86
- return item
87
-
88
54
  def get_desired_state(
89
55
  self, acs_policies: list[gql_acs_policies.AcsPolicyV1]
90
56
  ) -> list[JiraNotifier]:
91
57
  return [
92
- self._build_jira_notifier(ep)
58
+ JiraNotifier.from_escalation_policy(ep)
93
59
  for ep in self._get_escalation_policies(acs_policies)
94
60
  ]
95
61
 
@@ -152,5 +118,9 @@ class AcsNotifiersIntegration(QontractReconcileIntegration[NoParams]):
152
118
  ) as acs_api:
153
119
  current_state = acs_api.get_jira_notifiers()
154
120
  self.reconcile(
155
- desired_state, current_state, acs_api, jira_credentials, dry_run
121
+ current_state=current_state,
122
+ desired_state=desired_state,
123
+ acs_api=acs_api,
124
+ jira_credentials=jira_credentials,
125
+ dry_run=dry_run,
156
126
  )
reconcile/acs_policies.py CHANGED
@@ -8,6 +8,7 @@ from reconcile.gql_definitions.acs.acs_policies import (
8
8
  AcsPolicyV1,
9
9
  )
10
10
  from reconcile.utils import gql
11
+ from reconcile.utils.acs.notifiers import JiraNotifier
11
12
  from reconcile.utils.acs.policies import AcsPolicyApi, Policy, PolicyCondition, Scope
12
13
  from reconcile.utils.differ import diff_iterables
13
14
  from reconcile.utils.runtime.integration import (
@@ -62,12 +63,21 @@ class AcsPoliciesIntegration(QontractReconcileIntegration[NoParams]):
62
63
  conditions = [
63
64
  pc for c in gql_policy.conditions if (pc := self._build_policy_condition(c))
64
65
  ]
66
+ jira_notifier = (
67
+ notifier_name_to_id.get(
68
+ JiraNotifier.from_escalation_policy(
69
+ gql_policy.integrations.notifiers.jira.escalation_policy
70
+ ).name
71
+ )
72
+ if gql_policy.integrations
73
+ and gql_policy.integrations.notifiers
74
+ and gql_policy.integrations.notifiers.jira
75
+ else None
76
+ )
65
77
  return Policy(
66
78
  name=gql_policy.name,
67
79
  description=gql_policy.description,
68
- notifiers=sorted([notifier_name_to_id[n] for n in gql_policy.notifiers])
69
- if gql_policy.notifiers
70
- else [],
80
+ notifiers=[jira_notifier] if jira_notifier else [],
71
81
  severity=f"{gql_policy.severity.upper()}_SEVERITY", # align with acs api severity value format
72
82
  scope=sorted(
73
83
  [
@@ -24,7 +24,6 @@ query AcsPolicy {
24
24
  name
25
25
  description
26
26
  severity
27
- notifiers
28
27
  integrations {
29
28
  notifiers {
30
29
  jira {
@@ -211,7 +210,6 @@ class AcsPolicyV1(ConfiguredBaseModel):
211
210
  name: str = Field(..., alias="name")
212
211
  description: Optional[str] = Field(..., alias="description")
213
212
  severity: str = Field(..., alias="severity")
214
- notifiers: Optional[list[str]] = Field(..., alias="notifiers")
215
213
  integrations: Optional[AcsPolicyIntegrationsV1] = Field(..., alias="integrations")
216
214
  categories: list[str] = Field(..., alias="categories")
217
215
  scope: Union[AcsPolicyScopeClusterV1, AcsPolicyScopeNamespaceV1, AcsPolicyScopeV1] = Field(..., alias="scope")
@@ -283,7 +283,6 @@ def acs_policies(
283
283
  name="acs-policy-1",
284
284
  description="CVEs within app-sre clusters with CVSS score gte to 7 and fixable",
285
285
  severity="high",
286
- notifiers=[],
287
286
  integrations=AcsPolicyIntegrationsV1(
288
287
  notifiers=AcsPolicyIntegrationNotifiersV1(
289
288
  jira=AcsPolicyIntegrationNotifierJiraV1(
@@ -302,7 +301,6 @@ def acs_policies(
302
301
  name="acs-policy-2",
303
302
  description="image security policy violations of critical severity within app-sre namespaces",
304
303
  severity="critical",
305
- notifiers=[],
306
304
  integrations=AcsPolicyIntegrationsV1(
307
305
  notifiers=AcsPolicyIntegrationNotifiersV1(
308
306
  jira=AcsPolicyIntegrationNotifierJiraV1(
@@ -332,15 +330,11 @@ def test_integration_get_escalation_policies(
332
330
  assert result[0] == escalation_policy
333
331
 
334
332
 
335
- def test_build_jira_notifier(
336
- acs_notifier_integration: AcsNotifiersIntegration,
333
+ def test_build_jira_notifier_from_ecalation_policy(
337
334
  escalation_policy: AppEscalationPolicyV1,
338
335
  jira_notifier: JiraNotifier,
339
336
  ) -> None:
340
- assert (
341
- acs_notifier_integration._build_jira_notifier(escalation_policy)
342
- == jira_notifier
343
- )
337
+ assert JiraNotifier.from_escalation_policy(escalation_policy) == jira_notifier
344
338
 
345
339
 
346
340
  def test_get_desired_state(
@@ -37,7 +37,7 @@ CUSTOM_POLICY_ONE_NAME = "app-sre-clusters-fixable-cve-7-fixable"
37
37
  CUSTOM_POLICY_ONE_ID = "365d4e71-3241-4448-9f3d-eb0eed1c1820"
38
38
  CUSTOM_POLICY_TWO_NAME = "app-sre-namespaces-severity-critical"
39
39
  CUSTOM_POLICY_TWO_ID = "2200245e-b700-46c2-8793-3e437fca6aa0"
40
- JIRA_NOTIFIER_NAME = "app-sre-jira"
40
+ JIRA_NOTIFIER_NAME = "jira-test-ep"
41
41
  JIRA_NOTIFIER_ID = "54170627-da34-40cb-839a-af9fbeac10fb"
42
42
 
43
43
 
@@ -49,12 +49,11 @@ def query_data_desired_state() -> AcsPolicyQueryData:
49
49
  name=CUSTOM_POLICY_ONE_NAME,
50
50
  description="CVEs within app-sre clusters with CVSS score gte to 7 and fixable",
51
51
  severity="high",
52
- notifiers=[JIRA_NOTIFIER_NAME],
53
52
  integrations=AcsPolicyIntegrationsV1(
54
53
  notifiers=AcsPolicyIntegrationNotifiersV1(
55
54
  jira=AcsPolicyIntegrationNotifierJiraV1(
56
55
  escalationPolicy=AppEscalationPolicyV1(
57
- name="test-ep",
56
+ name=JIRA_NOTIFIER_NAME.replace("jira-", ""),
58
57
  channels=AppEscalationPolicyChannelsV1(
59
58
  jiraBoard=[
60
59
  JiraBoardV1(
@@ -99,37 +98,7 @@ def query_data_desired_state() -> AcsPolicyQueryData:
99
98
  name=CUSTOM_POLICY_TWO_NAME,
100
99
  description="image security policy violations of critical severity within app-sre namespaces",
101
100
  severity="critical",
102
- notifiers=[],
103
- integrations=AcsPolicyIntegrationsV1(
104
- notifiers=AcsPolicyIntegrationNotifiersV1(
105
- jira=AcsPolicyIntegrationNotifierJiraV1(
106
- escalationPolicy=AppEscalationPolicyV1(
107
- name="test-ep",
108
- channels=AppEscalationPolicyChannelsV1(
109
- jiraBoard=[
110
- JiraBoardV1(
111
- name="board",
112
- server=JiraServerV1(
113
- serverUrl="server",
114
- ),
115
- severityPriorityMappings=JiraSeverityPriorityMappingsV1(
116
- name="sp",
117
- mappings=[],
118
- ),
119
- issueType="Task",
120
- issueSecurityId="0",
121
- disable=DisableJiraBoardAutomationsV1(
122
- integrations=[]
123
- ),
124
- )
125
- ],
126
- jiraComponent="",
127
- jiraLabels=[],
128
- ),
129
- ),
130
- ),
131
- ),
132
- ),
101
+ integrations=None,
133
102
  categories=["vulnerability-management", "devops-best-practices"],
134
103
  scope=AcsPolicyScopeNamespaceV1(
135
104
  level="namespace",
@@ -3,6 +3,7 @@ from typing import Any, Optional
3
3
 
4
4
  from pydantic import BaseModel
5
5
 
6
+ from reconcile.gql_definitions.acs.acs_policies import AppEscalationPolicyV1
6
7
  from reconcile.utils.acs.base import AcsBaseApi
7
8
 
8
9
 
@@ -74,6 +75,37 @@ class JiraNotifier(BaseModel):
74
75
  },
75
76
  }
76
77
 
78
+ @staticmethod
79
+ def from_escalation_policy(
80
+ escalation_policy: AppEscalationPolicyV1,
81
+ ) -> "JiraNotifier":
82
+ jira_board = escalation_policy.channels.jira_board[0]
83
+
84
+ custom_fields: dict[str, Any] = {}
85
+ if jira_board.issue_security_id:
86
+ custom_fields["security"] = {"id": jira_board.issue_security_id}
87
+ if escalation_policy.channels.jira_component:
88
+ custom_fields["components"] = [
89
+ {"name": escalation_policy.channels.jira_component}
90
+ ]
91
+ if escalation_policy.channels.jira_labels:
92
+ custom_fields["labels"] = escalation_policy.channels.jira_labels
93
+
94
+ return JiraNotifier(
95
+ name=f"jira-{escalation_policy.name}",
96
+ board=jira_board.name,
97
+ url=jira_board.server.server_url,
98
+ issue_type=jira_board.issue_type or "Task",
99
+ severity_priority_mappings=sorted(
100
+ [
101
+ SeverityPriorityMapping(**vars(sp))
102
+ for sp in jira_board.severity_priority_mappings.mappings
103
+ ],
104
+ key=lambda m: m.severity,
105
+ ),
106
+ custom_fields=custom_fields,
107
+ )
108
+
77
109
 
78
110
  class AcsNotifiersApi(AcsBaseApi):
79
111
  """