qontract-reconcile 0.10.2.dev135__py3-none-any.whl → 0.10.2.dev136__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.
Files changed (35) hide show
  1. {qontract_reconcile-0.10.2.dev135.dist-info → qontract_reconcile-0.10.2.dev136.dist-info}/METADATA +1 -1
  2. {qontract_reconcile-0.10.2.dev135.dist-info → qontract_reconcile-0.10.2.dev136.dist-info}/RECORD +35 -29
  3. reconcile/aws_ami_share.py +4 -2
  4. reconcile/aws_ecr_image_pull_secrets.py +15 -7
  5. reconcile/aws_garbage_collector.py +1 -1
  6. reconcile/aws_iam_keys.py +24 -17
  7. reconcile/aws_iam_password_reset.py +4 -2
  8. reconcile/aws_support_cases_sos.py +19 -6
  9. reconcile/closedbox_endpoint_monitoring_base.py +4 -3
  10. reconcile/cna/client.py +3 -3
  11. reconcile/cna/integration.py +4 -5
  12. reconcile/cna/state.py +3 -3
  13. reconcile/email_sender.py +65 -56
  14. reconcile/gcr_mirror.py +11 -9
  15. reconcile/github_org.py +57 -52
  16. reconcile/github_owners.py +8 -5
  17. reconcile/github_repo_invites.py +1 -1
  18. reconcile/github_repo_permissions_validator.py +3 -3
  19. reconcile/github_users.py +16 -12
  20. reconcile/github_validator.py +1 -1
  21. reconcile/gitlab_fork_compliance.py +9 -8
  22. reconcile/gitlab_labeler.py +1 -1
  23. reconcile/gitlab_mr_sqs_consumer.py +6 -3
  24. reconcile/gitlab_owners.py +29 -12
  25. reconcile/gql_definitions/email_sender/__init__.py +0 -0
  26. reconcile/gql_definitions/email_sender/apps.py +64 -0
  27. reconcile/gql_definitions/email_sender/emails.py +133 -0
  28. reconcile/gql_definitions/email_sender/users.py +62 -0
  29. reconcile/gql_definitions/fragments/email_service.py +32 -0
  30. reconcile/gql_definitions/fragments/email_user.py +28 -0
  31. reconcile/queries.py +0 -44
  32. reconcile/utils/jinja2/utils.py +4 -2
  33. reconcile/utils/smtp_client.py +1 -1
  34. {qontract_reconcile-0.10.2.dev135.dist-info → qontract_reconcile-0.10.2.dev136.dist-info}/WHEEL +0 -0
  35. {qontract_reconcile-0.10.2.dev135.dist-info → qontract_reconcile-0.10.2.dev136.dist-info}/entry_points.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: qontract-reconcile
3
- Version: 0.10.2.dev135
3
+ Version: 0.10.2.dev136
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
@@ -2,16 +2,16 @@ reconcile/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
2
  reconcile/acs_notifiers.py,sha256=YIV9TrgWjBD8nFbrBvvU8-9s-AdezY4X5t90bFROCtM,4451
3
3
  reconcile/acs_policies.py,sha256=xNbhIlwE1u2URbEQcX-3C-pTu--XjrKAqGj0-Wd85dY,9152
4
4
  reconcile/acs_rbac.py,sha256=hOQNOzD9f2Nioxb9XlspqnpZXH1DurCTnMcJpgyeB4E,22598
5
- reconcile/aws_ami_share.py,sha256=cZeJadO6N_8SHCtldwK1SRxo7j7EnGxM6Ks2VQSFX3k,3743
6
- reconcile/aws_ecr_image_pull_secrets.py,sha256=TGEc_0nv8oxV2HqA8VdcM4HHP-B1YqmNOOU6FPwVFTY,2328
7
- reconcile/aws_garbage_collector.py,sha256=ddwU8IKTueAJc0TzymcREr7hcoVui9kOGvdH1B2EcuM,450
8
- reconcile/aws_iam_keys.py,sha256=GpxZR_A4ZQFlOQG1jpNiYhL5GMxdeTJ05aAYgUwWveE,3633
9
- reconcile/aws_iam_password_reset.py,sha256=q96mwr2KeEQ5bpNniGlgIMZTxiuLSodcYfX-tSaZPjA,3108
10
- reconcile/aws_support_cases_sos.py,sha256=hl_9L53yQYRQxKs3IWrd69Cc60XK067g_bJRM9B0udo,2975
5
+ reconcile/aws_ami_share.py,sha256=M_gT7y3cSAyT_Pm90PBCNDSmbZtqREqe2jNETh0i9Qs,3808
6
+ reconcile/aws_ecr_image_pull_secrets.py,sha256=F58PtX1GlB9XHqj8hGy9ItiTznXLAAKTNlWD9iT2MWI,2593
7
+ reconcile/aws_garbage_collector.py,sha256=PG_0qccQIW347WhdLAhfT9x0P9Mq_ojacvSy5vbJWj8,471
8
+ reconcile/aws_iam_keys.py,sha256=mw_lvmWqpJkzYW8Za6lHfxEMkT-_DOzWiCPhJAmYPIQ,3987
9
+ reconcile/aws_iam_password_reset.py,sha256=O0JX2N5kNRKs3u2xzu4NNrI6p0ag5JWy3MTsvZmtleg,3173
10
+ reconcile/aws_support_cases_sos.py,sha256=PDhilxQ4TBxVnxUPIUdTbKEaNUI0wzPiEsB91oHT2fY,3384
11
11
  reconcile/blackbox_exporter_endpoint_monitoring.py,sha256=O1wFp52EyF538c6txaWBs8eMtUIy19gyHZ6VzJ6QXS8,3512
