qontract-reconcile 0.10.2.dev456__py3-none-any.whl → 0.10.2.dev473__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.
Potentially problematic release.
This version of qontract-reconcile might be problematic. Click here for more details.
- {qontract_reconcile-0.10.2.dev456.dist-info → qontract_reconcile-0.10.2.dev473.dist-info}/METADATA +2 -2
- {qontract_reconcile-0.10.2.dev456.dist-info → qontract_reconcile-0.10.2.dev473.dist-info}/RECORD +26 -26
- reconcile/aus/base.py +0 -3
- reconcile/aws_account_manager/integration.py +13 -1
- reconcile/aws_account_manager/utils.py +1 -1
- reconcile/change_owners/README.md +1 -1
- reconcile/change_owners/change_owners.py +9 -9
- reconcile/change_owners/decision.py +1 -1
- reconcile/gql_definitions/aws_account_manager/aws_accounts.py +9 -0
- reconcile/gql_definitions/external_resources/external_resources_namespaces.py +3 -1
- reconcile/gql_definitions/introspection.json +15 -7
- reconcile/gql_definitions/terraform_resources/terraform_resources_namespaces.py +3 -1
- reconcile/quay_base.py +25 -6
- reconcile/quay_membership.py +35 -28
- reconcile/quay_mirror_org.py +6 -4
- reconcile/quay_permissions.py +81 -75
- reconcile/quay_repos.py +35 -37
- reconcile/queries.py +1 -1
- reconcile/templating/validator.py +4 -4
- reconcile/terraform_vpc_resources/merge_request.py +12 -2
- reconcile/terraform_vpc_resources/merge_request_manager.py +43 -19
- reconcile/typed_queries/saas_files.py +1 -1
- reconcile/utils/external_resource_spec.py +2 -0
- reconcile/utils/quay_api.py +74 -87
- {qontract_reconcile-0.10.2.dev456.dist-info → qontract_reconcile-0.10.2.dev473.dist-info}/WHEEL +0 -0
- {qontract_reconcile-0.10.2.dev456.dist-info → qontract_reconcile-0.10.2.dev473.dist-info}/entry_points.txt +0 -0
{qontract_reconcile-0.10.2.dev456.dist-info → qontract_reconcile-0.10.2.dev473.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.dev473
|
|
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
|
|
@@ -18,7 +18,7 @@ Requires-Dist: botocore==1.34.94
|
|
|
18
18
|
Requires-Dist: click<9.0,>=7.0
|
|
19
19
|
Requires-Dist: croniter<1.1.0,>=1.0.15
|
|
20
20
|
Requires-Dist: dateparser~=1.1.7
|
|
21
|
-
Requires-Dist: deepdiff==6.
|
|
21
|
+
Requires-Dist: deepdiff==8.6.1
|
|
22
22
|
Requires-Dist: dnspython~=2.1
|
|
23
23
|
Requires-Dist: dt==1.1.73
|
|
24
24
|
Requires-Dist: filetype~=1.2.0
|
{qontract_reconcile-0.10.2.dev456.dist-info → qontract_reconcile-0.10.2.dev473.dist-info}/RECORD
RENAMED
|
@@ -82,13 +82,13 @@ reconcile/openshift_tekton_resources.py,sha256=5mUWEQqU9RpMLQZxHOb6IkbbZzx4iJnaV
|
|
|
82
82
|
reconcile/openshift_upgrade_watcher.py,sha256=93l8X1-RHNtL89GzPg1XWivWart49l_hpAVFChvT6Wg,6643
|
|
83
83
|
reconcile/openshift_users.py,sha256=lxHYrOhKntLnRy5mVZfh_8XWvwZaUgzrDNqkoon905U,5508
|
|
84
84
|
reconcile/openshift_vault_secrets.py,sha256=Ax-_EBWWU1VRHYyKaUkGJkIjHGwWM3bZgjXL5CkPW8k,1883
|
|
85
|
-
reconcile/quay_base.py,sha256=
|
|
86
|
-
reconcile/quay_membership.py,sha256=
|
|
85
|
+
reconcile/quay_base.py,sha256=4gNca076ICJ2fDoTwCgcA3L-DqmVmBgHWLCubTk78uc,2832
|
|
86
|
+
reconcile/quay_membership.py,sha256=ul4KcEdarri0WzH3ZBHzXup7oF9MhGLDpCyHtfxuuZ0,6844
|
|
87
87
|
reconcile/quay_mirror.py,sha256=vhPL44TMEsritkiJhNQLf2Ir45RLApdO_mh3aZV0OuI,14334
|
|
88
|
-
reconcile/quay_mirror_org.py,sha256=
|
|
89
|
-
reconcile/quay_permissions.py,sha256=
|
|
90
|
-
reconcile/quay_repos.py,sha256=
|
|
91
|
-
reconcile/queries.py,sha256=
|
|
88
|
+
reconcile/quay_mirror_org.py,sha256=9YeOpRsuTOWxnql1oj-rbUAkb_aGSlzmHVbMyLhSalM,11092
|
|
89
|
+
reconcile/quay_permissions.py,sha256=wsQZ5wi2jrlTlV3Aq3dn_mJpjMlcjnjVvFNflBFBdGk,4706
|
|
90
|
+
reconcile/quay_repos.py,sha256=JpR9vyvDIdKfP4EwLw1c2X53LOjLZY35pJ8AvNxZIGo,7674
|
|
91
|
+
reconcile/queries.py,sha256=nEko5_luE4Xoj-nBI1XEX3YRcxfAObtvqZbN7LSlJVY,56597
|
|
92
92
|
reconcile/query_validator.py,sha256=csOSkKxcf6ZlpchJu4ck2jLYKUN6y1l-UmSQUFHgssY,1618
|
|
93
93
|
reconcile/requests_sender.py,sha256=g-tlrudvIqhneQPDMrfYF0Xsq7BSW2QcBPirl7hFM6I,4058
|
|
94
94
|
reconcile/resource_scraper.py,sha256=TcMhXga7konX9x97NhpoijnDGWA-ZjdpiiXjm5qCmPk,2249
|
|
@@ -118,7 +118,7 @@ reconcile/aus/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
|
118
118
|
reconcile/aus/advanced_upgrade_service.py,sha256=byOl5wtDRG_VJiN50IM3dwA9vQz39ibSEh9uY5HI9jE,24201
|
|
119
119
|
reconcile/aus/aus_label_source.py,sha256=o0S2f0qwcII_8nzhHZhRQ83gEZ1DrSXyO4xzSwLebuU,4382
|
|
120
120
|
reconcile/aus/aus_sts_gate_handler.py,sha256=7MDHtd4G_t3_ItcnpfpqN7sI6QbFNJEFGJOibfALI-o,2075
|
|
121
|
-
reconcile/aus/base.py,sha256=
|
|
121
|
+
reconcile/aus/base.py,sha256=NXknPntO9EwLTuQMyFxPVtw8r7d9IbwUg-GadDNOU5w,54078
|
|
122
122
|
reconcile/aus/cluster_version_data.py,sha256=rrMYtS-gSWwV4vibf3HKP06Hh3FHO4cBzhZzEInMRlo,7506
|
|
123
123
|
reconcile/aus/healthchecks.py,sha256=jR9c-syh9impnkV0fd6XW3Bnk7iRN5zv8oCRYM-yIRY,2700
|
|
124
124
|
reconcile/aus/metrics.py,sha256=BhIvZVTn25fIzijz3xFynJngS2sXDBTxxprUUVWJcFo,4246
|
|
@@ -139,11 +139,11 @@ reconcile/automated_actions/config/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQe
|
|
|
139
139
|
reconcile/automated_actions/config/integration.py,sha256=uvaZbLp4FQz3DHfr9dA77FyHaRJHTvJDgdqGp7wdCNg,15303
|
|
140
140
|
reconcile/aws_account_manager/README.md,sha256=_XFM3GZNHUzv--e_navqJuaUWpjC6QrHfulreHynFf0,262
|
|
141
141
|
reconcile/aws_account_manager/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
142
|
-
reconcile/aws_account_manager/integration.py,sha256=
|
|
142
|
+
reconcile/aws_account_manager/integration.py,sha256=qpqefqnq4sPtXW13LBL0D2a5wXdq44mZzi3JxJtM7P0,16042
|
|
143
143
|
reconcile/aws_account_manager/merge_request_manager.py,sha256=ePdn3c5MHZEW9iawgQWg7L5ydPLh0YZzfmRYV-rBCD8,3987
|
|
144
144
|
reconcile/aws_account_manager/metrics.py,sha256=YB10ea4kIGwJfs5N14RF-RoXPb-QQWaDBz1jLZ3YWE0,917
|
|
145
145
|
reconcile/aws_account_manager/reconciler.py,sha256=xbCih3aOFk_98Nxly7-W8QMrT67loTH2-HVyQudjH00,17162
|
|
146
|
-
reconcile/aws_account_manager/utils.py,sha256=
|
|
146
|
+
reconcile/aws_account_manager/utils.py,sha256=m40ntjpxREpVPuzJv4pCG3LWtojAeqEoPOfbeIbmQUU,1443
|
|
147
147
|
reconcile/aws_ami_cleanup/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
148
148
|
reconcile/aws_ami_cleanup/integration.py,sha256=NJhGzl9lMOG4VgYf8IsoZFJeYTRS1e5ORpHfIUEl3tA,9264
|
|
149
149
|
reconcile/aws_cloudwatch_log_retention/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -158,15 +158,15 @@ reconcile/aws_version_sync/utils.py,sha256=x-45QT7zAwdNvCg7w_qJNwLaksFcfz1_6KQoD
|
|
|
158
158
|
reconcile/aws_version_sync/merge_request_manager/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
159
159
|
reconcile/aws_version_sync/merge_request_manager/merge_request.py,sha256=2FbqLLdqxycWNvX1eNbwMjWSVBb7q0p-8t5Db0m7b4Q,4842
|
|
160
160
|
reconcile/aws_version_sync/merge_request_manager/merge_request_manager.py,sha256=7EwpSMsAYk41yEqb3uB_EjU73qqWeF28c7UTuQaNjUQ,5522
|
|
161
|
-
reconcile/change_owners/README.md,sha256=
|
|
161
|
+
reconcile/change_owners/README.md,sha256=ETmGkj1hRklv0EFoHTZ89NsM3yjta0ikoIPvjn96BZo,3944
|
|
162
162
|
reconcile/change_owners/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
163
163
|
reconcile/change_owners/approver.py,sha256=Z3_11vnK2WNOxjEEXVDh0224-_-qbt9d6mBeVE-7fsc,2259
|
|
164
164
|
reconcile/change_owners/bundle.py,sha256=6a51hi8yn2QwxQLQ4xc9zwlL5IT2sCbHriFuVJVeqzQ,5376
|
|
165
165
|
reconcile/change_owners/change_log_tracking.py,sha256=njIBC6pRb6U2GmeXxAAc_CruIfnDpEUhOp05DrPFsuk,9531
|
|
166
|
-
reconcile/change_owners/change_owners.py,sha256=
|
|
166
|
+
reconcile/change_owners/change_owners.py,sha256=Ay3KdLJBKH59xMdNYbiNTr2ow71bKPm0URiv4DjcB2M,18400
|
|
167
167
|
reconcile/change_owners/change_types.py,sha256=5eSvS2_npUriq9RN4LdAWdYUiNzF91K1pDUEVYDIQ4k,32023
|
|
168
168
|
reconcile/change_owners/changes.py,sha256=YTqwUYutQ6JVSSYmC2Ph5ROCiVix42Vnzy47-i57z4Q,18119
|
|
169
|
-
reconcile/change_owners/decision.py,sha256=
|
|
169
|
+
reconcile/change_owners/decision.py,sha256=WaT7ehJFYofsgSbbpabj3a5jniomxy8R4wQpb3xsdsw,7487
|
|
170
170
|
reconcile/change_owners/diff.py,sha256=xuyvnHcdRuQ8Twl0QST3rbbPo-hiH1uTycTet_AoT8k,8944
|
|
171
171
|
reconcile/change_owners/implicit_ownership.py,sha256=6BehZvx4IjrphmOt_LLLk9_02Fl5BY5jd00Wuz_PBZk,4234
|
|
172
172
|
reconcile/change_owners/self_service_roles.py,sha256=xSe5AKZxXAIo0vWOMM5hImQ_rd-dQ38y_5dG5L6X0so,9655
|
|
@@ -214,7 +214,7 @@ reconcile/glitchtip_project_alerts/integration.py,sha256=prje61EOuLEIZLLxlJS_YN0
|
|
|
214
214
|
reconcile/glitchtip_project_dsn/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
215
215
|
reconcile/glitchtip_project_dsn/integration.py,sha256=3GgcqUM6hWhLpo9Yx5Xr9vrdexF-WNevVCNL9bJ0Upc,8162
|
|
216
216
|
reconcile/gql_definitions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
217
|
-
reconcile/gql_definitions/introspection.json,sha256=
|
|
217
|
+
reconcile/gql_definitions/introspection.json,sha256=liDjRAOJ0_ZN7bagOacrd1yGlybaxK8V9rQTflnecxo,2429961
|
|
218
218
|
reconcile/gql_definitions/acs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
219
219
|
reconcile/gql_definitions/acs/acs_instances.py,sha256=VySMcnWddg-jXj-bj_ddLIwLX3u1GSFUm02H8rJDBYU,2167
|
|
220
220
|
reconcile/gql_definitions/acs/acs_policies.py,sha256=jEV1U8j4VYL9ih17JSK1tiz2s_1CegVECmXU-NVEQvA,4333
|
|
@@ -230,7 +230,7 @@ reconcile/gql_definitions/app_sre_tekton_access_revalidation/users.py,sha256=9x3
|
|
|
230
230
|
reconcile/gql_definitions/automated_actions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
231
231
|
reconcile/gql_definitions/automated_actions/instance.py,sha256=w-68URz5Q5DVR_dAn13r5mP5YgtutdVHOv3LGQmfxxM,15810
|
|
232
232
|
reconcile/gql_definitions/aws_account_manager/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
233
|
-
reconcile/gql_definitions/aws_account_manager/aws_accounts.py,sha256=
|
|
233
|
+
reconcile/gql_definitions/aws_account_manager/aws_accounts.py,sha256=dc3zbFPHW3eUcG3PPSKK498p_Q3a3DuJmyfVOPkfWIk,5401
|
|
234
234
|
reconcile/gql_definitions/aws_ami_cleanup/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
235
235
|
reconcile/gql_definitions/aws_ami_cleanup/aws_accounts.py,sha256=XmJ-8_77QnATbeDmXzFiaLkWsxdlkbMWHlTlP9nTqfY,4226
|
|
236
236
|
reconcile/gql_definitions/aws_cloudwatch_log_retention/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -307,7 +307,7 @@ reconcile/gql_definitions/endpoints_discovery/apps.py,sha256=p3hvzvrtkCCQfQoJ3mi
|
|
|
307
307
|
reconcile/gql_definitions/external_resources/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
308
308
|
reconcile/gql_definitions/external_resources/aws_accounts.py,sha256=bRzfuPDLJvVJRx7IzqAJKnqpd7SBWdj3trI1rNPeYnU,2033
|
|
309
309
|
reconcile/gql_definitions/external_resources/external_resources_modules.py,sha256=w07PFh526GaYnZRe-SH92MaxA-aeD2TDT2kG_3Da_HE,3241
|
|
310
|
-
reconcile/gql_definitions/external_resources/external_resources_namespaces.py,sha256=
|
|
310
|
+
reconcile/gql_definitions/external_resources/external_resources_namespaces.py,sha256=DGKKoJK7rOng2FBan8vxunLdlysX9Hb9_GTPsm2wyf8,46616
|
|
311
311
|
reconcile/gql_definitions/external_resources/external_resources_settings.py,sha256=RvAMgipgH3MoLfWaqCPaYUy8GS3v0Dr4Cod17OsaNx0,3567
|
|
312
312
|
reconcile/gql_definitions/external_resources/fragments/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
313
313
|
reconcile/gql_definitions/external_resources/fragments/external_resources_module_overrides.py,sha256=jjABgAhVx7LO3NJd9l90JH8s-_TJFvduBZRbdVquLfY,1313
|
|
@@ -427,7 +427,7 @@ reconcile/gql_definitions/terraform_repo/__init__.py,sha256=47DEQpj8HBSa-_TImW-5
|
|
|
427
427
|
reconcile/gql_definitions/terraform_repo/terraform_repo.py,sha256=vocF7fpLk4Rdz1maZ2Hi_d5l4bt3kuL2HyDGvFIUu8M,3868
|
|
428
428
|
reconcile/gql_definitions/terraform_resources/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
429
429
|
reconcile/gql_definitions/terraform_resources/database_access_manager.py,sha256=17CC1Wk65HtBn45Bo6iGsFNaLOnKD03MV3QQtixFtPw,4808
|
|
430
|
-
reconcile/gql_definitions/terraform_resources/terraform_resources_namespaces.py,sha256=
|
|
430
|
+
reconcile/gql_definitions/terraform_resources/terraform_resources_namespaces.py,sha256=oaLnYx6FtG33zDtE2TN8_iPXFfP8mRvPivYtoPo_8M8,44764
|
|
431
431
|
reconcile/gql_definitions/terraform_tgw_attachments/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
432
432
|
reconcile/gql_definitions/terraform_tgw_attachments/aws_accounts.py,sha256=VVWXcTGrHlZ8xqAf7p9Ygocwkm7dWZRaO_B6d_SamCc,2719
|
|
433
433
|
reconcile/gql_definitions/unleash_feature_toggles/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -507,7 +507,7 @@ reconcile/templates/rosa-classic-cluster-creation.sh.j2,sha256=7VlxlKpqIA9Pq7SMn
|
|
|
507
507
|
reconcile/templates/rosa-hcp-cluster-creation.sh.j2,sha256=UbLexFWBsDbSUUe3-5S5aLaH1u_t8ikZnoKd5QTk_ro,2376
|
|
508
508
|
reconcile/templating/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
509
509
|
reconcile/templating/renderer.py,sha256=nR1CM3DDOoLOH7UOxO0PMDkOmhiYFbGriKcjDA-Z8j8,14810
|
|
510
|
-
reconcile/templating/validator.py,sha256=
|
|
510
|
+
reconcile/templating/validator.py,sha256=cyvSNsQqheIBl78HHDu4u_H82rt0zC8_YZL5BtT_Y1w,5266
|
|
511
511
|
reconcile/templating/lib/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
512
512
|
reconcile/templating/lib/merge_request_manager.py,sha256=MaEI9Vrtblb5LIpaa394ACut0Rq_gzxJTfNVSgG113o,5234
|
|
513
513
|
reconcile/templating/lib/model.py,sha256=YVUIXuPny3_kpFgBMSud8q_ndY5o882wKiX0l0A14L4,481
|
|
@@ -518,8 +518,8 @@ reconcile/terraform_init/merge_request.py,sha256=3CYtgSd7Q9zjKg4wsDz437EPCRfGeZZ
|
|
|
518
518
|
reconcile/terraform_init/merge_request_manager.py,sha256=TQmtHq4DH-xgyYvuRyGu7VEgjPU2Yjj-uexIy-L7i88,3098
|
|
519
519
|
reconcile/terraform_vpc_resources/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
520
520
|
reconcile/terraform_vpc_resources/integration.py,sha256=q5il4l4Bd9fmCQePy4XSy5R3nokVvcz1v2znwadelhU,9703
|
|
521
|
-
reconcile/terraform_vpc_resources/merge_request.py,sha256=
|
|
522
|
-
reconcile/terraform_vpc_resources/merge_request_manager.py,sha256=
|
|
521
|
+
reconcile/terraform_vpc_resources/merge_request.py,sha256=MFRG7JQojmCTgr-9rLXVotcjH9mMIZZ0-kPai9UDJWA,1732
|
|
522
|
+
reconcile/terraform_vpc_resources/merge_request_manager.py,sha256=erCC9aY-gWMCVeLrFxG5_q3G2p3iVBS8eeYIUZR_6_o,4123
|
|
523
523
|
reconcile/typed_queries/__init__.py,sha256=rRk4CyslLsBr4vAh1pIPgt6s3P4R1M9NSEPLnyQgBpk,61
|
|
524
524
|
reconcile/typed_queries/alerting_services_settings.py,sha256=YKQd60O_2C_H103nLrYgcUInndM2vFypqW_NO706L2E,833
|
|
525
525
|
reconcile/typed_queries/app_interface_custom_messages.py,sha256=bgSAJEzqee8aiPVCj_bIIqb4VTkrF0-vti1dos7ebEg,684
|
|
@@ -560,7 +560,7 @@ reconcile/typed_queries/quay.py,sha256=3IMy9jjHF2f9t47EXZOQVA3p0nFkWFhaFhxhvib-7
|
|
|
560
560
|
reconcile/typed_queries/repos.py,sha256=8A93dKDt6igT4ClqMjt7YUTsoP4qh1Wnm0W3xsMgj48,824
|
|
561
561
|
reconcile/typed_queries/reserved_networks.py,sha256=XY9y3amtIQT0n06O0Toubqr_UmylJ2ELAv9-BJCK890,345
|
|
562
562
|
reconcile/typed_queries/rhcs_provider_settings.py,sha256=fxD84CPCiH25_qc02p48LOIJHv39Wlc1VwOhs9ZVsKk,743
|
|
563
|
-
reconcile/typed_queries/saas_files.py,sha256=
|
|
563
|
+
reconcile/typed_queries/saas_files.py,sha256=yVJiba_kIKYaRqSxXovNC2Zupf-KfWoVWQdOmeD1ccY,14666
|
|
564
564
|
reconcile/typed_queries/slack.py,sha256=r30lspctHloyygPn8_DVybxPwUWwiBpvBRRXiTVcQYk,251
|
|
565
565
|
reconcile/typed_queries/slo_documents.py,sha256=YMdox_-lBRqrdxamPhdnUlRTY_Ro35ptsupq7OaynUQ,362
|
|
566
566
|
reconcile/typed_queries/smtp.py,sha256=aSLglYa5bHKmlGwKkxq2RZqyMWuAf0a4S_mOuhDa084,542
|
|
@@ -604,7 +604,7 @@ reconcile/utils/environ.py,sha256=UOYbV7K1MpU7lwcjslKB7oJ7Ek8pOAwf12fA2lV9LM4,81
|
|
|
604
604
|
reconcile/utils/exceptions.py,sha256=2cKJD01d_uZM_j0CTcvDoo-WDisZJVYaeY2KUbfUHCc,686
|
|
605
605
|
reconcile/utils/expiration.py,sha256=6GrQp-sYDKf6scuzzUPxSS8_q_6IiQyjcdvZEVQZzGc,1353
|
|
606
606
|
reconcile/utils/extended_early_exit.py,sha256=QSktrmfw37zSRMNk930tDbQsVeKxaPPPD43e79DGwZw,6754
|
|
607
|
-
reconcile/utils/external_resource_spec.py,sha256=
|
|
607
|
+
reconcile/utils/external_resource_spec.py,sha256=itiV8s87pD5LZ7Xx_rMTf3P-VsEdR7F5Sh7EDXJIGdE,8309
|
|
608
608
|
reconcile/utils/external_resources.py,sha256=YzTb0xAcNdmKO326mGQy7BmST56CZcdru4lX7ai_7kw,7579
|
|
609
609
|
reconcile/utils/filtering.py,sha256=rvCr0drVeD9x4yVox-kvbHEufBktlz3yyQjM-y3IJsM,422
|
|
610
610
|
reconcile/utils/git.py,sha256=o4p9m8jlzCJDcutl2HErvGLhL6sZ1NB4Aw3zGcQIzso,2427
|
|
@@ -644,7 +644,7 @@ reconcile/utils/password_validator.py,sha256=knR6jJGc-v44v-hhQFvpYrEubuFfCCc3Qly
|
|
|
644
644
|
reconcile/utils/prometheus.py,sha256=Ad0rwLbxRuuYjHwkwJloHEdK0bvy42h-p-HIT1DhDhs,3832
|
|
645
645
|
reconcile/utils/promotion_state.py,sha256=4NTBswYkzxlJIIkMz4j92dOj-jn0m36DKQg8CqZEyo8,3910
|
|
646
646
|
reconcile/utils/promtool.py,sha256=YnqwMAzsQVGuBZ1j9zy3UcVPFQVJgBMLzQkxhK_KFkU,3079
|
|
647
|
-
reconcile/utils/quay_api.py,sha256=
|
|
647
|
+
reconcile/utils/quay_api.py,sha256=zlzM-1_GsVSQVd2z0SMwx3uv5wqzZ7JUKE5ZOqQPKXc,7728
|
|
648
648
|
reconcile/utils/quay_mirror.py,sha256=dpWCNv5lITwIk6Q9RkmqaQKHNk_JPy27UQEribJ7E-U,1324
|
|
649
649
|
reconcile/utils/raw_github_api.py,sha256=ZUDtOxdMSMs-Z0noKi0pyMtXHi5V2nCMFDB5JIM_oQ0,3057
|
|
650
650
|
reconcile/utils/repo_owners.py,sha256=c6Z-U5TkiRPvuhr_zYWvZG9HZGzoT-l-d2PJ33lGflE,6507
|
|
@@ -802,7 +802,7 @@ tools/saas_promotion_state/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJ
|
|
|
802
802
|
tools/saas_promotion_state/saas_promotion_state.py,sha256=uQv2QJAmUXP1g2GPIH30WTlvL9soY6m9lefpZEVDM5w,3965
|
|
803
803
|
tools/sre_checkpoints/__init__.py,sha256=CDaDaywJnmRCLyl_NCcvxi-Zc0hTi_3OdwKiFOyS39I,145
|
|
804
804
|
tools/sre_checkpoints/util.py,sha256=KcYVfa3UmJHVP_ocgrKe8NkrO5IDB9aWEDydSokPcRk,975
|
|
805
|
-
qontract_reconcile-0.10.2.
|
|
806
|
-
qontract_reconcile-0.10.2.
|
|
807
|
-
qontract_reconcile-0.10.2.
|
|
808
|
-
qontract_reconcile-0.10.2.
|
|
805
|
+
qontract_reconcile-0.10.2.dev473.dist-info/METADATA,sha256=cqVPSqOjgcxHnzId0KJ1x9lHen_cPLUwfkBQjZe6ULI,24948
|
|
806
|
+
qontract_reconcile-0.10.2.dev473.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
|
|
807
|
+
qontract_reconcile-0.10.2.dev473.dist-info/entry_points.txt,sha256=5i9l54La3vQrDLAdwDKQWC0iG4sV9RRfOb1BpvzOWLc,698
|
|
808
|
+
qontract_reconcile-0.10.2.dev473.dist-info/RECORD,,
|
reconcile/aus/base.py
CHANGED
|
@@ -128,12 +128,24 @@ class AwsAccountMgmtIntegration(
|
|
|
128
128
|
for payer_account in payer_accounts
|
|
129
129
|
for org_account in payer_account.organization_accounts or []
|
|
130
130
|
}
|
|
131
|
-
|
|
132
131
|
non_organization_accounts = [
|
|
133
132
|
account
|
|
134
133
|
for account in all_aws_accounts
|
|
135
134
|
if account.name not in all_organization_account_names
|
|
136
135
|
]
|
|
136
|
+
|
|
137
|
+
# check account requests for invalid emails
|
|
138
|
+
used_emails: set[str] = {
|
|
139
|
+
owner.email
|
|
140
|
+
for account in all_aws_accounts
|
|
141
|
+
for owner in account.account_owners
|
|
142
|
+
}
|
|
143
|
+
for payer_account in payer_accounts:
|
|
144
|
+
for account_request in payer_account.account_requests or []:
|
|
145
|
+
if account_request.account_owner.email in used_emails:
|
|
146
|
+
raise ValueError(
|
|
147
|
+
f"Invalid email for account request {account_request.name} in payer account {payer_account.name}. Email {account_request.account_owner.email} is already used."
|
|
148
|
+
)
|
|
137
149
|
return payer_accounts, non_organization_accounts
|
|
138
150
|
|
|
139
151
|
def save_access_key(self, account: str, access_key: AWSAccessKey) -> None:
|
|
@@ -24,7 +24,7 @@ def validate(account: AWSAccountV1) -> bool:
|
|
|
24
24
|
raise ExceptionGroup("Multiple quotas are referenced in the account", errors)
|
|
25
25
|
|
|
26
26
|
if account.organization_accounts or account.account_requests:
|
|
27
|
-
# it's payer account
|
|
27
|
+
# it's a "payer account"
|
|
28
28
|
if not account.premium_support:
|
|
29
29
|
raise ValueError(
|
|
30
30
|
f"Premium support is required for payer account {account.name}"
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
|
|
16
16
|
`change_owners` uses the `qontract-server` diff endpoint to get a highlevel overview what changed in an MR. It leverages `change_types` to find fine grained differences in datafiles and resourcefiles and build `BundleFileChange` objects that hold the state of diffs and diff coverage.
|
|
17
17
|
|
|
18
|
-
`change_owners` checks `BundleFileChange` objects for `change-types` that are `restrictive`. If the MR was created by a user, that has this `change-type` not assigned, the integration will fail. A user with this role assigned could issue an `/
|
|
18
|
+
`change_owners` checks `BundleFileChange` objects for `change-types` that are `restrictive`. If the MR was created by a user, that has this `change-type` not assigned, the integration will fail. A user with this role assigned could issue an `/ok-to-test` command to override this restriction.
|
|
19
19
|
|
|
20
20
|
`change_owners` reachs out to pluggable functionality to find out which `change-types` can be applied to which changes with a set of approvers. Currently, the only module to provide such `ChangeTypeContext` is `self_service_roles` which looks for explicitly bound `change-types` and files in the context of a `Role` with users and bots will can act as approvers.
|
|
21
21
|
|
|
@@ -131,7 +131,7 @@ def build_status_message(
|
|
|
131
131
|
# Check if changes are not admitted (security gate - takes priority)
|
|
132
132
|
if not change_admitted:
|
|
133
133
|
return f"""## ⏸️ Approval Required
|
|
134
|
-
Your changes need `/
|
|
134
|
+
Your changes need `/ok-to-test` approval from a listed approver before review can begin.
|
|
135
135
|
|
|
136
136
|
{approver_section}"""
|
|
137
137
|
|
|
@@ -322,22 +322,22 @@ def init_gitlab(gitlab_project_id: str) -> GitLabApi:
|
|
|
322
322
|
|
|
323
323
|
|
|
324
324
|
def is_coverage_admitted(
|
|
325
|
-
coverage: ChangeTypeContext, mr_author: str,
|
|
325
|
+
coverage: ChangeTypeContext, mr_author: str, ok_to_test_approvers: set[str]
|
|
326
326
|
) -> bool:
|
|
327
327
|
return any(
|
|
328
|
-
a.org_username == mr_author or a.org_username in
|
|
328
|
+
a.org_username == mr_author or a.org_username in ok_to_test_approvers
|
|
329
329
|
for a in coverage.approvers
|
|
330
330
|
)
|
|
331
331
|
|
|
332
332
|
|
|
333
333
|
def is_change_admitted(
|
|
334
|
-
changes: list[BundleFileChange], mr_author: str,
|
|
334
|
+
changes: list[BundleFileChange], mr_author: str, ok_to_test_approvers: set[str]
|
|
335
335
|
) -> bool:
|
|
336
336
|
# Checks if mr authors are allowed to do the changes in the merge request.
|
|
337
337
|
# If a change type is restrictive and the author is not an approver,
|
|
338
338
|
# this is not admitted.
|
|
339
339
|
# A change might be admitted if a user that has the restrictive change
|
|
340
|
-
# type is an approver or an approver adds an /
|
|
340
|
+
# type is an approver or an approver adds an /ok-to-test comment.
|
|
341
341
|
|
|
342
342
|
restrictive_coverages = [
|
|
343
343
|
c
|
|
@@ -351,7 +351,7 @@ def is_change_admitted(
|
|
|
351
351
|
change_types_approved = {
|
|
352
352
|
c.origin
|
|
353
353
|
for c in restrictive_coverages
|
|
354
|
-
if is_coverage_admitted(c, mr_author,
|
|
354
|
+
if is_coverage_admitted(c, mr_author, ok_to_test_approvers)
|
|
355
355
|
}
|
|
356
356
|
return change_types_to_approve == change_types_approved
|
|
357
357
|
|
|
@@ -442,14 +442,14 @@ def run(
|
|
|
442
442
|
merge_request = gl.get_merge_request(gitlab_merge_request_id)
|
|
443
443
|
|
|
444
444
|
comments = gl.get_merge_request_comments(merge_request)
|
|
445
|
-
|
|
446
|
-
c.username for c in comments if c.body.strip() == "/
|
|
445
|
+
ok_to_test_approvers = {
|
|
446
|
+
c.username for c in comments if c.body.strip() == "/ok-to-test"
|
|
447
447
|
}
|
|
448
448
|
|
|
449
449
|
change_admitted = is_change_admitted(
|
|
450
450
|
changes,
|
|
451
451
|
gl.get_merge_request_author_username(merge_request),
|
|
452
|
-
|
|
452
|
+
ok_to_test_approvers,
|
|
453
453
|
)
|
|
454
454
|
approver_decisions = get_approver_decisions_from_mr_comments(
|
|
455
455
|
gl.get_merge_request_comments(
|
|
@@ -97,6 +97,10 @@ query AWSAccountManagerAccounts {
|
|
|
97
97
|
...AWSAccountManaged
|
|
98
98
|
}
|
|
99
99
|
organizationAccountTags
|
|
100
|
+
# for account request email address verification
|
|
101
|
+
accountOwners {
|
|
102
|
+
email
|
|
103
|
+
}
|
|
100
104
|
}
|
|
101
105
|
}
|
|
102
106
|
"""
|
|
@@ -149,6 +153,10 @@ class AWSAccountRequestV1(ConfiguredBaseModel):
|
|
|
149
153
|
account_file_target_path: Optional[str] = Field(..., alias="accountFileTargetPath")
|
|
150
154
|
|
|
151
155
|
|
|
156
|
+
class AWSAccountV1_OwnerV1(ConfiguredBaseModel):
|
|
157
|
+
email: str = Field(..., alias="email")
|
|
158
|
+
|
|
159
|
+
|
|
152
160
|
class AWSAccountV1(AWSAccountManaged):
|
|
153
161
|
resources_default_region: str = Field(..., alias="resourcesDefaultRegion")
|
|
154
162
|
automation_token: VaultSecret = Field(..., alias="automationToken")
|
|
@@ -157,6 +165,7 @@ class AWSAccountV1(AWSAccountManaged):
|
|
|
157
165
|
account_requests: Optional[list[AWSAccountRequestV1]] = Field(..., alias="account_requests")
|
|
158
166
|
organization_accounts: Optional[list[AWSAccountManaged]] = Field(..., alias="organization_accounts")
|
|
159
167
|
organization_account_tags: Optional[Json] = Field(..., alias="organizationAccountTags")
|
|
168
|
+
account_owners: list[AWSAccountV1_OwnerV1] = Field(..., alias="accountOwners")
|
|
160
169
|
|
|
161
170
|
|
|
162
171
|
class AWSAccountManagerAccountsQueryData(ConfiguredBaseModel):
|
|
@@ -575,6 +575,7 @@ query ExternalResourcesNamespaces {
|
|
|
575
575
|
name
|
|
576
576
|
labels
|
|
577
577
|
servicePhase
|
|
578
|
+
costCenter
|
|
578
579
|
}
|
|
579
580
|
app {
|
|
580
581
|
path
|
|
@@ -1176,13 +1177,14 @@ class EnvironmentV1(ConfiguredBaseModel):
|
|
|
1176
1177
|
name: str = Field(..., alias="name")
|
|
1177
1178
|
labels: str = Field(..., alias="labels")
|
|
1178
1179
|
service_phase: str = Field(..., alias="servicePhase")
|
|
1180
|
+
cost_center: Optional[str] = Field(..., alias="costCenter")
|
|
1179
1181
|
|
|
1180
1182
|
|
|
1181
1183
|
class AppV1(ConfiguredBaseModel):
|
|
1182
1184
|
path: str = Field(..., alias="path")
|
|
1183
1185
|
name: str = Field(..., alias="name")
|
|
1184
1186
|
app_code: str = Field(..., alias="appCode")
|
|
1185
|
-
cost_center: str = Field(..., alias="costCenter")
|
|
1187
|
+
cost_center: Optional[str] = Field(..., alias="costCenter")
|
|
1186
1188
|
|
|
1187
1189
|
|
|
1188
1190
|
class ClusterSpecV1(ConfiguredBaseModel):
|
|
@@ -16708,13 +16708,9 @@
|
|
|
16708
16708
|
"description": null,
|
|
16709
16709
|
"args": [],
|
|
16710
16710
|
"type": {
|
|
16711
|
-
"kind": "
|
|
16712
|
-
"name":
|
|
16713
|
-
"ofType":
|
|
16714
|
-
"kind": "SCALAR",
|
|
16715
|
-
"name": "String",
|
|
16716
|
-
"ofType": null
|
|
16717
|
-
}
|
|
16711
|
+
"kind": "SCALAR",
|
|
16712
|
+
"name": "String",
|
|
16713
|
+
"ofType": null
|
|
16718
16714
|
},
|
|
16719
16715
|
"isDeprecated": false,
|
|
16720
16716
|
"deprecationReason": null
|
|
@@ -17229,6 +17225,18 @@
|
|
|
17229
17225
|
"isDeprecated": false,
|
|
17230
17226
|
"deprecationReason": null
|
|
17231
17227
|
},
|
|
17228
|
+
{
|
|
17229
|
+
"name": "costCenter",
|
|
17230
|
+
"description": null,
|
|
17231
|
+
"args": [],
|
|
17232
|
+
"type": {
|
|
17233
|
+
"kind": "SCALAR",
|
|
17234
|
+
"name": "String",
|
|
17235
|
+
"ofType": null
|
|
17236
|
+
},
|
|
17237
|
+
"isDeprecated": false,
|
|
17238
|
+
"deprecationReason": null
|
|
17239
|
+
},
|
|
17232
17240
|
{
|
|
17233
17241
|
"name": "namespaces",
|
|
17234
17242
|
"description": null,
|
|
@@ -521,6 +521,7 @@ query TerraformResourcesNamespaces {
|
|
|
521
521
|
environment {
|
|
522
522
|
name
|
|
523
523
|
servicePhase
|
|
524
|
+
costCenter
|
|
524
525
|
}
|
|
525
526
|
app {
|
|
526
527
|
name
|
|
@@ -1110,12 +1111,13 @@ class NamespaceTerraformProviderResourceAWSV1(NamespaceExternalResourceV1):
|
|
|
1110
1111
|
class EnvironmentV1(ConfiguredBaseModel):
|
|
1111
1112
|
name: str = Field(..., alias="name")
|
|
1112
1113
|
service_phase: str = Field(..., alias="servicePhase")
|
|
1114
|
+
cost_center: Optional[str] = Field(..., alias="costCenter")
|
|
1113
1115
|
|
|
1114
1116
|
|
|
1115
1117
|
class AppV1(ConfiguredBaseModel):
|
|
1116
1118
|
name: str = Field(..., alias="name")
|
|
1117
1119
|
app_code: str = Field(..., alias="appCode")
|
|
1118
|
-
cost_center: str = Field(..., alias="costCenter")
|
|
1120
|
+
cost_center: Optional[str] = Field(..., alias="costCenter")
|
|
1119
1121
|
|
|
1120
1122
|
|
|
1121
1123
|
class ClusterSpecV1(ConfiguredBaseModel):
|
reconcile/quay_base.py
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
from collections import namedtuple
|
|
1
|
+
from collections import UserDict, namedtuple
|
|
2
2
|
from typing import Any, TypedDict
|
|
3
3
|
|
|
4
4
|
from reconcile import queries
|
|
@@ -10,22 +10,34 @@ OrgKey = namedtuple("OrgKey", ["instance", "org_name"])
|
|
|
10
10
|
|
|
11
11
|
class OrgInfo(TypedDict):
|
|
12
12
|
url: str
|
|
13
|
-
api: QuayApi
|
|
14
13
|
push_token: dict[str, str] | None
|
|
15
14
|
teams: list[str]
|
|
16
15
|
managedRepos: bool
|
|
17
16
|
mirror: OrgKey | None
|
|
18
17
|
mirror_filters: dict[str, Any]
|
|
18
|
+
api: QuayApi
|
|
19
|
+
|
|
19
20
|
|
|
21
|
+
class QuayApiStore(UserDict[OrgKey, OrgInfo]):
|
|
22
|
+
def __init__(self) -> None:
|
|
23
|
+
super().__init__(get_quay_api_store())
|
|
20
24
|
|
|
21
|
-
|
|
25
|
+
def cleanup(self) -> None:
|
|
26
|
+
"""Close all QuayApi sessions."""
|
|
27
|
+
for org_info in self.data.values():
|
|
28
|
+
org_info["api"].cleanup()
|
|
22
29
|
|
|
30
|
+
def __enter__(self) -> "QuayApiStore":
|
|
31
|
+
return self
|
|
23
32
|
|
|
24
|
-
def
|
|
33
|
+
def __exit__(self, exc_type: Any, exc_val: Any, exc_tb: Any) -> None:
|
|
34
|
+
self.cleanup()
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def get_quay_api_store() -> dict[OrgKey, OrgInfo]:
|
|
25
38
|
"""
|
|
26
39
|
Returns a dictionary with a key for each Quay organization
|
|
27
40
|
managed in app-interface.
|
|
28
|
-
Each key contains an initiated QuayApi instance.
|
|
29
41
|
"""
|
|
30
42
|
quay_orgs = queries.get_quay_orgs()
|
|
31
43
|
settings = queries.get_app_interface_settings()
|
|
@@ -61,14 +73,21 @@ def get_quay_api_store() -> QuayApiStore:
|
|
|
61
73
|
else:
|
|
62
74
|
push_token = None
|
|
63
75
|
|
|
76
|
+
# Create QuayApi instance for this org
|
|
77
|
+
api = QuayApi(
|
|
78
|
+
token=token,
|
|
79
|
+
organization=org_name,
|
|
80
|
+
base_url=base_url,
|
|
81
|
+
)
|
|
82
|
+
|
|
64
83
|
org_info: OrgInfo = {
|
|
65
84
|
"url": base_url,
|
|
66
|
-
"api": QuayApi(token, org_name, base_url=base_url),
|
|
67
85
|
"push_token": push_token,
|
|
68
86
|
"teams": org_data.get("managedTeams") or [],
|
|
69
87
|
"managedRepos": bool(org_data.get("managedRepos")),
|
|
70
88
|
"mirror": mirror,
|
|
71
89
|
"mirror_filters": mirror_filters,
|
|
90
|
+
"api": api,
|
|
72
91
|
}
|
|
73
92
|
|
|
74
93
|
store[org_key] = org_info
|
reconcile/quay_membership.py
CHANGED
|
@@ -10,7 +10,7 @@ from reconcile.gql_definitions.quay_membership.quay_membership import (
|
|
|
10
10
|
PermissionQuayOrgTeamV1,
|
|
11
11
|
UserV1,
|
|
12
12
|
)
|
|
13
|
-
from reconcile.quay_base import QuayApiStore
|
|
13
|
+
from reconcile.quay_base import QuayApiStore
|
|
14
14
|
from reconcile.status import ExitCodes
|
|
15
15
|
from reconcile.utils import (
|
|
16
16
|
expiration,
|
|
@@ -58,10 +58,11 @@ def fetch_current_state(quay_api_store: QuayApiStore) -> AggregatedList:
|
|
|
58
58
|
state = AggregatedList()
|
|
59
59
|
|
|
60
60
|
for org_key, org_data in quay_api_store.items():
|
|
61
|
-
quay_api = org_data["api"]
|
|
62
61
|
teams = org_data["teams"]
|
|
63
62
|
if not teams:
|
|
64
63
|
continue
|
|
64
|
+
|
|
65
|
+
quay_api = org_data["api"]
|
|
65
66
|
for team in teams:
|
|
66
67
|
try:
|
|
67
68
|
members = quay_api.list_team_members(team)
|
|
@@ -77,7 +78,11 @@ def fetch_current_state(quay_api_store: QuayApiStore) -> AggregatedList:
|
|
|
77
78
|
# Teams are only added to the state if they exist so that
|
|
78
79
|
# there is a proper diff between the desired and current state.
|
|
79
80
|
state.add(
|
|
80
|
-
{
|
|
81
|
+
{
|
|
82
|
+
"service": "quay-membership",
|
|
83
|
+
"org": org_key.org_name,
|
|
84
|
+
"team": team,
|
|
85
|
+
},
|
|
81
86
|
members,
|
|
82
87
|
)
|
|
83
88
|
return state
|
|
@@ -117,9 +122,10 @@ class RunnerAction:
|
|
|
117
122
|
def action(params: dict, items: list) -> bool:
|
|
118
123
|
org = params["org"]
|
|
119
124
|
team = params["team"]
|
|
125
|
+
org_data = self.quay_api_store[org]
|
|
126
|
+
quay_api = org_data["api"]
|
|
120
127
|
|
|
121
128
|
missing_users = False
|
|
122
|
-
quay_api = self.quay_api_store[org]["api"]
|
|
123
129
|
for member in items:
|
|
124
130
|
logging.info([label, member, org, team])
|
|
125
131
|
user_exists = quay_api.user_exists(member)
|
|
@@ -147,10 +153,11 @@ class RunnerAction:
|
|
|
147
153
|
def action(params: dict, items: list) -> bool:
|
|
148
154
|
org = params["org"]
|
|
149
155
|
team = params["team"]
|
|
156
|
+
org_data = self.quay_api_store[org]
|
|
150
157
|
|
|
151
158
|
# Ensure all quay org/teams are declared as dependencies in a
|
|
152
159
|
# `/dependencies/quay-org-1.yml` datafile.
|
|
153
|
-
if team not in
|
|
160
|
+
if team not in org_data["teams"]:
|
|
154
161
|
raise RunnerError(
|
|
155
162
|
f"Quay team {team} is not defined as a "
|
|
156
163
|
f"managedTeam in the {org} org."
|
|
@@ -159,7 +166,7 @@ class RunnerAction:
|
|
|
159
166
|
logging.info([label, org, team])
|
|
160
167
|
|
|
161
168
|
if not self.dry_run:
|
|
162
|
-
quay_api =
|
|
169
|
+
quay_api = org_data["api"]
|
|
163
170
|
quay_api.create_or_update_team(team)
|
|
164
171
|
|
|
165
172
|
return True
|
|
@@ -172,12 +179,13 @@ class RunnerAction:
|
|
|
172
179
|
def action(params: dict, items: list) -> bool:
|
|
173
180
|
org = params["org"]
|
|
174
181
|
team = params["team"]
|
|
182
|
+
org_data = self.quay_api_store[org]
|
|
175
183
|
|
|
184
|
+
quay_api = org_data["api"]
|
|
176
185
|
if self.dry_run:
|
|
177
186
|
for member in items:
|
|
178
187
|
logging.info([label, member, org, team])
|
|
179
188
|
else:
|
|
180
|
-
quay_api = self.quay_api_store[org]["api"]
|
|
181
189
|
for member in items:
|
|
182
190
|
logging.info([label, member, org, team])
|
|
183
191
|
quay_api.remove_user_from_team(member, team)
|
|
@@ -188,24 +196,23 @@ class RunnerAction:
|
|
|
188
196
|
|
|
189
197
|
|
|
190
198
|
def run(dry_run: bool) -> None:
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
sys.exit(ExitCodes.ERROR)
|
|
199
|
+
with QuayApiStore() as quay_api_store:
|
|
200
|
+
current_state = fetch_current_state(quay_api_store)
|
|
201
|
+
desired_state = fetch_desired_state()
|
|
202
|
+
|
|
203
|
+
# calculate diff
|
|
204
|
+
diff = current_state.diff(desired_state)
|
|
205
|
+
logging.debug("State diff: %s", diff)
|
|
206
|
+
|
|
207
|
+
# Run actions
|
|
208
|
+
runner_action = RunnerAction(dry_run, quay_api_store)
|
|
209
|
+
runner = AggregatedDiffRunner(diff)
|
|
210
|
+
|
|
211
|
+
runner.register("insert", runner_action.create_team())
|
|
212
|
+
runner.register("update-insert", runner_action.add_to_team())
|
|
213
|
+
runner.register("update-delete", runner_action.del_from_team())
|
|
214
|
+
runner.register("delete", runner_action.del_from_team())
|
|
215
|
+
|
|
216
|
+
status = runner.run()
|
|
217
|
+
if not status:
|
|
218
|
+
sys.exit(ExitCodes.ERROR)
|