qontract-reconcile 0.10.0__py3-none-any.whl → 0.10.1.dev1203__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 (844) hide show
  1. qontract_reconcile-0.10.1.dev1203.dist-info/METADATA +500 -0
  2. qontract_reconcile-0.10.1.dev1203.dist-info/RECORD +771 -0
  3. {qontract_reconcile-0.10.0.dist-info → qontract_reconcile-0.10.1.dev1203.dist-info}/WHEEL +1 -2
  4. {qontract_reconcile-0.10.0.dist-info → qontract_reconcile-0.10.1.dev1203.dist-info}/entry_points.txt +4 -2
  5. reconcile/acs_notifiers.py +126 -0
  6. reconcile/acs_policies.py +243 -0
  7. reconcile/acs_rbac.py +596 -0
  8. reconcile/aus/advanced_upgrade_service.py +621 -8
  9. reconcile/aus/aus_label_source.py +115 -0
  10. reconcile/aus/base.py +1053 -353
  11. reconcile/{utils → aus}/cluster_version_data.py +27 -12
  12. reconcile/aus/healthchecks.py +77 -0
  13. reconcile/aus/metrics.py +158 -0
  14. reconcile/aus/models.py +245 -5
  15. reconcile/aus/node_pool_spec.py +35 -0
  16. reconcile/aus/ocm_addons_upgrade_scheduler_org.py +225 -110
  17. reconcile/aus/ocm_upgrade_scheduler.py +76 -71
  18. reconcile/aus/ocm_upgrade_scheduler_org.py +81 -23
  19. reconcile/aus/version_gate_approver.py +204 -0
  20. reconcile/aus/version_gates/__init__.py +12 -0
  21. reconcile/aus/version_gates/handler.py +33 -0
  22. reconcile/aus/version_gates/ingress_gate_handler.py +32 -0
  23. reconcile/aus/version_gates/ocp_gate_handler.py +26 -0
  24. reconcile/aus/version_gates/sts_version_gate_handler.py +100 -0
  25. reconcile/aws_account_manager/README.md +5 -0
  26. reconcile/aws_account_manager/integration.py +373 -0
  27. reconcile/aws_account_manager/merge_request_manager.py +114 -0
  28. reconcile/aws_account_manager/metrics.py +39 -0
  29. reconcile/aws_account_manager/reconciler.py +403 -0
  30. reconcile/aws_account_manager/utils.py +41 -0
  31. reconcile/aws_ami_cleanup/integration.py +273 -0
  32. reconcile/aws_ami_share.py +18 -14
  33. reconcile/aws_cloudwatch_log_retention/integration.py +253 -0
  34. reconcile/aws_iam_keys.py +1 -1
  35. reconcile/aws_iam_password_reset.py +56 -20
  36. reconcile/aws_saml_idp/integration.py +204 -0
  37. reconcile/aws_saml_roles/integration.py +322 -0
  38. reconcile/aws_support_cases_sos.py +2 -2
  39. reconcile/aws_version_sync/integration.py +430 -0
  40. reconcile/aws_version_sync/merge_request_manager/merge_request.py +156 -0
  41. reconcile/aws_version_sync/merge_request_manager/merge_request_manager.py +160 -0
  42. reconcile/aws_version_sync/utils.py +64 -0
  43. reconcile/blackbox_exporter_endpoint_monitoring.py +2 -5
  44. reconcile/change_owners/README.md +34 -0
  45. reconcile/change_owners/approver.py +7 -9
  46. reconcile/change_owners/bundle.py +134 -9
  47. reconcile/change_owners/change_log_tracking.py +236 -0
  48. reconcile/change_owners/change_owners.py +204 -194
  49. reconcile/change_owners/change_types.py +183 -265
  50. reconcile/change_owners/changes.py +488 -0
  51. reconcile/change_owners/decision.py +120 -41
  52. reconcile/change_owners/diff.py +63 -92
  53. reconcile/change_owners/implicit_ownership.py +19 -16
  54. reconcile/change_owners/self_service_roles.py +158 -35
  55. reconcile/change_owners/tester.py +20 -18
  56. reconcile/checkpoint.py +4 -6
  57. reconcile/cli.py +1523 -242
  58. reconcile/closedbox_endpoint_monitoring_base.py +10 -17
  59. reconcile/cluster_auth_rhidp/integration.py +257 -0
  60. reconcile/cluster_deployment_mapper.py +2 -5
  61. reconcile/cna/assets/asset.py +4 -7
  62. reconcile/cna/assets/null.py +2 -5
  63. reconcile/cna/integration.py +2 -3
  64. reconcile/cna/state.py +6 -9
  65. reconcile/dashdotdb_base.py +31 -10
  66. reconcile/dashdotdb_cso.py +3 -6
  67. reconcile/dashdotdb_dora.py +530 -0
  68. reconcile/dashdotdb_dvo.py +10 -13
  69. reconcile/dashdotdb_slo.py +75 -19
  70. reconcile/database_access_manager.py +753 -0
  71. reconcile/deadmanssnitch.py +207 -0
  72. reconcile/dynatrace_token_provider/dependencies.py +69 -0
  73. reconcile/dynatrace_token_provider/integration.py +656 -0
  74. reconcile/dynatrace_token_provider/metrics.py +62 -0
  75. reconcile/dynatrace_token_provider/model.py +14 -0
  76. reconcile/dynatrace_token_provider/ocm.py +140 -0
  77. reconcile/dynatrace_token_provider/validate.py +48 -0
  78. reconcile/endpoints_discovery/integration.py +348 -0
  79. reconcile/endpoints_discovery/merge_request.py +96 -0
  80. reconcile/endpoints_discovery/merge_request_manager.py +178 -0
  81. reconcile/external_resources/aws.py +204 -0
  82. reconcile/external_resources/factories.py +163 -0
  83. reconcile/external_resources/integration.py +194 -0
  84. reconcile/external_resources/integration_secrets_sync.py +47 -0
  85. reconcile/external_resources/manager.py +405 -0
  86. reconcile/external_resources/meta.py +17 -0
  87. reconcile/external_resources/metrics.py +95 -0
  88. reconcile/external_resources/model.py +350 -0
  89. reconcile/external_resources/reconciler.py +265 -0
  90. reconcile/external_resources/secrets_sync.py +465 -0
  91. reconcile/external_resources/state.py +258 -0
  92. reconcile/gabi_authorized_users.py +19 -11
  93. reconcile/gcr_mirror.py +43 -34
  94. reconcile/github_org.py +4 -6
  95. reconcile/github_owners.py +1 -1
  96. reconcile/github_repo_invites.py +2 -5
  97. reconcile/gitlab_fork_compliance.py +14 -13
  98. reconcile/gitlab_housekeeping.py +185 -91
  99. reconcile/gitlab_labeler.py +15 -14
  100. reconcile/gitlab_members.py +126 -120
  101. reconcile/gitlab_owners.py +53 -66
  102. reconcile/gitlab_permissions.py +167 -6
  103. reconcile/glitchtip/README.md +150 -0
  104. reconcile/glitchtip/integration.py +99 -51
  105. reconcile/glitchtip/reconciler.py +99 -70
  106. reconcile/glitchtip_project_alerts/__init__.py +0 -0
  107. reconcile/glitchtip_project_alerts/integration.py +333 -0
  108. reconcile/glitchtip_project_dsn/integration.py +43 -43
  109. reconcile/gql_definitions/acs/__init__.py +0 -0
  110. reconcile/gql_definitions/acs/acs_instances.py +83 -0
  111. reconcile/gql_definitions/acs/acs_policies.py +239 -0
  112. reconcile/gql_definitions/acs/acs_rbac.py +111 -0
  113. reconcile/gql_definitions/advanced_upgrade_service/aus_clusters.py +46 -8
  114. reconcile/gql_definitions/advanced_upgrade_service/aus_organization.py +38 -8
  115. reconcile/gql_definitions/app_interface_metrics_exporter/__init__.py +0 -0
  116. reconcile/gql_definitions/app_interface_metrics_exporter/onboarding_status.py +61 -0
  117. reconcile/gql_definitions/aws_account_manager/__init__.py +0 -0
  118. reconcile/gql_definitions/aws_account_manager/aws_accounts.py +177 -0
  119. reconcile/gql_definitions/aws_ami_cleanup/__init__.py +0 -0
  120. reconcile/gql_definitions/aws_ami_cleanup/aws_accounts.py +161 -0
  121. reconcile/gql_definitions/aws_saml_idp/__init__.py +0 -0
  122. reconcile/gql_definitions/aws_saml_idp/aws_accounts.py +117 -0
  123. reconcile/gql_definitions/aws_saml_roles/__init__.py +0 -0
  124. reconcile/gql_definitions/aws_saml_roles/aws_accounts.py +117 -0
  125. reconcile/gql_definitions/aws_saml_roles/roles.py +97 -0
  126. reconcile/gql_definitions/aws_version_sync/__init__.py +0 -0
  127. reconcile/gql_definitions/aws_version_sync/clusters.py +83 -0
  128. reconcile/gql_definitions/aws_version_sync/namespaces.py +143 -0
  129. reconcile/gql_definitions/change_owners/queries/change_types.py +16 -29
  130. reconcile/gql_definitions/change_owners/queries/self_service_roles.py +45 -11
  131. reconcile/gql_definitions/cluster_auth_rhidp/__init__.py +0 -0
  132. reconcile/gql_definitions/cluster_auth_rhidp/clusters.py +128 -0
  133. reconcile/gql_definitions/cna/queries/cna_provisioners.py +6 -8
  134. reconcile/gql_definitions/cna/queries/cna_resources.py +3 -5
  135. reconcile/gql_definitions/common/alerting_services_settings.py +2 -2
  136. reconcile/gql_definitions/common/app_code_component_repos.py +9 -5
  137. reconcile/gql_definitions/{glitchtip/glitchtip_settings.py → common/app_interface_custom_messages.py} +14 -16
  138. reconcile/gql_definitions/common/app_interface_dms_settings.py +86 -0
  139. reconcile/gql_definitions/common/app_interface_repo_settings.py +2 -2
  140. reconcile/gql_definitions/common/app_interface_state_settings.py +3 -5
  141. reconcile/gql_definitions/common/app_interface_vault_settings.py +3 -5
  142. reconcile/gql_definitions/common/app_quay_repos_escalation_policies.py +120 -0
  143. reconcile/gql_definitions/common/apps.py +72 -0
  144. reconcile/gql_definitions/common/aws_vpc_requests.py +109 -0
  145. reconcile/gql_definitions/common/aws_vpcs.py +84 -0
  146. reconcile/gql_definitions/common/clusters.py +120 -254
  147. reconcile/gql_definitions/common/clusters_minimal.py +11 -35
  148. reconcile/gql_definitions/common/clusters_with_dms.py +72 -0
  149. reconcile/gql_definitions/common/clusters_with_peering.py +70 -98
  150. reconcile/gql_definitions/common/github_orgs.py +2 -2
  151. reconcile/gql_definitions/common/jira_settings.py +68 -0
  152. reconcile/gql_definitions/common/jiralert_settings.py +68 -0
  153. reconcile/gql_definitions/common/namespaces.py +74 -32
  154. reconcile/gql_definitions/common/namespaces_minimal.py +4 -10
  155. reconcile/gql_definitions/common/ocm_env_telemeter.py +95 -0
  156. reconcile/gql_definitions/common/ocm_environments.py +4 -2
  157. reconcile/gql_definitions/common/pagerduty_instances.py +5 -5
  158. reconcile/gql_definitions/common/pgp_reencryption_settings.py +5 -11
  159. reconcile/gql_definitions/common/pipeline_providers.py +45 -90
  160. reconcile/gql_definitions/common/quay_instances.py +64 -0
  161. reconcile/gql_definitions/common/quay_orgs.py +68 -0
  162. reconcile/gql_definitions/common/reserved_networks.py +94 -0
  163. reconcile/gql_definitions/common/saas_files.py +133 -95
  164. reconcile/gql_definitions/common/saas_target_namespaces.py +41 -26
  165. reconcile/gql_definitions/common/saasherder_settings.py +2 -2
  166. reconcile/gql_definitions/common/slack_workspaces.py +62 -0
  167. reconcile/gql_definitions/common/smtp_client_settings.py +2 -2
  168. reconcile/gql_definitions/common/state_aws_account.py +77 -0
  169. reconcile/gql_definitions/common/users.py +3 -2
  170. reconcile/gql_definitions/cost_report/__init__.py +0 -0
  171. reconcile/gql_definitions/cost_report/app_names.py +68 -0
  172. reconcile/gql_definitions/cost_report/cost_namespaces.py +86 -0
  173. reconcile/gql_definitions/cost_report/settings.py +77 -0
  174. reconcile/gql_definitions/dashdotdb_slo/slo_documents_query.py +42 -12
  175. reconcile/gql_definitions/dynatrace_token_provider/__init__.py +0 -0
  176. reconcile/gql_definitions/dynatrace_token_provider/dynatrace_bootstrap_tokens.py +79 -0
  177. reconcile/gql_definitions/dynatrace_token_provider/token_specs.py +84 -0
  178. reconcile/gql_definitions/endpoints_discovery/__init__.py +0 -0
  179. reconcile/gql_definitions/endpoints_discovery/namespaces.py +127 -0
  180. reconcile/gql_definitions/external_resources/__init__.py +0 -0
  181. reconcile/gql_definitions/external_resources/aws_accounts.py +73 -0
  182. reconcile/gql_definitions/external_resources/external_resources_modules.py +78 -0
  183. reconcile/gql_definitions/external_resources/external_resources_namespaces.py +1111 -0
  184. reconcile/gql_definitions/external_resources/external_resources_settings.py +98 -0
  185. reconcile/gql_definitions/fragments/aus_organization.py +34 -39
  186. reconcile/gql_definitions/fragments/aws_account_common.py +62 -0
  187. reconcile/gql_definitions/fragments/aws_account_managed.py +57 -0
  188. reconcile/gql_definitions/fragments/aws_account_sso.py +35 -0
  189. reconcile/gql_definitions/fragments/aws_infra_management_account.py +2 -2
  190. reconcile/gql_definitions/fragments/aws_vpc.py +47 -0
  191. reconcile/gql_definitions/fragments/aws_vpc_request.py +65 -0
  192. reconcile/gql_definitions/fragments/aws_vpc_request_subnet.py +29 -0
  193. reconcile/gql_definitions/fragments/deplopy_resources.py +7 -7
  194. reconcile/gql_definitions/fragments/disable.py +28 -0
  195. reconcile/gql_definitions/fragments/jumphost_common_fields.py +2 -2
  196. reconcile/gql_definitions/fragments/membership_source.py +47 -0
  197. reconcile/gql_definitions/fragments/minimal_ocm_organization.py +29 -0
  198. reconcile/gql_definitions/fragments/oc_connection_cluster.py +4 -9
  199. reconcile/gql_definitions/fragments/ocm_environment.py +5 -5
  200. reconcile/gql_definitions/fragments/pipeline_provider_retention.py +30 -0
  201. reconcile/gql_definitions/fragments/prometheus_instance.py +48 -0
  202. reconcile/gql_definitions/fragments/resource_limits_requirements.py +29 -0
  203. reconcile/gql_definitions/fragments/{resource_requirements.py → resource_requests_requirements.py} +3 -3
  204. reconcile/gql_definitions/fragments/resource_values.py +2 -2
  205. reconcile/gql_definitions/fragments/saas_target_namespace.py +55 -12
  206. reconcile/gql_definitions/fragments/serviceaccount_token.py +38 -0
  207. reconcile/gql_definitions/fragments/terraform_state.py +36 -0
  208. reconcile/gql_definitions/fragments/upgrade_policy.py +5 -3
  209. reconcile/gql_definitions/fragments/user.py +3 -2
  210. reconcile/gql_definitions/fragments/vault_secret.py +2 -2
  211. reconcile/gql_definitions/gitlab_members/gitlab_instances.py +6 -2
  212. reconcile/gql_definitions/gitlab_members/permissions.py +3 -5
  213. reconcile/gql_definitions/glitchtip/glitchtip_instance.py +16 -2
  214. reconcile/gql_definitions/glitchtip/glitchtip_project.py +22 -23
  215. reconcile/gql_definitions/glitchtip_project_alerts/__init__.py +0 -0
  216. reconcile/gql_definitions/glitchtip_project_alerts/glitchtip_project.py +173 -0
  217. reconcile/gql_definitions/integrations/integrations.py +62 -45
  218. reconcile/gql_definitions/introspection.json +51176 -0
  219. reconcile/gql_definitions/jenkins_configs/jenkins_configs.py +13 -5
  220. reconcile/gql_definitions/jenkins_configs/jenkins_instances.py +79 -0
  221. reconcile/gql_definitions/jira/__init__.py +0 -0
  222. reconcile/gql_definitions/jira/jira_servers.py +80 -0
  223. reconcile/gql_definitions/jira_permissions_validator/__init__.py +0 -0
  224. reconcile/gql_definitions/jira_permissions_validator/jira_boards_for_permissions_validator.py +131 -0
  225. reconcile/gql_definitions/jumphosts/jumphosts.py +3 -5
  226. reconcile/gql_definitions/ldap_groups/__init__.py +0 -0
  227. reconcile/gql_definitions/ldap_groups/roles.py +111 -0
  228. reconcile/gql_definitions/ldap_groups/settings.py +79 -0
  229. reconcile/gql_definitions/maintenance/__init__.py +0 -0
  230. reconcile/gql_definitions/maintenance/maintenances.py +101 -0
  231. reconcile/gql_definitions/membershipsources/__init__.py +0 -0
  232. reconcile/gql_definitions/membershipsources/roles.py +112 -0
  233. reconcile/gql_definitions/ocm_labels/__init__.py +0 -0
  234. reconcile/gql_definitions/ocm_labels/clusters.py +112 -0
  235. reconcile/gql_definitions/ocm_labels/organizations.py +78 -0
  236. reconcile/gql_definitions/ocm_subscription_labels/__init__.py +0 -0
  237. reconcile/gql_definitions/openshift_cluster_bots/__init__.py +0 -0
  238. reconcile/gql_definitions/openshift_cluster_bots/clusters.py +126 -0
  239. reconcile/gql_definitions/openshift_groups/managed_groups.py +2 -2
  240. reconcile/gql_definitions/openshift_groups/managed_roles.py +3 -2
  241. reconcile/gql_definitions/openshift_serviceaccount_tokens/__init__.py +0 -0
  242. reconcile/gql_definitions/openshift_serviceaccount_tokens/tokens.py +132 -0
  243. reconcile/gql_definitions/quay_membership/quay_membership.py +3 -5
  244. reconcile/gql_definitions/rhidp/__init__.py +0 -0
  245. reconcile/gql_definitions/rhidp/organizations.py +96 -0
  246. reconcile/gql_definitions/service_dependencies/jenkins_instance_fragment.py +2 -2
  247. reconcile/gql_definitions/service_dependencies/service_dependencies.py +9 -31
  248. reconcile/gql_definitions/sharding/aws_accounts.py +2 -2
  249. reconcile/gql_definitions/sharding/ocm_organization.py +63 -0
  250. reconcile/gql_definitions/skupper_network/site_controller_template.py +2 -2
  251. reconcile/gql_definitions/skupper_network/skupper_networks.py +12 -38
  252. reconcile/gql_definitions/slack_usergroups/clusters.py +2 -2
  253. reconcile/gql_definitions/slack_usergroups/permissions.py +8 -15
  254. reconcile/gql_definitions/slack_usergroups/users.py +3 -2
  255. reconcile/gql_definitions/slo_documents/__init__.py +0 -0
  256. reconcile/gql_definitions/slo_documents/slo_documents.py +142 -0
  257. reconcile/gql_definitions/status_board/__init__.py +0 -0
  258. reconcile/gql_definitions/status_board/status_board.py +163 -0
  259. reconcile/gql_definitions/statuspage/statuspages.py +56 -7
  260. reconcile/gql_definitions/templating/__init__.py +0 -0
  261. reconcile/gql_definitions/templating/template_collection.py +130 -0
  262. reconcile/gql_definitions/templating/templates.py +108 -0
  263. reconcile/gql_definitions/terraform_cloudflare_dns/app_interface_cloudflare_dns_settings.py +4 -8
  264. reconcile/gql_definitions/terraform_cloudflare_dns/terraform_cloudflare_zones.py +8 -8
  265. reconcile/gql_definitions/terraform_cloudflare_resources/terraform_cloudflare_accounts.py +6 -8
  266. reconcile/gql_definitions/terraform_cloudflare_resources/terraform_cloudflare_resources.py +45 -56
  267. reconcile/gql_definitions/terraform_cloudflare_users/app_interface_setting_cloudflare_and_vault.py +4 -8
  268. reconcile/gql_definitions/terraform_cloudflare_users/terraform_cloudflare_roles.py +4 -8
  269. reconcile/gql_definitions/terraform_init/__init__.py +0 -0
  270. reconcile/gql_definitions/terraform_init/aws_accounts.py +93 -0
  271. reconcile/gql_definitions/terraform_repo/__init__.py +0 -0
  272. reconcile/gql_definitions/terraform_repo/terraform_repo.py +141 -0
  273. reconcile/gql_definitions/terraform_resources/database_access_manager.py +158 -0
  274. reconcile/gql_definitions/terraform_resources/terraform_resources_namespaces.py +153 -162
  275. reconcile/gql_definitions/terraform_tgw_attachments/__init__.py +0 -0
  276. reconcile/gql_definitions/terraform_tgw_attachments/aws_accounts.py +119 -0
  277. reconcile/gql_definitions/unleash_feature_toggles/__init__.py +0 -0
  278. reconcile/gql_definitions/unleash_feature_toggles/feature_toggles.py +113 -0
  279. reconcile/gql_definitions/vault_instances/vault_instances.py +17 -50
  280. reconcile/gql_definitions/vault_policies/vault_policies.py +2 -2
  281. reconcile/gql_definitions/vpc_peerings_validator/vpc_peerings_validator.py +49 -12
  282. reconcile/gql_definitions/vpc_peerings_validator/vpc_peerings_validator_peered_cluster_fragment.py +7 -2
  283. reconcile/integrations_manager.py +25 -13
  284. reconcile/jenkins/types.py +5 -1
  285. reconcile/jenkins_base.py +36 -0
  286. reconcile/jenkins_job_builder.py +10 -48
  287. reconcile/jenkins_job_builds_cleaner.py +40 -25
  288. reconcile/jenkins_job_cleaner.py +1 -3
  289. reconcile/jenkins_roles.py +22 -26
  290. reconcile/jenkins_webhooks.py +9 -6
  291. reconcile/jenkins_worker_fleets.py +11 -6
  292. reconcile/jira_permissions_validator.py +340 -0
  293. reconcile/jira_watcher.py +3 -5
  294. reconcile/ldap_groups/__init__.py +0 -0
  295. reconcile/ldap_groups/integration.py +279 -0
  296. reconcile/ldap_users.py +3 -0
  297. reconcile/ocm/types.py +39 -59
  298. reconcile/ocm_additional_routers.py +0 -1
  299. reconcile/ocm_addons_upgrade_tests_trigger.py +10 -15
  300. reconcile/ocm_aws_infrastructure_access.py +30 -32
  301. reconcile/ocm_clusters.py +217 -130
  302. reconcile/ocm_external_configuration_labels.py +15 -0
  303. reconcile/ocm_github_idp.py +1 -1
  304. reconcile/ocm_groups.py +25 -5
  305. reconcile/ocm_internal_notifications/__init__.py +0 -0
  306. reconcile/ocm_internal_notifications/integration.py +119 -0
  307. reconcile/ocm_labels/__init__.py +0 -0
  308. reconcile/ocm_labels/integration.py +409 -0
  309. reconcile/ocm_machine_pools.py +517 -108
  310. reconcile/ocm_upgrade_scheduler_org_updater.py +15 -11
  311. reconcile/openshift_base.py +609 -207
  312. reconcile/openshift_cluster_bots.py +344 -0
  313. reconcile/openshift_clusterrolebindings.py +15 -15
  314. reconcile/openshift_groups.py +42 -45
  315. reconcile/openshift_limitranges.py +1 -0
  316. reconcile/openshift_namespace_labels.py +22 -28
  317. reconcile/openshift_namespaces.py +22 -22
  318. reconcile/openshift_network_policies.py +4 -8
  319. reconcile/openshift_prometheus_rules.py +43 -0
  320. reconcile/openshift_resourcequotas.py +2 -16
  321. reconcile/openshift_resources.py +12 -10
  322. reconcile/openshift_resources_base.py +304 -328
  323. reconcile/openshift_rolebindings.py +18 -20
  324. reconcile/openshift_saas_deploy.py +105 -21
  325. reconcile/openshift_saas_deploy_change_tester.py +30 -35
  326. reconcile/openshift_saas_deploy_trigger_base.py +39 -36
  327. reconcile/openshift_saas_deploy_trigger_cleaner.py +41 -27
  328. reconcile/openshift_saas_deploy_trigger_configs.py +1 -2
  329. reconcile/openshift_saas_deploy_trigger_images.py +1 -2
  330. reconcile/openshift_saas_deploy_trigger_moving_commits.py +1 -2
  331. reconcile/openshift_saas_deploy_trigger_upstream_jobs.py +1 -2
  332. reconcile/openshift_serviceaccount_tokens.py +138 -74
  333. reconcile/openshift_tekton_resources.py +89 -24
  334. reconcile/openshift_upgrade_watcher.py +110 -62
  335. reconcile/openshift_users.py +16 -15
  336. reconcile/openshift_vault_secrets.py +11 -6
  337. reconcile/oum/__init__.py +0 -0
  338. reconcile/oum/base.py +387 -0
  339. reconcile/oum/labelset.py +55 -0
  340. reconcile/oum/metrics.py +71 -0
  341. reconcile/oum/models.py +69 -0
  342. reconcile/oum/providers.py +59 -0
  343. reconcile/oum/standalone.py +196 -0
  344. reconcile/prometheus_rules_tester/integration.py +31 -23
  345. reconcile/quay_base.py +4 -1
  346. reconcile/quay_membership.py +1 -2
  347. reconcile/quay_mirror.py +111 -61
  348. reconcile/quay_mirror_org.py +34 -21
  349. reconcile/quay_permissions.py +7 -3
  350. reconcile/quay_repos.py +24 -32
  351. reconcile/queries.py +263 -198
  352. reconcile/query_validator.py +3 -5
  353. reconcile/resource_scraper.py +3 -4
  354. reconcile/{template_tester.py → resource_template_tester.py} +3 -3
  355. reconcile/rhidp/__init__.py +0 -0
  356. reconcile/rhidp/common.py +214 -0
  357. reconcile/rhidp/metrics.py +20 -0
  358. reconcile/rhidp/ocm_oidc_idp/__init__.py +0 -0
  359. reconcile/rhidp/ocm_oidc_idp/base.py +221 -0
  360. reconcile/rhidp/ocm_oidc_idp/integration.py +56 -0
  361. reconcile/rhidp/ocm_oidc_idp/metrics.py +22 -0
  362. reconcile/rhidp/sso_client/__init__.py +0 -0
  363. reconcile/rhidp/sso_client/base.py +266 -0
  364. reconcile/rhidp/sso_client/integration.py +60 -0
  365. reconcile/rhidp/sso_client/metrics.py +39 -0
  366. reconcile/run_integration.py +293 -0
  367. reconcile/saas_auto_promotions_manager/integration.py +69 -24
  368. reconcile/saas_auto_promotions_manager/merge_request_manager/batcher.py +208 -0
  369. reconcile/saas_auto_promotions_manager/merge_request_manager/desired_state.py +28 -0
  370. reconcile/saas_auto_promotions_manager/merge_request_manager/merge_request.py +3 -4
  371. reconcile/saas_auto_promotions_manager/merge_request_manager/merge_request_manager_v2.py +172 -0
  372. reconcile/saas_auto_promotions_manager/merge_request_manager/metrics.py +42 -0
  373. reconcile/saas_auto_promotions_manager/merge_request_manager/mr_parser.py +226 -0
  374. reconcile/saas_auto_promotions_manager/merge_request_manager/open_merge_requests.py +23 -0
  375. reconcile/saas_auto_promotions_manager/merge_request_manager/renderer.py +108 -32
  376. reconcile/saas_auto_promotions_manager/meta.py +4 -0
  377. reconcile/saas_auto_promotions_manager/publisher.py +32 -4
  378. reconcile/saas_auto_promotions_manager/s3_exporter.py +77 -0
  379. reconcile/saas_auto_promotions_manager/subscriber.py +110 -23
  380. reconcile/saas_auto_promotions_manager/utils/saas_files_inventory.py +48 -41
  381. reconcile/saas_file_validator.py +16 -6
  382. reconcile/sendgrid_teammates.py +27 -12
  383. reconcile/service_dependencies.py +0 -3
  384. reconcile/signalfx_endpoint_monitoring.py +2 -5
  385. reconcile/skupper_network/integration.py +10 -11
  386. reconcile/skupper_network/models.py +3 -5
  387. reconcile/skupper_network/reconciler.py +28 -35
  388. reconcile/skupper_network/site_controller.py +8 -8
  389. reconcile/slack_base.py +4 -7
  390. reconcile/slack_usergroups.py +249 -171
  391. reconcile/sql_query.py +324 -171
  392. reconcile/status.py +0 -1
  393. reconcile/status_board.py +275 -0
  394. reconcile/statuspage/__init__.py +0 -5
  395. reconcile/statuspage/atlassian.py +219 -80
  396. reconcile/statuspage/integration.py +9 -97
  397. reconcile/statuspage/integrations/__init__.py +0 -0
  398. reconcile/statuspage/integrations/components.py +77 -0
  399. reconcile/statuspage/integrations/maintenances.py +111 -0
  400. reconcile/statuspage/page.py +107 -72
  401. reconcile/statuspage/state.py +6 -11
  402. reconcile/statuspage/status.py +8 -12
  403. reconcile/templates/rosa-classic-cluster-creation.sh.j2 +60 -0
  404. reconcile/templates/rosa-hcp-cluster-creation.sh.j2 +61 -0
  405. reconcile/templating/__init__.py +0 -0
  406. reconcile/templating/lib/__init__.py +0 -0
  407. reconcile/templating/lib/merge_request_manager.py +180 -0
  408. reconcile/templating/lib/model.py +20 -0
  409. reconcile/templating/lib/rendering.py +191 -0
  410. reconcile/templating/renderer.py +410 -0
  411. reconcile/templating/validator.py +153 -0
  412. reconcile/terraform_aws_route53.py +13 -10
  413. reconcile/terraform_cloudflare_dns.py +92 -122
  414. reconcile/terraform_cloudflare_resources.py +15 -13
  415. reconcile/terraform_cloudflare_users.py +27 -27
  416. reconcile/terraform_init/__init__.py +0 -0
  417. reconcile/terraform_init/integration.py +165 -0
  418. reconcile/terraform_init/merge_request.py +57 -0
  419. reconcile/terraform_init/merge_request_manager.py +102 -0
  420. reconcile/terraform_repo.py +403 -0
  421. reconcile/terraform_resources.py +266 -168
  422. reconcile/terraform_tgw_attachments.py +417 -167
  423. reconcile/terraform_users.py +40 -17
  424. reconcile/terraform_vpc_peerings.py +310 -142
  425. reconcile/terraform_vpc_resources/__init__.py +0 -0
  426. reconcile/terraform_vpc_resources/integration.py +220 -0
  427. reconcile/terraform_vpc_resources/merge_request.py +57 -0
  428. reconcile/terraform_vpc_resources/merge_request_manager.py +107 -0
  429. reconcile/typed_queries/alerting_services_settings.py +1 -2
  430. reconcile/typed_queries/app_interface_custom_messages.py +24 -0
  431. reconcile/typed_queries/app_interface_deadmanssnitch_settings.py +17 -0
  432. reconcile/typed_queries/app_interface_metrics_exporter/__init__.py +0 -0
  433. reconcile/typed_queries/app_interface_metrics_exporter/onboarding_status.py +13 -0
  434. reconcile/typed_queries/app_interface_repo_url.py +1 -2
  435. reconcile/typed_queries/app_interface_state_settings.py +1 -3
  436. reconcile/typed_queries/app_interface_vault_settings.py +1 -2
  437. reconcile/typed_queries/app_quay_repos_escalation_policies.py +14 -0
  438. reconcile/typed_queries/apps.py +11 -0
  439. reconcile/typed_queries/aws_vpc_requests.py +9 -0
  440. reconcile/typed_queries/aws_vpcs.py +12 -0
  441. reconcile/typed_queries/cloudflare.py +10 -0
  442. reconcile/typed_queries/clusters.py +7 -5
  443. reconcile/typed_queries/clusters_minimal.py +6 -5
  444. reconcile/typed_queries/clusters_with_dms.py +16 -0
  445. reconcile/typed_queries/cost_report/__init__.py +0 -0
  446. reconcile/typed_queries/cost_report/app_names.py +22 -0
  447. reconcile/typed_queries/cost_report/cost_namespaces.py +43 -0
  448. reconcile/typed_queries/cost_report/settings.py +15 -0
  449. reconcile/typed_queries/dynatrace.py +10 -0
  450. reconcile/typed_queries/dynatrace_environments.py +14 -0
  451. reconcile/typed_queries/dynatrace_token_provider_token_specs.py +14 -0
  452. reconcile/typed_queries/external_resources.py +46 -0
  453. reconcile/typed_queries/get_state_aws_account.py +20 -0
  454. reconcile/typed_queries/glitchtip.py +10 -0
  455. reconcile/typed_queries/jenkins.py +25 -0
  456. reconcile/typed_queries/jira.py +7 -0
  457. reconcile/typed_queries/jira_settings.py +16 -0
  458. reconcile/typed_queries/jiralert_settings.py +22 -0
  459. reconcile/typed_queries/ocm.py +8 -0
  460. reconcile/typed_queries/pagerduty_instances.py +2 -7
  461. reconcile/typed_queries/quay.py +23 -0
  462. reconcile/typed_queries/repos.py +20 -8
  463. reconcile/typed_queries/reserved_networks.py +12 -0
  464. reconcile/typed_queries/saas_files.py +221 -167
  465. reconcile/typed_queries/slack.py +7 -0
  466. reconcile/typed_queries/slo_documents.py +12 -0
  467. reconcile/typed_queries/status_board.py +58 -0
  468. reconcile/typed_queries/tekton_pipeline_providers.py +1 -2
  469. reconcile/typed_queries/terraform_namespaces.py +1 -2
  470. reconcile/typed_queries/terraform_tgw_attachments/__init__.py +0 -0
  471. reconcile/typed_queries/terraform_tgw_attachments/aws_accounts.py +16 -0
  472. reconcile/typed_queries/unleash.py +10 -0
  473. reconcile/typed_queries/users.py +11 -0
  474. reconcile/typed_queries/vault.py +10 -0
  475. reconcile/unleash_feature_toggles/__init__.py +0 -0
  476. reconcile/unleash_feature_toggles/integration.py +287 -0
  477. reconcile/utils/acs/__init__.py +0 -0
  478. reconcile/utils/acs/base.py +81 -0
  479. reconcile/utils/acs/notifiers.py +143 -0
  480. reconcile/utils/acs/policies.py +163 -0
  481. reconcile/utils/acs/rbac.py +277 -0
  482. reconcile/utils/aggregated_list.py +11 -9
  483. reconcile/utils/amtool.py +6 -4
  484. reconcile/utils/aws_api.py +279 -66
  485. reconcile/utils/aws_api_typed/__init__.py +0 -0
  486. reconcile/utils/aws_api_typed/account.py +23 -0
  487. reconcile/utils/aws_api_typed/api.py +273 -0
  488. reconcile/utils/aws_api_typed/dynamodb.py +16 -0
  489. reconcile/utils/aws_api_typed/iam.py +67 -0
  490. reconcile/utils/aws_api_typed/organization.py +152 -0
  491. reconcile/utils/aws_api_typed/s3.py +26 -0
  492. reconcile/utils/aws_api_typed/service_quotas.py +79 -0
  493. reconcile/utils/aws_api_typed/sts.py +36 -0
  494. reconcile/utils/aws_api_typed/support.py +79 -0
  495. reconcile/utils/aws_helper.py +42 -3
  496. reconcile/utils/batches.py +11 -0
  497. reconcile/utils/binary.py +7 -9
  498. reconcile/utils/cloud_resource_best_practice/__init__.py +0 -0
  499. reconcile/utils/cloud_resource_best_practice/aws_rds.py +66 -0
  500. reconcile/utils/clusterhealth/__init__.py +0 -0
  501. reconcile/utils/clusterhealth/providerbase.py +39 -0
  502. reconcile/utils/clusterhealth/telemeter.py +39 -0
  503. reconcile/utils/config.py +3 -4
  504. reconcile/utils/deadmanssnitch_api.py +86 -0
  505. reconcile/utils/differ.py +205 -0
  506. reconcile/utils/disabled_integrations.py +4 -6
  507. reconcile/utils/dynatrace/__init__.py +0 -0
  508. reconcile/utils/dynatrace/client.py +93 -0
  509. reconcile/utils/early_exit_cache.py +289 -0
  510. reconcile/utils/elasticsearch_exceptions.py +5 -0
  511. reconcile/utils/environ.py +2 -2
  512. reconcile/utils/exceptions.py +4 -0
  513. reconcile/utils/expiration.py +4 -8
  514. reconcile/utils/extended_early_exit.py +210 -0
  515. reconcile/utils/external_resource_spec.py +34 -12
  516. reconcile/utils/external_resources.py +48 -20
  517. reconcile/utils/filtering.py +16 -0
  518. reconcile/utils/git.py +49 -16
  519. reconcile/utils/github_api.py +10 -9
  520. reconcile/utils/gitlab_api.py +333 -190
  521. reconcile/utils/glitchtip/client.py +97 -100
  522. reconcile/utils/glitchtip/models.py +89 -11
  523. reconcile/utils/gql.py +157 -58
  524. reconcile/utils/grouping.py +17 -0
  525. reconcile/utils/helm.py +89 -18
  526. reconcile/utils/helpers.py +51 -0
  527. reconcile/utils/imap_client.py +5 -6
  528. reconcile/utils/internal_groups/__init__.py +0 -0
  529. reconcile/utils/internal_groups/client.py +160 -0
  530. reconcile/utils/internal_groups/models.py +71 -0
  531. reconcile/utils/jenkins_api.py +10 -34
  532. reconcile/utils/jinja2/__init__.py +0 -0
  533. reconcile/utils/{jinja2_ext.py → jinja2/extensions.py} +6 -4
  534. reconcile/utils/jinja2/filters.py +142 -0
  535. reconcile/utils/jinja2/utils.py +278 -0
  536. reconcile/utils/jira_client.py +165 -8
  537. reconcile/utils/jjb_client.py +47 -35
  538. reconcile/utils/jobcontroller/__init__.py +0 -0
  539. reconcile/utils/jobcontroller/controller.py +413 -0
  540. reconcile/utils/jobcontroller/models.py +195 -0
  541. reconcile/utils/jsonpath.py +4 -5
  542. reconcile/utils/jump_host.py +13 -12
  543. reconcile/utils/keycloak.py +106 -0
  544. reconcile/utils/ldap_client.py +35 -6
  545. reconcile/utils/lean_terraform_client.py +115 -6
  546. reconcile/utils/membershipsources/__init__.py +0 -0
  547. reconcile/utils/membershipsources/app_interface_resolver.py +60 -0
  548. reconcile/utils/membershipsources/models.py +91 -0
  549. reconcile/utils/membershipsources/resolver.py +110 -0
  550. reconcile/utils/merge_request_manager/__init__.py +0 -0
  551. reconcile/utils/merge_request_manager/merge_request_manager.py +99 -0
  552. reconcile/utils/merge_request_manager/parser.py +67 -0
  553. reconcile/utils/metrics.py +511 -1
  554. reconcile/utils/models.py +123 -0
  555. reconcile/utils/mr/README.md +198 -0
  556. reconcile/utils/mr/__init__.py +14 -10
  557. reconcile/utils/mr/app_interface_reporter.py +2 -2
  558. reconcile/utils/mr/aws_access.py +4 -4
  559. reconcile/utils/mr/base.py +51 -31
  560. reconcile/utils/mr/clusters_updates.py +10 -7
  561. reconcile/utils/mr/glitchtip_access_reporter.py +2 -4
  562. reconcile/utils/mr/labels.py +14 -1
  563. reconcile/utils/mr/notificator.py +1 -3
  564. reconcile/utils/mr/ocm_update_recommended_version.py +1 -2
  565. reconcile/utils/mr/ocm_upgrade_scheduler_org_updates.py +7 -3
  566. reconcile/utils/mr/promote_qontract.py +203 -0
  567. reconcile/utils/mr/user_maintenance.py +24 -4
  568. reconcile/utils/oauth2_backend_application_session.py +132 -0
  569. reconcile/utils/oc.py +194 -170
  570. reconcile/utils/oc_connection_parameters.py +40 -51
  571. reconcile/utils/oc_filters.py +11 -13
  572. reconcile/utils/oc_map.py +14 -35
  573. reconcile/utils/ocm/__init__.py +30 -1
  574. reconcile/utils/ocm/addons.py +228 -0
  575. reconcile/utils/ocm/base.py +618 -5
  576. reconcile/utils/ocm/cluster_groups.py +5 -56
  577. reconcile/utils/ocm/clusters.py +111 -99
  578. reconcile/utils/ocm/identity_providers.py +66 -0
  579. reconcile/utils/ocm/label_sources.py +75 -0
  580. reconcile/utils/ocm/labels.py +139 -54
  581. reconcile/utils/ocm/manifests.py +39 -0
  582. reconcile/utils/ocm/ocm.py +182 -928
  583. reconcile/utils/ocm/products.py +758 -0
  584. reconcile/utils/ocm/search_filters.py +20 -28
  585. reconcile/utils/ocm/service_log.py +32 -79
  586. reconcile/utils/ocm/sre_capability_labels.py +51 -0
  587. reconcile/utils/ocm/status_board.py +66 -0
  588. reconcile/utils/ocm/subscriptions.py +49 -59
  589. reconcile/utils/ocm/syncsets.py +39 -0
  590. reconcile/utils/ocm/upgrades.py +181 -0
  591. reconcile/utils/ocm_base_client.py +71 -36
  592. reconcile/utils/openshift_resource.py +113 -67
  593. reconcile/utils/output.py +18 -11
  594. reconcile/utils/pagerduty_api.py +16 -10
  595. reconcile/utils/parse_dhms_duration.py +13 -1
  596. reconcile/utils/prometheus.py +123 -0
  597. reconcile/utils/promotion_state.py +56 -19
  598. reconcile/utils/promtool.py +5 -8
  599. reconcile/utils/quay_api.py +13 -25
  600. reconcile/utils/raw_github_api.py +3 -5
  601. reconcile/utils/repo_owners.py +2 -8
  602. reconcile/utils/rest_api_base.py +126 -0
  603. reconcile/utils/rosa/__init__.py +0 -0
  604. reconcile/utils/rosa/rosa_cli.py +310 -0
  605. reconcile/utils/rosa/session.py +201 -0
  606. reconcile/utils/ruamel.py +16 -0
  607. reconcile/utils/runtime/__init__.py +0 -1
  608. reconcile/utils/runtime/desired_state_diff.py +9 -20
  609. reconcile/utils/runtime/environment.py +33 -8
  610. reconcile/utils/runtime/integration.py +28 -12
  611. reconcile/utils/runtime/meta.py +1 -3
  612. reconcile/utils/runtime/runner.py +8 -11
  613. reconcile/utils/runtime/sharding.py +93 -36
  614. reconcile/utils/saasherder/__init__.py +1 -1
  615. reconcile/utils/saasherder/interfaces.py +143 -138
  616. reconcile/utils/saasherder/models.py +201 -43
  617. reconcile/utils/saasherder/saasherder.py +508 -378
  618. reconcile/utils/secret_reader.py +22 -27
  619. reconcile/utils/semver_helper.py +15 -1
  620. reconcile/utils/slack_api.py +124 -36
  621. reconcile/utils/smtp_client.py +1 -2
  622. reconcile/utils/sqs_gateway.py +10 -6
  623. reconcile/utils/state.py +276 -127
  624. reconcile/utils/terraform/config_client.py +6 -7
  625. reconcile/utils/terraform_client.py +284 -125
  626. reconcile/utils/terrascript/cloudflare_client.py +38 -17
  627. reconcile/utils/terrascript/cloudflare_resources.py +67 -18
  628. reconcile/utils/terrascript/models.py +2 -3
  629. reconcile/utils/terrascript/resources.py +1 -2
  630. reconcile/utils/terrascript_aws_client.py +1292 -540
  631. reconcile/utils/three_way_diff_strategy.py +157 -0
  632. reconcile/utils/unleash/__init__.py +11 -0
  633. reconcile/utils/{unleash.py → unleash/client.py} +35 -29
  634. reconcile/utils/unleash/server.py +145 -0
  635. reconcile/utils/vault.py +42 -32
  636. reconcile/utils/vaultsecretref.py +2 -4
  637. reconcile/utils/vcs.py +250 -0
  638. reconcile/vault_replication.py +38 -31
  639. reconcile/vpc_peerings_validator.py +82 -13
  640. tools/app_interface_metrics_exporter.py +70 -0
  641. tools/app_interface_reporter.py +44 -157
  642. tools/cli_commands/container_images_report.py +154 -0
  643. tools/cli_commands/cost_report/__init__.py +0 -0
  644. tools/cli_commands/cost_report/aws.py +137 -0
  645. tools/cli_commands/cost_report/cost_management_api.py +155 -0
  646. tools/cli_commands/cost_report/model.py +49 -0
  647. tools/cli_commands/cost_report/openshift.py +166 -0
  648. tools/cli_commands/cost_report/openshift_cost_optimization.py +187 -0
  649. tools/cli_commands/cost_report/response.py +124 -0
  650. tools/cli_commands/cost_report/util.py +72 -0
  651. tools/cli_commands/cost_report/view.py +524 -0
  652. tools/cli_commands/erv2.py +620 -0
  653. tools/cli_commands/gpg_encrypt.py +5 -8
  654. tools/cli_commands/systems_and_tools.py +489 -0
  655. tools/glitchtip_access_revalidation.py +1 -1
  656. tools/qontract_cli.py +2301 -673
  657. tools/saas_metrics_exporter/__init__.py +0 -0
  658. tools/saas_metrics_exporter/commit_distance/__init__.py +0 -0
  659. tools/saas_metrics_exporter/commit_distance/channel.py +63 -0
  660. tools/saas_metrics_exporter/commit_distance/commit_distance.py +103 -0
  661. tools/saas_metrics_exporter/commit_distance/metrics.py +19 -0
  662. tools/saas_metrics_exporter/main.py +99 -0
  663. tools/saas_promotion_state/__init__.py +0 -0
  664. tools/saas_promotion_state/saas_promotion_state.py +105 -0
  665. tools/sd_app_sre_alert_report.py +145 -0
  666. tools/template_validation.py +107 -0
  667. e2e_tests/cli.py +0 -83
  668. e2e_tests/create_namespace.py +0 -43
  669. e2e_tests/dedicated_admin_rolebindings.py +0 -44
  670. e2e_tests/dedicated_admin_test_base.py +0 -39
  671. e2e_tests/default_network_policies.py +0 -47
  672. e2e_tests/default_project_labels.py +0 -52
  673. e2e_tests/network_policy_test_base.py +0 -17
  674. e2e_tests/test_base.py +0 -56
  675. qontract_reconcile-0.10.0.dist-info/LICENSE +0 -201
  676. qontract_reconcile-0.10.0.dist-info/METADATA +0 -63
  677. qontract_reconcile-0.10.0.dist-info/RECORD +0 -586
  678. qontract_reconcile-0.10.0.dist-info/top_level.txt +0 -4
  679. reconcile/ecr_mirror.py +0 -152
  680. reconcile/github_scanner.py +0 -74
  681. reconcile/gitlab_integrations.py +0 -63
  682. reconcile/gql_definitions/ocm_oidc_idp/clusters.py +0 -195
  683. reconcile/gql_definitions/ocp_release_mirror/ocp_release_mirror.py +0 -287
  684. reconcile/integrations_validator.py +0 -18
  685. reconcile/jenkins_plugins.py +0 -129
  686. reconcile/kafka_clusters.py +0 -208
  687. reconcile/ocm_cluster_admin.py +0 -42
  688. reconcile/ocm_oidc_idp.py +0 -198
  689. reconcile/ocp_release_mirror.py +0 -373
  690. reconcile/prometheus_rules_tester_old.py +0 -436
  691. reconcile/saas_auto_promotions_manager/merge_request_manager/merge_request_manager.py +0 -279
  692. reconcile/saas_auto_promotions_manager/utils/vcs.py +0 -141
  693. reconcile/sentry_config.py +0 -613
  694. reconcile/sentry_helper.py +0 -69
  695. reconcile/test/conftest.py +0 -187
  696. reconcile/test/fixtures.py +0 -24
  697. reconcile/test/saas_auto_promotions_manager/conftest.py +0 -69
  698. reconcile/test/saas_auto_promotions_manager/merge_request_manager/merge_request_manager/conftest.py +0 -110
  699. reconcile/test/saas_auto_promotions_manager/merge_request_manager/merge_request_manager/data_keys.py +0 -10
  700. reconcile/test/saas_auto_promotions_manager/merge_request_manager/merge_request_manager/test_housekeeping.py +0 -200
  701. reconcile/test/saas_auto_promotions_manager/merge_request_manager/merge_request_manager/test_merge_request_manager.py +0 -151
  702. reconcile/test/saas_auto_promotions_manager/merge_request_manager/renderer/conftest.py +0 -63
  703. reconcile/test/saas_auto_promotions_manager/merge_request_manager/renderer/data_keys.py +0 -4
  704. reconcile/test/saas_auto_promotions_manager/merge_request_manager/renderer/test_content_multiple_namespaces.py +0 -46
  705. reconcile/test/saas_auto_promotions_manager/merge_request_manager/renderer/test_content_single_namespace.py +0 -94
  706. reconcile/test/saas_auto_promotions_manager/merge_request_manager/renderer/test_content_single_target.py +0 -44
  707. reconcile/test/saas_auto_promotions_manager/subscriber/conftest.py +0 -74
  708. reconcile/test/saas_auto_promotions_manager/subscriber/data_keys.py +0 -11
  709. reconcile/test/saas_auto_promotions_manager/subscriber/test_content_hash.py +0 -155
  710. reconcile/test/saas_auto_promotions_manager/subscriber/test_diff.py +0 -173
  711. reconcile/test/saas_auto_promotions_manager/subscriber/test_multiple_channels_config_hash.py +0 -226
  712. reconcile/test/saas_auto_promotions_manager/subscriber/test_multiple_channels_moving_ref.py +0 -224
  713. reconcile/test/saas_auto_promotions_manager/subscriber/test_single_channel_with_single_publisher.py +0 -350
  714. reconcile/test/saas_auto_promotions_manager/test_integration_test.py +0 -129
  715. reconcile/test/saas_auto_promotions_manager/utils/saas_files_inventory/test_multiple_publishers_for_single_channel.py +0 -70
  716. reconcile/test/saas_auto_promotions_manager/utils/saas_files_inventory/test_saas_files_use_target_config_hash.py +0 -63
  717. reconcile/test/saas_auto_promotions_manager/utils/saas_files_inventory/test_saas_files_with_auto_promote.py +0 -74
  718. reconcile/test/saas_auto_promotions_manager/utils/saas_files_inventory/test_saas_files_without_auto_promote.py +0 -65
  719. reconcile/test/test_aggregated_list.py +0 -237
  720. reconcile/test/test_amtool.py +0 -37
  721. reconcile/test/test_auto_promoter.py +0 -295
  722. reconcile/test/test_aws_ami_share.py +0 -68
  723. reconcile/test/test_aws_iam_keys.py +0 -70
  724. reconcile/test/test_aws_iam_password_reset.py +0 -35
  725. reconcile/test/test_aws_support_cases_sos.py +0 -23
  726. reconcile/test/test_checkpoint.py +0 -178
  727. reconcile/test/test_cli.py +0 -41
  728. reconcile/test/test_closedbox_endpoint_monitoring.py +0 -207
  729. reconcile/test/test_gabi_authorized_users.py +0 -72
  730. reconcile/test/test_github_org.py +0 -154
  731. reconcile/test/test_github_repo_invites.py +0 -123
  732. reconcile/test/test_gitlab_housekeeping.py +0 -88
  733. reconcile/test/test_gitlab_labeler.py +0 -129
  734. reconcile/test/test_gitlab_members.py +0 -283
  735. reconcile/test/test_instrumented_wrappers.py +0 -18
  736. reconcile/test/test_integrations_manager.py +0 -995
  737. reconcile/test/test_jenkins_worker_fleets.py +0 -55
  738. reconcile/test/test_jump_host.py +0 -117
  739. reconcile/test/test_ldap_users.py +0 -123
  740. reconcile/test/test_make.py +0 -28
  741. reconcile/test/test_ocm_additional_routers.py +0 -134
  742. reconcile/test/test_ocm_addons_upgrade_scheduler_org.py +0 -149
  743. reconcile/test/test_ocm_clusters.py +0 -598
  744. reconcile/test/test_ocm_clusters_manifest_updates.py +0 -89
  745. reconcile/test/test_ocm_oidc_idp.py +0 -315
  746. reconcile/test/test_ocm_update_recommended_version.py +0 -145
  747. reconcile/test/test_ocm_upgrade_scheduler.py +0 -614
  748. reconcile/test/test_ocm_upgrade_scheduler_org_updater.py +0 -129
  749. reconcile/test/test_openshift_base.py +0 -730
  750. reconcile/test/test_openshift_namespace_labels.py +0 -345
  751. reconcile/test/test_openshift_namespaces.py +0 -256
  752. reconcile/test/test_openshift_resource.py +0 -415
  753. reconcile/test/test_openshift_resources_base.py +0 -440
  754. reconcile/test/test_openshift_saas_deploy_change_tester.py +0 -310
  755. reconcile/test/test_openshift_tekton_resources.py +0 -253
  756. reconcile/test/test_openshift_upgrade_watcher.py +0 -146
  757. reconcile/test/test_prometheus_rules_tester.py +0 -151
  758. reconcile/test/test_prometheus_rules_tester_old.py +0 -77
  759. reconcile/test/test_quay_membership.py +0 -86
  760. reconcile/test/test_quay_mirror.py +0 -109
  761. reconcile/test/test_quay_mirror_org.py +0 -70
  762. reconcile/test/test_quay_repos.py +0 -59
  763. reconcile/test/test_queries.py +0 -53
  764. reconcile/test/test_repo_owners.py +0 -47
  765. reconcile/test/test_requests_sender.py +0 -139
  766. reconcile/test/test_saasherder.py +0 -1074
  767. reconcile/test/test_saasherder_allowed_secret_paths.py +0 -127
  768. reconcile/test/test_secret_reader.py +0 -153
  769. reconcile/test/test_slack_base.py +0 -185
  770. reconcile/test/test_slack_usergroups.py +0 -744
  771. reconcile/test/test_sql_query.py +0 -19
  772. reconcile/test/test_terraform_cloudflare_dns.py +0 -117
  773. reconcile/test/test_terraform_cloudflare_resources.py +0 -106
  774. reconcile/test/test_terraform_cloudflare_users.py +0 -749
  775. reconcile/test/test_terraform_resources.py +0 -257
  776. reconcile/test/test_terraform_tgw_attachments.py +0 -631
  777. reconcile/test/test_terraform_users.py +0 -57
  778. reconcile/test/test_terraform_vpc_peerings.py +0 -499
  779. reconcile/test/test_terraform_vpc_peerings_build_desired_state.py +0 -1061
  780. reconcile/test/test_unleash.py +0 -138
  781. reconcile/test/test_utils_aws_api.py +0 -240
  782. reconcile/test/test_utils_aws_helper.py +0 -80
  783. reconcile/test/test_utils_cluster_version_data.py +0 -177
  784. reconcile/test/test_utils_data_structures.py +0 -13
  785. reconcile/test/test_utils_disabled_integrations.py +0 -86
  786. reconcile/test/test_utils_expiration.py +0 -109
  787. reconcile/test/test_utils_external_resource_spec.py +0 -383
  788. reconcile/test/test_utils_external_resources.py +0 -247
  789. reconcile/test/test_utils_github_api.py +0 -73
  790. reconcile/test/test_utils_gitlab_api.py +0 -20
  791. reconcile/test/test_utils_gpg.py +0 -69
  792. reconcile/test/test_utils_gql.py +0 -81
  793. reconcile/test/test_utils_helm.py +0 -306
  794. reconcile/test/test_utils_helpers.py +0 -55
  795. reconcile/test/test_utils_imap_client.py +0 -65
  796. reconcile/test/test_utils_jjb_client.py +0 -52
  797. reconcile/test/test_utils_jsonpath.py +0 -286
  798. reconcile/test/test_utils_ldap_client.py +0 -51
  799. reconcile/test/test_utils_mr.py +0 -226
  800. reconcile/test/test_utils_mr_clusters_updates.py +0 -77
  801. reconcile/test/test_utils_oc.py +0 -984
  802. reconcile/test/test_utils_ocm.py +0 -110
  803. reconcile/test/test_utils_pagerduty_api.py +0 -251
  804. reconcile/test/test_utils_parse_dhms_duration.py +0 -34
  805. reconcile/test/test_utils_password_validator.py +0 -155
  806. reconcile/test/test_utils_quay_api.py +0 -86
  807. reconcile/test/test_utils_semver_helper.py +0 -19
  808. reconcile/test/test_utils_sharding.py +0 -56
  809. reconcile/test/test_utils_slack_api.py +0 -439
  810. reconcile/test/test_utils_smtp_client.py +0 -73
  811. reconcile/test/test_utils_state.py +0 -256
  812. reconcile/test/test_utils_terraform.py +0 -13
  813. reconcile/test/test_utils_terraform_client.py +0 -585
  814. reconcile/test/test_utils_terraform_config_client.py +0 -219
  815. reconcile/test/test_utils_terrascript_aws_client.py +0 -277
  816. reconcile/test/test_utils_terrascript_cloudflare_client.py +0 -597
  817. reconcile/test/test_utils_terrascript_cloudflare_resources.py +0 -26
  818. reconcile/test/test_vault_replication.py +0 -515
  819. reconcile/test/test_vault_utils.py +0 -47
  820. reconcile/test/test_version_bump.py +0 -18
  821. reconcile/test/test_vpc_peerings_validator.py +0 -103
  822. reconcile/test/test_wrong_region.py +0 -78
  823. reconcile/typed_queries/glitchtip_settings.py +0 -18
  824. reconcile/typed_queries/ocp_release_mirror.py +0 -11
  825. reconcile/unleash_watcher.py +0 -120
  826. reconcile/utils/git_secrets.py +0 -63
  827. reconcile/utils/mr/auto_promoter.py +0 -218
  828. reconcile/utils/sentry_client.py +0 -383
  829. release/test_version.py +0 -50
  830. release/version.py +0 -100
  831. tools/test/test_qontract_cli.py +0 -60
  832. tools/test/test_sre_checkpoints.py +0 -79
  833. /e2e_tests/__init__.py → /reconcile/aus/upgrades.py +0 -0
  834. /reconcile/{gql_definitions/ocp_release_mirror → aws_account_manager}/__init__.py +0 -0
  835. /reconcile/{test → aws_ami_cleanup}/__init__.py +0 -0
  836. /reconcile/{test/saas_auto_promotions_manager → aws_cloudwatch_log_retention}/__init__.py +0 -0
  837. /reconcile/{test/saas_auto_promotions_manager/merge_request_manager → aws_saml_idp}/__init__.py +0 -0
  838. /reconcile/{test/saas_auto_promotions_manager/merge_request_manager/merge_request_manager → aws_saml_roles}/__init__.py +0 -0
  839. /reconcile/{test/saas_auto_promotions_manager/merge_request_manager/renderer → aws_version_sync}/__init__.py +0 -0
  840. /reconcile/{test/saas_auto_promotions_manager/subscriber → aws_version_sync/merge_request_manager}/__init__.py +0 -0
  841. /reconcile/{test/saas_auto_promotions_manager/utils → cluster_auth_rhidp}/__init__.py +0 -0
  842. /reconcile/{test/saas_auto_promotions_manager/utils/saas_files_inventory → dynatrace_token_provider}/__init__.py +0 -0
  843. {release → reconcile/endpoints_discovery}/__init__.py +0 -0
  844. {tools/test → reconcile/external_resources}/__init__.py +0 -0
@@ -0,0 +1,258 @@
1
+ import logging
2
+ from collections.abc import Mapping
3
+ from datetime import UTC, datetime
4
+ from enum import StrEnum
5
+ from typing import Any
6
+
7
+ from pydantic import BaseModel
8
+
9
+ from reconcile.external_resources.model import (
10
+ ExternalResourceKey,
11
+ ExternalResourceModuleConfiguration,
12
+ Reconciliation,
13
+ ReconciliationStatus,
14
+ ResourceStatus,
15
+ )
16
+ from reconcile.utils.aws_api_typed.api import AWSApi
17
+
18
+ DATE_FORMAT = "%Y-%m-%dT%H:%M:%SZ"
19
+
20
+
21
+ class StateNotFoundError(Exception):
22
+ pass
23
+
24
+
25
+ class ReconcileStatus(StrEnum):
26
+ SUCCESS: str = "SUCCESS"
27
+ ERROR: str = "ERROR"
28
+ IN_PROGRESS: str = "IN_PROGRESS"
29
+ NOT_EXISTS: str = "NOT_EXISTS"
30
+
31
+
32
+ class ExternalResourceState(BaseModel):
33
+ key: ExternalResourceKey
34
+ ts: datetime
35
+ resource_status: ResourceStatus
36
+ reconciliation: Reconciliation
37
+
38
+ def update_resource_status(
39
+ self, reconciliation_status: ReconciliationStatus
40
+ ) -> None:
41
+ if self.reconciliation_needs_state_update(reconciliation_status):
42
+ self.ts = datetime.now()
43
+ self.resource_status = reconciliation_status.resource_status
44
+
45
+ def reconciliation_needs_state_update(
46
+ self, reconciliation_status: ReconciliationStatus
47
+ ) -> bool:
48
+ return (
49
+ self.resource_status.is_in_progress or self.resource_status.does_not_exist
50
+ ) and not reconciliation_status.resource_status.is_in_progress
51
+
52
+
53
+ class DynamoDBStateAdapter:
54
+ # Table PK
55
+ ER_KEY_HASH = "external_resource_key_hash"
56
+
57
+ RESOURCE_STATUS = "resource_status"
58
+ TIMESTAMP = "time_stamp"
59
+
60
+ ER_KEY = "external_resource_key"
61
+ ER_KEY_PROVISION_PROVIDER = "provision_provider"
62
+ ER_KEY_PROVISIONER_NAME = "provisioner_name"
63
+ ER_KEY_PROVIDER = "provider"
64
+ ER_KEY_IDENTIFIER = "identifier"
65
+
66
+ RECONC = "reconciliation"
67
+ RECONC_RESOURCE_HASH = "resource_hash"
68
+ RECONC_INPUT = "input"
69
+ RECONC_ACTION = "action"
70
+
71
+ MODCONF = "module_configuration"
72
+ MODCONF_IMAGE = "image"
73
+ MODCONF_VERSION = "version"
74
+ MODCONF_DRIFT_MINS = "drift_detection_minutes"
75
+ MODCONF_TIMEOUT_MINS = "timeout_minutes"
76
+
77
+ def _get_value(self, item: Mapping[str, Any], key: str, _type: str = "S") -> Any:
78
+ return item[key][_type]
79
+
80
+ def deserialize(
81
+ self,
82
+ item: Mapping[str, Any],
83
+ partial_data: bool = False,
84
+ ) -> ExternalResourceState:
85
+ _key = self._get_value(item, self.ER_KEY, _type="M")
86
+ key = ExternalResourceKey(
87
+ provision_provider=self._get_value(_key, self.ER_KEY_PROVISION_PROVIDER),
88
+ provisioner_name=self._get_value(_key, self.ER_KEY_PROVISIONER_NAME),
89
+ provider=self._get_value(_key, self.ER_KEY_PROVIDER),
90
+ identifier=self._get_value(_key, self.ER_KEY_IDENTIFIER),
91
+ )
92
+ _reconciliation = self._get_value(item, self.RECONC, _type="M")
93
+
94
+ if partial_data:
95
+ r = Reconciliation(
96
+ key=key,
97
+ resource_hash=self._get_value(
98
+ _reconciliation, self.RECONC_RESOURCE_HASH
99
+ ),
100
+ )
101
+ else:
102
+ _modconf = self._get_value(_reconciliation, self.MODCONF, _type="M")
103
+ r = Reconciliation(
104
+ key=key,
105
+ resource_hash=self._get_value(
106
+ _reconciliation, self.RECONC_RESOURCE_HASH
107
+ ),
108
+ input=self._get_value(_reconciliation, self.RECONC_INPUT),
109
+ action=self._get_value(_reconciliation, self.RECONC_ACTION),
110
+ module_configuration=ExternalResourceModuleConfiguration(
111
+ image=self._get_value(_modconf, self.MODCONF_IMAGE),
112
+ version=self._get_value(_modconf, self.MODCONF_VERSION),
113
+ reconcile_drift_interval_minutes=self._get_value(
114
+ _modconf, self.MODCONF_DRIFT_MINS, _type="N"
115
+ ),
116
+ reconcile_timeout_minutes=self._get_value(
117
+ _modconf, self.MODCONF_TIMEOUT_MINS, _type="N"
118
+ ),
119
+ ),
120
+ )
121
+
122
+ return ExternalResourceState(
123
+ key=key,
124
+ ts=self._get_value(item, self.TIMESTAMP),
125
+ resource_status=self._get_value(item, self.RESOURCE_STATUS),
126
+ reconciliation=r,
127
+ )
128
+
129
+ def serialize(self, state: ExternalResourceState) -> dict[str, Any]:
130
+ return {
131
+ self.ER_KEY_HASH: {"S": state.key.hash()},
132
+ self.TIMESTAMP: {"S": state.ts.isoformat()},
133
+ self.RESOURCE_STATUS: {"S": state.resource_status.value},
134
+ self.ER_KEY: {
135
+ "M": {
136
+ self.ER_KEY_PROVISION_PROVIDER: {"S": state.key.provision_provider},
137
+ self.ER_KEY_PROVISIONER_NAME: {"S": state.key.provisioner_name},
138
+ self.ER_KEY_PROVIDER: {"S": state.key.provider},
139
+ self.ER_KEY_IDENTIFIER: {"S": state.key.identifier},
140
+ }
141
+ },
142
+ self.RECONC: {
143
+ "M": {
144
+ self.RECONC_RESOURCE_HASH: {
145
+ "S": state.reconciliation.resource_hash
146
+ },
147
+ self.RECONC_ACTION: {"S": state.reconciliation.action.value},
148
+ self.RECONC_INPUT: {"S": state.reconciliation.input},
149
+ self.MODCONF: {
150
+ "M": {
151
+ self.MODCONF_IMAGE: {
152
+ "S": state.reconciliation.module_configuration.image
153
+ },
154
+ self.MODCONF_VERSION: {
155
+ "S": state.reconciliation.module_configuration.version
156
+ },
157
+ self.MODCONF_DRIFT_MINS: {
158
+ "N": str(
159
+ state.reconciliation.module_configuration.reconcile_drift_interval_minutes
160
+ )
161
+ },
162
+ self.MODCONF_TIMEOUT_MINS: {
163
+ "N": str(
164
+ state.reconciliation.module_configuration.reconcile_timeout_minutes
165
+ )
166
+ },
167
+ }
168
+ },
169
+ }
170
+ },
171
+ }
172
+
173
+
174
+ class ExternalResourcesStateDynamoDB:
175
+ PARTIALS_PROJECTED_VALUES = ",".join([
176
+ DynamoDBStateAdapter.ER_KEY,
177
+ DynamoDBStateAdapter.TIMESTAMP,
178
+ DynamoDBStateAdapter.RESOURCE_STATUS,
179
+ f"{DynamoDBStateAdapter.RECONC}.{DynamoDBStateAdapter.RECONC_RESOURCE_HASH}",
180
+ ])
181
+
182
+ def __init__(self, aws_api: AWSApi, table_name: str) -> None:
183
+ self.adapter = DynamoDBStateAdapter()
184
+ self.aws_api = aws_api
185
+ self._table = table_name
186
+ self.partial_resources = self._get_partial_resources()
187
+
188
+ def get_external_resource_state(
189
+ self, key: ExternalResourceKey
190
+ ) -> ExternalResourceState:
191
+ data = self.aws_api.dynamodb.boto3_client.get_item(
192
+ TableName=self._table,
193
+ ConsistentRead=True,
194
+ Key={self.adapter.ER_KEY_HASH: {"S": key.hash()}},
195
+ )
196
+ if "Item" in data:
197
+ return self.adapter.deserialize(data["Item"])
198
+ else:
199
+ return ExternalResourceState(
200
+ key=key,
201
+ ts=datetime.now(UTC),
202
+ resource_status=ResourceStatus.NOT_EXISTS,
203
+ reconciliation=Reconciliation(key=key),
204
+ reconciliation_errors=0,
205
+ )
206
+
207
+ def set_external_resource_state(
208
+ self,
209
+ state: ExternalResourceState,
210
+ ) -> None:
211
+ self.aws_api.dynamodb.boto3_client.put_item(
212
+ TableName=self._table, Item=self.adapter.serialize(state)
213
+ )
214
+
215
+ def del_external_resource_state(self, key: ExternalResourceKey) -> None:
216
+ self.aws_api.dynamodb.boto3_client.delete_item(
217
+ TableName=self._table,
218
+ Key={self.adapter.ER_KEY_HASH: {"S": key.hash()}},
219
+ )
220
+
221
+ def _get_partial_resources(
222
+ self,
223
+ ) -> dict[ExternalResourceKey, ExternalResourceState]:
224
+ """A Partial Resoure is the minimum resource data reguired
225
+ to check if a resource has been removed from the configuration.
226
+ Getting less data from DynamoDb saves money and the logic does not need it.
227
+ """
228
+ logging.debug("Getting Managed resources from DynamoDb")
229
+ partials = {}
230
+ for item in self.aws_api.dynamodb.boto3_client.scan(
231
+ TableName=self._table, ProjectionExpression=self.PARTIALS_PROJECTED_VALUES
232
+ ).get("Items", []):
233
+ s = self.adapter.deserialize(item, partial_data=True)
234
+ partials[s.key] = s
235
+ return partials
236
+
237
+ def get_all_resource_keys(self) -> set[ExternalResourceKey]:
238
+ return set(self.partial_resources)
239
+
240
+ def get_keys_by_status(
241
+ self, resource_status: ResourceStatus
242
+ ) -> set[ExternalResourceKey]:
243
+ return {
244
+ k
245
+ for k, v in self.partial_resources.items()
246
+ if v.resource_status == resource_status
247
+ }
248
+
249
+ def update_resource_status(
250
+ self, key: ExternalResourceKey, status: ResourceStatus
251
+ ) -> None:
252
+ self.aws_api.dynamodb.boto3_client.update_item(
253
+ TableName=self._table,
254
+ Key={self.adapter.ER_KEY_HASH: {"S": key.hash()}},
255
+ UpdateExpression="set resource_status=:new_value",
256
+ ExpressionAttributeValues={":new_value": {"S": status.value}},
257
+ ReturnValues="UPDATED_NEW",
258
+ )
@@ -10,16 +10,14 @@ from datetime import (
10
10
  date,
11
11
  datetime,
12
12
  )
