qontract-reconcile 0.10.1rc881__py3-none-any.whl → 0.10.1rc883__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.1rc881
3
+ Version: 0.10.1rc883
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
@@ -61,7 +61,7 @@ reconcile/ocm_groups.py,sha256=CluPyvmwE5JOZS2HQSReC1sD8L1ChhnJlAg8lcwdtxc,3395
61
61
  reconcile/ocm_machine_pools.py,sha256=oY4oLPm5Y_ajBV8KFg2LuBQvsZl-CxTjSxEyxg4b2OI,16634
62
62
  reconcile/ocm_update_recommended_version.py,sha256=IYkfLXIprOW1jguZeELcGP1iBPuj-b53R-FTqKulMl8,4204
63
63
  reconcile/ocm_upgrade_scheduler_org_updater.py,sha256=sQSicCyU-TPtIBYsSn97qzYiQLFaMmOMSFr1OP6tOck,4308
64
- reconcile/openshift_base.py,sha256=mE_NuKgEFsZDeA3kUo4iMsvIF1wN5yemUHeuE0M9fbY,49735
64
+ reconcile/openshift_base.py,sha256=xM14RxKYqbFQZH3kTHcvh8gEXNPpNCWZ4-SiVvFP09U,49797
65
65
  reconcile/openshift_cluster_bots.py,sha256=eRPYZqWMKFNxLlSN0QG97V5t1iIESQ0BbGaiaQP5VB0,10940
66
66
  reconcile/openshift_clusterrolebindings.py,sha256=QfSy1Ik8eEY5XObc1Q4xyhqyErZenJmbPv_u9wcDNNo,5864
67
67
  reconcile/openshift_groups.py,sha256=fqBQ6ITDOArkC_zOjskmMigdCUDq3wntLZ0NcppXaFc,9414
@@ -197,7 +197,7 @@ reconcile/glitchtip/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSu
197
197
  reconcile/glitchtip/integration.py,sha256=SCfdllg0cywCyLKCA66yUm9Z_Sb8t5E0jDEKdwRk6HI,8372
198
198
  reconcile/glitchtip/reconciler.py,sha256=nUvDv7qG1ly0cA16MmlL6NV71yl1mJYLT2mui7lmi0Y,12402
199
199
  reconcile/glitchtip_project_alerts/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
200
- reconcile/glitchtip_project_alerts/integration.py,sha256=HI_HgvTTc2K-8Md0SpEBs6tOZ3CQm-AbOatbw_NrKqg,12425
200
+ reconcile/glitchtip_project_alerts/integration.py,sha256=VFvKHso8CgsvRT8Bv5ASSehOtE39w8Cvy9SaNSgPIM0,13846
201
201
  reconcile/glitchtip_project_dsn/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
202
202
  reconcile/glitchtip_project_dsn/integration.py,sha256=5c8RVIO3Wjz2kBfB52EmxZ6VP2JQ1rLGMM9lybNhdAE,8109
203
203
  reconcile/gql_definitions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -311,7 +311,7 @@ reconcile/gql_definitions/glitchtip/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQ
311
311
  reconcile/gql_definitions/glitchtip/glitchtip_instance.py,sha256=QUfLhRkdE_-SorWgLBB8LHFD6kihbFwEoVByCLax3yM,2781
312
312
  reconcile/gql_definitions/glitchtip/glitchtip_project.py,sha256=AojrkCDGbVjY0TOkfookz-9tqLA9txY7_xNdsWe174c,6004
313
313
  reconcile/gql_definitions/glitchtip_project_alerts/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
314
- reconcile/gql_definitions/glitchtip_project_alerts/glitchtip_project.py,sha256=pnkysdaQtdiVVxz9s7V8qttFygqcXOuXREd4LF7tCW8,4466
314
+ reconcile/gql_definitions/glitchtip_project_alerts/glitchtip_project.py,sha256=Pv6RcuIzpNmGc43eEq64nnKG0Dr7H0wjy5Xg1_oRltM,5197
315
315
  reconcile/gql_definitions/integrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
