qontract-reconcile 0.10.1rc217__py3-none-any.whl → 0.10.1rc218__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.1rc217
3
+ Version: 0.10.1rc218
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
@@ -23,12 +23,12 @@ reconcile/github_repo_invites.py,sha256=n5_gUcGotBBnvx3F41auCqX_gbZKut_XRTWGlsrK
23
23
  reconcile/github_repo_permissions_validator.py,sha256=dcbXdUx6imjNchjp3pg9-z1i7lFEGOr_28GvsiwO5Xw,1734
24
24
  reconcile/github_users.py,sha256=nfTq78QRONIfDVj-5O3bD6psllJjzWFnog-EJ1WqFPU,3672
25
25
  reconcile/github_validator.py,sha256=cVTVxJIGR4a1Jz8wrdXEAb_CMpXUzvykVmUURX4cook,917
26
- reconcile/gitlab_fork_compliance.py,sha256=XEwm5tlTvoY95py4MsBHgGcw6_8tWtJ9hLyUKa6y2_k,4246
27
- reconcile/gitlab_housekeeping.py,sha256=UesYfhhQMzXkL9oWTr2yh8r0wZKIEe9PshTAYTXsqk4,22169
26
+ reconcile/gitlab_fork_compliance.py,sha256=nLrwtoj5bTlaMutpKUc4R6lqZtpqB0otcIOMNfIxUsU,4223
27
+ reconcile/gitlab_housekeeping.py,sha256=9rZZ97R0eMHW67YksHM2ATmHLQoq62bmimfUSeI_M0Q,21276
28
28
  reconcile/gitlab_labeler.py,sha256=avNifNROyGhko6WDAaTH3ixA86qzxdBsSk1IisRoxao,4635
29
29
  reconcile/gitlab_members.py,sha256=M6LwFOrwgvl1NNdOJa1mrQFUon-bEVv1AyhGeLed454,8443
30
30
  reconcile/gitlab_mr_sqs_consumer.py,sha256=O46mdziPgGOndbU-0_UJKJVUaiEoVzJPEgKm4_UvYoI,2571
31
- reconcile/gitlab_owners.py,sha256=3OwGjPsKzKBtp0l2wWfh1RwnWYDeLejykCq5SHof0vk,13922
31
+ reconcile/gitlab_owners.py,sha256=n5_pX841OST3dGfMUEXtqIcyqV4NjzSEvh2E0up7Y1c,13876
32
32
  reconcile/gitlab_permissions.py,sha256=ciEKj_wnRbS_vs_ZwcUeD6HkWVe3osAuotFqJSmvd94,1638
33
33
  reconcile/gitlab_projects.py,sha256=K3tFf_aD1W4Ijp5q-9Qek3kwFGEWPcZ1kd7tzFJ4GyQ,1781
34
34
  reconcile/integrations_manager.py,sha256=zUCh1bYrnNoT_6SSQO-yYA2QdDxfCuzwb1tjcByIOaE,8885
@@ -126,7 +126,7 @@ reconcile/aws_ami_cleanup/integration.py,sha256=E--71oG3HhrUgBieAf51wNE1N1xtsuOa
126
126
  reconcile/change_owners/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
127
127
  reconcile/change_owners/approver.py,sha256=L7XJWJ-rgn8BOmeMb6lBDV8lHFCUaNoHGDSD7OH03vA,2244
128
128
  reconcile/change_owners/bundle.py,sha256=Bh9v08tIw8TieG4EE9kVI9iFN1sW7Z6Zyb8DTbsv6F0,5371
129
- reconcile/change_owners/change_owners.py,sha256=L3Glirkd5a6TnPyseANq8THhnV6oJP_2PcqAfxhkjxE,13257
129
+ reconcile/change_owners/change_owners.py,sha256=2Z182TKDpcvPwLtyTDbHdA11IMXuWrBSQxUoeUmdXbU,13268
130
130
  reconcile/change_owners/change_types.py,sha256=3UFjyuTW0-si9pvaKfqGCWGwTiBVi7n9HZnfHk_x5iY,31486