12
12
  reconcile/checkpoint.py,sha256=_JhMxrye5BgkRMxWYuf7Upli6XayPINKSsuo3ynHTRc,5010
13
13
  reconcile/cli.py,sha256=hwqPcZVmazrhzq1esPBk5jNHSzpfr7o9EmuuMqiPxfg,108430
14
- reconcile/closedbox_endpoint_monitoring_base.py,sha256=MvGKBqH9PdHWdMjhLuptze-dk0Tifhp3-0SZdI-7Fmo,4862
14
+ reconcile/closedbox_endpoint_monitoring_base.py,sha256=al7m8EgnnYx90rY1REryW3byN_ItfJfAzEeLtjbCfi0,4921
15
15
  reconcile/cluster_deployment_mapper.py,sha256=5gumAaRCcFXsabUJ1dnuUy9WrP_FEEM5JnOnE8ch9sE,2326
16
16
  reconcile/dashdotdb_base.py,sha256=83ZWIf5JJk3P_D69y2TmXRcQr6ELJGlv10OM0h7fJVs,4767
17
17
  reconcile/dashdotdb_cso.py,sha256=QRK0YfIqO4rehs8btD3l_GXIO2ZIycTQEKEthBdB0xA,3639
@@ -20,21 +20,21 @@ reconcile/dashdotdb_dvo.py,sha256=lCkZ0iby6HrNQb-3kYb6xrt8wCjVUZYxKzz9SiStfHU,89
20
20
  reconcile/dashdotdb_slo.py,sha256=PU1GzT6Uy07IIO3Y62cFfRfaBJYUPrMkMp71Up80_bg,8334
21
21
  reconcile/database_access_manager.py,sha256=Z3aAmw2LsmMIIor-bOGzziVZdVNC82Gmw8oHBUAFf-8,25577
22
22
  reconcile/deadmanssnitch.py,sha256=n-5W-djUgwzpmdDM4eQIZpkkDmHY0vndt-42LJXI4Y8,7491
23
- reconcile/email_sender.py,sha256=6KCJa0HV_ZRuUy3gUSB-b-oE3XBI-zxjWyiX3jXe-24,3481
23
+ reconcile/email_sender.py,sha256=38Wvl6WHqCwlqLx4oxVJOIeDmoJsyitD3g1F4jTkAj8,4246
24
24
  reconcile/gabi_authorized_users.py,sha256=Jwvo97nzUX3NIl2VHKuZlT0-I40qk2VnACbafe91T2o,4854
25
- reconcile/gcr_mirror.py,sha256=KXdVlZ8EK69GeMeC4TvwnSZklbijUp4icjKOX3y8IWc,8742
26
- reconcile/github_org.py,sha256=4Jq7YMinWgfrTQDgewq7rhViS8fn8e65G09HiHfb9aw,13431
27
- reconcile/github_owners.py,sha256=s9NDIqTbaqgGE5lj89eh3Sr52B-6SCUWQILzQlzGyxw,2949
28
- reconcile/github_repo_invites.py,sha256=3GOBGZq1DKMIuyYsDxHqXDnMTWlJfeu248-m3ajfV8Y,2672
29
- reconcile/github_repo_permissions_validator.py,sha256=dcbXdUx6imjNchjp3pg9-z1i7lFEGOr_28GvsiwO5Xw,1734
30
- reconcile/github_users.py,sha256=nfTq78QRONIfDVj-5O3bD6psllJjzWFnog-EJ1WqFPU,3672
31
- reconcile/github_validator.py,sha256=cVTVxJIGR4a1Jz8wrdXEAb_CMpXUzvykVmUURX4cook,917
32
- reconcile/gitlab_fork_compliance.py,sha256=c7UfqSAsW04c1bWJmXXaQDwtUcG4Kb6nCJAyRU2uAuw,4449
25
+ reconcile/gcr_mirror.py,sha256=cdTd0CZU0qUsXJqe5k4dgpMQlyk__nyeGH0f_Cky3C0,8957
26
+ reconcile/github_org.py,sha256=Wc5cZamatuWsW2ZJT2ib5ps8l3iY3RXHwNUxVJerqz0,14173
27
+ reconcile/github_owners.py,sha256=viE1KJ-zaTxuZ5yItg2C263J0brn-Q-3hR_DkYDMbhY,3122
28
+ reconcile/github_repo_invites.py,sha256=U9UCzNVwrZ7MqODtFah8ogH0NNY-XjBin7G9gqHtCUY,2690
29
+ reconcile/github_repo_permissions_validator.py,sha256=DsM5IdEw3HvrpSRR9ZYjOLwE7QqD9cEhmFgM0QhHl5o,1784
30
+ reconcile/github_users.py,sha256=QdX164LZrm8sqggMj-0beCzWofpS6OEBfzKNrWPrfj0,3934
31
+ reconcile/github_validator.py,sha256=-j17tn3csFVjPMSPL3te48iWVkPZCncRXdeKeLdGjjQ,931
32
+ reconcile/gitlab_fork_compliance.py,sha256=RbHckzLnE9zkOFHJANzoejEMMbMAivmqJVs3Suvp9lU,4591
33
33
  reconcile/gitlab_housekeeping.py,sha256=Gy1mhn33xGp9IyQFqs4VrBmhwJBD6x90XITDR_pU4MU,25416