316
316
  reconcile/gql_definitions/integrations/integrations.py,sha256=LfpgVbCCCk20ohwP5pDea5fwxMFGrcgE6J_WHBuGqek,11595
317
317
  reconcile/gql_definitions/jenkins_configs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -674,7 +674,7 @@ reconcile/utils/make.py,sha256=QaEwucrzbl8-VHS66Wfdjfo0ubmAcvt_hZGpiGsKU50,231
674
674
  reconcile/utils/metrics.py,sha256=ot4dBO-KLZRowvNozm7jG0RWjcVsH1SL-lQ0jJgBBZM,18645
675
675
  reconcile/utils/models.py,sha256=It_Q1WNIvw_EDCsiSWzIgpSPr_X9jMgbJI-DR3N23xY,4677
676
676
  reconcile/utils/oauth2_backend_application_session.py,sha256=6W16sMpnWEPFDUX7qi5Cui2yOnmLfpgUxWtB3Ii35D0,4177
677
- reconcile/utils/oc.py,sha256=OB78zd4xzc80ZneENHEdVzeevFyq8a34hNmefwyBw6A,65612
677
+ reconcile/utils/oc.py,sha256=D8NhbFTIeIvqzPLAqTD6-fyU4tgJHc4ofnqaY2VI0Nw,65802
678
678
  reconcile/utils/oc_connection_parameters.py,sha256=85slrnDigYwYmzhyceVkMElWzFArp4ge1d-fHXVqh0w,9729
679
679
  reconcile/utils/oc_filters.py,sha256=R2Lf3fo0jQCeE62Ygeo_KN24XbAosq0QbjimYG6qHI4,1402
680
680
  reconcile/utils/oc_map.py,sha256=nT69J5pdPeIDnIYjD9fwY6GkE3BMQCf-AF0rmHJuUNw,9068
@@ -838,8 +838,8 @@ tools/test/test_app_interface_metrics_exporter.py,sha256=SX7qL3D1SIRKFo95FoQztvf
838
838
  tools/test/test_qontract_cli.py,sha256=_D61RFGAN5x44CY1tYbouhlGXXABwYfxKSWSQx3Jrss,4941
839
839
  tools/test/test_sd_app_sre_alert_report.py,sha256=v363r9zM7__0kR5K6mvJoGFcM9BvE33fWAayrqkpojA,2116
840
840
  tools/test/test_sre_checkpoints.py,sha256=SKqPPTl9ua0RFdSSofnoQX-JZE6dFLO3LRhfQzqtfh8,2607
841
- qontract_reconcile-0.10.1rc881.dist-info/METADATA,sha256=aWt-wXRL72DWuJYJh5aKEqNiw9lbIpToGNsTP6zL8tI,2273
842
- qontract_reconcile-0.10.1rc881.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
843
- qontract_reconcile-0.10.1rc881.dist-info/entry_points.txt,sha256=GKQqCl2j2X1BJQ69een6rHcR26PmnxnONLNOQB-nRjY,491
844
- qontract_reconcile-0.10.1rc881.dist-info/top_level.txt,sha256=l5ISPoXzt0SdR4jVdkfa7RPSKNc8zAHYWAnR-Dw8Ey8,24
845
- qontract_reconcile-0.10.1rc881.dist-info/RECORD,,
841
+ qontract_reconcile-0.10.1rc883.dist-info/METADATA,sha256=AKEYLPW_CulRDgZJEvwVpBQkIh4k2QvbPHq-QYXjQv4,2273
842
+ qontract_reconcile-0.10.1rc883.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
843
+ qontract_reconcile-0.10.1rc883.dist-info/entry_points.txt,sha256=GKQqCl2j2X1BJQ69een6rHcR26PmnxnONLNOQB-nRjY,491
844
+ qontract_reconcile-0.10.1rc883.dist-info/top_level.txt,sha256=l5ISPoXzt0SdR4jVdkfa7RPSKNc8zAHYWAnR-Dw8Ey8,24
845
+ qontract_reconcile-0.10.1rc883.dist-info/RECORD,,
@@ -123,30 +123,16 @@ class GlitchtipProjectAlertsIntegration(
123
123
  )
