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.
- {qontract_reconcile-0.10.2.dev314.dist-info → qontract_reconcile-0.10.2.dev316.dist-info}/METADATA +1 -1
- {qontract_reconcile-0.10.2.dev314.dist-info → qontract_reconcile-0.10.2.dev316.dist-info}/RECORD +18 -18
- reconcile/requests_sender.py +8 -3
- reconcile/sendgrid_teammates.py +20 -9
- reconcile/status.py +2 -2
- reconcile/terraform_aws_route53.py +11 -7
- reconcile/terraform_cloudflare_resources.py +6 -5
- reconcile/terraform_users.py +17 -16
- reconcile/utils/mr/__init__.py +3 -1
- reconcile/utils/mr/app_interface_reporter.py +4 -1
- reconcile/utils/mr/aws_access.py +1 -1
- reconcile/utils/mr/base.py +2 -2
- reconcile/utils/mr/clusters_updates.py +4 -2
- reconcile/utils/mr/ocm_upgrade_scheduler_org_updates.py +4 -1
- reconcile/utils/mr/user_maintenance.py +4 -4
- tools/qontract_cli.py +1 -1
- {qontract_reconcile-0.10.2.dev314.dist-info → qontract_reconcile-0.10.2.dev316.dist-info}/WHEEL +0 -0
- {qontract_reconcile-0.10.2.dev314.dist-info → qontract_reconcile-0.10.2.dev316.dist-info}/entry_points.txt +0 -0
{qontract_reconcile-0.10.2.dev314.dist-info → qontract_reconcile-0.10.2.dev316.dist-info}/METADATA
RENAMED
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: qontract-reconcile
|
3
|
-
Version: 0.10.2.
|
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
|
{qontract_reconcile-0.10.2.dev314.dist-info → qontract_reconcile-0.10.2.dev316.dist-info}/RECORD
RENAMED
@@ -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=
|
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=
|
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=
|
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=
|
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=
|
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=
|
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=
|
709
|
-
reconcile/utils/mr/app_interface_reporter.py,sha256=
|
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=
|
712
|
-
reconcile/utils/mr/base.py,sha256=
|
713
|
-
reconcile/utils/mr/clusters_updates.py,sha256=
|
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=
|
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=
|
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=
|
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.
|
800
|
-
qontract_reconcile-0.10.2.
|
801
|
-
qontract_reconcile-0.10.2.
|
802
|
-
qontract_reconcile-0.10.2.
|
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,,
|
reconcile/requests_sender.py
CHANGED
@@ -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(
|
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
|
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
|
reconcile/sendgrid_teammates.py
CHANGED
@@ -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__(
|
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(
|
31
|
-
|
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(
|
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
|
29
|
-
|
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
|
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
|
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}
|
reconcile/terraform_users.py
CHANGED
@@ -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:
|
99
|
-
roles:
|
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:
|
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:
|
193
|
-
skip_reencrypt_accounts:
|
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
|
|
reconcile/utils/mr/__init__.py
CHANGED
@@ -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__(
|
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
|
reconcile/utils/mr/aws_access.py
CHANGED
@@ -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
|
reconcile/utils/mr/base.py
CHANGED
@@ -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
|
-
|
1302
|
+
None,
|
1303
1303
|
1,
|
1304
1304
|
skip_accounts,
|
1305
1305
|
account_name=account_name,
|
{qontract_reconcile-0.10.2.dev314.dist-info → qontract_reconcile-0.10.2.dev316.dist-info}/WHEEL
RENAMED
File without changes
|
File without changes
|