qontract-reconcile 0.10.2.dev314__py3-none-any.whl → 0.10.2.dev316__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.dev314
3
+ Version: 0.10.2.dev316
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
@@ -90,27 +90,27 @@ reconcile/quay_permissions.py,sha256=BF539lRxjpgwm88WzazklzgaCF_ipRALwbO2AdpqUqE
90
90
  reconcile/quay_repos.py,sha256=fBleLzMtfDmTidpzbrTt8kGCy-Bk3J06EO4hhyghGnQ,7570
91
91
  reconcile/queries.py,sha256=FLUZBtFC2S-e6yjtC1Oq968CJP6t3nc36NPj0wYa0bE,53472
92
92
  reconcile/query_validator.py,sha256=csOSkKxcf6ZlpchJu4ck2jLYKUN6y1l-UmSQUFHgssY,1618
93
- reconcile/requests_sender.py,sha256=914iluuF4UVgG3VyxxtnHOu4yf6YKS2fIy6PViSsFTQ,3875
93
+ reconcile/requests_sender.py,sha256=g-tlrudvIqhneQPDMrfYF0Xsq7BSW2QcBPirl7hFM6I,4058
94
94
  reconcile/resource_scraper.py,sha256=sg10j7lwAE8JxsyBTaxixOR3QYnePctsNuwOLiz4QVg,2309
95
95
  reconcile/resource_template_tester.py,sha256=DsKvBuNLPxm4Fa-e1YHHySnhThm5i_j-nF3G4b02Mz0,2416
96
96
  reconcile/run_integration.py,sha256=M2rIpcx7k0vGkTHdgm0h1efLOWiJ-O2WbYPHKtvIpWA,10214
97
97
  reconcile/saas_file_validator.py,sha256=wmO7yni6zCiQN2micOQ1HdA0-3-N3IvBbBYLLzbNvsI,2499
98
- reconcile/sendgrid_teammates.py,sha256=oO8QbLb4s1o8A6CGiCagN9CmS05BSS_WLztuY0Ym9D8,4773
98
+ reconcile/sendgrid_teammates.py,sha256=rknegYin7214pfqXmCALh8cd8n_qha18fGEr4_1ZFOQ,5183
99
99
  reconcile/service_dependencies.py,sha256=KydjllianL0lUwhroBAPui7jrnhHSq7j2PB6CoV2nuU,4349
100
100
  reconcile/signalfx_endpoint_monitoring.py,sha256=Nqgsg1cflSd2nNnm89y_e8c--7xLUqTrKOHkDs-qADE,2868
101
101
  reconcile/slack_base.py,sha256=I-msunWxfgu5bSwXYulGbtLjxUB_tRmTCAUCU-3nabI,3484
102
102
  reconcile/slack_usergroups.py,sha256=3uQVZK0WeZfvE1g7xQwciKCcC3LifDa3NuE1ygQ0cRk,30174
103
103
  reconcile/sql_query.py,sha256=FVwANLPWjkUHqN2OXJ-vnX5hqqcO6rTdyLEO4HkmAgM,26397
104
- reconcile/status.py,sha256=cY4IJFXemhxptRJqR4qaaOWqei9e4jgLXuVSGajMsjg,544
104
+ reconcile/status.py,sha256=h73oaSxO5sftEGqFrXVAlySBvNYPWpowDaYYplcky5A,565
105
105
  reconcile/status_board.py,sha256=0vTQzxrFPTmJtzNOC-iaJG_BmXbDe2vgBUe0LMUyfDE,15313
106
- reconcile/terraform_aws_route53.py,sha256=CWp5bE3ddUrJGNNvG8YmkSPyNHCWtOc1GEDVLnbOY9Q,10043
106
+ reconcile/terraform_aws_route53.py,sha256=p_NZDjZzOJSgFTY7KJ1qHERWaTGvFJSykY8uIYgSmVg,10183
107
107
  reconcile/terraform_cloudflare_dns.py,sha256=0Eu46o_BBEEq-B-CCvKop9VTbwrvliCKGSS9gLBSJE4,13456
108
- reconcile/terraform_cloudflare_resources.py,sha256=tK-BxQeNdZjf59deKd51Roz868e7UXe52XvcHsffJK0,14982
108
+ reconcile/terraform_cloudflare_resources.py,sha256=HlctpWi-9NxtsO3hL9fpPpD0m5v5bgL0LRQsp7ToeAs,15047
109
109
  reconcile/terraform_cloudflare_users.py,sha256=mlSYNktRetBvw8mi2TUSdKSZw0aQ821VeU6OQ1WcV3U,13516