124
124
  )
125
125
  if glitchtip_project.jira and gjb_alert_url:
126
- jira_project_key = None
127
- if glitchtip_project.jira.project:
128
- jira_project_key = glitchtip_project.jira.project
129
- elif (
130
- glitchtip_project.jira.board
131
- and integration_is_enabled(
132
- QONTRACT_INTEGRATION, glitchtip_project.jira.board
133
- )
134
- and integration_is_enabled(
135
- jira_permissions_validator.QONTRACT_INTEGRATION,
136
- glitchtip_project.jira.board,
137
- )
138
- ):
139
- jira_project_key = glitchtip_project.jira.board.name
126
+ params: dict[str, str | list[str]] = {}
127
+ token_params = {"token": gjb_token} if gjb_token else {}
128
+ alert_labels = glitchtip_project.jira.labels or []
140
129
 
141
- if jira_project_key:
142
- params: dict[str, str | list] = {}
143
- if gjb_token:
144
- params["token"] = gjb_token
145
- if glitchtip_project.jira.labels:
146
- params["labels"] = glitchtip_project.jira.labels
147
- url = (
148
- f"{gjb_alert_url}/{jira_project_key}?{urlencode(params, True)}"
149
- )
130
+ if glitchtip_project.jira.project:
131
+ params = {
132
+ "labels": alert_labels,
133
+ "components": glitchtip_project.jira.components or [],
134
+ } | token_params
135
+ url = f"{gjb_alert_url}/{glitchtip_project.jira.project}?{urlencode(params, True)}"
150
136
  alerts.append(
151
137
  ProjectAlert(
152
138
  name=GJB_ALERT_NAME,
@@ -160,6 +146,47 @@ class GlitchtipProjectAlertsIntegration(
160
146
  ],
161
147
  )
162
148
  )
149
+
150
+ elif (
151
+ glitchtip_project.jira.escalation_policy
152
+ and glitchtip_project.jira.escalation_policy.channels.jira_board
153
+ ):
154
+ # definition via escalation policy
155
+ channels = glitchtip_project.jira.escalation_policy.channels
156
+ for board in channels.jira_board:
157
+ if not integration_is_enabled(
158
+ QONTRACT_INTEGRATION, board
159
+ ) or not integration_is_enabled(
160
+ jira_permissions_validator.QONTRACT_INTEGRATION, board
161
+ ):
162
+ continue
163
+ params = {
164
+ "labels": alert_labels + (channels.jira_labels or []),
165
+ "components": [channels.jira_component]
166
+ if channels.jira_component
167
+ else [],
168
+ } | token_params
169
+ if board.issue_type:
170
+ params["issue_type"] = board.issue_type
171
+ url = f"{gjb_alert_url}/{board.name}?{urlencode(params, True)}"
172
+ alerts.append(
173
+ ProjectAlert(
174
+ name=GJB_ALERT_NAME,
175
+ timespan_minutes=1,
176
+ quantity=1,
177
+ recipients=[
178
+ ProjectAlertRecipient(
179
+ recipient_type=RecipientType.WEBHOOK,
180
+ url=url,
181
+ )
182
+ ],
183
+ )
184
+ )
185
+ else:
186
+ raise ValueError(
187
+ "Jira integration requires either project or escalation policy to be set"
188
+ )
189
+
163
190
  # check for duplicates
164
191
  if not webhook_urls_are_unique(alerts):