34
- reconcile/gitlab_labeler.py,sha256=4xJHmVX155fclrHqkR926sL1GH6RTN5XfZ8PnqNXbRA,4534
34
+ reconcile/gitlab_labeler.py,sha256=BA2dbXsN9hErUwJl22qcxfeH7XiPCuQ9LN3NddWdnpo,4540
35
35
  reconcile/gitlab_members.py,sha256=MUIgYDLeJx2-_vMypyq2Pa17cpKdXATYhtVACS2ghpQ,8297
36
- reconcile/gitlab_mr_sqs_consumer.py,sha256=O46mdziPgGOndbU-0_UJKJVUaiEoVzJPEgKm4_UvYoI,2571
37
- reconcile/gitlab_owners.py,sha256=qDiCe5So5IaNOQl9i2kbUryzJKMFqEy5nRaEj2sGf6A,13938
36
+ reconcile/gitlab_mr_sqs_consumer.py,sha256=i_MDVfA3Uk_TJiNkfEJzhO6_rwR7z3I3dH9oEw686U4,2681
37
+ reconcile/gitlab_owners.py,sha256=nIEsf3QWI3yIw_Bxy5oMaCmszTaNZDwQVaaZZxPgh4g,14447
38
38
  reconcile/gitlab_permissions.py,sha256=gSGH6gAdJbPy5Z0rQGUqiNQSHty_tXQ_3Y4OQP_8nFs,8067
39
39
  reconcile/gitlab_projects.py,sha256=K3tFf_aD1W4Ijp5q-9Qek3kwFGEWPcZ1kd7tzFJ4GyQ,1781
40
40
  reconcile/integrations_manager.py,sha256=CY7cOj5dzt2se4IOg11VQvGQ-eTvLML5Q42Z9SSgeSk,9463
@@ -94,7 +94,7 @@ reconcile/quay_mirror.py,sha256=0KtQFwrvMNtlsPJ9F_-ICaVIjgIUjFxqipvAPcvyg3Q,1533
94
94
  reconcile/quay_mirror_org.py,sha256=tXKuF6JtmaNRwu8_g_65U_Vpd6sFBYeXmJA-flVhylE,10764
95
95
  reconcile/quay_permissions.py,sha256=9KOutS1w4RFQqkvMSy54VtsKNx56-phzP6yI_rEW-B8,4244
96
96
  reconcile/quay_repos.py,sha256=cuEYG0HUe0ut5yvLdEwOF5-CmccpXQHRb_wDazvDrvQ,6895
97
- reconcile/queries.py,sha256=ICAkBP8atJEZlPCniMJljb2hJAZdvSZdT1-ciLqVGl8,51560
97
+ reconcile/queries.py,sha256=XU5ksCW6f8AmVHsg8WEAxiL4cwzLBkpvsYn9EqZ228Q,50890
98
98
  reconcile/query_validator.py,sha256=MSh5pKLBksws4AqfuvT8nrIGucIbqX-IOzYyPYTLO7k,1491
99
99
  reconcile/requests_sender.py,sha256=914iluuF4UVgG3VyxxtnHOu4yf6YKS2fIy6PViSsFTQ,3875
100
100
  reconcile/resource_scraper.py,sha256=znXCHrU7YwPfKuxGBiUrV7T1tYtn4vlz9qmZlfy6Flg,2307
@@ -179,9 +179,9 @@ reconcile/change_owners/tester.py,sha256=ijDaSbFYT8fPinhjPrRlw_TCarTTJK5nUgzHSi1
179
179
  reconcile/cluster_auth_rhidp/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
180
180
  reconcile/cluster_auth_rhidp/integration.py,sha256=KIAiP_XFjsOA2OE8oFJa8lD0T1a7EwOmhct2xbj7tr8,9560
181
181
  reconcile/cna/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
182
- reconcile/cna/client.py,sha256=t9gJDrKf4ApBlgu8c4QUbmzrYoSo1QPsnAGfucva2_U,1562
183
- reconcile/cna/integration.py,sha256=OKL4VCDEhcBqhd0KBcRugxGbfFDclsnUucEJc6Jln6c,5090
184
- reconcile/cna/state.py,sha256=FIF8Vqq996IKf79sVlNbpSGJcDZUp-aB9QGK7dKWkmk,4477
182
+ reconcile/cna/client.py,sha256=32-G3fDZfVvkCN1vg0EbcsMNYBdJvXoXYI2ShFg6lbc,1586
183
+ reconcile/cna/integration.py,sha256=dybEWkSCl7V5OC7ZQYIN2j4QV2yWstIUEQy1GpYI2oI,5106
184
+ reconcile/cna/state.py,sha256=mJghfMGZZtyh8e6GwNNajI2AxEEJQ4e51tAgQ26zEuQ,4501
185
185
  reconcile/cna/assets/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
186
186
  reconcile/cna/assets/asset.py,sha256=KWgA4fuDAEGsJwmR52WwK_YgSJMW-1cV2la3lmNf4iE,834
187
187
  reconcile/cna/assets/asset_factory.py,sha256=7T7X_J6xIsoGETqBRI45_EyIKEdQcnRPt_GAuVuLQcc,785
@@ -309,6 +309,10 @@ reconcile/gql_definitions/dashdotdb_slo/slo_documents_query.py,sha256=MYYpVOc8Ze
309
309
  reconcile/gql_definitions/dynatrace_token_provider/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
310
310
  reconcile/gql_definitions/dynatrace_token_provider/dynatrace_bootstrap_tokens.py,sha256=5gTuAnR2rnx2k6Rn7FMEAzw6GCZ6F5HZbqkmJ9-3NI4,2244
311
311
  reconcile/gql_definitions/dynatrace_token_provider/token_specs.py,sha256=XGsMuB8gowRpqJjkD_KRomx-1OswzyWbF4qjVdhionk,2555
312
+ reconcile/gql_definitions/email_sender/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
313
+ reconcile/gql_definitions/email_sender/apps.py,sha256=prqXdFkeTQ31hF2E7e9sldr3F8iklGHsPAsTx3cOkeM,1715
314
+ reconcile/gql_definitions/email_sender/emails.py,sha256=JoEL_Urtepeho4VZGlHjrYOTImibtNtaj2va0zMaSFU,3454
315
+ reconcile/gql_definitions/email_sender/users.py,sha256=RAqJ3QqtR0ku_mumqQ4jZkP1hFqLExleJajEu5KVhIs,1670
312
316
  reconcile/gql_definitions/endpoints_discovery/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
313
317
  reconcile/gql_definitions/endpoints_discovery/apps.py,sha256=aBWRAwDUJQ32ghJS4cPQcR9SNl20Fcwd3pxHDB3YJQY,3172
314
318
  reconcile/gql_definitions/external_resources/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -331,6 +335,8 @@ reconcile/gql_definitions/fragments/aws_vpc_request.py,sha256=o0qUsPrFXs8GAbtgMX
331
335
  reconcile/gql_definitions/fragments/aws_vpc_request_subnet.py,sha256=qaTFT8cGzEslw51nUeb45Nfnv6kFxUm4CWrRR3xfBvA,760
332
336
  reconcile/gql_definitions/fragments/deplopy_resources.py,sha256=0u3xYqL5NpMf149BJLfPhHqAOWu06aLULdNk_2Mulxg,1089
333
337
  reconcile/gql_definitions/fragments/disable.py,sha256=Ojw98OSxcovrtmw_aAyhaVHhIa1MSUbBfKX4i2IpI74,715
338
+ reconcile/gql_definitions/fragments/email_service.py,sha256=0wKpICsg4pcMfr2lszvnqbuPX7wVYoJ5cYFU2uQkHbY,803
339
+ reconcile/gql_definitions/fragments/email_user.py,sha256=UOKbXXNH2Z_7ckgCeCMiBvbfs4qMMYs4PVqxSKNNmBQ,690
334
340
  reconcile/gql_definitions/fragments/jumphost_common_fields.py,sha256=FOqqDRqzPdt4ZNTRRZPFYCKE1HIa1ATF0u0NsdZzyaw,1034
335
341
  reconcile/gql_definitions/fragments/membership_source.py,sha256=rVjAIAhhAoH0_fUfltlFlGvYbvpRRAK4S6dH8OJ5hHE,1390
336
342
  reconcile/gql_definitions/fragments/minimal_ocm_organization.py,sha256=G7uEwGR2qjtXl3yUUMWAzbihNKor0jj1_fcSd9qQOjw,731
@@ -645,7 +651,7 @@ reconcile/utils/secret_reader.py,sha256=MaP56KZaAE35EyYbgAitdm6fUSxdzWeGFSOym9qi
645
651
  reconcile/utils/semver_helper.py,sha256=-WfPOMSA2v1h7hT3PwVf-Htg7wOsoKlQC1JdmDX2Ars,1268
646
652
  reconcile/utils/sharding.py,sha256=DDBHfs5TT9UgjmzewiXUjbncnrPuceAZWeOA4veGa7s,843
647
653
  reconcile/utils/slack_api.py,sha256=iaOFzv3wiZRhcgYK2NB4lsG6ymNsGk2MEuj0PgZVp7w,17355
648
- reconcile/utils/smtp_client.py,sha256=ee8FHnCMt_uhDBJOvIfFtyutbToq-Ni5MECC_c8DXnA,2769
654
+ reconcile/utils/smtp_client.py,sha256=0xefB4I9E5eBB-FlxFJYjvz3Kvuqi_K3Ma_Wk0NAQKM,2779
649
655
  reconcile/utils/sqs_gateway.py,sha256=XNIf3PY4UCPNufP2Ul0UJj3fKlt5larBba-VTT-41Fg,2265
650
656
  reconcile/utils/state.py,sha256=az4tBmZ0EdbFcAGiBVUxs3cr2-BVWsuDQiNTvjjQq8s,16378
651
657
  reconcile/utils/structs.py,sha256=LcbLEg8WxfRqM6nW7NhcWN0YeqF7SQzxOgntmLs1SgY,352
@@ -688,7 +694,7 @@ reconcile/utils/internal_groups/models.py,sha256=y_IqBVqfGqNXiu0VudvBWFrm_-uafVm
688
694
  reconcile/utils/jinja2/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