110
110
  reconcile/terraform_repo.py,sha256=vVJfaCV9775FGMMTHfoobaPetSlJMiQ4arNudL2pvh8,15607
111
111
  reconcile/terraform_resources.py,sha256=AXO3_Ehcg3I6ao7qiKzXC4Mk6BqwMoNooXU50c2zSTA,19555
112
112
  reconcile/terraform_tgw_attachments.py,sha256=P2HivCjT5AlyODy-fu1qAK5355nDEArE8E4NQlIlF7U,18933
113
- reconcile/terraform_users.py,sha256=lzLco8t0_XQ4gWkZdvfOJIckDQpDUqTKqxGcT2P3W_k,10334
113
+ reconcile/terraform_users.py,sha256=xa-UK2iTy0HRFAGfFQvxTbBaypsqx3O0XGVWIU9yIxI,10659
114
114
  reconcile/terraform_vpc_peerings.py,sha256=rMotDHy3Fd5QTxrOGjCJ3f2vICk3fmxrKYVCIU8p_y4,27787
115
115
  reconcile/vault_replication.py,sha256=trtbB-jDwca822J5I_s0zlwFtlyaiAtqgbPeqp7Cggc,17714
116
116
  reconcile/vpc_peerings_validator.py,sha256=_77eu6DSy6VjTE5mhV-sOIVOGIiBvDEEDCdwwRdrgVQ,7101
@@ -705,20 +705,20 @@ reconcile/utils/merge_request_manager/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCe
705
705
  reconcile/utils/merge_request_manager/merge_request_manager.py,sha256=3EP6Yw_zB7nY0OkU8D_32nDqta1TITgtRI0cSmOlNQg,3332
706
706
  reconcile/utils/merge_request_manager/parser.py,sha256=5pGoz8Q6EuYXlUc1z-D0FahdRP2YLO8CpACoa9HcgtQ,2098
707
707
  reconcile/utils/mr/README.md,sha256=i9sCLkDFhSxAUtpa_I1_TxhR5vPOLcowuwn2VEWO41w,5794
708
- reconcile/utils/mr/__init__.py,sha256=RCpzyzmuP2gBCmTl-5ODNNwAnnbllGiNwWN-A_zG2EE,2593
709
- reconcile/utils/mr/app_interface_reporter.py,sha256=8ZcPlObg-At8Q20jVVTRqJYD4n_cYUjRRcGidNy4YjU,1804
708
+ reconcile/utils/mr/__init__.py,sha256=pgg5cAbf3c6GWBXanvz2SPFXLtUE_sYEKiHcY202og8,2633
709
+ reconcile/utils/mr/app_interface_reporter.py,sha256=5mRrGfyy8vkkOT3Rtw1ejteEdWBQW09VIxkUafckIj0,1899
710
710
  reconcile/utils/mr/app_sre_tekton_access_report.py,sha256=i7JeTkyaq0HyVGbAFKCNbiLy3NVE05IXqJzwArsGre4,1513
711
- reconcile/utils/mr/aws_access.py,sha256=G3pPPMQiL_TO1zGWEgH4gn_SHPFXfkCUvhCUGaT34KE,2657
712
- reconcile/utils/mr/base.py,sha256=M1Lg6zDYUhST4OMLuZzrosLtzc80Za6a1ejF6YyCjRg,8147
713
- reconcile/utils/mr/clusters_updates.py,sha256=T9eONmyTshEcd6UbYNDAslC6bw-Klql-Vr0scQBZnJE,2313
711
+ reconcile/utils/mr/aws_access.py,sha256=_mDOidMHi6xAyMdxU_fgSvpq3V1k4efXoBk4ZTDvKWw,2672
712
+ reconcile/utils/mr/base.py,sha256=5N0Ns9IKDtNL3UwopOWQMC-gf_8Hj48z0TaoQvI-EvY,8170
713
+ reconcile/utils/mr/clusters_updates.py,sha256=HbJYy3LdkfdE1oGpyfKli3g5rmVu4B73DrAQMTm7wWw,2410
714
714
  reconcile/utils/mr/glitchtip_access_reporter.py,sha256=cTkOtzdgeKPaqro0VS2hDuAClQiN4nZATh-mplQC-AI,1369
