qontract-reconcile 0.10.2.dev27__py3-none-any.whl → 0.10.2.dev28__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.4
2
2
  Name: qontract-reconcile
3
- Version: 0.10.2.dev27
3
+ Version: 0.10.2.dev28
4
4
  Summary: Collection of tools to reconcile services with their desired state as defined in the app-interface DB.
5
5
  Project-URL: homepage, https://github.com/app-sre/qontract-reconcile
6
6
  Project-URL: repository, https://github.com/app-sre/qontract-reconcile
@@ -10,7 +10,7 @@ reconcile/aws_iam_password_reset.py,sha256=q96mwr2KeEQ5bpNniGlgIMZTxiuLSodcYfX-t
10
10
  reconcile/aws_support_cases_sos.py,sha256=hl_9L53yQYRQxKs3IWrd69Cc60XK067g_bJRM9B0udo,2975
11
11
  reconcile/blackbox_exporter_endpoint_monitoring.py,sha256=O1wFp52EyF538c6txaWBs8eMtUIy19gyHZ6VzJ6QXS8,3512
12
12
  reconcile/checkpoint.py,sha256=_JhMxrye5BgkRMxWYuf7Upli6XayPINKSsuo3ynHTRc,5010
13
- reconcile/cli.py,sha256=BCfKBc5BRq-9Y5WYe8sUoz9ufOsB1WwMvylx6mBf6CQ,107806
13
+ reconcile/cli.py,sha256=vHCmBcriMEqwVDj_7wujQFbrYa4b6yiiFTYCByWkbwg,107407
14
14
  reconcile/closedbox_endpoint_monitoring_base.py,sha256=MvGKBqH9PdHWdMjhLuptze-dk0Tifhp3-0SZdI-7Fmo,4862
15
15
  reconcile/cluster_deployment_mapper.py,sha256=5gumAaRCcFXsabUJ1dnuUy9WrP_FEEM5JnOnE8ch9sE,2326
16
16
  reconcile/dashdotdb_base.py,sha256=83ZWIf5JJk3P_D69y2TmXRcQr6ELJGlv10OM0h7fJVs,4767
@@ -46,7 +46,7 @@ reconcile/jenkins_roles.py,sha256=HadmoNhgOoKMFZJmCe_Gdg0_a9k_1MuOXidtr801nUU,45
46
46
  reconcile/jenkins_webhooks.py,sha256=dzMT1ywXjeAo5sHj-ittW06Ed3beAUPjnc_oCAtD-Rg,2150
47
47
  reconcile/jenkins_webhooks_cleaner.py,sha256=JsN_NVPfZJwv1JtSzZXDIHUqGiefL-DRffFnDGau9aY,1539
48
48
  reconcile/jenkins_worker_fleets.py,sha256=L2wEXpd4xuEHrXGss4iH788nG8UlLSYduZe1EY2IVw4,5377
49
- reconcile/jira_permissions_validator.py,sha256=uuwzizb16jTWGctDB0cG0t9l3trDxZuK2SJA-9w7tfA,14872
49
+ reconcile/jira_permissions_validator.py,sha256=DCKUyaqwUcIN4BuNtdREQW44K9yFxa1RUuA8a-dzXFE,13336
50
50
  reconcile/jira_watcher.py,sha256=L_UL2MKm2SoIGNsCLThm28pnqCkoFc154JWsD6bURug,3593
51
51
  reconcile/ldap_users.py,sha256=7hdO5CAPl-VNBvDRmKHg13LoblHXXPt7YEKNGomAoGg,3158
52
52
  reconcile/mr_client_gateway.py,sha256=WhjMd-sIXDFCV8-rt8CEjurJ5OYB1pOD0K3o0tZRXQg,1885
@@ -766,7 +766,7 @@ tools/saas_promotion_state/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJ
766
766
  tools/saas_promotion_state/saas_promotion_state.py,sha256=UfwwRLS5Ya4_Nh1w5n1dvoYtchQvYE9yj1VANt2IKqI,3925
767
767
  tools/sre_checkpoints/__init__.py,sha256=CDaDaywJnmRCLyl_NCcvxi-Zc0hTi_3OdwKiFOyS39I,145
768
768
  tools/sre_checkpoints/util.py,sha256=zEDbGr18ZeHNQwW8pUsr2JRjuXIPz--WAGJxZo9sv_Y,894