13
- from typing import (
14
- Any,
15
- Optional,
16
- )
13
+ from typing import Any
17
14
 
18
15
  import reconcile.openshift_base as ob
19
16
  from reconcile import queries
20
17
  from reconcile.status import ExitCodes
21
18
  from reconcile.utils.aggregated_list import RunnerException
22
19
  from reconcile.utils.defer import defer
20
+ from reconcile.utils.disabled_integrations import integration_is_enabled
23
21
  from reconcile.utils.external_resources import get_external_resource_specs
24
22
  from reconcile.utils.openshift_resource import (
25
23
  OpenshiftResource,
@@ -29,7 +27,7 @@ from reconcile.utils.semver_helper import make_semver
29
27
 
30
28
  QONTRACT_INTEGRATION = "gabi-authorized-users"
31
29
  QONTRACT_INTEGRATION_VERSION = make_semver(0, 1, 0)
32
- EXPIRATION_DAYS_MAX = 90
30
+ EXPIRATION_DAYS_MAX = 365
33
31
 
34
32
 
35
33
  def construct_gabi_oc_resource(
@@ -76,6 +74,14 @@ def fetch_desired_state(
76
74
  namespace = i["namespace"]
77
75
  account = i["account"]
78
76
  identifier = i["identifier"]
77
+ cluster = namespace["cluster"]
78
+ if not integration_is_enabled(QONTRACT_INTEGRATION, cluster):
79
+ logging.debug(
80
+ f"For cluster {cluster['name']} the integration "
81
+ f"{QONTRACT_INTEGRATION} is not enabled. Skipping."
82
+ )
83
+ continue
84
+
79
85
  specs = get_external_resource_specs(namespace)
80
86
  found = False
81
87
  for spec in specs:
@@ -86,13 +92,14 @@ def fetch_desired_state(
86
92
  break
87
93
  if not found:
88
94
  raise RunnerException(
89
- f"Could not find RDS identifier {identifier} "
90
- f'for account {account} in namespace {namespace["name"]}'
95
+ f'[gabi:{g["name"]} (path: {g["path"]})] Could not find RDS identifier {identifier} '
96
+ f'for account {account} in namespace {namespace["name"]}. '
97
+ "If this is a removed read only instance, consider updating the identifier to the source replica."
91
98
  )
92
- users = get_usernames(g["users"], namespace["cluster"])
99
+ users = get_usernames(g["users"], cluster)
93
100
  resource = construct_gabi_oc_resource(g["name"], expiration_date, users)
94
101
  ri.add_desired(
95
- namespace["cluster"]["name"],
102
+ cluster["name"],
96
103
  namespace["name"],
97
104
  resource.kind,
98
105
  resource.name,
@@ -104,9 +111,9 @@ def fetch_desired_state(
104
111
  def run(
105
112
  dry_run: bool,
106
113
  thread_pool_size: int = 10,
107
- internal: Optional[bool] = None,
114
+ internal: bool | None = None,
108
115
  use_jump_host: bool = True,
109
- defer: Optional[Callable] = None,
116
+ defer: Callable | None = None,
110
117
  ) -> None:
111
118
  gabi_instances = queries.get_gabi_instances()
112
119
  if not gabi_instances:
@@ -127,6 +134,7 @@ def run(
127
134
  if defer:
128
135
  defer(oc_map.cleanup)
129
136
  fetch_desired_state(gabi_instances, ri)
137
+ ob.publish_metrics(ri, QONTRACT_INTEGRATION)
130
138
  ob.realize_data(dry_run, oc_map, ri, thread_pool_size)
131
139
 
132
140
  if ri.has_error_registered():
reconcile/gcr_mirror.py CHANGED
@@ -5,7 +5,9 @@ import re
5
5
  import tempfile
6
6
  import time
7
7
  from collections import defaultdict
8
+ from typing import Any, Self
8
9
 
10
+ import requests
9
11
  from sretoolbox.container import (
10
12
  Image,
11
13
  Skopeo,
@@ -20,10 +22,10 @@ from reconcile.utils.secret_reader import SecretReader
20
22
  _LOG = logging.getLogger(__name__)
21
23
 
22
24
  QONTRACT_INTEGRATION = "gcr-mirror"
25
+ REQUEST_TIMEOUT = 60
23
26
 
24
27
 
25
28
  class QuayMirror:
26
-
27
29
  GCR_PROJECT_CATALOG_QUERY = """
28
30
  {
29
31
  projects: gcp_projects_v1 {
@@ -71,6 +73,13 @@ class QuayMirror:
71
73
  self.secret_reader = SecretReader(settings=settings)
72
74
  self.skopeo_cli = Skopeo(dry_run)
73
75
  self.push_creds = self._get_push_creds()
76
+ self.session = requests.Session()
77
+
78
+ def __enter__(self) -> Self:
79
+ return self
80
+
81
+ def __exit__(self, exc_type: Any, exc_value: Any, traceback: Any) -> None:
82
+ self.session.close()
74
83
 
75
84
  def run(self):
76
85
  sync_tasks = self.process_sync_tasks()
@@ -104,25 +113,19 @@ class QuayMirror:
104
113
  if item["mirror"] is None:
105
114
  continue
106
115
 
107
- summary[project].append(
108
- {
109
- "name": item["name"],
110
- "mirror": item["mirror"],
111
- "server_url": server_url,
112
- }
113
- )
116
+ summary[project].append({
117
+ "name": item["name"],
118
+ "mirror": item["mirror"],
119
+ "server_url": server_url,
120
+ })
114
121
 
115
122
  return summary
116
123
 
117
124
  @staticmethod
118
125
  def sync_tag(tags, tags_exclude, candidate):
119
126
  if tags is not None:
120
- for tag in tags:
121
- if re.match(tag, candidate):
122
- return True
123
- # When tags is defined, we don't look at
124
- # tags_exclude
125
- return False
127
+ # When tags is defined, we don't look at tags_exclude
128
+ return any(re.match(tag, candidate) for tag in tags)
126
129
 
127
130
  if tags_exclude is not None:
128
131
  for tag_exclude in tags_exclude:
@@ -143,7 +146,11 @@ class QuayMirror:
143
146
  sync_tasks = defaultdict(list)
144
147
  for org, data in summary.items():
145
148
  for item in data:
146
- image = Image(f'{item["server_url"]}/{org}/{item["name"]}')
149
+ image = Image(
150
+ f'{item["server_url"]}/{org}/{item["name"]}',
151
+ session=self.session,
152
+ timeout=REQUEST_TIMEOUT,
153
+ )
147
154
 
148
155
  mirror_url = item["mirror"]["url"]
149
156
 
@@ -157,7 +164,13 @@ class QuayMirror:
157
164
  password = raw_data["token"]
158
165
  mirror_creds = f"{username}:{password}"
159
166
 
160
- image_mirror = Image(mirror_url, username=username, password=password)
167
+ image_mirror = Image(
168
+ mirror_url,
169
+ username=username,
170
+ password=password,
171
+ session=self.session,
172
+ timeout=REQUEST_TIMEOUT,
173
+ )
161
174
 
162
175
  tags = item["mirror"].get("tags")
163
176
  tags_exclude = item["mirror"].get("tagsExclude")
@@ -176,13 +189,11 @@ class QuayMirror:
176
189
  downstream,
177
190
  upstream,
178
191
  )
179
- sync_tasks[org].append(
180
- {
181
- "mirror_url": str(upstream),
182
- "mirror_creds": mirror_creds,
183
- "image_url": str(downstream),
184
- }
185
- )
192
+ sync_tasks[org].append({
193
+ "mirror_url": str(upstream),
194
+ "mirror_creds": mirror_creds,
195
+ "image_url": str(downstream),
196
+ })
186
197
  continue
187
198
 
188
199
  # Deep (slow) check only in non dry-run mode
@@ -214,13 +225,11 @@ class QuayMirror:
214
225
  _LOG.debug(
215
226
  "Image %s and mirror %s are out of sync", downstream, upstream
216
227
  )
217
- sync_tasks[org].append(
218
- {
219
- "mirror_url": str(upstream),
220
- "mirror_creds": mirror_creds,
221
- "image_url": str(downstream),
222
- }
223
- )
228
+ sync_tasks[org].append({
229
+ "mirror_url": str(upstream),
230
+ "mirror_creds": mirror_creds,
231
+ "image_url": str(downstream),
232
+ })
224
233
 
225
234
  return sync_tasks
226
235
 
@@ -228,7 +237,7 @@ class QuayMirror:
228
237
  control_file_name = "qontract-reconcile-gcr-mirror.timestamp"
229
238
  control_file_path = os.path.join(tempfile.gettempdir(), control_file_name)
230
239
  try:
231
- with open(control_file_path, "r") as file_obj:
240
+ with open(control_file_path, encoding="locale") as file_obj:
232
241
  last_deep_sync = float(file_obj.read())
233
242
  except FileNotFoundError:
234
243
  self._record_timestamp(control_file_path)
@@ -243,7 +252,7 @@ class QuayMirror:
243
252
 
244
253
  @staticmethod
245
254
  def _record_timestamp(path):
246
- with open(path, "w") as file_object:
255
+ with open(path, "w", encoding="locale") as file_object:
247
256
  file_object.write(str(time.time()))
248
257
 
249
258
  def _get_push_creds(self):
@@ -263,5 +272,5 @@ class QuayMirror:
263
272
 
264
273
 
265
274
  def run(dry_run):
266
- gcr_mirror = QuayMirror(dry_run)
267
- gcr_mirror.run()
275
+ with QuayMirror(dry_run) as gcr_mirror:
276
+ gcr_mirror.run()
reconcile/github_org.py CHANGED
@@ -128,7 +128,7 @@ def get_config(default=False):
128
128
 
129
129
  def get_default_config():
130
130
  github_config = get_config(default=True)
131
- return list(github_config["github"].values())[0]
131
+ return next(iter(github_config["github"].values()))
132
132
 
133
133
 
134
134
  @retry()
@@ -198,7 +198,7 @@ def fetch_desired_state(infer_clusters=True):
198
198
  for role in roles:
199
199
  permissions = list(
200
200
  filter(
201
- lambda p: p.get("service") in ["github-org", "github-org-team"],
201
+ lambda p: p.get("service") in {"github-org", "github-org-team"},
202
202
  role["permissions"],
203
203
  )
204
204
  )
@@ -238,7 +238,7 @@ def fetch_desired_state(infer_clusters=True):
238
238
  )
239
239
  for cluster in clusters:
240
240
  for auth in cluster["auth"]:
241
- if auth["service"] not in ["github-org", "github-org-team"]:
241
+ if auth["service"] not in {"github-org", "github-org-team"}:
242
242
  continue
243
243
 
244
244
  cluster_name = cluster["name"]
@@ -438,9 +438,7 @@ def run(dry_run):
438
438
 
439
439
  assert (
440
440
  current_orgs == desired_orgs
441
- ), "Current orgs ({}) don't match desired orgs ({})".format(
442
- current_orgs, desired_orgs
443
- )
441
+ ), f"Current orgs ({current_orgs}) don't match desired orgs ({desired_orgs})"
444
442
 
445
443
  # Calculate diff
446
444
  diff = current_state.diff(desired_state)
@@ -48,7 +48,7 @@ def fetch_desired_state():
48
48
  permissions = [
49
49
  p
50
50
  for p in role["permissions"]
51
- if p.get("service") in ["github-org", "github-org-team"]
51
+ if p.get("service") in {"github-org", "github-org-team"}
52
52
  and p.get("role") == "owner"
53
53
  ]
54
54
  if not permissions:
@@ -5,10 +5,7 @@ from collections.abc import (
5
5
  Mapping,
6
6
  )
7
7
  from dataclasses import dataclass
8
- from typing import (
9
- Any,
10
- Optional,
11
- )
8
+ from typing import Any
12
9
 
13
10
  from reconcile import queries
14
11
  from reconcile.utils import (
@@ -27,7 +24,7 @@ class CodeComponents:
27
24
 
28
25
 
29
26
  def _parse_code_components(
30
- raw: Optional[Iterable[Mapping[str, Any]]]
27
+ raw: Iterable[Mapping[str, Any]] | None,
31
28
  ) -> CodeComponents:
32
29
  urls = set()
33
30
  known_orgs = set()
@@ -1,14 +1,16 @@
1
1
  import logging
2
2
  import sys
3
3
 
4
- from gitlab import (
5
- MAINTAINER_ACCESS,
6
- GitlabGetError,
7
- )
4
+ from gitlab import GitlabGetError
5
+ from gitlab.const import MAINTAINER_ACCESS
8
6
 
9
7
  from reconcile import queries
8
+ from reconcile.typed_queries.app_interface_vault_settings import (
9
+ get_app_interface_vault_settings,
10
+ )
10
11
  from reconcile.utils.gitlab_api import GitLabApi
11
12
  from reconcile.utils.mr.labels import BLOCKED_BOT_ACCESS
13
+ from reconcile.utils.secret_reader import create_secret_reader
12
14
 
13
15
  LOG = logging.getLogger(__name__)
14
16
 
@@ -29,7 +31,6 @@ MSG_ACCESS = (
29
31
 
30
32
 
31
33
  class GitlabForkCompliance:
32
-
33
34
  OK = 0x0000
34
35
  ERR_MASTER_BRANCH = 0x0001
35
36
  ERR_NOT_A_MEMBER = 0x0002
@@ -41,10 +42,11 @@ class GitlabForkCompliance:
41
42
  self.maintainers_group = maintainers_group
42
43
 
43
44
  self.instance = queries.get_gitlab_instance()
44
- self.settings = queries.get_app_interface_settings()
45
+ vault_settings = get_app_interface_vault_settings()
46
+ self.secret_reader = create_secret_reader(use_vault=vault_settings.vault)
45
47
 
46
48
  self.gl_cli = GitLabApi(
47
- self.instance, project_id=project_id, settings=self.settings
49
+ self.instance, project_id=project_id, secret_reader=self.secret_reader
48
50
  )
49
51
  self.mr = self.gl_cli.get_merge_request(mr_id)
50
52
 
@@ -67,7 +69,7 @@ class GitlabForkCompliance:
67
69
  # who are not
68
70
  if self.maintainers_group:
69
71
  group = self.gl_cli.gl.groups.get(self.maintainers_group)
70
- maintainers = group.members.list()
72
+ maintainers = group.members.list(iterator=True)
71
73
  project_maintainers = self.src.get_project_maintainers()
72
74
  for member in maintainers:
73
75
  if member.username in project_maintainers:
@@ -79,9 +81,8 @@ class GitlabForkCompliance:
79
81
 
80
82
  # Last but not least, we remove the blocked label, in case
81
83
  # it is set
82
- mr_labels = self.gl_cli.get_merge_request_labels(self.mr.iid)
83
- if BLOCKED_BOT_ACCESS in mr_labels:
84
- self.gl_cli.remove_label_from_merge_request(self.mr.iid, BLOCKED_BOT_ACCESS)
84
+ if BLOCKED_BOT_ACCESS in self.mr.labels:
85
+ self.gl_cli.remove_label(self.mr, BLOCKED_BOT_ACCESS)
85
86
 
86
87
  sys.exit(self.exit_code)
87
88
 
@@ -98,7 +99,7 @@ class GitlabForkCompliance:
98
99
  self.src = GitLabApi(
99
100
  self.instance,
100
101
  project_id=self.mr.source_project_id,
101
- settings=self.settings,
102
+ secret_reader=self.secret_reader,
102
103
  )
103
104
  except GitlabGetError:
104
105
  self.handle_error("access denied for user {bot}", MSG_ACCESS)
@@ -114,7 +115,7 @@ class GitlabForkCompliance:
114
115
 
115
116
  def handle_error(self, log_msg, mr_msg):
116
117
  LOG.error([log_msg.format(bot=self.gl_cli.user.username)])
117
- self.gl_cli.add_label_to_merge_request(self.mr.iid, BLOCKED_BOT_ACCESS)
118
+ self.gl_cli.add_label_to_merge_request(self.mr, BLOCKED_BOT_ACCESS)
118
119
  comment = mr_msg.format(
119
120
  user=self.mr.author["username"],
120
121
  bot=self.gl_cli.user.username,