715
715
  reconcile/utils/mr/labels.py,sha256=9QRTRjZAtq45zELd9SwavaraczMjwjn5no3RK1YxFTg,825
716
716
  reconcile/utils/mr/notificator.py,sha256=f8IcGQ1_iBsXJFnhPsWQ7UE3NfigaOrXcVieJPplYrY,2955
717
717
  reconcile/utils/mr/ocm_update_recommended_version.py,sha256=KGOBURLE3XMynjAFej5D5PO9MJRDqMeoL1C8jLJMhD8,1570
718
- reconcile/utils/mr/ocm_upgrade_scheduler_org_updates.py,sha256=0myPruETuT6V2bjSSVPVsQu0ZHE9Jf3kRx5htt_fhKM,3038
718
+ reconcile/utils/mr/ocm_upgrade_scheduler_org_updates.py,sha256=Ykktb8diTv1u5ierJmbtbG04gkzUl3N3FgekKlUc5zg,3117
719
719
  reconcile/utils/mr/promote_qontract.py,sha256=oOjfxkDAFhMDWCT9xaRyLSYHcc67jCc34s_tENOuHGw,7226
720
720
  reconcile/utils/mr/update_access_report_base.py,sha256=LOXTIonpfxXrvZI9nPqkszW3OnuIgbFM7pFpqHxTMp0,4395
721
- reconcile/utils/mr/user_maintenance.py,sha256=OC9-3YkpXsYKZGsdOdx-NLq7AkjgrhDR2JL7hov7BV8,5669
721
+ reconcile/utils/mr/user_maintenance.py,sha256=_YwrGRube_Z_d00rkh0p7rMAtEz60R2Qec7u-pGmizU,5728
722
722
  reconcile/utils/ocm/__init__.py,sha256=Y-bp8GomMpyCo0tFW6kJ78-ZG1UIupYRtBzbMWU0kwM,798
723
723
  reconcile/utils/ocm/addons.py,sha256=_LDdJ-gapM3s5exKlIUt-MlXZTAUoHezbYBU0QmvfWQ,7335
724
724
  reconcile/utils/ocm/base.py,sha256=sy8mD9srj5dJjRIk8u8RRmj_D7h4MnpxtZwm4S4BWf8,14883
@@ -770,7 +770,7 @@ tools/app_sre_tekton_access_reporter.py,sha256=5qmkevJdlb2j_lpGC5Pu1Pmo0eomX5Zxz
770
770
  tools/app_sre_tekton_access_revalidation.py,sha256=vwL1o_j7oSTOhrHNH1znpgjA2LHGzb8yc5iG3aaY4m0,2684
771
771
  tools/glitchtip_access_reporter.py,sha256=wnaiDGW4MkYONV_erltnJ6nGkEj0kQrAiv04NNnOS0k,2859
772
772
  tools/glitchtip_access_revalidation.py,sha256=jjeLO53LTbz_LfQw3G2Cs8lVLO_6xqU39BYyTH3cEPE,2764
773
- tools/qontract_cli.py,sha256=KyK2iCSh68cPolZygQtYb18ZtjIUlFw4aZT9D5p91kw,159892
773
+ tools/qontract_cli.py,sha256=T_BEnJZt23_XeaQYZZxUvPiCAroe_RPtU43wJTPqXFg,159891
774
774
  tools/template_validation.py,sha256=Xn9X4sGFznx-rvBDnq9Kq16rfET8V3bqH1EwavsGBac,3335
775
775
  tools/cli_commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
776
776
  tools/cli_commands/container_images_report.py,sha256=8mAjCS6XR0yD7k0mfiVBlt6xbYU47q_ftdYNi5o5VKE,5566
@@ -796,7 +796,7 @@ tools/saas_promotion_state/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJ
796
796
  tools/saas_promotion_state/saas_promotion_state.py,sha256=uQv2QJAmUXP1g2GPIH30WTlvL9soY6m9lefpZEVDM5w,3965
797
797
  tools/sre_checkpoints/__init__.py,sha256=CDaDaywJnmRCLyl_NCcvxi-Zc0hTi_3OdwKiFOyS39I,145
798
798
  tools/sre_checkpoints/util.py,sha256=KcYVfa3UmJHVP_ocgrKe8NkrO5IDB9aWEDydSokPcRk,975