769
- qontract_reconcile-0.10.2.dev27.dist-info/METADATA,sha256=Nr3x_-2IN6jO8C6UVvoDJmObBt8_Y6OZ54Ok0UsHikA,24665
770
- qontract_reconcile-0.10.2.dev27.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
771
- qontract_reconcile-0.10.2.dev27.dist-info/entry_points.txt,sha256=JniHZPadNOILPyfSl0LF2YSp3Db7K2_W2CN7i9f3Gos,540
772
- qontract_reconcile-0.10.2.dev27.dist-info/RECORD,,
769
+ qontract_reconcile-0.10.2.dev28.dist-info/METADATA,sha256=b2MPIc5XBW0hxukARgJFyKClbJwKN80IL4K4BLeU_G4,24665
770
+ qontract_reconcile-0.10.2.dev28.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
771
+ qontract_reconcile-0.10.2.dev28.dist-info/entry_points.txt,sha256=JniHZPadNOILPyfSl0LF2YSp3Db7K2_W2CN7i9f3Gos,540
772
+ qontract_reconcile-0.10.2.dev28.dist-info/RECORD,,
reconcile/cli.py CHANGED
@@ -1162,28 +1162,15 @@ def jenkins_webhooks_cleaner(ctx):
1162
1162
  "--jira-board-name", help="The Jira board to act on.", default=None, multiple=True
1163
1163
  )
1164
1164
  @click.option("--board-check-interval", help="Check interval in minutes", default=120)
1165
- @enable_extended_early_exit
1166
- @extended_early_exit_cache_ttl_seconds
1167
- @log_cached_log_output
1168
1165
  @click.pass_context
1169
- def jira_permissions_validator(
1170
- ctx,
1171
- jira_board_name,
1172
- board_check_interval,
1173
- enable_extended_early_exit,
1174
- extended_early_exit_cache_ttl_seconds,
1175
- log_cached_log_output,
1176
- ):
1166
+ def jira_permissions_validator(ctx, jira_board_name, board_check_interval):
1177
1167
  import reconcile.jira_permissions_validator
1178
1168
 
1179
1169
  run_integration(
1180
1170
  reconcile.jira_permissions_validator,
1181
1171
  ctx.obj,
1182
1172
  jira_board_name=jira_board_name,
1183
- board_check_interval=board_check_interval,
1184
- enable_extended_early_exit=enable_extended_early_exit,
1185
- extended_early_exit_cache_ttl_seconds=extended_early_exit_cache_ttl_seconds,
1186
- log_cached_log_output=log_cached_log_output,
1173
+ board_check_interval_sec=board_check_interval * 60,
1187
1174
  )
1188
1175
 
1189
1176
 
@@ -1,4 +1,5 @@
1
1
  import logging
2
+ import random
2
3
  import sys
3
4
  import time
4
5
  from collections.abc import Callable, Iterable
@@ -23,16 +24,11 @@ from reconcile.typed_queries.jiralert_settings import get_jiralert_settings
23
24
  from reconcile.utils import gql, metrics
24
25
  from reconcile.utils.defer import defer
25
26
  from reconcile.utils.disabled_integrations import integration_is_enabled
26
- from reconcile.utils.extended_early_exit import (
27
- ExtendedEarlyExitRunnerResult,
28
- extended_early_exit_run,
29
- )
30
27
  from reconcile.utils.jira_client import JiraClient, JiraWatcherSettings
31
28
  from reconcile.utils.runtime.integration import DesiredStateShardConfig
32
29
  from reconcile.utils.secret_reader import SecretReaderBase, create_secret_reader
33
30
  from reconcile.utils.semver_helper import make_semver
34
31
  from reconcile.utils.state import State, init_state
35
- from reconcile.utils.unleash import get_feature_toggle_state
36
32
 
37
33
  QONTRACT_INTEGRATION = "jira-permissions-validator"
38
34
  QONTRACT_INTEGRATION_VERSION = make_semver(1, 2, 0)
@@ -70,7 +66,7 @@ class ValidationError(IntFlag):
70
66
 
71
67
  class RunnerParams(TypedDict):
72
68
  boards: list[JiraBoardV1]
73
- board_check_interval: int
69
+ board_check_interval_sec: int
74
70
  dry_run: bool
75
71
 
76
72
 