689
695
  reconcile/utils/jinja2/extensions.py,sha256=7K-uo6G2eCWa98MHT8fRPYIKCLQB_5D2keqQ_LyAfHM,1293
690
696
  reconcile/utils/jinja2/filters.py,sha256=JfO_14APySBPidsMvHXG-8dULNPddZCE15Umjk_aSBk,4830
691
- reconcile/utils/jinja2/utils.py,sha256=adxVFY4WvBGIToEEr8KwqLzp6uDxSipTBzZWwnRqbNQ,8700
697
+ reconcile/utils/jinja2/utils.py,sha256=AQYEhrA4eEl7-tjf8KyVheSGWS3n-56K7zoJIH9IMF4,8819
692
698
  reconcile/utils/jobcontroller/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
693
699
  reconcile/utils/jobcontroller/controller.py,sha256=Vh08lZuCSIIceWGSDhBB00iFwTI9eeKZW1sfHlkAvSo,15373
694
700
  reconcile/utils/jobcontroller/models.py,sha256=x9YIvWfYOOvXNKToFVx1H7qDrZb0Sa1KI_4Y0gl7rMM,6336
@@ -791,7 +797,7 @@ tools/saas_promotion_state/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJ
791
797
  tools/saas_promotion_state/saas_promotion_state.py,sha256=UfwwRLS5Ya4_Nh1w5n1dvoYtchQvYE9yj1VANt2IKqI,3925
792
798
  tools/sre_checkpoints/__init__.py,sha256=CDaDaywJnmRCLyl_NCcvxi-Zc0hTi_3OdwKiFOyS39I,145
793
799
  tools/sre_checkpoints/util.py,sha256=zEDbGr18ZeHNQwW8pUsr2JRjuXIPz--WAGJxZo9sv_Y,894
794
- qontract_reconcile-0.10.2.dev135.dist-info/METADATA,sha256=OmObsM9l7n-M8XKiFzj-KByzt8R4NLvzOLm22SNnumM,24568
795
- qontract_reconcile-0.10.2.dev135.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
796
- qontract_reconcile-0.10.2.dev135.dist-info/entry_points.txt,sha256=5i9l54La3vQrDLAdwDKQWC0iG4sV9RRfOb1BpvzOWLc,698
797
- qontract_reconcile-0.10.2.dev135.dist-info/RECORD,,
800
+ qontract_reconcile-0.10.2.dev136.dist-info/METADATA,sha256=UzAvn2oHDRdlTZTyBA6HDVAVsDtCEsw4ubf7GYLIiI0,24568
801
+ qontract_reconcile-0.10.2.dev136.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
802
+ qontract_reconcile-0.10.2.dev136.dist-info/entry_points.txt,sha256=5i9l54La3vQrDLAdwDKQWC0iG4sV9RRfOb1BpvzOWLc,698
803
+ qontract_reconcile-0.10.2.dev136.dist-info/RECORD,,
@@ -1,5 +1,6 @@
1
1
  import logging
2
2
  from collections.abc import (
3
+ Callable,
3
4
  Iterable,
4
5
  Mapping,
5
6
  )
@@ -37,12 +38,13 @@ def get_region(
37
38
 
38
39
 
39
40
  @defer
40
- def run(dry_run, defer=None):
41
+ def run(dry_run: bool, defer: Callable | None = None) -> None:
41
42
  accounts = queries.get_aws_accounts(sharing=True)
42
43
  sharing_accounts = filter_accounts(accounts)
43
44
  settings = queries.get_app_interface_settings()
44
45
  aws_api = AWSApi(1, sharing_accounts, settings=settings, init_users=False)
45
- defer(aws_api.cleanup)
46
+ if defer:
47
+ defer(aws_api.cleanup)
46
48
 
47
49
  for src_account in sharing_accounts:
48
50
  sharing = src_account.get("sharing")
@@ -1,6 +1,8 @@
1
1
  import base64
2
2
  import json
3
3
  import logging
4
+ from collections.abc import Mapping
5
+ from typing import Any
4
6
 
5
7
  from reconcile import queries
6
8
  from reconcile.utils.aws_api import AWSApi
@@ -9,15 +11,15 @@ from reconcile.utils.vault import VaultClient
9
11
  QONTRACT_INTEGRATION = "aws-ecr-image-pull-secrets"
10
12
 
11
13
 
12
- def enc_dec(data):
14
+ def enc_dec(data: str) -> str:
13
15
  return base64.b64encode(data.encode("utf-8")).decode("utf-8")
14
16
 
15
17
 
16
- def get_password(token):
18
+ def get_password(token: str) -> str:
17
19
  return base64.b64decode(token).decode("utf-8").split(":")[1]
18
20
 
19
21
 
20
- def construct_dockercfg_secret_data(data):
22
+ def construct_dockercfg_secret_data(data: Mapping[str, Any]) -> dict[str, str]:
21
23
  auth_data = data["authorizationData"][0]
22
24
  server = auth_data["proxyEndpoint"]
23
25
  token = auth_data["authorizationToken"]
@@ -36,7 +38,7 @@ def construct_dockercfg_secret_data(data):
36
38
  return {".dockerconfigjson": enc_dec(json.dumps(data))}
37
39
 
38
40
 
39
- def construct_basic_auth_secret_data(data):
41
+ def construct_basic_auth_secret_data(data: Mapping[str, Any]) -> dict[str, str]:
40
42
  auth_data = data["authorizationData"][0]
41
43
  token = auth_data["authorizationToken"]
42
44
  password = get_password(token)
@@ -44,17 +46,23 @@ def construct_basic_auth_secret_data(data):
44
46
  return {"user": enc_dec("AWS"), "token": enc_dec(password), "url": url}
45
47
 
46
48
 
47
- def write_output_to_vault(dry_run, vault_path, account, secret_data, name):
49
+ def write_output_to_vault(
50
+ dry_run: bool,
51
+ vault_path: str,
52
+ account: str,
53
+ secret_data: Mapping[str, str],
54
+ name: str,
55
+ ) -> None:
48
56
  integration_name = QONTRACT_INTEGRATION
49
57
  secret_path = f"{vault_path}/{integration_name}/{account}/{name}"
50
58
  secret = {"path": secret_path, "data": secret_data}
51
59
  logging.info(["write_secret", secret_path])
52
60
  vault_client = VaultClient()
53
61
  if not dry_run:
54
- vault_client.write(secret)
62
+ vault_client.write(secret) # type: ignore
55
63
 
56
64
 
57
- def run(dry_run, vault_output_path=""):
65
+ def run(dry_run: bool, vault_output_path: str = "") -> None:
58
66
  accounts = [a for a in queries.get_aws_accounts() if a.get("ecrs")]
59
67
  settings = queries.get_app_interface_settings()
60
68
  with AWSApi(1, accounts, settings=settings, init_ecr_auth_tokens=True) as aws:
@@ -4,7 +4,7 @@ from reconcile.utils.aws_api import AWSApi
4
4
  QONTRACT_INTEGRATION = "aws-garbage-collector"
5
5
 
6
6
 
7
- def run(dry_run, thread_pool_size=10):
7
+ def run(dry_run: bool, thread_pool_size: int = 10) -> None:
8
8
  accounts = [a for a in queries.get_aws_accounts() if a.get("garbageCollection")]
9
9
  settings = queries.get_app_interface_settings()
10
10
  with AWSApi(thread_pool_size, accounts, settings=settings) as aws:
reconcile/aws_iam_keys.py CHANGED
@@ -1,28 +1,28 @@
1
1
  import logging
2
2
  import shutil
3
3
  import sys
4
+ from collections.abc import Callable, Iterable, Mapping
4
5
  from typing import Any
5
6
 
6
7
  from reconcile import queries
7
8
  from reconcile.utils.aws_api import AWSApi
8
9
  from reconcile.utils.defer import defer
9
- from reconcile.utils.state import (
10
- State,
11
- init_state,
12
- )
10
+ from reconcile.utils.state import State, init_state
13
11
  from reconcile.utils.terrascript_aws_client import TerrascriptClient as Terrascript
14
12
 
15
13
  QONTRACT_INTEGRATION = "aws-iam-keys"
16
14
 
17
15
 
18
- def filter_accounts(accounts, account_name):
16
+ def filter_accounts(
17
+ accounts: Iterable[dict[str, Any]], account_name: str | None
18
+ ) -> list[dict[str, Any]]:
19
19
  accounts = [a for a in accounts if a.get("deleteKeys")]
20
20
  if account_name:
21
21
  accounts = [a for a in accounts if a["name"] == account_name]
22
22
  return accounts
23
23
 
24
24
 
25
- def get_keys_to_delete(accounts) -> dict[str, list[str]]:
25
+ def get_keys_to_delete(accounts: Iterable[dict[str, Any]]) -> dict[str, list[str]]:
26
26
  return {
27
27
  account["name"]: account["deleteKeys"]
28
28
  for account in accounts
@@ -37,13 +37,17 @@ def should_run(state: State, keys_to_delete: dict[str, list[str]]) -> bool:
37
37
  return False
38
38
 
39
39
 
40
- def update_state(state: State, keys_to_update: dict[str, list[str]]):
40
+ def update_state(state: State, keys_to_update: dict[str, list[str]]) -> None:
41
41
  for account_name, keys in keys_to_update.items():
42
42
  if state.get(account_name, []) != keys:
43
43
  state.add(account_name, keys, force=True)
44
44
 
45
45
 
46
- def init_tf_working_dirs(accounts, thread_pool_size, settings):
46
+ def init_tf_working_dirs(
47
+ accounts: Iterable[dict[str, Any]],
48
+ thread_pool_size: int,
49
+ settings: Mapping[str, Any],
50
+ ) -> dict[str, str]:
47
51
  # copied here to avoid circular dependency
48
52
  QONTRACT_INTEGRATION = "terraform_resources"
49
53
  QONTRACT_TF_PREFIX = "qrtf"
@@ -64,19 +68,19 @@ def init_tf_working_dirs(accounts, thread_pool_size, settings):
64
68
  return ts.dump()
65
69
 
66
70
 
67
- def cleanup(working_dirs):
71
+ def cleanup(working_dirs: Mapping[str, str]) -> None:
68
72
  for wd in working_dirs.values():
69
73
  shutil.rmtree(wd)
70
74
 
71
75
 
72
76
  @defer
73
77
  def run(
74
- dry_run,
75
- thread_pool_size=10,
76
- disable_service_account_keys=False,
77
- account_name=None,
78
- defer=None,
79
- ):
78
+ dry_run: bool,
79
+ thread_pool_size: int = 10,
80
+ disable_service_account_keys: bool = False,
81
+ account_name: str | None = None,
82
+ defer: Callable | None = None,
83
+ ) -> None:
80
84
  accounts = filter_accounts(
81
85
  queries.get_aws_accounts(terraform_state=True), account_name
82
86
  )
@@ -88,7 +92,8 @@ def run(
88
92
 
89
93
  settings = queries.get_app_interface_settings()
90
94
  state = init_state(integration=QONTRACT_INTEGRATION)
91
- defer(state.cleanup)
95
+ if defer:
96
+ defer(state.cleanup)
92
97
  keys_to_delete = get_keys_to_delete(accounts)
93
98
  if not should_run(state, keys_to_delete):
94
99
  logging.debug("nothing to do here")
@@ -97,7 +102,9 @@ def run(
97
102
  return
98
103
 
99
104
  working_dirs = init_tf_working_dirs(accounts, thread_pool_size, settings)
100
- defer(lambda: cleanup(working_dirs))
105
+ if defer:
106
+ defer(lambda: cleanup(working_dirs))
107
+
101
108
  with AWSApi(thread_pool_size, accounts, settings=settings) as aws:
102
109
  error, service_account_recycle_complete = aws.delete_keys(
103
110
  dry_run, keys_to_delete, working_dirs, disable_service_account_keys
@@ -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
  )
@@ -44,12 +45,13 @@ class AwsAccountWithResets(BaseModel):
44
45
 
45
46
 
46
47
  @defer
47
- def run(dry_run, defer=None):
48
+ def run(dry_run: bool, defer: Callable | None = None) -> None:
48
49
  accounts = queries.get_aws_accounts(reset_passwords=True)
49
50
  settings = queries.get_app_interface_settings()
50
51
  roles = queries.get_roles(aws=True, saas_files=False)
51
52
  state = init_state(integration=QONTRACT_INTEGRATION)
52
- defer(state.cleanup)
53
+ if defer:
54
+ defer(state.cleanup)
53
55
 
54
56
  accounts_to_reset: list[AwsAccountWithResets] = []
55
57
 
@@ -1,5 +1,7 @@
1
1
  import itertools
2
2
  import logging
3
+ from collections.abc import Callable, Iterable, Mapping
4
+ from typing import Any
3
5
 
4
6
  from reconcile import (
5
7
  mr_client_gateway,
@@ -12,11 +14,11 @@ from reconcile.utils.mr import CreateDeleteAwsAccessKey
12
14
  QONTRACT_INTEGRATION = "aws-support-cases-sos"
13
15
 
14
16
 
15
- def filter_accounts(accounts):
17
+ def filter_accounts(accounts: Iterable[dict[str, Any]]) -> list[dict[str, Any]]:
16
18
  return [a for a in accounts if a.get("premiumSupport")]
17
19
 
18
20
 
19
- def get_deleted_keys(accounts):
21
+ def get_deleted_keys(accounts: Iterable[dict[str, Any]]) -> dict[str, list[str]]:
20
22
  return {
21
23
  account["name"]: account["deleteKeys"]
22
24
  for account in accounts
@@ -24,7 +26,9 @@ def get_deleted_keys(accounts):
24
26
  }
25
27
 
26
28
 
27
- def get_keys_to_delete(aws_support_cases):
29
+ def get_keys_to_delete(
30
+ aws_support_cases: Mapping[str, Iterable[Mapping[str, Any]]],
31
+ ) -> list[dict[str, str]]:
28
32
  search_pattern = "We have become aware that the AWS Access Key "
29
33
  keys = []
30
34
  # ref:
@@ -43,10 +47,17 @@ def get_keys_to_delete(aws_support_cases):
43
47
 
44
48
 
45
49
  @defer
46
- def act(dry_run, gitlab_project_id, accounts, keys_to_delete, defer=None):
50
+ def act(
51
+ dry_run: bool,
52
+ gitlab_project_id: str | None,
53
+ accounts: Iterable[dict[str, Any]],
54
+ keys_to_delete: list[dict[str, str]],
55
+ defer: Callable | None = None,
56
+ ) -> None:
47
57
  if not dry_run and keys_to_delete:
48
58
  mr_cli = mr_client_gateway.init(gitlab_project_id=gitlab_project_id)
49
- defer(mr_cli.cleanup)
59
+ if defer:
60
+ defer(mr_cli.cleanup)
50
61
 
51
62
  for k in keys_to_delete:
52
63
  account = k["account"]
@@ -59,7 +70,9 @@ def act(dry_run, gitlab_project_id, accounts, keys_to_delete, defer=None):
59
70
  mr.submit(cli=mr_cli)
60
71
 
61
72
 
62
- def run(dry_run, gitlab_project_id=None, thread_pool_size=10, enable_deletion=False):
73
+ def run(
74
+ dry_run: bool, gitlab_project_id: str | None = None, thread_pool_size: int = 10
75
+ ) -> None:
63
76
  accounts = filter_accounts(queries.get_aws_accounts())
64
77
  settings = queries.get_app_interface_settings()
65
78
  deleted_keys = get_deleted_keys(accounts)
@@ -63,7 +63,7 @@ class EndpointMonitoringProvider:
63
63
  return None
64
64
 
65
65
  @property
66
- def metric_labels(self):
66
+ def metric_labels(self) -> dict[str, Any]:
67
67
  return json.loads(self.metricLabels) if self.metricLabels else {}
68
68
 
69
69
 
@@ -136,7 +136,7 @@ def run_for_provider(
136
136
  thread_pool_size: int,
137
137
  internal: bool,
138
138
  use_jump_host: bool,
139
- defer=None,
139
+ defer: Callable | None = None,
140
140
  ) -> None:
141
141
  # prepare
142
142
  desired_endpoints = get_endpoints(provider)
@@ -152,7 +152,8 @@ def run_for_provider(
152
152
  integration_version=integration_version,
153
153
  override_managed_types=["Probe"],
154
154
  )
155
- defer(oc_map.cleanup)
155
+ if defer:
156
+ defer(oc_map.cleanup)
156
157
 
157
158
  # reconcile
158
159
  for ep_mon_provider, endpoints in desired_endpoints.items():
reconcile/cna/client.py CHANGED
@@ -23,7 +23,7 @@ class CNAClient:
23
23
  cnas = self._ocm_client.get(api_path="/api/cna-management/v1/cnas")
24
24
  return cnas.get("items", [])
25
25
 
26
- def create(self, asset: Asset, dry_run: bool = False):
26
+ def create(self, asset: Asset, dry_run: bool = False) -> None:
27
27
  if dry_run:
28
28
  logging.info("CREATE %s", asset)
29
29
  return
@@ -32,7 +32,7 @@ class CNAClient:
32
32
  data=asset.api_payload(),
33
33
  )
34
34
 
35
- def delete(self, asset: Asset, dry_run: bool = False):
35
+ def delete(self, asset: Asset, dry_run: bool = False) -> None:
36
36
  if dry_run:
37
37
  logging.info("DELETE %s", asset)
38
38
  return
@@ -41,7 +41,7 @@ class CNAClient:
41
41
  api_path=asset.href,
42
42
  )
43
43
 
44
- def update(self, asset: Asset, dry_run: bool = False):
44
+ def update(self, asset: Asset, dry_run: bool = False) -> None:
45
45
  if dry_run:
46
46
  logging.info("UPDATE %s", asset)
47
47
  return
@@ -46,13 +46,13 @@ class CNAIntegration:
46
46
  namespaces: Iterable[NamespaceV1],
47
47
  desired_states: Mapping[str, State] | None = None,
48
48
  current_states: Mapping[str, State] | None = None,
49
- ):
49
+ ) -> None:
50
50
  self._cna_clients = cna_clients