799
- qontract_reconcile-0.10.2.dev314.dist-info/METADATA,sha256=FQlklTqmyArlTeakJ4eRZC7EB_SBoTf-tZy1jMd9EAk,24916
800
- qontract_reconcile-0.10.2.dev314.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
801
- qontract_reconcile-0.10.2.dev314.dist-info/entry_points.txt,sha256=5i9l54La3vQrDLAdwDKQWC0iG4sV9RRfOb1BpvzOWLc,698
802
- qontract_reconcile-0.10.2.dev314.dist-info/RECORD,,
799
+ qontract_reconcile-0.10.2.dev316.dist-info/METADATA,sha256=Tsr2Ebs2NqZuHQVUUdN0A9gp3-_wKiGi0AwdZco5mdI,24916
800
+ qontract_reconcile-0.10.2.dev316.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
801
+ qontract_reconcile-0.10.2.dev316.dist-info/entry_points.txt,sha256=5i9l54La3vQrDLAdwDKQWC0iG4sV9RRfOb1BpvzOWLc,698
802
+ qontract_reconcile-0.10.2.dev316.dist-info/RECORD,,
@@ -1,6 +1,8 @@
1
1
  import logging
2
2
  import sys
3
+ from collections.abc import Callable, Mapping
3
4
  from subprocess import CalledProcessError
5
+ from typing import Any
4
6
 