165
192
  raise ValueError(
@@ -58,10 +58,18 @@ query GlitchtipProjectsWithAlerts {
58
58
  }
59
59
  jira {
60
60
  project
61
- board {
62
- name
63
- disable {
64
- integrations
61
+ components
62
+ escalationPolicy {
63
+ channels {
64
+ jiraBoard {
65
+ name
66
+ issueType
67
+ disable {
68
+ integrations
69
+ }
70
+ }
71
+ jiraComponent
72
+ jiraLabels
65
73
  }
66
74
  }
67
75
  labels
@@ -113,12 +121,24 @@ class DisableJiraBoardAutomationsV1(ConfiguredBaseModel):
113
121
 
114
122
  class JiraBoardV1(ConfiguredBaseModel):
115
123
  name: str = Field(..., alias="name")
124
+ issue_type: Optional[str] = Field(..., alias="issueType")
116
125
  disable: Optional[DisableJiraBoardAutomationsV1] = Field(..., alias="disable")
117
126
 
118
127
 
128
+ class AppEscalationPolicyChannelsV1(ConfiguredBaseModel):
129
+ jira_board: list[JiraBoardV1] = Field(..., alias="jiraBoard")
130
+ jira_component: Optional[str] = Field(..., alias="jiraComponent")
131
+ jira_labels: Optional[list[str]] = Field(..., alias="jiraLabels")
132
+
133
+
134
+ class AppEscalationPolicyV1(ConfiguredBaseModel):
135
+ channels: AppEscalationPolicyChannelsV1 = Field(..., alias="channels")
136
+
137
+
119
138
  class GlitchtipProjectJiraV1(ConfiguredBaseModel):
120
139
  project: Optional[str] = Field(..., alias="project")
121
- board: Optional[JiraBoardV1] = Field(..., alias="board")
140
+ components: Optional[list[str]] = Field(..., alias="components")
141
+ escalation_policy: Optional[AppEscalationPolicyV1] = Field(..., alias="escalationPolicy")
122
142
  labels: Optional[list[str]] = Field(..., alias="labels")
123
143
 
124
144
 
@@ -40,6 +40,7 @@ from reconcile.utils.oc import (
40
40
  OCClient,
41
41
  OCLogMsg,
42
42
  PrimaryClusterIPCanNotBeUnsetError,
43
+ RequestEntityTooLargeError,
43
44
  StatefulSetUpdateForbidden,
44
45
  StatusCodeError,
45
46
  UnsupportedMediaTypeError,
@@ -402,7 +403,7 @@ def apply(
402
403
 
403
404
  try:
404
405
  oc.apply(namespace, annotated)
405
- except InvalidValueApplyError:
406
+ except (InvalidValueApplyError, RequestEntityTooLargeError):
406
407
  oc.remove_last_applied_configuration(
407
408
  namespace, resource_type, resource.name
408
409
  )
reconcile/utils/oc.py CHANGED
@@ -127,6 +127,10 @@ class JobNotRunningError(Exception):
127
127
  pass
128
128
 
129
129
 
130
+ class RequestEntityTooLargeError(Exception):
131
+ pass
132
+
133
+
130
134
  class OCDecorators:
131
135
  @classmethod
132
136
  def process_reconcile_time(cls, function):
@@ -1118,6 +1122,8 @@ class OCCli: # pylint: disable=too-many-public-methods
1118
1122
  raise StatefulSetUpdateForbidden(f"[{self.server}]: {err}")
1119
1123
  if "the object has been modified" in err:
1120
1124
  raise ObjectHasBeenModifiedError(f"[{self.server}]: {err}")
1125
+ if "Request entity too large" in err:
1126
+ raise RequestEntityTooLargeError(f"[{self.server}]: {err}")
1121
1127
  if not (allow_not_found and "NotFound" in err):
1122
1128
  raise StatusCodeError(f"[{self.server}]: {err}")
1123
1129