qontract-reconcile 0.10.2.dev456__py3-none-any.whl → 0.10.2.dev465__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.

@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: qontract-reconcile
3
- Version: 0.10.2.dev456
3
+ Version: 0.10.2.dev465
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.7.1
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
@@ -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=ph9gxWQ5JcusY9S8gAa1Lz1Z_1rd_0W6w_aZYO9Ypzc,54136
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=kVh8BgIOYDo482ExldGhuqmj1KN8qtlO15YVRvLxMDU,15397
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=iYPPOtbZ7FiKkz9v5f1YXRIHw5YFOtSavUkF8oMwfJY,1439
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=NEXVw4SioTWTGo9elSQUjqY10RIUoisl4zkzEBvly8s,3946
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=9M0_D52xiRiN7UQe-q22C0FZZCdWmCAWXajieGYjJRk,18418
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=755rHmrnhfM_xVKnCPlLPOVm_TCJVb3lSkkUvxFM61Q,7491
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=RA-nGyii90zEWBMoF1mBiv2ue-d0mV5ofxwAJHOVj-M,2429636
217
+ reconcile/gql_definitions/introspection.json,sha256=t_E8pSEQnQWn0rV-lMmdBnC5G6_KgF8qm0Og0VcdBYA,2430149
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=p-ojQL0zeY_u694irRGG2HT6XaWkksoOtzCkPrdkXJo,5133
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=XRqi539Xu_lFwmK_pyb_5VvwDjIlcUrRwX1Ht9WiRG0,46525
310
+ reconcile/gql_definitions/external_resources/external_resources_namespaces.py,sha256=jA2Q_j8-zEL57jJ10rb4xyUzQyOJZdKyHFquxQVd0pw,46606
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=wO8dycnslrO5THKDma8VSRboO5bSiBDUiYbJqMhr_6s,44673
430
+ reconcile/gql_definitions/terraform_resources/terraform_resources_namespaces.py,sha256=q-X_7yCtlAXR1eTOfb9V1q9vWQymrP8lg5lKUOwkWrk,44754
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
@@ -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=F6F59Uo1fkap3mpNjV7YoVfcSf2tN_ixowBaMpxaLyc,14667
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=y-jZvio-kPIqQ07ApWegbx5DWUnlkL8cXTg586mHBqc,8188
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
@@ -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.dev456.dist-info/METADATA,sha256=s_WqWgoFL4Yacm8I8TJYk6b3-Q_Wn9ONhB7GxO9tsN8,24948
806
- qontract_reconcile-0.10.2.dev456.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
807
- qontract_reconcile-0.10.2.dev456.dist-info/entry_points.txt,sha256=5i9l54La3vQrDLAdwDKQWC0iG4sV9RRfOb1BpvzOWLc,698
808
- qontract_reconcile-0.10.2.dev456.dist-info/RECORD,,
805
+ qontract_reconcile-0.10.2.dev465.dist-info/METADATA,sha256=ScW_C4JCmkdyTIXDqZrqfFVmZtjNv3mNn_WklW7ZtTo,24948
806
+ qontract_reconcile-0.10.2.dev465.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
807
+ qontract_reconcile-0.10.2.dev465.dist-info/entry_points.txt,sha256=5i9l54La3vQrDLAdwDKQWC0iG4sV9RRfOb1BpvzOWLc,698
808
+ qontract_reconcile-0.10.2.dev465.dist-info/RECORD,,
reconcile/aus/base.py CHANGED
@@ -460,9 +460,6 @@ class AddonUpgradePolicy(AbstractUpgradePolicy, arbitrary_types_allowed=True):
460
460
  addon_id: str
461
461
  addon_service: AddonService
462
462
 
463
- class Config:
464
- arbitrary_types_allowed = True
465
-
466
463
  def create(
467
464
  self,
468
465
  ocm_api: OCMBaseClient,
@@ -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 `/good-to-test` command to override this restriction.
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 `/good-to-test` approval from a listed approver before review can begin.
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, good_to_test_approvers: set[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 good_to_test_approvers
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, good_to_test_approvers: set[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 /good-to-test comment.
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, good_to_test_approvers)
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
- good_to_test_approvers = {
446
- c.username for c in comments if c.body.strip() == "/good-to-test"
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
- good_to_test_approvers,
452
+ ok_to_test_approvers,
453
453
  )
454
454
  approver_decisions = get_approver_decisions_from_mr_comments(
455
455
  gl.get_merge_request_comments(
@@ -20,7 +20,7 @@ class DecisionCommand(Enum):
20
20
  CANCEL_APPROVED = "/lgtm cancel"
21
21
  HOLD = "/hold"
22
22
  CANCEL_HOLD = "/hold cancel"
23
- GOOD_TO_TEST = "/good-to-test"
23
+ OK_TO_TEST = "/ok-to-test"
24
24
 
25
25
 
26
26
  @dataclass
@@ -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,6 +1177,7 @@ 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):
@@ -17229,6 +17229,18 @@
17229
17229
  "isDeprecated": false,
17230
17230
  "deprecationReason": null
17231
17231
  },
17232
+ {
17233
+ "name": "costCenter",
17234
+ "description": null,
17235
+ "args": [],
17236
+ "type": {
17237
+ "kind": "SCALAR",
17238
+ "name": "String",
17239
+ "ofType": null
17240
+ },
17241
+ "isDeprecated": false,
17242
+ "deprecationReason": null
17243
+ },
17232
17244
  {
17233
17245
  "name": "namespaces",
17234
17246
  "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,6 +1111,7 @@ 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):
@@ -83,7 +83,7 @@ class SaasResourceTemplateTarget(
83
83
  if used_for_security_is_enabled():
84
84
  # When USED_FOR_SECURITY is enabled, use blake2s without digest_size and truncate to 20 bytes
85
85
  # This is needed for FIPS compliance where digest_size parameter is not supported
86
- return hashlib.blake2s(data).digest()[:20].hex()
86
+ return hashlib.sha256(data).digest()[:20].hex()
87
87
  else:
88
88
  # Default behavior: use blake2s with digest_size=20
89
89
  return hashlib.blake2s(data, digest_size=20).hexdigest()
@@ -157,6 +157,8 @@ class ExternalResourceSpec:
157
157
  tags["cost-center"] = cost_center
158
158
  if service_phase := self.namespace["environment"].get("servicePhase"):
159
159
  tags["service-phase"] = service_phase
160
+ if cost_center := self.namespace["environment"].get("costCenter"):
161
+ tags["cost-center"] = cost_center
160
162
 
161
163
  resource_tags_str = self.resource.get("tags")
162
164
  if resource_tags_str: