qontract-reconcile 0.10.1rc882__py3-none-any.whl → 0.10.1rc884__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.1rc882
3
+ Version: 0.10.1rc884
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
@@ -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
@@ -472,7 +472,7 @@ reconcile/terraform_init/integration.py,sha256=xcFKTc_or3xB3kE_I3OECNkkgbwALIwwd
472
472
  reconcile/terraform_init/merge_request.py,sha256=3CYtgSd7Q9zjKg4wsDz437EPCRfGeZZ8fZ0Y-ChKXJY,1475
473
473
  reconcile/terraform_init/merge_request_manager.py,sha256=fMcT6hbdEF3nFATJpvr8BedvQHq_MzFkgVJSloBNwOQ,3101
474
474
  reconcile/terraform_vpc_resources/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
475
- reconcile/terraform_vpc_resources/integration.py,sha256=hQX5JWrC-MSwICs4FMJ_pbTa5eTQP6VrmE58z_XYclg,8204
475
+ reconcile/terraform_vpc_resources/integration.py,sha256=evBNlUo5KwXoY3az7rOKaV3d7W578wRU2N98zJrKXYI,8209
476
476
  reconcile/terraform_vpc_resources/merge_request.py,sha256=loRymUigCIvaaT0s_NzktZchh-DGRQnCICdBSCAcFPY,1503
477
477
  reconcile/terraform_vpc_resources/merge_request_manager.py,sha256=Vj2nuQbQyrL4q_il1My-bLxYNh_r3YXqX45P8fwtP6Q,3259
478
478
  reconcile/test/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -702,7 +702,7 @@ reconcile/utils/sqs_gateway.py,sha256=gFl9DM4DmGnptuxTOe4lS3YTyE80eSAvK42ljS8h4d
702
702
  reconcile/utils/state.py,sha256=DRxzuOw3Iha-b2esBMjZTZ5K-OxfrGbkyEvpTT5xHTs,16369
703
703
  reconcile/utils/structs.py,sha256=LcbLEg8WxfRqM6nW7NhcWN0YeqF7SQzxOgntmLs1SgY,352
704
704
  reconcile/utils/template.py,sha256=wTvRU4AnAV_o042tD4Mwls2dwWMuk7MKnde3MaCjaYg,331
705
- reconcile/utils/terraform_client.py,sha256=mZEKpu6nbfiQd60wRkc8-5sljBTUTOgaAKnF89itMzU,32085
705
+ reconcile/utils/terraform_client.py,sha256=XYtCz4af3BvJ6loDheOzDE6d4IZXOMFr4LCf2jqx3EU,32481
706
706
  reconcile/utils/terrascript_aws_client.py,sha256=msKley24-PiYt3lsPUNzKh2tpMj4MpGjF7lXFr0sBM0,276187
707
707
  reconcile/utils/three_way_diff_strategy.py,sha256=OniTnogBkdgy_7Xg51N1MgjS-Qtk8uM1ccjWaiXxiV8,4895
708
708
  reconcile/utils/throughput.py,sha256=iP4UWAe2LVhDo69mPPmgo9nQ7RxHD6_GS8MZe-aSiuM,344
@@ -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.1rc882.dist-info/METADATA,sha256=h86zL76A3OqZCu_IiZB3FL-aoKD2jRhyQV3yAgRGVI8,2273
842
- qontract_reconcile-0.10.1rc882.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
843
- qontract_reconcile-0.10.1rc882.dist-info/entry_points.txt,sha256=GKQqCl2j2X1BJQ69een6rHcR26PmnxnONLNOQB-nRjY,491
844
- qontract_reconcile-0.10.1rc882.dist-info/top_level.txt,sha256=l5ISPoXzt0SdR4jVdkfa7RPSKNc8zAHYWAnR-Dw8Ey8,24
845
- qontract_reconcile-0.10.1rc882.dist-info/RECORD,,
841
+ qontract_reconcile-0.10.1rc884.dist-info/METADATA,sha256=9uV_JpZyviuoBDMGVALW8Dggyct-WRRrS6pEGcGUD00,2273
842
+ qontract_reconcile-0.10.1rc884.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
843
+ qontract_reconcile-0.10.1rc884.dist-info/entry_points.txt,sha256=GKQqCl2j2X1BJQ69een6rHcR26PmnxnONLNOQB-nRjY,491
844
+ qontract_reconcile-0.10.1rc884.dist-info/top_level.txt,sha256=l5ISPoXzt0SdR4jVdkfa7RPSKNc8zAHYWAnR-Dw8Ey8,24
845
+ qontract_reconcile-0.10.1rc884.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
 
@@ -164,7 +164,7 @@ class TerraformVpcResources(QontractReconcileIntegration[TerraformVpcResourcesPa
164
164
  thread_pool_size=thread_pool_size,
165
165
  )
166
166
 
167
- tf_client.plan(enable_deletion=enable_deletion)
167
+ tf_client.safe_plan(enable_deletion=enable_deletion)
168
168
 
169
169
  if dry_run:
170
170
  sys.exit(ExitCodes.SUCCESS)
@@ -209,6 +209,15 @@ class TerraformClient: # pylint: disable=too-many-public-methods
209
209
  self.created_users.extend(created_users)
210
210
  return disabled_deletions_detected, errors
211
211
 
212
+ def safe_plan(self, enable_deletion: bool) -> None:
213
+ """Raises exception if errors are detected at plan step"""
214
+ disable_deletions_detected, errors = self.plan(enable_deletion)
215
+
216
+ if errors:
217
+ raise RuntimeError("Terraform plan has errors")
218
+ if disable_deletions_detected:
219
+ raise RuntimeError("Terraform plan has disabled deletions detected")
220
+
212
221
  @retry()
213
222
  def terraform_plan(
214
223
  self, spec: TerraformSpec, enable_deletion: bool