131
131
  reconcile/change_owners/changes.py,sha256=KrtaDTM_jxyYsHPUEjJCWJr186L4a-NsxCnztdSUry4,16912
132
132
  reconcile/change_owners/decision.py,sha256=JBMhNG8UqaKzTZgaKQLTPn8KW8CSEvq8clP76ZfQT6s,6381
@@ -330,7 +330,7 @@ reconcile/test/test_closedbox_endpoint_monitoring.py,sha256=isMHYwRWMFARU2nbJgbl
330
330
  reconcile/test/test_gabi_authorized_users.py,sha256=vyO9-1w6OtGQJvJuTazJMVAjQbUd90sgsHcMyIYkUC8,2483
331
331
  reconcile/test/test_github_org.py,sha256=j3KeB4OnSln1gm2hidce49xdMru-j75NS3cM-AEgzZc,4511
332
332
  reconcile/test/test_github_repo_invites.py,sha256=QJ0VFk5B59rx4XtHoT6XOGWw9xRIZMen_cgtviN_Vi8,3419
333
- reconcile/test/test_gitlab_housekeeping.py,sha256=ScFp3ztym2Q4lJwuTclq9HIHaT8JAymGoP1t-ynRFCQ,10049
333
+ reconcile/test/test_gitlab_housekeeping.py,sha256=7EpWikaWJH52IlA2PZs7vz4GEgID-_dfZBpJNlwhMSw,10018
334
334
  reconcile/test/test_gitlab_labeler.py,sha256=vFLUJXSIaCduj6wSqgw7Fg7FhlopaDnYI5SLzNHtLoY,4362
335
335
  reconcile/test/test_gitlab_members.py,sha256=dP_dm-1THba9Vyzcq-EX1tdmBoX2hq8R-MY4Uqknq5s,9896
336
336
  reconcile/test/test_instrumented_wrappers.py,sha256=CZzhnQH0c4i7-Rxjg7-0dfFMvVPegLHL46z5NHOOCwo,608
@@ -464,7 +464,7 @@ reconcile/utils/filtering.py,sha256=dw7Ok7HXjZb0ruvCWHFh194rtunX1COLDTRnNfOpwQU,
464
464
  reconcile/utils/git.py,sha256=kgjN93MMB5mnkuNb1n53f5kldGGf5u0pBHj9YJbiE_c,1455
465
465
  reconcile/utils/git_secrets.py,sha256=897nRs7tycA3m7YYeVEbzOhI8RFrI9IJT2E0di1eJhc,1956
466
466
  reconcile/utils/github_api.py,sha256=6gdlKK0W3vZpxbbtOcohRgvZ4YkiSki7Gxdb16goHPo,2316
467
- reconcile/utils/gitlab_api.py,sha256=6udOgddf0qcTSgJTJcSHL5YJrUKiAFnTg7ZrHXKbhso,24939
467
+ reconcile/utils/gitlab_api.py,sha256=v_cf2xt7trUlYFRYsuJ9ZkCEtFiO_0coAjlxBjjHedc,24839
468
468
  reconcile/utils/gpg.py,sha256=EKG7_fdMv8BMlV5yUdPiqoTx-KrzmVSEAl2sLkaKwWI,1123
469
469
  reconcile/utils/gql.py,sha256=KogegLFsvjiTWqPBDSb4qJToISrdsDeLJ3gkHwi1DQ8,11672
470
470
  reconcile/utils/helm.py,sha256=IWlB_LrBK6ydwNQuZP2aMJGrtQw0lW7qdFqSrd3r8lg,1321
@@ -577,8 +577,8 @@ tools/test/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
577
577
  tools/test/test_qontract_cli.py,sha256=awwTHEc2DWlykuqGIYM0WOBoSL0KRnOraCLk3C7izis,1401
578
578
  tools/test/test_sd_app_sre_alert_report.py,sha256=JeLhgzpKCPgLvptwg_4ZvJHLVWKNG1T5845HXTkMBxA,1826
579
579
  tools/test/test_sre_checkpoints.py,sha256=SKqPPTl9ua0RFdSSofnoQX-JZE6dFLO3LRhfQzqtfh8,2607