@@ -206,7 +202,7 @@ def validate_boards(
206
202
  jira_boards: Iterable[JiraBoardV1],
207
203
  default_issue_type: str,
208
204
  default_reopen_state: str,
209
- board_check_interval: int,
205
+ board_check_interval_sec: int,
210
206
  dry_run: bool,
211
207
  state: State,
212
208
  jira_client_class: type[JiraClient] = JiraClient,
@@ -214,8 +210,8 @@ def validate_boards(
214
210
  error = False
215
211
  jira_clients: dict[str, JiraClient] = {}
216
212
  for board in jira_boards:
217
- last_successful_run = state.get(board.name, 0)
218
- if not dry_run and time.time() <= last_successful_run + board_check_interval:
213
+ next_run_time = state.get(board.name, 0)
214
+ if not dry_run and time.time() <= next_run_time:
219
215
  logging.debug(f"[{board.name}] Skipping board")
220
216
  continue
221
217
 
@@ -243,8 +239,13 @@ def validate_boards(
243
239
  # no errors
244
240
  logging.debug(f"[{board.name}] is valid")
245
241
  if not dry_run:
246
- # remember time of the last successful run
247
- state[board.name] = time.time()
242
+ # set the run time for the next check
243
+ state[board.name] = (
244
+ time.time()
245
+ + board_check_interval_sec
246
+ # add some randomness to avoid all boards checking at the same time
247
+ + random.randint(0, 3600)
248
+ )
248
249
  case ValidationError.PERMISSION_ERROR:
249
250
  # we don't have all the permissions, but we can create jira tickets
250
251
  metrics_container.set_gauge(
@@ -290,57 +291,15 @@ def export_boards(boards: list[JiraBoardV1]) -> list[dict]:
290
291
  return [board.dict() for board in boards]
291
292
 
292
293
 
294
+ @defer
293
295
  def run(
294
296
  dry_run: bool,
295
297
  jira_board_name: list[str] | None = None,
296
- board_check_interval: int = 3600,
297
- enable_extended_early_exit: bool = False,
298
- extended_early_exit_cache_ttl_seconds: int = 3600,
299
- log_cached_log_output: bool = False,
298
+ board_check_interval_sec: int = 3600,
299
+ defer: Callable | None = None,
300
300
  ) -> None:
301
301
  gql_api = gql.get_api()
302
302
  boards = get_jira_boards(query_func=gql_api.query, jira_board_names=jira_board_name)
303
- runner_params: RunnerParams = {
304
- "boards": boards,
305
- "dry_run": dry_run,
306
- "board_check_interval": board_check_interval,
307
- }
308
- if enable_extended_early_exit and get_feature_toggle_state(
309
- "jira-permissions-validator-extended-early-exit",
310
- default=True,
311
- ):
312
- vault_settings = get_app_interface_vault_settings()
313
- secret_reader = create_secret_reader(use_vault=vault_settings.vault)
314
-
315
- cache_source = CacheSource(
316
- boards=export_boards(boards),
317
- )
318
- extended_early_exit_run(
319
- integration=QONTRACT_INTEGRATION,
320
- integration_version=QONTRACT_INTEGRATION_VERSION,
321
- # don't use `dry_run` in the cache key because this is a read-only integration
322
- dry_run=False,
323
- cache_source=cache_source,
324
- shard="_".join(set(jira_board_name)) if jira_board_name else "",
325
- ttl_seconds=extended_early_exit_cache_ttl_seconds,
326
- logger=logging.getLogger(),
327
- runner=runner,
328
- runner_params=runner_params,
329
- secret_reader=secret_reader,
330
- log_cached_log_output=log_cached_log_output,
331
- )
332
- else:
333
- runner(**runner_params)
334
-
335
-
336
- @defer
337
- def runner(
338
- boards: list[JiraBoardV1],
339
- dry_run: bool,
340
- board_check_interval: int,
341
- defer: Callable | None = None,
342
- ) -> ExtendedEarlyExitRunnerResult:
343
- gql_api = gql.get_api()
344
303
  settings = get_jira_settings(gql_api=gql_api)
345
304
  jiralert_settings = get_jiralert_settings(query_func=gql_api.query)
346
305
  vault_settings = get_app_interface_vault_settings()
@@ -357,7 +316,7 @@ def runner(
357
316
  jira_boards=boards,
358
317
  default_issue_type=jiralert_settings.default_issue_type,
359
318
  default_reopen_state=jiralert_settings.default_reopen_state,
360
- board_check_interval=board_check_interval,
319
+ board_check_interval_sec=board_check_interval_sec,
361
320
  dry_run=dry_run,
362
321
  state=state,
363
322
  )
@@ -365,8 +324,6 @@ def runner(
365
324
  if error:
366
325
  sys.exit(ExitCodes.ERROR)
367
326
 
368
- return ExtendedEarlyExitRunnerResult(payload=export_boards(boards), applied_count=0)
369
-
370
327
 
371
328
  def early_exit_desired_state(
372
329
  *args: Any, jira_board_name: list[str] | None = None, **kwargs: Any