51
51
  self._namespaces = namespaces
52
52
  self._desired_states = desired_states or defaultdict(State)
53
53
  self._current_states = current_states or defaultdict(State)
54
54
 
55
- def assemble_desired_states(self):
55
+ def assemble_desired_states(self) -> None:
56
56
  self._desired_states = defaultdict(State)
57
57
  for namespace in self._namespaces:
58
58
  for provider in namespace.external_resources or []:
@@ -64,7 +64,7 @@ class CNAIntegration:
64
64
  asset_factory_from_schema(resource)
65
65
  )
66
66
 
67
- def assemble_current_states(self):
67
+ def assemble_current_states(self) -> None:
68
68
  self._current_states = defaultdict(State)
69
69
  for name, client in self._cna_clients.items():
70
70
  cnas = client.list_assets()
@@ -72,7 +72,7 @@ class CNAIntegration:
72
72
  state.add_raw_data(cnas)
73
73
  self._current_states[name] = state
74
74
 
75
- def provision(self, dry_run: bool = False):
75
+ def provision(self, dry_run: bool = False) -> None:
76
76
  for provisioner_name, cna_client in self._cna_clients.items():
77
77
  desired_state = self._desired_states[provisioner_name]
78
78
  current_state = self._current_states[provisioner_name]
@@ -119,7 +119,6 @@ def run(
119
119
  dry_run: bool,
120
120
  # TODO: Threadpool not used yet - will be used once we understand scopes in more detail
121
121
  thread_pool_size: int,
122
- defer=None,
123
122
  ) -> None:
124
123
  settings = get_app_interface_vault_settings()
125
124
  secret_reader = create_secret_reader(use_vault=settings.vault)
reconcile/cna/state.py CHANGED
@@ -50,7 +50,7 @@ class State:
50
50
  # pytest should show nice diff
51
51
  return str(self._assets)
52
52
 
53
- def _validate_addition(self, asset: Asset):
53
+ def _validate_addition(self, asset: Asset) -> None:
54
54
  if asset.kind not in self._assets:
55
55
  raise CNAStateError(f"State doesn't know asset_kind {asset.kind}")
56
56
  if asset.name in self._assets[asset.kind]:
@@ -58,11 +58,11 @@ class State:
58
58
  f"Duplicate asset name found in state: kind={asset.kind}, name={asset.name}"
59
59
  )
60
60
 
61
- def add_asset(self, asset: Asset):
61
+ def add_asset(self, asset: Asset) -> None:
62
62
  self._validate_addition(asset=asset)
63
63
  self._assets[asset.kind][asset.name] = asset
64
64
 
65
- def add_raw_data(self, data: Iterable[Mapping[str, Any]]):
65
+ def add_raw_data(self, data: Iterable[Mapping[str, Any]]) -> None:
66
66
  for cna in data:
67
67
  asset = asset_factory_from_raw_data(cna)
68
68
  self._validate_addition(asset=asset)