580
- qontract_reconcile-0.10.1rc217.dist-info/METADATA,sha256=QBRhW6c0O_YoDfAeIiX0W6crUJADXZDV6w2iSbSSE5I,2328
581
- qontract_reconcile-0.10.1rc217.dist-info/WHEEL,sha256=AtBG6SXL3KF_v0NxLf0ehyVOh0cold-JbJYXNGorC6Q,92
582
- qontract_reconcile-0.10.1rc217.dist-info/entry_points.txt,sha256=ErVY2Jp-0Rtuq5KOtMlW5yvna4nIEuc_1YbEdEdcy9o,301
583
- qontract_reconcile-0.10.1rc217.dist-info/top_level.txt,sha256=l5ISPoXzt0SdR4jVdkfa7RPSKNc8zAHYWAnR-Dw8Ey8,24
584
- qontract_reconcile-0.10.1rc217.dist-info/RECORD,,
580
+ qontract_reconcile-0.10.1rc218.dist-info/METADATA,sha256=NYrL4Jw0x9csqevY8_axCXnpuJXmobKSqauptV79qqY,2328
581
+ qontract_reconcile-0.10.1rc218.dist-info/WHEEL,sha256=AtBG6SXL3KF_v0NxLf0ehyVOh0cold-JbJYXNGorC6Q,92
582
+ qontract_reconcile-0.10.1rc218.dist-info/entry_points.txt,sha256=ErVY2Jp-0Rtuq5KOtMlW5yvna4nIEuc_1YbEdEdcy9o,301
583
+ qontract_reconcile-0.10.1rc218.dist-info/top_level.txt,sha256=l5ISPoXzt0SdR4jVdkfa7RPSKNc8zAHYWAnR-Dw8Ey8,24
584
+ qontract_reconcile-0.10.1rc218.dist-info/RECORD,,
@@ -372,9 +372,8 @@ def run(
372
372
  # e.g. gitlab-housekeeper rejects direct lgtm labels and the review-queue
373
373
  # skips MRs with this label
374
374
  if SELF_SERVICEABLE in labels:
375
- gl.remove_label_from_merge_request(
376
- gitlab_merge_request_id, SELF_SERVICEABLE
377
- )
375
+ merge_request = gl.get_merge_request(gitlab_merge_request_id)
376
+ gl.remove_label(merge_request, SELF_SERVICEABLE)
378
377
 
379
378
  except BaseException:
380
379
  logging.error(traceback.format_exc())
@@ -80,7 +80,7 @@ class GitlabForkCompliance:
80
80
  # it is set
81
81
  mr_labels = self.gl_cli.get_merge_request_labels(self.mr.iid)
82
82
  if BLOCKED_BOT_ACCESS in mr_labels:
83
- self.gl_cli.remove_label_from_merge_request(self.mr.iid, BLOCKED_BOT_ACCESS)
83
+ self.gl_cli.remove_label(self.mr, BLOCKED_BOT_ACCESS)
84
84
 
85
85
  sys.exit(self.exit_code)
86
86
 
@@ -214,8 +214,7 @@ def handle_stale_items(
214
214
  now = datetime.utcnow()
215
215
  for item in items:
216
216
  item_iid = item.attributes.get("iid")
217
- item_labels = get_labels(item, gl)
218
- if AUTO_MERGE in item_labels:
217
+ if AUTO_MERGE in item.labels:
219
218
  if item.merge_status == MRStatus.UNCHECKED:
220
219
  # this call triggers a status recheck
221
220
  item = gl.get_merge_request(item_iid)
@@ -227,16 +226,16 @@ def handle_stale_items(
227
226
  current_interval = now.date() - update_date.date()
228
227
  if current_interval > timedelta(days=days_interval):
229
228
  # if item does not have 'stale' label - add it
230
- if LABEL not in item_labels:
229
+ if LABEL not in item.labels:
231
230
  logging.info(["add_label", gl.project.name, item_type, item_iid, LABEL])
232
231
  if not dry_run:
233
- gl.add_label(item, item_type, LABEL)
232
+ gl.add_label(item, LABEL)
234
233
  # if item has 'stale' label - close it
235
234
  else:
236
235
  close_item(dry_run, gl, enable_closing, item_type, item)
237
236
  # if item is under days_interval
238
237
  else:
239
- if LABEL not in item_labels:
238
+ if LABEL not in item.labels:
240
239
  continue
241
240
 
242
241
  # if item has 'stale' label - check the notes
@@ -261,7 +260,7 @@ def handle_stale_items(
261
260
  ["remove_label", gl.project.name, item_type, item_iid, LABEL]
262
261
  )
263
262
  if not dry_run:
264
- gl.remove_label(item, item_type, LABEL)
263
+ gl.remove_label(item, LABEL)
265
264
 
266
265
 
267
266
  def is_good_to_merge(labels):
@@ -277,21 +276,6 @@ def is_rebased(mr, gl: GitLabApi) -> bool:
277
276
  return len(result["commits"]) == 0
278
277
 
279
278
 
280
- def get_labels(mr: ProjectMergeRequest, gl: GitLabApi) -> list[str]:
281
- """
282
- This function used to contain logic for checking if labels were empty and calling
283
- gl.get_merge_request_labels() if they were missing because there were reports of the
284
- label attribute being empty sometimes when it shouldn't be. This was an expensive
285
- approach, increasing the runtime of the integration by something around 20-30%.
286
- Through investigation in APPSRE-6653 it was determined this no longer appears to be
287
- an issue.
288
-
289
- This is being left to continue to abstract the way that labels are pulled in case
290
- this becomes an issue again in the future.
291
- """
292
- return mr.attributes.get("labels")
293
-
294
-
295
279
  def get_merge_requests(
296
280
  dry_run: bool,
297
281
  gl: GitLabApi,
@@ -324,7 +308,7 @@ def preprocess_merge_requests(
324
308
  if len(mr.commits()) == 0:
325
309
  continue
326
310
 
327
- labels = get_labels(mr, gl)
311
+ labels = mr.labels
328
312
  if not labels:
329
313
  continue
330
314
 
@@ -336,7 +320,7 @@ def preprocess_merge_requests(
336
320
  + "suitable for self serviceable MRs. removing 'lgtm' label"
337
321
  )
338
322
  if not dry_run:
339
- gl.remove_label_from_merge_request(mr.iid, LGTM)
323
+ gl.remove_label(mr, LGTM)
340
324
  continue
341
325
 
342
326
  label_events = gl.get_merge_request_label_events(mr)
@@ -366,18 +350,17 @@ def preprocess_merge_requests(
366
350
  approved_by = added_by
367
351
 
368
352
  for bad_label in labels_by_unauthorized_users - labels_by_authorized_users:
369
- if bad_label not in labels:
353
+ if bad_label not in mr.labels:
370
354
  continue
371
355
  logging.warning(
372
356
  f"[{gl.project.name}/{mr.iid}] someone added a label who "
373
357
  f"isn't allowed. removing label {bad_label}"
374
358
  )
375
- # Remove bad_label from the cached labels list. Otherwise, we may face a caching bug
376
- labels.remove(bad_label)
377
359
  if not dry_run:
378
- gl.remove_label_from_merge_request(mr.iid, bad_label)
360
+ # TODO: optimize this to remove all bad labels at once
361
+ gl.remove_label(mr, bad_label)
379
362
 
380
- if not is_good_to_merge(labels):
363
+ if not is_good_to_merge(mr.labels):
381
364
  continue
382
365
 
383
366
  label_priority = min(
@@ -540,7 +523,7 @@ def merge_merge_requests(
540
523
  if not dry_run and merges < merge_limit:
541
524
  try:
542
525
  mr.merge()
543
- labels = get_labels(mr, gl)
526
+ labels = mr.labels
544
527
  merged_merge_requests.labels(
545
528
  project_id=mr.target_project_id,
546
529
  self_service=SELF_SERVICEABLE in labels,
@@ -370,7 +370,7 @@ def act(repo, dry_run, instance, settings, defer=None):
370
370
  f"- removing approval"
371
371
  ]
372
372
  )
373
- gitlab_cli.remove_label_from_merge_request(mr.iid, APPROVED)
373
+ gitlab_cli.remove_label(mr, APPROVED)
374
374
 
375
375
  if approval_status["report"] is not None:
376
376
  _LOG.info(
@@ -382,7 +382,7 @@ def act(repo, dry_run, instance, settings, defer=None):
382
382
  )
383
383
 
384
384
  if not dry_run:
385
- gitlab_cli.remove_label_from_merge_request(mr.iid, APPROVED)
385
+ gitlab_cli.remove_label(mr, APPROVED)
386
386
  mr.notes.create({"body": approval_status["report"]})
387
387
  continue
388
388
 
@@ -177,9 +177,7 @@ def can_be_merged_merge_request() -> ProjectMergeRequest:
177
177
  mr.merge_status = "can_be_merged"
178
178
  mr.work_in_progress = False
179
179
  mr.commits.return_value = [create_autospec(ProjectCommit)]
180
- mr.attributes = {
181
- "labels": ["lgtm"],
182
- }
180
+ mr.labels = ["lgtm"]
183
181
  mr.iid = 1
184
182
  mr.target_project_id = 3
185
183
  mr.author = {"username": "user"}
@@ -14,6 +14,7 @@ import gitlab
14
14
  import urllib3
15
15
  from gitlab.v4.objects import (
16
16
  CurrentUser,
17
+ ProjectIssue,
17
18
  ProjectMergeRequest,
18
19
  ProjectMergeRequestNote,
19
20
  )
@@ -449,14 +450,6 @@ class GitLabApi: # pylint: disable=too-many-public-methods
449
450
  merge_request = self.project.mergerequests.get(mr_id)
450
451
  self.update_labels(merge_request, "merge-request", labels)
451
452
 
452
- def remove_label_from_merge_request(self, mr_id, label):
453
- gitlab_request.labels(integration=INTEGRATION_NAME).inc()
454
- merge_request = self.project.mergerequests.get(mr_id)
455
- labels = merge_request.attributes.get("labels")
456
- if label in labels:
457
- labels.remove(label)
458
- self.update_labels(merge_request, "merge-request", labels)
459
-
460
453
  def add_comment_to_merge_request(self, mr_id, body):
461
454
  gitlab_request.labels(integration=INTEGRATION_NAME).inc()
462
455
  merge_request = self.project.mergerequests.get(mr_id)
@@ -480,20 +473,34 @@ class GitLabApi: # pylint: disable=too-many-public-methods
480
473
  gitlab_request.labels(integration=INTEGRATION_NAME).inc()
481
474
  self.project.labels.create({"name": label_text, "color": label_color})
482
475
 
483
- def add_label(self, item, item_type, label):
484
- note_body = (
485
- "item has been marked as {0}. " "to remove say `/{0} cancel`"
486
- ).format(label)
487
- labels = item.attributes.get("labels")
476
+ @staticmethod
477
+ def add_label(
478
+ item: ProjectMergeRequest | ProjectIssue,
479
+ label: str,
480
+ ):
481
+ labels = item.labels
482
+ if label in labels:
483
+ return
488
484
  labels.append(label)
485
+ note_body = (
486
+ f"item has been marked as {label}. " f"to remove say `/{label} cancel`"
487
+ )
489
488
  gitlab_request.labels(integration=INTEGRATION_NAME).inc()
490
489
  item.notes.create({"body": note_body})
491
- self.update_labels(item, item_type, labels)
490
+ gitlab_request.labels(integration=INTEGRATION_NAME).inc()
491
+ item.save()
492
492
 
493
- def remove_label(self, item, item_type, label):
494
- labels = item.attributes.get("labels")
493
+ @staticmethod
494
+ def remove_label(
495
+ item: ProjectMergeRequest | ProjectIssue,
496
+ label: str,
497
+ ):
498
+ labels = item.labels
499
+ if label not in labels:
500
+ return
495
501
  labels.remove(label)
496
- self.update_labels(item, item_type, labels)
502
+ gitlab_request.labels(integration=INTEGRATION_NAME).inc()
503
+ item.save()
497
504
 
498
505
  def update_labels(self, item, item_type, labels):
499
506
  if item_type == "issue":