5
7
  from reconcile import (
6
8
  queries,
@@ -44,7 +46,9 @@ Encrypted credentials:
44
46
  """
45
47
 
46
48
 
47
- def get_encrypted_credentials(credentials_name, user, settings):
49
+ def get_encrypted_credentials(
50
+ credentials_name: str, user: Mapping[str, Any], settings: Mapping[str, Any]
51
+ ) -> str | None:
48
52
  credentials_map = settings["credentials"]
49
53
  credentials_map_item = [c for c in credentials_map if c["name"] == credentials_name]
50
54
  if len(credentials_map_item) != 1:
@@ -59,7 +63,7 @@ def get_encrypted_credentials(credentials_name, user, settings):
59
63
 
60
64
 
61
65
  @defer
62
- def run(dry_run, defer=None):
66
+ def run(dry_run: bool, defer: Callable | None = None) -> None:
63
67
  settings = queries.get_app_interface_settings()
64
68
  vault_settings = get_app_interface_vault_settings()
65
69
  secret_reader = create_secret_reader(use_vault=vault_settings.vault)
@@ -76,7 +80,8 @@ def run(dry_run, defer=None):
76
80
  integration=QONTRACT_INTEGRATION,
77
81
  secret_reader=secret_reader,
78
82
  )
79
- defer(state.cleanup)
83
+ if defer:
84
+ defer(state.cleanup)
80
85
  credentials_requests = queries.get_credentials_requests()
81
86
 
82
87
  # validate no 2 requests have the same name
@@ -1,5 +1,7 @@
1
1
  import logging
2
2
  import sys
3
+ from collections.abc import Iterable, Mapping
4
+ from typing import Any
3
5
 
4
6
  import sendgrid
5
7
  from sretoolbox.utils import retry
@@ -17,18 +19,22 @@ class SendGridAPIError(Exception):
17
19
 
18
20
 
19
21
  class Teammate:
20
- def __init__(self, email, pending_token=None, username=None):
22
+ def __init__(
23
+ self, email: str, pending_token: str | None = None, username: str | None = None
24
+ ) -> None:
21
25
  self.email = email
22
- self.username = username or email.split("@")[0]
26
+ self.username = username or email.split("@", maxsplit=1)[0]
23
27
  self.pending_token = pending_token
24
28
 
25
29
  @property
26
- def pending(self):
30
+ def pending(self) -> bool:
27
31
  return bool(self.pending_token)
28
32
 
29
33
 
30
- def fetch_desired_state(users):
31
- desired_state = {}
34
+ def fetch_desired_state(
35
+ users: Iterable[Mapping[str, Any]],
36
+ ) -> dict[str, list[Teammate]]:
37
+ desired_state: dict[str, list[Teammate]] = {}
32
38
  for user in users:
33
39
  roles = user.get("roles") or []
34
40
  for role in roles:
@@ -42,7 +48,7 @@ def fetch_desired_state(users):
42
48
 
43
49
 
44
50
  @retry()
45
- def fetch_current_state(sg_client):
51
+ def fetch_current_state(sg_client: sendgrid.SendGridAPIClient) -> list[Teammate]:
46
52
  state = []
47
53
  limit = 100
48
54
 
@@ -79,7 +85,7 @@ def fetch_current_state(sg_client):
79
85
  return state
80
86
 
81
87
 
82
- def raise_if_error(response):
88
+ def raise_if_error(response: Any) -> None:
83
89
  """
84
90
  Raises an SendGridAPIError if the request has returned an error
85
91
  """
@@ -87,7 +93,12 @@ def raise_if_error(response):
87
93
  raise SendGridAPIError(response.body.decode("utf-8"))
88
94
 
89
95
 
90
- def act(dry_run, sg_client, desired_state, current_state):
96
+ def act(
97
+ dry_run: bool,
98
+ sg_client: sendgrid.SendGridAPIClient,
99
+ desired_state: Iterable[Teammate],
100
+ current_state: Iterable[Teammate],
101
+ ) -> bool:
91
102
  """
92
103
  Reconciles current state with desired state.
93
104
 
@@ -145,7 +156,7 @@ def act(dry_run, sg_client, desired_state, current_state):
145
156
  return error
146
157
 
147
158
 
148
- def run(dry_run):
159
+ def run(dry_run: bool) -> None:
149
160
  settings = queries.get_app_interface_settings()
150
161
  secret_reader = SecretReader(settings=settings)
151
162
 
reconcile/status.py CHANGED
@@ -11,7 +11,7 @@ class ExitCodes:
11
11
  class _RunningState:
12
12
  _state: dict[Any, Any] = {}
13
13
 
14
- def __init__(self):
14
+ def __init__(self) -> None:
15
15
  self.__dict__ = self._state
16
16
 
17
17
 
@@ -22,7 +22,7 @@ class RunningState(_RunningState):
22
22
  by the callers.
23
23
  """
24
24
 
25
- def __getattr__(self, item):
25
+ def __getattr__(self, item: str) -> None:
26
26
  """
27
27
  Default value for attributes not explicitly created is None.
28
28
  """
@@ -1,6 +1,7 @@
1
1
  import logging
2
2
  import sys
3
3
  from collections.abc import (
4
+ Callable,
4
5
  Iterable,
5
6
  Mapping,
6
7
  )
@@ -25,8 +26,10 @@ QONTRACT_INTEGRATION_VERSION = make_semver(0, 1, 0)
25
26
 
26
27
 
27
28
  def build_desired_state(
28
- zones: Iterable[Mapping], all_accounts: Iterable[Mapping], settings: Mapping
29
- ) -> list[dict]:
29
+ zones: Iterable[Mapping[str, Any]],
30
+ all_accounts: Iterable[Mapping[str, Any]],
31
+ settings: Mapping[str, Any],
32
+ ) -> list[dict[str, Any]]:
30
33
  """
31
34
  Build the desired state from the app-interface resources
32
35
 
@@ -36,7 +39,7 @@ def build_desired_state(
36
39
  :rtype: list of dict
37
40
  """
38
41
 
39
- desired_state = []
42
+ desired_state: list[dict[str, Any]] = []
40
43
  for zone in zones:
41
44
  account = zone["account"]
42
45
  account_name = account["name"]
@@ -208,8 +211,8 @@ def run(
208
211
  enable_deletion: bool = True,
209
212
  thread_pool_size: int = DEFAULT_THREAD_POOL_SIZE,
210
213
  account_name: str | None = None,
211
- defer=None,
212
- ):
214
+ defer: Callable | None = None,
215
+ ) -> None:
213
216
  settings = queries.get_app_interface_settings()
214
217
  zones = queries.get_dns_zones(account_name=account_name)
215
218
 
@@ -255,7 +258,8 @@ def run(
255
258
  if tf is None:
256
259
  sys.exit(ExitCodes.ERROR)
257
260
 
258
- defer(tf.cleanup)
261
+ if defer:
262
+ defer(tf.cleanup)
259
263
 
260
264
  _, err = tf.plan(enable_deletion)
261
265
  if err:
@@ -269,7 +273,7 @@ def run(
269
273
  sys.exit(ExitCodes.ERROR)
270
274
 
271
275
 
272
- def early_exit_desired_state(*args, **kwargs) -> dict[str, Any]:
276
+ def early_exit_desired_state(*args: Any, **kwargs: Any) -> dict[str, Any]:
273
277
  return {
274
278
  "zones": queries.get_dns_zones(),
275
279
  }
@@ -1,6 +1,6 @@
1
1
  import logging
2
2
  import sys
3
- from collections.abc import Iterable
3
+ from collections.abc import Callable, Iterable
4
4
  from typing import (
5
5
  Any,
6
6
  cast,
@@ -193,7 +193,7 @@ def _populate_oc_resources(
193
193
  spec: CurrentStateSpec,
194
194
  ri: ResourceInventory,
195
195
  account_names: Iterable[str] | None,
196
- ):
196
+ ) -> None:
197
197
  """
198
198
  This was taken from terraform_resources and might be a later candidate for DRY.
199
199
  """
@@ -315,7 +315,7 @@ def run(
315
315
  vault_output_path: str = "",
316
316
  internal: bool | None = None,
317
317
  use_jump_host: bool = True,
318
- defer=None,
318
+ defer: Callable | None = None,
319
319
  ) -> None:
320
320
  vault_settings = get_app_interface_vault_settings()
321
321
  secret_reader = create_secret_reader(use_vault=vault_settings.vault)
@@ -392,7 +392,8 @@ def run(
392
392
  working_dirs,
393
393
  thread_pool_size,
394
394
  )
395
- defer(tf.cleanup)
395
+ if defer:
396
+ defer(tf.cleanup)
396
397
 
397
398
  disabled_deletions_detected, err = tf.plan(enable_deletion)
398
399
  if err:
@@ -440,7 +441,7 @@ def _get_cloudflare_desired_state() -> tuple[
440
441
  return query_accounts, query_resources
441
442
 
442
443
 
443
- def early_exit_desired_state(*args, **kwargs) -> dict[str, Any]:
444
+ def early_exit_desired_state(*args: Any, **kwargs: Any) -> dict[str, Any]:
444
445
  desired_state = _get_cloudflare_desired_state()
445
446
 
446
447
  return {state.__repr_name__(): state.dict() for state in desired_state}
@@ -1,4 +1,5 @@
1
1
  import sys
2
+ from collections.abc import Iterable, Mapping
2
3
  from textwrap import indent
3
4
  from typing import (
4
5
  Any,
@@ -95,9 +96,9 @@ def get_tf_roles() -> list[Role]:
95
96
 
96
97
 
97
98
  def _filter_participating_aws_accounts(
98
- accounts: list,
99
- roles: list[dict[str, Any]],
100
- ) -> list:
99
+ accounts: Iterable[dict[str, Any]],
100
+ roles: Iterable[Mapping[str, Any]],
101
+ ) -> list[dict[str, Any]]:
101
102
  participating_aws_account_names: set[str] = set()
102
103
  for role in roles:
103
104
  participating_aws_account_names.update(
@@ -111,7 +112,7 @@ def _filter_participating_aws_accounts(
111
112
 
112
113
 
113
114
  def setup(
114
- print_to_file,
115
+ print_to_file: str | None,
115
116
  thread_pool_size: int,
116
117
  skip_reencrypt_accounts: list[str],
117
118
  appsre_pgp_key: str | None = None,
@@ -146,10 +147,10 @@ def setup(
146
147
 
147
148
 
148
149
  def send_email_invites(
149
- new_users,
150
+ new_users: Iterable[tuple[str, str, str, str]],
150
151
  smtp_client: SmtpClient,
151
- skip_reencrypt_accounts: list[str],
152
- ):
152
+ skip_reencrypt_accounts: Iterable[str],
153
+ ) -> None:
153
154
  msg_template = """
154
155
  You have been invited to join the {} AWS account!
155
156
  Below you will find credentials for the first sign in.
@@ -189,9 +190,9 @@ Encrypted password: {}
189
190
  def write_user_to_vault(
190
191
  vault_client: _VaultClient,
191
192
  vault_path: str,
192
- new_users: list[tuple[str, str, str, str]],
193
- skip_reencrypt_accounts: list[str],
194
- ):
193
+ new_users: Iterable[tuple[str, str, str, str]],
194
+ skip_reencrypt_accounts: Iterable[str],
195
+ ) -> None:
195
196
  for account, console_url, user_name, enc_password in new_users:
196
197
  if account in skip_reencrypt_accounts:
197
198
  continue
@@ -208,13 +209,13 @@ def write_user_to_vault(
208
209
  vault_client.write(desired_secret, decode_base64=False)
209
210
 
210
211
 
211
- def cleanup_and_exit(tf=None, status=False):
212
+ def cleanup_and_exit(tf: Terraform | None = None, status: bool = False) -> None:
212
213
  if tf is not None:
213
214
  tf.cleanup()
214
215
  sys.exit(status)
215
216
 
216
217
 
217
- def get_reencrypt_settings():
218
+ def get_reencrypt_settings() -> tuple[list[str], str | None, Any]:
218
219
  all_reencrypt_settings = query(
219
220
  query_func=gql.get_api().query
220
221
  ).pgp_reencryption_settings
@@ -243,7 +244,7 @@ def run(
243
244
  thread_pool_size: int = DEFAULT_THREAD_POOL_SIZE,
244
245
  send_mails: bool = True,
245
246
  account_name: str | None = None,
246
- ):
247
+ ) -> None:
247
248
  skip_accounts, appsre_pgp_key, reencrypt_settings = get_reencrypt_settings()
248
249
 
249
250
  # setup errors should skip resources that will lead
@@ -319,7 +320,7 @@ def run(
319
320
  cleanup_and_exit(tf, setup_err)
320
321
 
321
322
 
322
- def early_exit_desired_state(*args, **kwargs) -> dict[str, Any]:
323
+ def early_exit_desired_state(*args: Any, **kwargs: Any) -> dict[str, Any]:
323
324
  """
324
325
  Finding diffs in deeply nested structures is time/resource consuming.
325
326
  Having a unique known property to identify objects makes it easier to match
@@ -330,11 +331,11 @@ def early_exit_desired_state(*args, **kwargs) -> dict[str, Any]:
330
331
  for the DeepDiff library used in qontract-reconcile.
331
332
  """
332
333
 
333
- def add_account_identity(acc):
334
+ def add_account_identity(acc: dict[str, Any]) -> dict[str, Any]:
334
335
  acc[IDENTIFIER_FIELD_NAME] = acc["path"]
335
336
  return acc
336
337
 
337
- def add_role_identity(role):
338
+ def add_role_identity(role: dict[str, Any]) -> dict[str, Any]:
338
339
  role[IDENTIFIER_FIELD_NAME] = role["name"]
339
340
  return role
340
341
 
@@ -1,3 +1,5 @@
1
+ from typing import Any
2
+
1
3
  from reconcile.utils.mr.app_interface_reporter import CreateAppInterfaceReporter
2
4
  from reconcile.utils.mr.aws_access import CreateDeleteAwsAccessKey
3
5
  from reconcile.utils.mr.base import (
@@ -44,7 +46,7 @@ class UnknownMergeRequestTypeError(Exception):
44
46
  """
45
47
 
46
48
 
47
- def init_from_sqs_message(message) -> MergeRequestBase:
49
+ def init_from_sqs_message(message: dict[str, Any]) -> MergeRequestBase:
48
50
  # First, let's find the classes that are inheriting from
49
51
  # MergeRequestBase and create a map where the class.name is
50
52
  # the key and the class itself is the value.
@@ -1,3 +1,4 @@
1
+ from collections.abc import Iterable
1
2
  from datetime import datetime
2
3
  from pathlib import Path
3
4
 
@@ -14,7 +15,9 @@ from reconcile.utils.mr.labels import AUTO_MERGE
14
15
  class CreateAppInterfaceReporter(MergeRequestBase):
15
16
  name = "create_app_interface_reporter_mr"
16
17
 
17
- def __init__(self, reports, email_body, reports_path):
18
+ def __init__(
19
+ self, reports: Iterable[dict[str, str]], email_body: str, reports_path: str
20
+ ) -> None:
18
21
  self.reports = reports
19
22
  self.email_body = email_body
20
23
  self.reports_path = reports_path
@@ -18,7 +18,7 @@ BODY_TEMPLATE = PROJ_ROOT / "templates" / "aws_access_key_email.j2"
18
18
  class CreateDeleteAwsAccessKey(MergeRequestBase):
19
19
  name = "create_delete_aws_access_key_mr"
20
20
 
21
- def __init__(self, account, path, key):
21
+ def __init__(self, account: str, path: str, key: str):
22
22
  self.account = account
23
23
  self.path = path.lstrip("/")
24
24
  self.key = key
@@ -45,14 +45,14 @@ class MergeRequestBase(ABC):
45
45
 
46
46
  name = "merge-request-base"
47
47
 
48
- def __init__(self):
48
+ def __init__(self) -> None:
49
49
  # Let's first get all the attributes from the instance
50
50
  # and use for the SQS Msg payload. With that, the msg
51
51
  # to the SQS is enough to create a new, similar, instance
52
52
  # of the child class.
53
53
  self.sqs_msg_data = {**self.__dict__}
54
54
 
55
- self.labels = [DO_NOT_MERGE_HOLD]
55
+ self.labels: Iterable[str] = [DO_NOT_MERGE_HOLD]
56
56
 
57
57
  random_id = str(uuid4())[:6]
58
58
  self.branch = f"{self.name}-{random_id}"
@@ -1,4 +1,6 @@
1
+ from collections.abc import Mapping
1
2
  from io import StringIO
3
+ from typing import Any
2
4
 
3
5
  from ruamel.yaml import YAML
4
6
 
@@ -15,7 +17,7 @@ yaml.width = 4096
15
17
  class CreateClustersUpdates(MergeRequestBase):
16
18
  name = "create_clusters_updates_mr"
17
19
 
18
- def __init__(self, clusters_updates):
20
+ def __init__(self, clusters_updates: Mapping[str, dict[str, Any]]):
19
21
  self.clusters_updates = clusters_updates
20
22
 
21
23
  super().__init__()
@@ -30,7 +32,7 @@ class CreateClustersUpdates(MergeRequestBase):
30
32
  def description(self) -> str:
31
33
  return DecisionCommand.APPROVED.value
32
34
 
33
- def process(self, gitlab_cli: GitLabApi):
35
+ def process(self, gitlab_cli: GitLabApi) -> None:
34
36
  changes = False
35
37
  for cluster_name, cluster_updates in self.clusters_updates.items():
36
38
  if not cluster_updates:
@@ -1,3 +1,6 @@
1
+ from collections.abc import Mapping
2
+ from typing import Any
3
+
1
4
  from ruamel import yaml
2
5
 
3
6
  from reconcile.utils.gitlab_api import GitLabApi
@@ -8,7 +11,7 @@ from reconcile.utils.mr.labels import AUTO_MERGE
8
11
  class CreateOCMUpgradeSchedulerOrgUpdates(MergeRequestBase):
9
12
  name = "create_ocm_upgrade_scheduler_org_updates_mr"
10
13
 
11
- def __init__(self, updates_info):
14
+ def __init__(self, updates_info: Mapping[str, Any]):
12
15
  self.updates_info = updates_info
13
16
 
14
17
  super().__init__()
@@ -24,14 +24,14 @@ class PathSpec(BaseModel):
24
24
  path: str
25
25
 
26
26
  @validator("path")
27
- def prepend_data_to_path(cls, v):
27
+ def prepend_data_to_path(cls, v: str) -> str:
28
28
  return "data" + v
29
29
 
30
30
 
31
31
  class CreateDeleteUserAppInterface(MergeRequestBase):
32
32
  name = "create_delete_user_mr"
33
33
 
34
- def __init__(self, username, paths: Iterable[PathSpec]):
34
+ def __init__(self, username: str, paths: Iterable[PathSpec]) -> None:
35
35
  self.username = username
36
36
  self.paths = paths
37
37
 
@@ -120,7 +120,7 @@ class CreateDeleteUserInfra(MergeRequestBase):
120
120
 
121
121
  name = "create_ssh_key_mr"
122
122
 
123
- def __init__(self, usernames):
123
+ def __init__(self, usernames: Iterable[str]):
124
124
  self.usernames = usernames
125
125
 
126
126
  super().__init__()
@@ -135,7 +135,7 @@ class CreateDeleteUserInfra(MergeRequestBase):
135
135
  def description(self) -> str:
136
136
  return "delete user(s)"
137
137
 
138
- def process(self, gitlab_cli):
138
+ def process(self, gitlab_cli: GitLabApi) -> None:
139
139
  raw_file = gitlab_cli.get_raw_file(
140
140
  project=gitlab_cli.project,
141
141
  path=self.PLAYBOOK,
tools/qontract_cli.py CHANGED
@@ -1299,7 +1299,7 @@ def user_credentials_migrate_output(ctx: click.Context, account_name: str) -> No
1299
1299
  skip_accounts, appsre_pgp_key, _ = tfu.get_reencrypt_settings()
1300
1300
 
1301
1301
  accounts, working_dirs, _, aws_api = tfu.setup(
1302
- False,
1302
+ None,
1303
1303
  1,
1304
1304
  skip_accounts,
1305
1305
  account_name=account_name,