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.
- qontract_reconcile-0.10.1.dev1203.dist-info/METADATA +500 -0
- qontract_reconcile-0.10.1.dev1203.dist-info/RECORD +771 -0
- {qontract_reconcile-0.10.0.dist-info → qontract_reconcile-0.10.1.dev1203.dist-info}/WHEEL +1 -2
- {qontract_reconcile-0.10.0.dist-info → qontract_reconcile-0.10.1.dev1203.dist-info}/entry_points.txt +4 -2
- reconcile/acs_notifiers.py +126 -0
- reconcile/acs_policies.py +243 -0
- reconcile/acs_rbac.py +596 -0
- reconcile/aus/advanced_upgrade_service.py +621 -8
- reconcile/aus/aus_label_source.py +115 -0
- reconcile/aus/base.py +1053 -353
- reconcile/{utils → aus}/cluster_version_data.py +27 -12
- reconcile/aus/healthchecks.py +77 -0
- reconcile/aus/metrics.py +158 -0
- reconcile/aus/models.py +245 -5
- reconcile/aus/node_pool_spec.py +35 -0
- reconcile/aus/ocm_addons_upgrade_scheduler_org.py +225 -110
- reconcile/aus/ocm_upgrade_scheduler.py +76 -71
- reconcile/aus/ocm_upgrade_scheduler_org.py +81 -23
- reconcile/aus/version_gate_approver.py +204 -0
- reconcile/aus/version_gates/__init__.py +12 -0
- reconcile/aus/version_gates/handler.py +33 -0
- reconcile/aus/version_gates/ingress_gate_handler.py +32 -0
- reconcile/aus/version_gates/ocp_gate_handler.py +26 -0
- reconcile/aus/version_gates/sts_version_gate_handler.py +100 -0
- reconcile/aws_account_manager/README.md +5 -0
- reconcile/aws_account_manager/integration.py +373 -0
- reconcile/aws_account_manager/merge_request_manager.py +114 -0
- reconcile/aws_account_manager/metrics.py +39 -0
- reconcile/aws_account_manager/reconciler.py +403 -0
- reconcile/aws_account_manager/utils.py +41 -0
- reconcile/aws_ami_cleanup/integration.py +273 -0
- reconcile/aws_ami_share.py +18 -14
- reconcile/aws_cloudwatch_log_retention/integration.py +253 -0
- reconcile/aws_iam_keys.py +1 -1
- reconcile/aws_iam_password_reset.py +56 -20
- reconcile/aws_saml_idp/integration.py +204 -0
- reconcile/aws_saml_roles/integration.py +322 -0
- reconcile/aws_support_cases_sos.py +2 -2
- reconcile/aws_version_sync/integration.py +430 -0
- reconcile/aws_version_sync/merge_request_manager/merge_request.py +156 -0
- reconcile/aws_version_sync/merge_request_manager/merge_request_manager.py +160 -0
- reconcile/aws_version_sync/utils.py +64 -0
- reconcile/blackbox_exporter_endpoint_monitoring.py +2 -5
- reconcile/change_owners/README.md +34 -0
- reconcile/change_owners/approver.py +7 -9
- reconcile/change_owners/bundle.py +134 -9
- reconcile/change_owners/change_log_tracking.py +236 -0
- reconcile/change_owners/change_owners.py +204 -194
- reconcile/change_owners/change_types.py +183 -265
- reconcile/change_owners/changes.py +488 -0
- reconcile/change_owners/decision.py +120 -41
- reconcile/change_owners/diff.py +63 -92
- reconcile/change_owners/implicit_ownership.py +19 -16
- reconcile/change_owners/self_service_roles.py +158 -35
- reconcile/change_owners/tester.py +20 -18
- reconcile/checkpoint.py +4 -6
- reconcile/cli.py +1523 -242
- reconcile/closedbox_endpoint_monitoring_base.py +10 -17
- reconcile/cluster_auth_rhidp/integration.py +257 -0
- reconcile/cluster_deployment_mapper.py +2 -5
- reconcile/cna/assets/asset.py +4 -7
- reconcile/cna/assets/null.py +2 -5
- reconcile/cna/integration.py +2 -3
- reconcile/cna/state.py +6 -9
- reconcile/dashdotdb_base.py +31 -10
- reconcile/dashdotdb_cso.py +3 -6
- reconcile/dashdotdb_dora.py +530 -0
- reconcile/dashdotdb_dvo.py +10 -13
- reconcile/dashdotdb_slo.py +75 -19
- reconcile/database_access_manager.py +753 -0
- reconcile/deadmanssnitch.py +207 -0
- reconcile/dynatrace_token_provider/dependencies.py +69 -0
- reconcile/dynatrace_token_provider/integration.py +656 -0
- reconcile/dynatrace_token_provider/metrics.py +62 -0
- reconcile/dynatrace_token_provider/model.py +14 -0
- reconcile/dynatrace_token_provider/ocm.py +140 -0
- reconcile/dynatrace_token_provider/validate.py +48 -0
- reconcile/endpoints_discovery/integration.py +348 -0
- reconcile/endpoints_discovery/merge_request.py +96 -0
- reconcile/endpoints_discovery/merge_request_manager.py +178 -0
- reconcile/external_resources/aws.py +204 -0
- reconcile/external_resources/factories.py +163 -0
- reconcile/external_resources/integration.py +194 -0
- reconcile/external_resources/integration_secrets_sync.py +47 -0
- reconcile/external_resources/manager.py +405 -0
- reconcile/external_resources/meta.py +17 -0
- reconcile/external_resources/metrics.py +95 -0
- reconcile/external_resources/model.py +350 -0
- reconcile/external_resources/reconciler.py +265 -0
- reconcile/external_resources/secrets_sync.py +465 -0
- reconcile/external_resources/state.py +258 -0
- reconcile/gabi_authorized_users.py +19 -11
- reconcile/gcr_mirror.py +43 -34
- reconcile/github_org.py +4 -6
- reconcile/github_owners.py +1 -1
- reconcile/github_repo_invites.py +2 -5
- reconcile/gitlab_fork_compliance.py +14 -13
- reconcile/gitlab_housekeeping.py +185 -91
- reconcile/gitlab_labeler.py +15 -14
- reconcile/gitlab_members.py +126 -120
- reconcile/gitlab_owners.py +53 -66
- reconcile/gitlab_permissions.py +167 -6
- reconcile/glitchtip/README.md +150 -0
- reconcile/glitchtip/integration.py +99 -51
- reconcile/glitchtip/reconciler.py +99 -70
- reconcile/glitchtip_project_alerts/__init__.py +0 -0
- reconcile/glitchtip_project_alerts/integration.py +333 -0
- reconcile/glitchtip_project_dsn/integration.py +43 -43
- reconcile/gql_definitions/acs/__init__.py +0 -0
- reconcile/gql_definitions/acs/acs_instances.py +83 -0
- reconcile/gql_definitions/acs/acs_policies.py +239 -0
- reconcile/gql_definitions/acs/acs_rbac.py +111 -0
- reconcile/gql_definitions/advanced_upgrade_service/aus_clusters.py +46 -8
- reconcile/gql_definitions/advanced_upgrade_service/aus_organization.py +38 -8
- reconcile/gql_definitions/app_interface_metrics_exporter/__init__.py +0 -0
- reconcile/gql_definitions/app_interface_metrics_exporter/onboarding_status.py +61 -0
- reconcile/gql_definitions/aws_account_manager/__init__.py +0 -0
- reconcile/gql_definitions/aws_account_manager/aws_accounts.py +177 -0
- reconcile/gql_definitions/aws_ami_cleanup/__init__.py +0 -0
- reconcile/gql_definitions/aws_ami_cleanup/aws_accounts.py +161 -0
- reconcile/gql_definitions/aws_saml_idp/__init__.py +0 -0
- reconcile/gql_definitions/aws_saml_idp/aws_accounts.py +117 -0
- reconcile/gql_definitions/aws_saml_roles/__init__.py +0 -0
- reconcile/gql_definitions/aws_saml_roles/aws_accounts.py +117 -0
- reconcile/gql_definitions/aws_saml_roles/roles.py +97 -0
- reconcile/gql_definitions/aws_version_sync/__init__.py +0 -0
- reconcile/gql_definitions/aws_version_sync/clusters.py +83 -0
- reconcile/gql_definitions/aws_version_sync/namespaces.py +143 -0
- reconcile/gql_definitions/change_owners/queries/change_types.py +16 -29
- reconcile/gql_definitions/change_owners/queries/self_service_roles.py +45 -11
- reconcile/gql_definitions/cluster_auth_rhidp/__init__.py +0 -0
- reconcile/gql_definitions/cluster_auth_rhidp/clusters.py +128 -0
- reconcile/gql_definitions/cna/queries/cna_provisioners.py +6 -8
- reconcile/gql_definitions/cna/queries/cna_resources.py +3 -5
- reconcile/gql_definitions/common/alerting_services_settings.py +2 -2
- reconcile/gql_definitions/common/app_code_component_repos.py +9 -5
- reconcile/gql_definitions/{glitchtip/glitchtip_settings.py → common/app_interface_custom_messages.py} +14 -16
- reconcile/gql_definitions/common/app_interface_dms_settings.py +86 -0
- reconcile/gql_definitions/common/app_interface_repo_settings.py +2 -2
- reconcile/gql_definitions/common/app_interface_state_settings.py +3 -5
- reconcile/gql_definitions/common/app_interface_vault_settings.py +3 -5
- reconcile/gql_definitions/common/app_quay_repos_escalation_policies.py +120 -0
- reconcile/gql_definitions/common/apps.py +72 -0
- reconcile/gql_definitions/common/aws_vpc_requests.py +109 -0
- reconcile/gql_definitions/common/aws_vpcs.py +84 -0
- reconcile/gql_definitions/common/clusters.py +120 -254
- reconcile/gql_definitions/common/clusters_minimal.py +11 -35
- reconcile/gql_definitions/common/clusters_with_dms.py +72 -0
- reconcile/gql_definitions/common/clusters_with_peering.py +70 -98
- reconcile/gql_definitions/common/github_orgs.py +2 -2
- reconcile/gql_definitions/common/jira_settings.py +68 -0
- reconcile/gql_definitions/common/jiralert_settings.py +68 -0
- reconcile/gql_definitions/common/namespaces.py +74 -32
- reconcile/gql_definitions/common/namespaces_minimal.py +4 -10
- reconcile/gql_definitions/common/ocm_env_telemeter.py +95 -0
- reconcile/gql_definitions/common/ocm_environments.py +4 -2
- reconcile/gql_definitions/common/pagerduty_instances.py +5 -5
- reconcile/gql_definitions/common/pgp_reencryption_settings.py +5 -11
- reconcile/gql_definitions/common/pipeline_providers.py +45 -90
- reconcile/gql_definitions/common/quay_instances.py +64 -0
- reconcile/gql_definitions/common/quay_orgs.py +68 -0
- reconcile/gql_definitions/common/reserved_networks.py +94 -0
- reconcile/gql_definitions/common/saas_files.py +133 -95
- reconcile/gql_definitions/common/saas_target_namespaces.py +41 -26
- reconcile/gql_definitions/common/saasherder_settings.py +2 -2
- reconcile/gql_definitions/common/slack_workspaces.py +62 -0
- reconcile/gql_definitions/common/smtp_client_settings.py +2 -2
- reconcile/gql_definitions/common/state_aws_account.py +77 -0
- reconcile/gql_definitions/common/users.py +3 -2
- reconcile/gql_definitions/cost_report/__init__.py +0 -0
- reconcile/gql_definitions/cost_report/app_names.py +68 -0
- reconcile/gql_definitions/cost_report/cost_namespaces.py +86 -0
- reconcile/gql_definitions/cost_report/settings.py +77 -0
- reconcile/gql_definitions/dashdotdb_slo/slo_documents_query.py +42 -12
- reconcile/gql_definitions/dynatrace_token_provider/__init__.py +0 -0
- reconcile/gql_definitions/dynatrace_token_provider/dynatrace_bootstrap_tokens.py +79 -0
- reconcile/gql_definitions/dynatrace_token_provider/token_specs.py +84 -0
- reconcile/gql_definitions/endpoints_discovery/__init__.py +0 -0
- reconcile/gql_definitions/endpoints_discovery/namespaces.py +127 -0
- reconcile/gql_definitions/external_resources/__init__.py +0 -0
- reconcile/gql_definitions/external_resources/aws_accounts.py +73 -0
- reconcile/gql_definitions/external_resources/external_resources_modules.py +78 -0
- reconcile/gql_definitions/external_resources/external_resources_namespaces.py +1111 -0
- reconcile/gql_definitions/external_resources/external_resources_settings.py +98 -0
- reconcile/gql_definitions/fragments/aus_organization.py +34 -39
- reconcile/gql_definitions/fragments/aws_account_common.py +62 -0
- reconcile/gql_definitions/fragments/aws_account_managed.py +57 -0
- reconcile/gql_definitions/fragments/aws_account_sso.py +35 -0
- reconcile/gql_definitions/fragments/aws_infra_management_account.py +2 -2
- reconcile/gql_definitions/fragments/aws_vpc.py +47 -0
- reconcile/gql_definitions/fragments/aws_vpc_request.py +65 -0
- reconcile/gql_definitions/fragments/aws_vpc_request_subnet.py +29 -0
- reconcile/gql_definitions/fragments/deplopy_resources.py +7 -7
- reconcile/gql_definitions/fragments/disable.py +28 -0
- reconcile/gql_definitions/fragments/jumphost_common_fields.py +2 -2
- reconcile/gql_definitions/fragments/membership_source.py +47 -0
- reconcile/gql_definitions/fragments/minimal_ocm_organization.py +29 -0
- reconcile/gql_definitions/fragments/oc_connection_cluster.py +4 -9
- reconcile/gql_definitions/fragments/ocm_environment.py +5 -5
- reconcile/gql_definitions/fragments/pipeline_provider_retention.py +30 -0
- reconcile/gql_definitions/fragments/prometheus_instance.py +48 -0
- reconcile/gql_definitions/fragments/resource_limits_requirements.py +29 -0
- reconcile/gql_definitions/fragments/{resource_requirements.py → resource_requests_requirements.py} +3 -3
- reconcile/gql_definitions/fragments/resource_values.py +2 -2
- reconcile/gql_definitions/fragments/saas_target_namespace.py +55 -12
- reconcile/gql_definitions/fragments/serviceaccount_token.py +38 -0
- reconcile/gql_definitions/fragments/terraform_state.py +36 -0
- reconcile/gql_definitions/fragments/upgrade_policy.py +5 -3
- reconcile/gql_definitions/fragments/user.py +3 -2
- reconcile/gql_definitions/fragments/vault_secret.py +2 -2
- reconcile/gql_definitions/gitlab_members/gitlab_instances.py +6 -2
- reconcile/gql_definitions/gitlab_members/permissions.py +3 -5
- reconcile/gql_definitions/glitchtip/glitchtip_instance.py +16 -2
- reconcile/gql_definitions/glitchtip/glitchtip_project.py +22 -23
- reconcile/gql_definitions/glitchtip_project_alerts/__init__.py +0 -0
- reconcile/gql_definitions/glitchtip_project_alerts/glitchtip_project.py +173 -0
- reconcile/gql_definitions/integrations/integrations.py +62 -45
- reconcile/gql_definitions/introspection.json +51176 -0
- reconcile/gql_definitions/jenkins_configs/jenkins_configs.py +13 -5
- reconcile/gql_definitions/jenkins_configs/jenkins_instances.py +79 -0
- reconcile/gql_definitions/jira/__init__.py +0 -0
- reconcile/gql_definitions/jira/jira_servers.py +80 -0
- reconcile/gql_definitions/jira_permissions_validator/__init__.py +0 -0
- reconcile/gql_definitions/jira_permissions_validator/jira_boards_for_permissions_validator.py +131 -0
- reconcile/gql_definitions/jumphosts/jumphosts.py +3 -5
- reconcile/gql_definitions/ldap_groups/__init__.py +0 -0
- reconcile/gql_definitions/ldap_groups/roles.py +111 -0
- reconcile/gql_definitions/ldap_groups/settings.py +79 -0
- reconcile/gql_definitions/maintenance/__init__.py +0 -0
- reconcile/gql_definitions/maintenance/maintenances.py +101 -0
- reconcile/gql_definitions/membershipsources/__init__.py +0 -0
- reconcile/gql_definitions/membershipsources/roles.py +112 -0
- reconcile/gql_definitions/ocm_labels/__init__.py +0 -0
- reconcile/gql_definitions/ocm_labels/clusters.py +112 -0
- reconcile/gql_definitions/ocm_labels/organizations.py +78 -0
- reconcile/gql_definitions/ocm_subscription_labels/__init__.py +0 -0
- reconcile/gql_definitions/openshift_cluster_bots/__init__.py +0 -0
- reconcile/gql_definitions/openshift_cluster_bots/clusters.py +126 -0
- reconcile/gql_definitions/openshift_groups/managed_groups.py +2 -2
- reconcile/gql_definitions/openshift_groups/managed_roles.py +3 -2
- reconcile/gql_definitions/openshift_serviceaccount_tokens/__init__.py +0 -0
- reconcile/gql_definitions/openshift_serviceaccount_tokens/tokens.py +132 -0
- reconcile/gql_definitions/quay_membership/quay_membership.py +3 -5
- reconcile/gql_definitions/rhidp/__init__.py +0 -0
- reconcile/gql_definitions/rhidp/organizations.py +96 -0
- reconcile/gql_definitions/service_dependencies/jenkins_instance_fragment.py +2 -2
- reconcile/gql_definitions/service_dependencies/service_dependencies.py +9 -31
- reconcile/gql_definitions/sharding/aws_accounts.py +2 -2
- reconcile/gql_definitions/sharding/ocm_organization.py +63 -0
- reconcile/gql_definitions/skupper_network/site_controller_template.py +2 -2
- reconcile/gql_definitions/skupper_network/skupper_networks.py +12 -38
- reconcile/gql_definitions/slack_usergroups/clusters.py +2 -2
- reconcile/gql_definitions/slack_usergroups/permissions.py +8 -15
- reconcile/gql_definitions/slack_usergroups/users.py +3 -2
- reconcile/gql_definitions/slo_documents/__init__.py +0 -0
- reconcile/gql_definitions/slo_documents/slo_documents.py +142 -0
- reconcile/gql_definitions/status_board/__init__.py +0 -0
- reconcile/gql_definitions/status_board/status_board.py +163 -0
- reconcile/gql_definitions/statuspage/statuspages.py +56 -7
- reconcile/gql_definitions/templating/__init__.py +0 -0
- reconcile/gql_definitions/templating/template_collection.py +130 -0
- reconcile/gql_definitions/templating/templates.py +108 -0
- reconcile/gql_definitions/terraform_cloudflare_dns/app_interface_cloudflare_dns_settings.py +4 -8
- reconcile/gql_definitions/terraform_cloudflare_dns/terraform_cloudflare_zones.py +8 -8
- reconcile/gql_definitions/terraform_cloudflare_resources/terraform_cloudflare_accounts.py +6 -8
- reconcile/gql_definitions/terraform_cloudflare_resources/terraform_cloudflare_resources.py +45 -56
- reconcile/gql_definitions/terraform_cloudflare_users/app_interface_setting_cloudflare_and_vault.py +4 -8
- reconcile/gql_definitions/terraform_cloudflare_users/terraform_cloudflare_roles.py +4 -8
- reconcile/gql_definitions/terraform_init/__init__.py +0 -0
- reconcile/gql_definitions/terraform_init/aws_accounts.py +93 -0
- reconcile/gql_definitions/terraform_repo/__init__.py +0 -0
- reconcile/gql_definitions/terraform_repo/terraform_repo.py +141 -0
- reconcile/gql_definitions/terraform_resources/database_access_manager.py +158 -0
- reconcile/gql_definitions/terraform_resources/terraform_resources_namespaces.py +153 -162
- reconcile/gql_definitions/terraform_tgw_attachments/__init__.py +0 -0
- reconcile/gql_definitions/terraform_tgw_attachments/aws_accounts.py +119 -0
- reconcile/gql_definitions/unleash_feature_toggles/__init__.py +0 -0
- reconcile/gql_definitions/unleash_feature_toggles/feature_toggles.py +113 -0
- reconcile/gql_definitions/vault_instances/vault_instances.py +17 -50
- reconcile/gql_definitions/vault_policies/vault_policies.py +2 -2
- reconcile/gql_definitions/vpc_peerings_validator/vpc_peerings_validator.py +49 -12
- reconcile/gql_definitions/vpc_peerings_validator/vpc_peerings_validator_peered_cluster_fragment.py +7 -2
- reconcile/integrations_manager.py +25 -13
- reconcile/jenkins/types.py +5 -1
- reconcile/jenkins_base.py +36 -0
- reconcile/jenkins_job_builder.py +10 -48
- reconcile/jenkins_job_builds_cleaner.py +40 -25
- reconcile/jenkins_job_cleaner.py +1 -3
- reconcile/jenkins_roles.py +22 -26
- reconcile/jenkins_webhooks.py +9 -6
- reconcile/jenkins_worker_fleets.py +11 -6
- reconcile/jira_permissions_validator.py +340 -0
- reconcile/jira_watcher.py +3 -5
- reconcile/ldap_groups/__init__.py +0 -0
- reconcile/ldap_groups/integration.py +279 -0
- reconcile/ldap_users.py +3 -0
- reconcile/ocm/types.py +39 -59
- reconcile/ocm_additional_routers.py +0 -1
- reconcile/ocm_addons_upgrade_tests_trigger.py +10 -15
- reconcile/ocm_aws_infrastructure_access.py +30 -32
- reconcile/ocm_clusters.py +217 -130
- reconcile/ocm_external_configuration_labels.py +15 -0
- reconcile/ocm_github_idp.py +1 -1
- reconcile/ocm_groups.py +25 -5
- reconcile/ocm_internal_notifications/__init__.py +0 -0
- reconcile/ocm_internal_notifications/integration.py +119 -0
- reconcile/ocm_labels/__init__.py +0 -0
- reconcile/ocm_labels/integration.py +409 -0
- reconcile/ocm_machine_pools.py +517 -108
- reconcile/ocm_upgrade_scheduler_org_updater.py +15 -11
- reconcile/openshift_base.py +609 -207
- reconcile/openshift_cluster_bots.py +344 -0
- reconcile/openshift_clusterrolebindings.py +15 -15
- reconcile/openshift_groups.py +42 -45
- reconcile/openshift_limitranges.py +1 -0
- reconcile/openshift_namespace_labels.py +22 -28
- reconcile/openshift_namespaces.py +22 -22
- reconcile/openshift_network_policies.py +4 -8
- reconcile/openshift_prometheus_rules.py +43 -0
- reconcile/openshift_resourcequotas.py +2 -16
- reconcile/openshift_resources.py +12 -10
- reconcile/openshift_resources_base.py +304 -328
- reconcile/openshift_rolebindings.py +18 -20
- reconcile/openshift_saas_deploy.py +105 -21
- reconcile/openshift_saas_deploy_change_tester.py +30 -35
- reconcile/openshift_saas_deploy_trigger_base.py +39 -36
- reconcile/openshift_saas_deploy_trigger_cleaner.py +41 -27
- reconcile/openshift_saas_deploy_trigger_configs.py +1 -2
- reconcile/openshift_saas_deploy_trigger_images.py +1 -2
- reconcile/openshift_saas_deploy_trigger_moving_commits.py +1 -2
- reconcile/openshift_saas_deploy_trigger_upstream_jobs.py +1 -2
- reconcile/openshift_serviceaccount_tokens.py +138 -74
- reconcile/openshift_tekton_resources.py +89 -24
- reconcile/openshift_upgrade_watcher.py +110 -62
- reconcile/openshift_users.py +16 -15
- reconcile/openshift_vault_secrets.py +11 -6
- reconcile/oum/__init__.py +0 -0
- reconcile/oum/base.py +387 -0
- reconcile/oum/labelset.py +55 -0
- reconcile/oum/metrics.py +71 -0
- reconcile/oum/models.py +69 -0
- reconcile/oum/providers.py +59 -0
- reconcile/oum/standalone.py +196 -0
- reconcile/prometheus_rules_tester/integration.py +31 -23
- reconcile/quay_base.py +4 -1
- reconcile/quay_membership.py +1 -2
- reconcile/quay_mirror.py +111 -61
- reconcile/quay_mirror_org.py +34 -21
- reconcile/quay_permissions.py +7 -3
- reconcile/quay_repos.py +24 -32
- reconcile/queries.py +263 -198
- reconcile/query_validator.py +3 -5
- reconcile/resource_scraper.py +3 -4
- reconcile/{template_tester.py → resource_template_tester.py} +3 -3
- reconcile/rhidp/__init__.py +0 -0
- reconcile/rhidp/common.py +214 -0
- reconcile/rhidp/metrics.py +20 -0
- reconcile/rhidp/ocm_oidc_idp/__init__.py +0 -0
- reconcile/rhidp/ocm_oidc_idp/base.py +221 -0
- reconcile/rhidp/ocm_oidc_idp/integration.py +56 -0
- reconcile/rhidp/ocm_oidc_idp/metrics.py +22 -0
- reconcile/rhidp/sso_client/__init__.py +0 -0
- reconcile/rhidp/sso_client/base.py +266 -0
- reconcile/rhidp/sso_client/integration.py +60 -0
- reconcile/rhidp/sso_client/metrics.py +39 -0
- reconcile/run_integration.py +293 -0
- reconcile/saas_auto_promotions_manager/integration.py +69 -24
- reconcile/saas_auto_promotions_manager/merge_request_manager/batcher.py +208 -0
- reconcile/saas_auto_promotions_manager/merge_request_manager/desired_state.py +28 -0
- reconcile/saas_auto_promotions_manager/merge_request_manager/merge_request.py +3 -4
- reconcile/saas_auto_promotions_manager/merge_request_manager/merge_request_manager_v2.py +172 -0
- reconcile/saas_auto_promotions_manager/merge_request_manager/metrics.py +42 -0
- reconcile/saas_auto_promotions_manager/merge_request_manager/mr_parser.py +226 -0
- reconcile/saas_auto_promotions_manager/merge_request_manager/open_merge_requests.py +23 -0
- reconcile/saas_auto_promotions_manager/merge_request_manager/renderer.py +108 -32
- reconcile/saas_auto_promotions_manager/meta.py +4 -0
- reconcile/saas_auto_promotions_manager/publisher.py +32 -4
- reconcile/saas_auto_promotions_manager/s3_exporter.py +77 -0
- reconcile/saas_auto_promotions_manager/subscriber.py +110 -23
- reconcile/saas_auto_promotions_manager/utils/saas_files_inventory.py +48 -41
- reconcile/saas_file_validator.py +16 -6
- reconcile/sendgrid_teammates.py +27 -12
- reconcile/service_dependencies.py +0 -3
- reconcile/signalfx_endpoint_monitoring.py +2 -5
- reconcile/skupper_network/integration.py +10 -11
- reconcile/skupper_network/models.py +3 -5
- reconcile/skupper_network/reconciler.py +28 -35
- reconcile/skupper_network/site_controller.py +8 -8
- reconcile/slack_base.py +4 -7
- reconcile/slack_usergroups.py +249 -171
- reconcile/sql_query.py +324 -171
- reconcile/status.py +0 -1
- reconcile/status_board.py +275 -0
- reconcile/statuspage/__init__.py +0 -5
- reconcile/statuspage/atlassian.py +219 -80
- reconcile/statuspage/integration.py +9 -97
- reconcile/statuspage/integrations/__init__.py +0 -0
- reconcile/statuspage/integrations/components.py +77 -0
- reconcile/statuspage/integrations/maintenances.py +111 -0
- reconcile/statuspage/page.py +107 -72
- reconcile/statuspage/state.py +6 -11
- reconcile/statuspage/status.py +8 -12
- reconcile/templates/rosa-classic-cluster-creation.sh.j2 +60 -0
- reconcile/templates/rosa-hcp-cluster-creation.sh.j2 +61 -0
- reconcile/templating/__init__.py +0 -0
- reconcile/templating/lib/__init__.py +0 -0
- reconcile/templating/lib/merge_request_manager.py +180 -0
- reconcile/templating/lib/model.py +20 -0
- reconcile/templating/lib/rendering.py +191 -0
- reconcile/templating/renderer.py +410 -0
- reconcile/templating/validator.py +153 -0
- reconcile/terraform_aws_route53.py +13 -10
- reconcile/terraform_cloudflare_dns.py +92 -122
- reconcile/terraform_cloudflare_resources.py +15 -13
- reconcile/terraform_cloudflare_users.py +27 -27
- reconcile/terraform_init/__init__.py +0 -0
- reconcile/terraform_init/integration.py +165 -0
- reconcile/terraform_init/merge_request.py +57 -0
- reconcile/terraform_init/merge_request_manager.py +102 -0
- reconcile/terraform_repo.py +403 -0
- reconcile/terraform_resources.py +266 -168
- reconcile/terraform_tgw_attachments.py +417 -167
- reconcile/terraform_users.py +40 -17
- reconcile/terraform_vpc_peerings.py +310 -142
- reconcile/terraform_vpc_resources/__init__.py +0 -0
- reconcile/terraform_vpc_resources/integration.py +220 -0
- reconcile/terraform_vpc_resources/merge_request.py +57 -0
- reconcile/terraform_vpc_resources/merge_request_manager.py +107 -0
- reconcile/typed_queries/alerting_services_settings.py +1 -2
- reconcile/typed_queries/app_interface_custom_messages.py +24 -0
- reconcile/typed_queries/app_interface_deadmanssnitch_settings.py +17 -0
- reconcile/typed_queries/app_interface_metrics_exporter/__init__.py +0 -0
- reconcile/typed_queries/app_interface_metrics_exporter/onboarding_status.py +13 -0
- reconcile/typed_queries/app_interface_repo_url.py +1 -2
- reconcile/typed_queries/app_interface_state_settings.py +1 -3
- reconcile/typed_queries/app_interface_vault_settings.py +1 -2
- reconcile/typed_queries/app_quay_repos_escalation_policies.py +14 -0
- reconcile/typed_queries/apps.py +11 -0
- reconcile/typed_queries/aws_vpc_requests.py +9 -0
- reconcile/typed_queries/aws_vpcs.py +12 -0
- reconcile/typed_queries/cloudflare.py +10 -0
- reconcile/typed_queries/clusters.py +7 -5
- reconcile/typed_queries/clusters_minimal.py +6 -5
- reconcile/typed_queries/clusters_with_dms.py +16 -0
- reconcile/typed_queries/cost_report/__init__.py +0 -0
- reconcile/typed_queries/cost_report/app_names.py +22 -0
- reconcile/typed_queries/cost_report/cost_namespaces.py +43 -0
- reconcile/typed_queries/cost_report/settings.py +15 -0
- reconcile/typed_queries/dynatrace.py +10 -0
- reconcile/typed_queries/dynatrace_environments.py +14 -0
- reconcile/typed_queries/dynatrace_token_provider_token_specs.py +14 -0
- reconcile/typed_queries/external_resources.py +46 -0
- reconcile/typed_queries/get_state_aws_account.py +20 -0
- reconcile/typed_queries/glitchtip.py +10 -0
- reconcile/typed_queries/jenkins.py +25 -0
- reconcile/typed_queries/jira.py +7 -0
- reconcile/typed_queries/jira_settings.py +16 -0
- reconcile/typed_queries/jiralert_settings.py +22 -0
- reconcile/typed_queries/ocm.py +8 -0
- reconcile/typed_queries/pagerduty_instances.py +2 -7
- reconcile/typed_queries/quay.py +23 -0
- reconcile/typed_queries/repos.py +20 -8
- reconcile/typed_queries/reserved_networks.py +12 -0
- reconcile/typed_queries/saas_files.py +221 -167
- reconcile/typed_queries/slack.py +7 -0
- reconcile/typed_queries/slo_documents.py +12 -0
- reconcile/typed_queries/status_board.py +58 -0
- reconcile/typed_queries/tekton_pipeline_providers.py +1 -2
- reconcile/typed_queries/terraform_namespaces.py +1 -2
- reconcile/typed_queries/terraform_tgw_attachments/__init__.py +0 -0
- reconcile/typed_queries/terraform_tgw_attachments/aws_accounts.py +16 -0
- reconcile/typed_queries/unleash.py +10 -0
- reconcile/typed_queries/users.py +11 -0
- reconcile/typed_queries/vault.py +10 -0
- reconcile/unleash_feature_toggles/__init__.py +0 -0
- reconcile/unleash_feature_toggles/integration.py +287 -0
- reconcile/utils/acs/__init__.py +0 -0
- reconcile/utils/acs/base.py +81 -0
- reconcile/utils/acs/notifiers.py +143 -0
- reconcile/utils/acs/policies.py +163 -0
- reconcile/utils/acs/rbac.py +277 -0
- reconcile/utils/aggregated_list.py +11 -9
- reconcile/utils/amtool.py +6 -4
- reconcile/utils/aws_api.py +279 -66
- reconcile/utils/aws_api_typed/__init__.py +0 -0
- reconcile/utils/aws_api_typed/account.py +23 -0
- reconcile/utils/aws_api_typed/api.py +273 -0
- reconcile/utils/aws_api_typed/dynamodb.py +16 -0
- reconcile/utils/aws_api_typed/iam.py +67 -0
- reconcile/utils/aws_api_typed/organization.py +152 -0
- reconcile/utils/aws_api_typed/s3.py +26 -0
- reconcile/utils/aws_api_typed/service_quotas.py +79 -0
- reconcile/utils/aws_api_typed/sts.py +36 -0
- reconcile/utils/aws_api_typed/support.py +79 -0
- reconcile/utils/aws_helper.py +42 -3
- reconcile/utils/batches.py +11 -0
- reconcile/utils/binary.py +7 -9
- reconcile/utils/cloud_resource_best_practice/__init__.py +0 -0
- reconcile/utils/cloud_resource_best_practice/aws_rds.py +66 -0
- reconcile/utils/clusterhealth/__init__.py +0 -0
- reconcile/utils/clusterhealth/providerbase.py +39 -0
- reconcile/utils/clusterhealth/telemeter.py +39 -0
- reconcile/utils/config.py +3 -4
- reconcile/utils/deadmanssnitch_api.py +86 -0
- reconcile/utils/differ.py +205 -0
- reconcile/utils/disabled_integrations.py +4 -6
- reconcile/utils/dynatrace/__init__.py +0 -0
- reconcile/utils/dynatrace/client.py +93 -0
- reconcile/utils/early_exit_cache.py +289 -0
- reconcile/utils/elasticsearch_exceptions.py +5 -0
- reconcile/utils/environ.py +2 -2
- reconcile/utils/exceptions.py +4 -0
- reconcile/utils/expiration.py +4 -8
- reconcile/utils/extended_early_exit.py +210 -0
- reconcile/utils/external_resource_spec.py +34 -12
- reconcile/utils/external_resources.py +48 -20
- reconcile/utils/filtering.py +16 -0
- reconcile/utils/git.py +49 -16
- reconcile/utils/github_api.py +10 -9
- reconcile/utils/gitlab_api.py +333 -190
- reconcile/utils/glitchtip/client.py +97 -100
- reconcile/utils/glitchtip/models.py +89 -11
- reconcile/utils/gql.py +157 -58
- reconcile/utils/grouping.py +17 -0
- reconcile/utils/helm.py +89 -18
- reconcile/utils/helpers.py +51 -0
- reconcile/utils/imap_client.py +5 -6
- reconcile/utils/internal_groups/__init__.py +0 -0
- reconcile/utils/internal_groups/client.py +160 -0
- reconcile/utils/internal_groups/models.py +71 -0
- reconcile/utils/jenkins_api.py +10 -34
- reconcile/utils/jinja2/__init__.py +0 -0
- reconcile/utils/{jinja2_ext.py → jinja2/extensions.py} +6 -4
- reconcile/utils/jinja2/filters.py +142 -0
- reconcile/utils/jinja2/utils.py +278 -0
- reconcile/utils/jira_client.py +165 -8
- reconcile/utils/jjb_client.py +47 -35
- reconcile/utils/jobcontroller/__init__.py +0 -0
- reconcile/utils/jobcontroller/controller.py +413 -0
- reconcile/utils/jobcontroller/models.py +195 -0
- reconcile/utils/jsonpath.py +4 -5
- reconcile/utils/jump_host.py +13 -12
- reconcile/utils/keycloak.py +106 -0
- reconcile/utils/ldap_client.py +35 -6
- reconcile/utils/lean_terraform_client.py +115 -6
- reconcile/utils/membershipsources/__init__.py +0 -0
- reconcile/utils/membershipsources/app_interface_resolver.py +60 -0
- reconcile/utils/membershipsources/models.py +91 -0
- reconcile/utils/membershipsources/resolver.py +110 -0
- reconcile/utils/merge_request_manager/__init__.py +0 -0
- reconcile/utils/merge_request_manager/merge_request_manager.py +99 -0
- reconcile/utils/merge_request_manager/parser.py +67 -0
- reconcile/utils/metrics.py +511 -1
- reconcile/utils/models.py +123 -0
- reconcile/utils/mr/README.md +198 -0
- reconcile/utils/mr/__init__.py +14 -10
- reconcile/utils/mr/app_interface_reporter.py +2 -2
- reconcile/utils/mr/aws_access.py +4 -4
- reconcile/utils/mr/base.py +51 -31
- reconcile/utils/mr/clusters_updates.py +10 -7
- reconcile/utils/mr/glitchtip_access_reporter.py +2 -4
- reconcile/utils/mr/labels.py +14 -1
- reconcile/utils/mr/notificator.py +1 -3
- reconcile/utils/mr/ocm_update_recommended_version.py +1 -2
- reconcile/utils/mr/ocm_upgrade_scheduler_org_updates.py +7 -3
- reconcile/utils/mr/promote_qontract.py +203 -0
- reconcile/utils/mr/user_maintenance.py +24 -4
- reconcile/utils/oauth2_backend_application_session.py +132 -0
- reconcile/utils/oc.py +194 -170
- reconcile/utils/oc_connection_parameters.py +40 -51
- reconcile/utils/oc_filters.py +11 -13
- reconcile/utils/oc_map.py +14 -35
- reconcile/utils/ocm/__init__.py +30 -1
- reconcile/utils/ocm/addons.py +228 -0
- reconcile/utils/ocm/base.py +618 -5
- reconcile/utils/ocm/cluster_groups.py +5 -56
- reconcile/utils/ocm/clusters.py +111 -99
- reconcile/utils/ocm/identity_providers.py +66 -0
- reconcile/utils/ocm/label_sources.py +75 -0
- reconcile/utils/ocm/labels.py +139 -54
- reconcile/utils/ocm/manifests.py +39 -0
- reconcile/utils/ocm/ocm.py +182 -928
- reconcile/utils/ocm/products.py +758 -0
- reconcile/utils/ocm/search_filters.py +20 -28
- reconcile/utils/ocm/service_log.py +32 -79
- reconcile/utils/ocm/sre_capability_labels.py +51 -0
- reconcile/utils/ocm/status_board.py +66 -0
- reconcile/utils/ocm/subscriptions.py +49 -59
- reconcile/utils/ocm/syncsets.py +39 -0
- reconcile/utils/ocm/upgrades.py +181 -0
- reconcile/utils/ocm_base_client.py +71 -36
- reconcile/utils/openshift_resource.py +113 -67
- reconcile/utils/output.py +18 -11
- reconcile/utils/pagerduty_api.py +16 -10
- reconcile/utils/parse_dhms_duration.py +13 -1
- reconcile/utils/prometheus.py +123 -0
- reconcile/utils/promotion_state.py +56 -19
- reconcile/utils/promtool.py +5 -8
- reconcile/utils/quay_api.py +13 -25
- reconcile/utils/raw_github_api.py +3 -5
- reconcile/utils/repo_owners.py +2 -8
- reconcile/utils/rest_api_base.py +126 -0
- reconcile/utils/rosa/__init__.py +0 -0
- reconcile/utils/rosa/rosa_cli.py +310 -0
- reconcile/utils/rosa/session.py +201 -0
- reconcile/utils/ruamel.py +16 -0
- reconcile/utils/runtime/__init__.py +0 -1
- reconcile/utils/runtime/desired_state_diff.py +9 -20
- reconcile/utils/runtime/environment.py +33 -8
- reconcile/utils/runtime/integration.py +28 -12
- reconcile/utils/runtime/meta.py +1 -3
- reconcile/utils/runtime/runner.py +8 -11
- reconcile/utils/runtime/sharding.py +93 -36
- reconcile/utils/saasherder/__init__.py +1 -1
- reconcile/utils/saasherder/interfaces.py +143 -138
- reconcile/utils/saasherder/models.py +201 -43
- reconcile/utils/saasherder/saasherder.py +508 -378
- reconcile/utils/secret_reader.py +22 -27
- reconcile/utils/semver_helper.py +15 -1
- reconcile/utils/slack_api.py +124 -36
- reconcile/utils/smtp_client.py +1 -2
- reconcile/utils/sqs_gateway.py +10 -6
- reconcile/utils/state.py +276 -127
- reconcile/utils/terraform/config_client.py +6 -7
- reconcile/utils/terraform_client.py +284 -125
- reconcile/utils/terrascript/cloudflare_client.py +38 -17
- reconcile/utils/terrascript/cloudflare_resources.py +67 -18
- reconcile/utils/terrascript/models.py +2 -3
- reconcile/utils/terrascript/resources.py +1 -2
- reconcile/utils/terrascript_aws_client.py +1292 -540
- reconcile/utils/three_way_diff_strategy.py +157 -0
- reconcile/utils/unleash/__init__.py +11 -0
- reconcile/utils/{unleash.py → unleash/client.py} +35 -29
- reconcile/utils/unleash/server.py +145 -0
- reconcile/utils/vault.py +42 -32
- reconcile/utils/vaultsecretref.py +2 -4
- reconcile/utils/vcs.py +250 -0
- reconcile/vault_replication.py +38 -31
- reconcile/vpc_peerings_validator.py +82 -13
- tools/app_interface_metrics_exporter.py +70 -0
- tools/app_interface_reporter.py +44 -157
- tools/cli_commands/container_images_report.py +154 -0
- tools/cli_commands/cost_report/__init__.py +0 -0
- tools/cli_commands/cost_report/aws.py +137 -0
- tools/cli_commands/cost_report/cost_management_api.py +155 -0
- tools/cli_commands/cost_report/model.py +49 -0
- tools/cli_commands/cost_report/openshift.py +166 -0
- tools/cli_commands/cost_report/openshift_cost_optimization.py +187 -0
- tools/cli_commands/cost_report/response.py +124 -0
- tools/cli_commands/cost_report/util.py +72 -0
- tools/cli_commands/cost_report/view.py +524 -0
- tools/cli_commands/erv2.py +620 -0
- tools/cli_commands/gpg_encrypt.py +5 -8
- tools/cli_commands/systems_and_tools.py +489 -0
- tools/glitchtip_access_revalidation.py +1 -1
- tools/qontract_cli.py +2301 -673
- tools/saas_metrics_exporter/__init__.py +0 -0
- tools/saas_metrics_exporter/commit_distance/__init__.py +0 -0
- tools/saas_metrics_exporter/commit_distance/channel.py +63 -0
- tools/saas_metrics_exporter/commit_distance/commit_distance.py +103 -0
- tools/saas_metrics_exporter/commit_distance/metrics.py +19 -0
- tools/saas_metrics_exporter/main.py +99 -0
- tools/saas_promotion_state/__init__.py +0 -0
- tools/saas_promotion_state/saas_promotion_state.py +105 -0
- tools/sd_app_sre_alert_report.py +145 -0
- tools/template_validation.py +107 -0
- e2e_tests/cli.py +0 -83
- e2e_tests/create_namespace.py +0 -43
- e2e_tests/dedicated_admin_rolebindings.py +0 -44
- e2e_tests/dedicated_admin_test_base.py +0 -39
- e2e_tests/default_network_policies.py +0 -47
- e2e_tests/default_project_labels.py +0 -52
- e2e_tests/network_policy_test_base.py +0 -17
- e2e_tests/test_base.py +0 -56
- qontract_reconcile-0.10.0.dist-info/LICENSE +0 -201
- qontract_reconcile-0.10.0.dist-info/METADATA +0 -63
- qontract_reconcile-0.10.0.dist-info/RECORD +0 -586
- qontract_reconcile-0.10.0.dist-info/top_level.txt +0 -4
- reconcile/ecr_mirror.py +0 -152
- reconcile/github_scanner.py +0 -74
- reconcile/gitlab_integrations.py +0 -63
- reconcile/gql_definitions/ocm_oidc_idp/clusters.py +0 -195
- reconcile/gql_definitions/ocp_release_mirror/ocp_release_mirror.py +0 -287
- reconcile/integrations_validator.py +0 -18
- reconcile/jenkins_plugins.py +0 -129
- reconcile/kafka_clusters.py +0 -208
- reconcile/ocm_cluster_admin.py +0 -42
- reconcile/ocm_oidc_idp.py +0 -198
- reconcile/ocp_release_mirror.py +0 -373
- reconcile/prometheus_rules_tester_old.py +0 -436
- reconcile/saas_auto_promotions_manager/merge_request_manager/merge_request_manager.py +0 -279
- reconcile/saas_auto_promotions_manager/utils/vcs.py +0 -141
- reconcile/sentry_config.py +0 -613
- reconcile/sentry_helper.py +0 -69
- reconcile/test/conftest.py +0 -187
- reconcile/test/fixtures.py +0 -24
- reconcile/test/saas_auto_promotions_manager/conftest.py +0 -69
- reconcile/test/saas_auto_promotions_manager/merge_request_manager/merge_request_manager/conftest.py +0 -110
- reconcile/test/saas_auto_promotions_manager/merge_request_manager/merge_request_manager/data_keys.py +0 -10
- reconcile/test/saas_auto_promotions_manager/merge_request_manager/merge_request_manager/test_housekeeping.py +0 -200
- reconcile/test/saas_auto_promotions_manager/merge_request_manager/merge_request_manager/test_merge_request_manager.py +0 -151
- reconcile/test/saas_auto_promotions_manager/merge_request_manager/renderer/conftest.py +0 -63
- reconcile/test/saas_auto_promotions_manager/merge_request_manager/renderer/data_keys.py +0 -4
- reconcile/test/saas_auto_promotions_manager/merge_request_manager/renderer/test_content_multiple_namespaces.py +0 -46
- reconcile/test/saas_auto_promotions_manager/merge_request_manager/renderer/test_content_single_namespace.py +0 -94
- reconcile/test/saas_auto_promotions_manager/merge_request_manager/renderer/test_content_single_target.py +0 -44
- reconcile/test/saas_auto_promotions_manager/subscriber/conftest.py +0 -74
- reconcile/test/saas_auto_promotions_manager/subscriber/data_keys.py +0 -11
- reconcile/test/saas_auto_promotions_manager/subscriber/test_content_hash.py +0 -155
- reconcile/test/saas_auto_promotions_manager/subscriber/test_diff.py +0 -173
- reconcile/test/saas_auto_promotions_manager/subscriber/test_multiple_channels_config_hash.py +0 -226
- reconcile/test/saas_auto_promotions_manager/subscriber/test_multiple_channels_moving_ref.py +0 -224
- reconcile/test/saas_auto_promotions_manager/subscriber/test_single_channel_with_single_publisher.py +0 -350
- reconcile/test/saas_auto_promotions_manager/test_integration_test.py +0 -129
- reconcile/test/saas_auto_promotions_manager/utils/saas_files_inventory/test_multiple_publishers_for_single_channel.py +0 -70
- reconcile/test/saas_auto_promotions_manager/utils/saas_files_inventory/test_saas_files_use_target_config_hash.py +0 -63
- reconcile/test/saas_auto_promotions_manager/utils/saas_files_inventory/test_saas_files_with_auto_promote.py +0 -74
- reconcile/test/saas_auto_promotions_manager/utils/saas_files_inventory/test_saas_files_without_auto_promote.py +0 -65
- reconcile/test/test_aggregated_list.py +0 -237
- reconcile/test/test_amtool.py +0 -37
- reconcile/test/test_auto_promoter.py +0 -295
- reconcile/test/test_aws_ami_share.py +0 -68
- reconcile/test/test_aws_iam_keys.py +0 -70
- reconcile/test/test_aws_iam_password_reset.py +0 -35
- reconcile/test/test_aws_support_cases_sos.py +0 -23
- reconcile/test/test_checkpoint.py +0 -178
- reconcile/test/test_cli.py +0 -41
- reconcile/test/test_closedbox_endpoint_monitoring.py +0 -207
- reconcile/test/test_gabi_authorized_users.py +0 -72
- reconcile/test/test_github_org.py +0 -154
- reconcile/test/test_github_repo_invites.py +0 -123
- reconcile/test/test_gitlab_housekeeping.py +0 -88
- reconcile/test/test_gitlab_labeler.py +0 -129
- reconcile/test/test_gitlab_members.py +0 -283
- reconcile/test/test_instrumented_wrappers.py +0 -18
- reconcile/test/test_integrations_manager.py +0 -995
- reconcile/test/test_jenkins_worker_fleets.py +0 -55
- reconcile/test/test_jump_host.py +0 -117
- reconcile/test/test_ldap_users.py +0 -123
- reconcile/test/test_make.py +0 -28
- reconcile/test/test_ocm_additional_routers.py +0 -134
- reconcile/test/test_ocm_addons_upgrade_scheduler_org.py +0 -149
- reconcile/test/test_ocm_clusters.py +0 -598
- reconcile/test/test_ocm_clusters_manifest_updates.py +0 -89
- reconcile/test/test_ocm_oidc_idp.py +0 -315
- reconcile/test/test_ocm_update_recommended_version.py +0 -145
- reconcile/test/test_ocm_upgrade_scheduler.py +0 -614
- reconcile/test/test_ocm_upgrade_scheduler_org_updater.py +0 -129
- reconcile/test/test_openshift_base.py +0 -730
- reconcile/test/test_openshift_namespace_labels.py +0 -345
- reconcile/test/test_openshift_namespaces.py +0 -256
- reconcile/test/test_openshift_resource.py +0 -415
- reconcile/test/test_openshift_resources_base.py +0 -440
- reconcile/test/test_openshift_saas_deploy_change_tester.py +0 -310
- reconcile/test/test_openshift_tekton_resources.py +0 -253
- reconcile/test/test_openshift_upgrade_watcher.py +0 -146
- reconcile/test/test_prometheus_rules_tester.py +0 -151
- reconcile/test/test_prometheus_rules_tester_old.py +0 -77
- reconcile/test/test_quay_membership.py +0 -86
- reconcile/test/test_quay_mirror.py +0 -109
- reconcile/test/test_quay_mirror_org.py +0 -70
- reconcile/test/test_quay_repos.py +0 -59
- reconcile/test/test_queries.py +0 -53
- reconcile/test/test_repo_owners.py +0 -47
- reconcile/test/test_requests_sender.py +0 -139
- reconcile/test/test_saasherder.py +0 -1074
- reconcile/test/test_saasherder_allowed_secret_paths.py +0 -127
- reconcile/test/test_secret_reader.py +0 -153
- reconcile/test/test_slack_base.py +0 -185
- reconcile/test/test_slack_usergroups.py +0 -744
- reconcile/test/test_sql_query.py +0 -19
- reconcile/test/test_terraform_cloudflare_dns.py +0 -117
- reconcile/test/test_terraform_cloudflare_resources.py +0 -106
- reconcile/test/test_terraform_cloudflare_users.py +0 -749
- reconcile/test/test_terraform_resources.py +0 -257
- reconcile/test/test_terraform_tgw_attachments.py +0 -631
- reconcile/test/test_terraform_users.py +0 -57
- reconcile/test/test_terraform_vpc_peerings.py +0 -499
- reconcile/test/test_terraform_vpc_peerings_build_desired_state.py +0 -1061
- reconcile/test/test_unleash.py +0 -138
- reconcile/test/test_utils_aws_api.py +0 -240
- reconcile/test/test_utils_aws_helper.py +0 -80
- reconcile/test/test_utils_cluster_version_data.py +0 -177
- reconcile/test/test_utils_data_structures.py +0 -13
- reconcile/test/test_utils_disabled_integrations.py +0 -86
- reconcile/test/test_utils_expiration.py +0 -109
- reconcile/test/test_utils_external_resource_spec.py +0 -383
- reconcile/test/test_utils_external_resources.py +0 -247
- reconcile/test/test_utils_github_api.py +0 -73
- reconcile/test/test_utils_gitlab_api.py +0 -20
- reconcile/test/test_utils_gpg.py +0 -69
- reconcile/test/test_utils_gql.py +0 -81
- reconcile/test/test_utils_helm.py +0 -306
- reconcile/test/test_utils_helpers.py +0 -55
- reconcile/test/test_utils_imap_client.py +0 -65
- reconcile/test/test_utils_jjb_client.py +0 -52
- reconcile/test/test_utils_jsonpath.py +0 -286
- reconcile/test/test_utils_ldap_client.py +0 -51
- reconcile/test/test_utils_mr.py +0 -226
- reconcile/test/test_utils_mr_clusters_updates.py +0 -77
- reconcile/test/test_utils_oc.py +0 -984
- reconcile/test/test_utils_ocm.py +0 -110
- reconcile/test/test_utils_pagerduty_api.py +0 -251
- reconcile/test/test_utils_parse_dhms_duration.py +0 -34
- reconcile/test/test_utils_password_validator.py +0 -155
- reconcile/test/test_utils_quay_api.py +0 -86
- reconcile/test/test_utils_semver_helper.py +0 -19
- reconcile/test/test_utils_sharding.py +0 -56
- reconcile/test/test_utils_slack_api.py +0 -439
- reconcile/test/test_utils_smtp_client.py +0 -73
- reconcile/test/test_utils_state.py +0 -256
- reconcile/test/test_utils_terraform.py +0 -13
- reconcile/test/test_utils_terraform_client.py +0 -585
- reconcile/test/test_utils_terraform_config_client.py +0 -219
- reconcile/test/test_utils_terrascript_aws_client.py +0 -277
- reconcile/test/test_utils_terrascript_cloudflare_client.py +0 -597
- reconcile/test/test_utils_terrascript_cloudflare_resources.py +0 -26
- reconcile/test/test_vault_replication.py +0 -515
- reconcile/test/test_vault_utils.py +0 -47
- reconcile/test/test_version_bump.py +0 -18
- reconcile/test/test_vpc_peerings_validator.py +0 -103
- reconcile/test/test_wrong_region.py +0 -78
- reconcile/typed_queries/glitchtip_settings.py +0 -18
- reconcile/typed_queries/ocp_release_mirror.py +0 -11
- reconcile/unleash_watcher.py +0 -120
- reconcile/utils/git_secrets.py +0 -63
- reconcile/utils/mr/auto_promoter.py +0 -218
- reconcile/utils/sentry_client.py +0 -383
- release/test_version.py +0 -50
- release/version.py +0 -100
- tools/test/test_qontract_cli.py +0 -60
- tools/test/test_sre_checkpoints.py +0 -79
- /e2e_tests/__init__.py → /reconcile/aus/upgrades.py +0 -0
- /reconcile/{gql_definitions/ocp_release_mirror → aws_account_manager}/__init__.py +0 -0
- /reconcile/{test → aws_ami_cleanup}/__init__.py +0 -0
- /reconcile/{test/saas_auto_promotions_manager → aws_cloudwatch_log_retention}/__init__.py +0 -0
- /reconcile/{test/saas_auto_promotions_manager/merge_request_manager → aws_saml_idp}/__init__.py +0 -0
- /reconcile/{test/saas_auto_promotions_manager/merge_request_manager/merge_request_manager → aws_saml_roles}/__init__.py +0 -0
- /reconcile/{test/saas_auto_promotions_manager/merge_request_manager/renderer → aws_version_sync}/__init__.py +0 -0
- /reconcile/{test/saas_auto_promotions_manager/subscriber → aws_version_sync/merge_request_manager}/__init__.py +0 -0
- /reconcile/{test/saas_auto_promotions_manager/utils → cluster_auth_rhidp}/__init__.py +0 -0
- /reconcile/{test/saas_auto_promotions_manager/utils/saas_files_inventory → dynatrace_token_provider}/__init__.py +0 -0
- {release → reconcile/endpoints_discovery}/__init__.py +0 -0
- {tools/test → reconcile/external_resources}/__init__.py +0 -0
@@ -16,14 +16,13 @@ from enum import Enum
|
|
16
16
|
from typing import (
|
17
17
|
Any,
|
18
18
|
Optional,
|
19
|
-
Tuple,
|
20
19
|
)
|
21
20
|
|
22
|
-
import anymarkup
|
23
21
|
import jinja2
|
24
22
|
import jinja2.meta
|
25
23
|
import jsonpath_ng
|
26
24
|
import networkx
|
25
|
+
from pydantic import Json
|
27
26
|
|
28
27
|
from reconcile.change_owners.approver import (
|
29
28
|
Approver,
|
@@ -34,13 +33,7 @@ from reconcile.change_owners.bundle import (
|
|
34
33
|
FileDiffResolver,
|
35
34
|
FileRef,
|
36
35
|
)
|
37
|
-
from reconcile.change_owners.diff import
|
38
|
-
SHA256SUM_FIELD_NAME,
|
39
|
-
SHA256SUM_PATH,
|
40
|
-
Diff,
|
41
|
-
DiffType,
|
42
|
-
extract_diffs,
|
43
|
-
)
|
36
|
+
from reconcile.change_owners.diff import Diff
|
44
37
|
from reconcile.gql_definitions.change_owners.queries.change_types import (
|
45
38
|
ChangeTypeChangeDetectorChangeTypeProviderV1,
|
46
39
|
ChangeTypeChangeDetectorJsonPathProviderV1,
|
@@ -62,11 +55,12 @@ class ChangeTypePriority(Enum):
|
|
62
55
|
CRITICAL = "critical"
|
63
56
|
URGENT = "urgent"
|
64
57
|
HIGH = "high"
|
58
|
+
PROGRESSIVE_DELIVERY = "progressive-delivery"
|
65
59
|
MEDIUM = "medium"
|
66
60
|
LOW = "low"
|
67
61
|
|
68
62
|
|
69
|
-
def parent_of_jsonpath(path: jsonpath_ng.JSONPath) ->
|
63
|
+
def parent_of_jsonpath(path: jsonpath_ng.JSONPath) -> jsonpath_ng.JSONPath | None:
|
70
64
|
# todo - figure out if this is enough of if we have other
|
71
65
|
# structures where a parent can be extracted
|
72
66
|
if isinstance(path, jsonpath_ng.Child):
|
@@ -86,6 +80,20 @@ class DiffCoverage:
|
|
86
80
|
|
87
81
|
parent: Optional["DiffCoverage"] = None
|
88
82
|
|
83
|
+
@property
|
84
|
+
def diff_fragments(self) -> Sequence["DiffCoverage"]:
|
85
|
+
return self._split_into
|
86
|
+
|
87
|
+
@property
|
88
|
+
def change_owner_labels(self) -> set[str]:
|
89
|
+
"""
|
90
|
+
Returns a list of change-owner labels of all involved change-type contexts.
|
91
|
+
"""
|
92
|
+
labels = {label for c in self.coverage for label in c.change_owner_labels or {}}
|
93
|
+
for _split in self._split_into:
|
94
|
+
labels.update(_split.change_owner_labels)
|
95
|
+
return labels
|
96
|
+
|
89
97
|
def relative_path(self) -> jsonpath_ng.JSONPath:
|
90
98
|
if self.parent:
|
91
99
|
path = remove_prefix_from_path(self.diff.path, self.parent.diff.path)
|
@@ -192,7 +200,7 @@ class DiffCoverage:
|
|
192
200
|
|
193
201
|
return None
|
194
202
|
|
195
|
-
def add_covering_context(self, ctx: "ChangeTypeContext"):
|
203
|
+
def add_covering_context(self, ctx: "ChangeTypeContext") -> None:
|
196
204
|
self.coverage.append(ctx)
|
197
205
|
for s in self._split_into:
|
198
206
|
s.add_covering_context(ctx)
|
@@ -216,172 +224,6 @@ class DiffCoverage:
|
|
216
224
|
return coverages
|
217
225
|
|
218
226
|
|
219
|
-
@dataclass
|
220
|
-
class BundleFileChange:
|
221
|
-
"""
|
222
|
-
Represents a file within an app-interface bundle that changed during an MR.
|
223
|
-
It holds the old and new state of that file, along with precise differences
|
224
|
-
between those states.
|
225
|
-
"""
|
226
|
-
|
227
|
-
fileref: FileRef
|
228
|
-
old: Optional[dict[str, Any]]
|
229
|
-
new: Optional[dict[str, Any]]
|
230
|
-
diffs: list[Diff]
|
231
|
-
_diff_coverage: dict[str, DiffCoverage] = field(init=False, default_factory=dict)
|
232
|
-
|
233
|
-
def __post_init__(self) -> None:
|
234
|
-
self._diff_coverage = {d.path_str(): DiffCoverage(d, []) for d in self.diffs}
|
235
|
-
|
236
|
-
def cover_changes(self, change_type_context: "ChangeTypeContext") -> list[Diff]:
|
237
|
-
"""
|
238
|
-
Figure out if a ChangeTypeV1 covers detected changes within the BundleFile.
|
239
|
-
Base idea:
|
240
|
-
|
241
|
-
- a ChangeTypeV1 defines path patterns that are considered self-approvable
|
242
|
-
- if a change (diff) is located under one of the allowed paths of the
|
243
|
-
ChangeTypeV1, it is considered "covered" by that ChangeTypeV1 in a certain
|
244
|
-
context (e.g. a RoleV1) and allows the approvers of that context (e.g.
|
245
|
-
the members of that role) to approve that particular change.
|
246
|
-
|
247
|
-
The change-type contexts that cover a change, are registered in the
|
248
|
-
`DiffCoverage.coverage` list right next to the Diff that is covered.
|
249
|
-
"""
|
250
|
-
covered_diffs = {}
|
251
|
-
# observe the new state for added fields or list items or entire object sutrees
|
252
|
-
covered_diffs.update(
|
253
|
-
self._cover_changes_for_diffs(
|
254
|
-
self._filter_diffs([DiffType.ADDED, DiffType.CHANGED]),
|
255
|
-
self.new,
|
256
|
-
change_type_context,
|
257
|
-
)
|
258
|
-
)
|
259
|
-
# look at the old state for removed fields or list items or object subtrees
|
260
|
-
covered_diffs.update(
|
261
|
-
self._cover_changes_for_diffs(
|
262
|
-
self._filter_diffs([DiffType.REMOVED]), self.old, change_type_context
|
263
|
-
)
|
264
|
-
)
|
265
|
-
return list(covered_diffs.values())
|
266
|
-
|
267
|
-
def _cover_changes_for_diffs(
|
268
|
-
self,
|
269
|
-
diffs: list[DiffCoverage],
|
270
|
-
file_content: Any,
|
271
|
-
change_type_context: "ChangeTypeContext",
|
272
|
-
) -> dict[str, Diff]:
|
273
|
-
|
274
|
-
covered_diffs = {}
|
275
|
-
if diffs:
|
276
|
-
for (
|
277
|
-
allowed_path
|
278
|
-
) in change_type_context.change_type_processor.allowed_changed_paths(
|
279
|
-
self.fileref, file_content, change_type_context
|
280
|
-
):
|
281
|
-
for dc in diffs:
|
282
|
-
if dc.changed_path_covered_by_path(allowed_path):
|
283
|
-
covered_diffs[dc.diff.path_str()] = dc.diff
|
284
|
-
dc.coverage.append(change_type_context)
|
285
|
-
elif SHA256SUM_PATH != allowed_path and dc.path_under_changed_path(
|
286
|
-
allowed_path
|
287
|
-
):
|
288
|
-
# the self-service path allowed by the change-type is covering
|
289
|
-
# only parts of the diff. we will split the diff into a
|
290
|
-
# smaller part, that can be covered by the change-type.
|
291
|
-
# but the rest of the diff needs to be covered by another
|
292
|
-
# change-type, either in full or again as a split.
|
293
|
-
sub_dc = dc.split(allowed_path, change_type_context)
|
294
|
-
if not sub_dc:
|
295
|
-
raise Exception(
|
296
|
-
f"unable to create a subdiff for path {allowed_path} on diff {dc.diff.path_str()}"
|
297
|
-
)
|
298
|
-
covered_diffs[str(allowed_path)] = sub_dc.diff
|
299
|
-
|
300
|
-
return covered_diffs
|
301
|
-
|
302
|
-
def _filter_diffs(self, diff_types: list[DiffType]) -> list[DiffCoverage]:
|
303
|
-
return [
|
304
|
-
d for d in self._diff_coverage.values() if d.diff.diff_type in diff_types
|
305
|
-
]
|
306
|
-
|
307
|
-
def all_changes_covered(self) -> bool:
|
308
|
-
return all(d.is_covered() for d in self.diff_coverage)
|
309
|
-
|
310
|
-
def raw_diff_count(self) -> int:
|
311
|
-
return len(self._diff_coverage)
|
312
|
-
|
313
|
-
@property
|
314
|
-
def diff_coverage(self) -> Sequence[DiffCoverage]:
|
315
|
-
"""
|
316
|
-
returns the meaningful set of diffs, potentially more fine grained than
|
317
|
-
what was originally detected for to the BundleFileChange.
|
318
|
-
"""
|
319
|
-
coverages: list[DiffCoverage] = []
|
320
|
-
for dc in self._diff_coverage.values():
|
321
|
-
coverages.extend(dc.fine_grained_diff_coverages().values())
|
322
|
-
return coverages
|
323
|
-
|
324
|
-
def involved_change_types(self) -> list["ChangeTypeProcessor"]:
|
325
|
-
"""
|
326
|
-
returns all the change-types that are involved in the coverage
|
327
|
-
of all changes
|
328
|
-
"""
|
329
|
-
change_types = []
|
330
|
-
for dc in self.diff_coverage:
|
331
|
-
for ctx in dc.coverage:
|
332
|
-
change_types.append(ctx.change_type_processor)
|
333
|
-
return change_types
|
334
|
-
|
335
|
-
|
336
|
-
def parse_resource_file_content(content: Optional[Any]) -> tuple[Any, Optional[str]]:
|
337
|
-
if content:
|
338
|
-
try:
|
339
|
-
data = anymarkup.parse(content, force_types=None)
|
340
|
-
return data, data.get("$schema")
|
341
|
-
except Exception:
|
342
|
-
# not parsable content - we will just deal with the plain content
|
343
|
-
return content, None
|
344
|
-
else:
|
345
|
-
return None, None
|
346
|
-
|
347
|
-
|
348
|
-
def create_bundle_file_change(
|
349
|
-
path: str,
|
350
|
-
schema: Optional[str],
|
351
|
-
file_type: BundleFileType,
|
352
|
-
old_file_content: Any,
|
353
|
-
new_file_content: Any,
|
354
|
-
) -> Optional[BundleFileChange]:
|
355
|
-
"""
|
356
|
-
this is a factory method that creates a BundleFileChange object based
|
357
|
-
on the old and new content of a file from app-interface. it detects differences
|
358
|
-
within the old and new state of the file and represents them as instances
|
359
|
-
of the Diff dataclass. for diff detection, the amazing `deepdiff` python
|
360
|
-
library is used.
|
361
|
-
"""
|
362
|
-
fileref = FileRef(path=path, schema=schema, file_type=file_type)
|
363
|
-
|
364
|
-
# try to parse the content of a resourcefile
|
365
|
-
# it falls back to the plain file content if parsing does not work
|
366
|
-
if file_type == BundleFileType.RESOURCEFILE:
|
367
|
-
old_file_content, _ = parse_resource_file_content(old_file_content)
|
368
|
-
new_file_content, _ = parse_resource_file_content(new_file_content)
|
369
|
-
|
370
|
-
diffs = extract_diffs(
|
371
|
-
old_file_content=old_file_content,
|
372
|
-
new_file_content=new_file_content,
|
373
|
-
)
|
374
|
-
|
375
|
-
if diffs:
|
376
|
-
return BundleFileChange(
|
377
|
-
fileref=fileref,
|
378
|
-
old=old_file_content,
|
379
|
-
new=new_file_content,
|
380
|
-
diffs=diffs,
|
381
|
-
)
|
382
|
-
return None
|
383
|
-
|
384
|
-
|
385
227
|
class PathExpression:
|
386
228
|
"""
|
387
229
|
PathExpression is a wrapper around a JSONPath expression that can contain
|
@@ -411,14 +253,12 @@ class PathExpression:
|
|
411
253
|
if self.parsed_jsonpath:
|
412
254
|
return self.parsed_jsonpath
|
413
255
|
|
414
|
-
expr = self.template.render(
|
415
|
-
|
416
|
-
|
417
|
-
}
|
418
|
-
)
|
256
|
+
expr = self.template.render({
|
257
|
+
self.CTX_FILE_PATH_VAR_NAME: ctx.context_file.path,
|
258
|
+
})
|
419
259
|
return parse_jsonpath(expr)
|
420
260
|
|
421
|
-
def __eq__(self, obj):
|
261
|
+
def __eq__(self, obj: object) -> bool:
|
422
262
|
return (
|
423
263
|
isinstance(obj, PathExpression)
|
424
264
|
and obj.jsonpath_expression == self.jsonpath_expression
|
@@ -426,20 +266,35 @@ class PathExpression:
|
|
426
266
|
|
427
267
|
|
428
268
|
@dataclass
|
429
|
-
class
|
269
|
+
class FileChange:
|
270
|
+
file_ref: FileRef
|
271
|
+
old: dict[str, Any] | None
|
272
|
+
new: dict[str, Any] | None
|
273
|
+
old_backrefs: set[FileRef] = field(default_factory=set)
|
274
|
+
new_backrefs: set[FileRef] = field(default_factory=set)
|
275
|
+
|
276
|
+
|
277
|
+
class OwnershipContext(ABC):
|
278
|
+
@abstractmethod
|
279
|
+
def find_ownership_context(
|
280
|
+
self,
|
281
|
+
context_schema: str | None,
|
282
|
+
change: FileChange,
|
283
|
+
) -> list[FileRef]: ...
|
284
|
+
|
285
|
+
|
286
|
+
@dataclass
|
287
|
+
class ForwardrefOwnershipContext(OwnershipContext):
|
430
288
|
selector: jsonpath_ng.JSONPath
|
431
|
-
when:
|
289
|
+
when: str | None = None
|
432
290
|
|
433
291
|
def find_ownership_context(
|
434
292
|
self,
|
435
|
-
context_schema:
|
436
|
-
|
437
|
-
new_data: Optional[dict[str, Any]] = None,
|
293
|
+
context_schema: str | None,
|
294
|
+
change: FileChange,
|
438
295
|
) -> list[FileRef]:
|
439
|
-
|
440
|
-
|
441
|
-
old_contexts = {e.value for e in self.selector.find(old_data)}
|
442
|
-
new_contexts = {e.value for e in self.selector.find(new_data)}
|
296
|
+
old_contexts = {e.value for e in self.selector.find(change.old)}
|
297
|
+
new_contexts = {e.value for e in self.selector.find(change.new)}
|
443
298
|
|
444
299
|
# apply conditions
|
445
300
|
if self.when == "added":
|
@@ -461,6 +316,46 @@ class OwnershipContext:
|
|
461
316
|
]
|
462
317
|
|
463
318
|
|
319
|
+
@dataclass
|
320
|
+
class BackrefOwnershipContext(OwnershipContext):
|
321
|
+
selector: jsonpath_ng.JSONPath
|
322
|
+
file_diff_resolver: FileDiffResolver
|
323
|
+
when: str | None = None
|
324
|
+
|
325
|
+
def find_ownership_context(
|
326
|
+
self,
|
327
|
+
context_schema: str | None,
|
328
|
+
change: FileChange,
|
329
|
+
) -> list[FileRef]:
|
330
|
+
# get backref datafile content
|
331
|
+
backref_datafile_content = {
|
332
|
+
ref: self.file_diff_resolver.lookup_file_diff(ref)
|
333
|
+
for ref in change.old_backrefs.union(change.new_backrefs)
|
334
|
+
}
|
335
|
+
|
336
|
+
# extract contexts
|
337
|
+
# we only care for those backrefs that mention the changed file at the selector
|
338
|
+
old_contexts = {
|
339
|
+
ref
|
340
|
+
for ref, data in backref_datafile_content.items()
|
341
|
+
if any(f.value == change.file_ref.path for f in self.selector.find(data[0]))
|
342
|
+
}
|
343
|
+
new_contexts = {
|
344
|
+
ref
|
345
|
+
for ref, data in backref_datafile_content.items()
|
346
|
+
if any(f.value == change.file_ref.path for f in self.selector.find(data[1]))
|
347
|
+
}
|
348
|
+
|
349
|
+
# apply conditions
|
350
|
+
if self.when == "added":
|
351
|
+
return list(new_contexts.difference(old_contexts))
|
352
|
+
if self.when == "removed":
|
353
|
+
return list(old_contexts.difference(new_contexts))
|
354
|
+
if self.when is None and old_contexts == new_contexts:
|
355
|
+
return list(old_contexts)
|
356
|
+
return []
|
357
|
+
|
358
|
+
|
464
359
|
@dataclass
|
465
360
|
class ContextExpansion:
|
466
361
|
"""
|
@@ -475,16 +370,22 @@ class ContextExpansion:
|
|
475
370
|
def expand_from_file_ref(
|
476
371
|
self,
|
477
372
|
file_ref: FileRef,
|
478
|
-
expansion_trail: Set[
|
373
|
+
expansion_trail: Set[tuple[str, FileRef]],
|
479
374
|
) -> list["ResolvedContext"]:
|
480
375
|
old_data, new_data = self.file_diff_resolver.lookup_file_diff(file_ref)
|
481
|
-
return self.expand(
|
376
|
+
return self.expand(
|
377
|
+
FileChange(
|
378
|
+
file_ref=file_ref,
|
379
|
+
old=old_data,
|
380
|
+
new=new_data,
|
381
|
+
),
|
382
|
+
expansion_trail,
|
383
|
+
)
|
482
384
|
|
483
385
|
def expand(
|
484
386
|
self,
|
485
|
-
|
486
|
-
|
487
|
-
expansion_trail: Set[Tuple[str, FileRef]],
|
387
|
+
change: FileChange,
|
388
|
+
expansion_trail: Set[tuple[str, FileRef]],
|
488
389
|
) -> list["ResolvedContext"]:
|
489
390
|
"""
|
490
391
|
Find context based on the `self.context`, lookup the file diff for
|
@@ -493,17 +394,18 @@ class ContextExpansion:
|
|
493
394
|
"""
|
494
395
|
context_file_refs = self.context.find_ownership_context(
|
495
396
|
context_schema=self.change_type.context_schema,
|
496
|
-
|
497
|
-
new_data=new_data,
|
397
|
+
change=change,
|
498
398
|
)
|
499
|
-
expaned_context_file_refs: list[
|
399
|
+
expaned_context_file_refs: list[ResolvedContext] = []
|
500
400
|
for ref in context_file_refs:
|
501
401
|
ref_old_data, ref_new_data = self.file_diff_resolver.lookup_file_diff(ref)
|
502
402
|
expaned_context_file_refs.extend(
|
503
403
|
self.change_type.find_context_file_refs(
|
504
|
-
|
505
|
-
|
506
|
-
|
404
|
+
change=FileChange(
|
405
|
+
file_ref=ref,
|
406
|
+
old=ref_old_data,
|
407
|
+
new=ref_new_data,
|
408
|
+
),
|
507
409
|
expansion_trail=expansion_trail,
|
508
410
|
)
|
509
411
|
)
|
@@ -528,28 +430,25 @@ class ChangeDetector(ABC):
|
|
528
430
|
Represents an item from a change-types `change` list.
|
529
431
|
"""
|
530
432
|
|
531
|
-
context_schema:
|
532
|
-
change_schema:
|
533
|
-
context:
|
433
|
+
context_schema: str | None
|
434
|
+
change_schema: str | None
|
435
|
+
context: OwnershipContext | None
|
534
436
|
|
535
437
|
@abstractmethod
|
536
438
|
def find_context_file_refs(
|
537
439
|
self,
|
538
|
-
|
539
|
-
|
540
|
-
) -> list[FileRef]:
|
541
|
-
...
|
440
|
+
change: FileChange,
|
441
|
+
) -> list[FileRef]: ...
|
542
442
|
|
543
443
|
|
544
444
|
@dataclass
|
545
445
|
class JsonPathChangeDetector(ChangeDetector):
|
546
446
|
json_path_selectors: list[str]
|
547
447
|
|
548
|
-
def __post_init__(self):
|
448
|
+
def __post_init__(self) -> None:
|
549
449
|
self._json_path_expressions = [
|
550
450
|
PathExpression(jsonpath_expression)
|
551
451
|
for jsonpath_expression in self.json_path_selectors
|
552
|
-
+ [f"'{SHA256SUM_FIELD_NAME}'"]
|
553
452
|
]
|
554
453
|
|
555
454
|
@property
|
@@ -558,12 +457,12 @@ class JsonPathChangeDetector(ChangeDetector):
|
|
558
457
|
|
559
458
|
def find_context_file_refs(
|
560
459
|
self,
|
561
|
-
|
562
|
-
new_data: Optional[dict[str, Any]] = None,
|
460
|
+
change: FileChange,
|
563
461
|
) -> list[FileRef]:
|
564
462
|
if self.context:
|
565
463
|
return self.context.find_ownership_context(
|
566
|
-
self.context_schema,
|
464
|
+
context_schema=self.context_schema,
|
465
|
+
change=change,
|
567
466
|
)
|
568
467
|
return []
|
569
468
|
|
@@ -577,19 +476,22 @@ class ChangeTypeProcessor:
|
|
577
476
|
"""
|
578
477
|
|
579
478
|
name: str
|
479
|
+
labels: Json | None
|
580
480
|
description: str
|
581
481
|
priority: ChangeTypePriority
|
582
482
|
context_type: BundleFileType
|
583
|
-
context_schema:
|
483
|
+
context_schema: str | None
|
584
484
|
disabled: bool
|
585
485
|
implicit_ownership: list[ChangeTypeImplicitOwnershipV1]
|
486
|
+
restrictive: bool | None = False
|
586
487
|
|
587
|
-
def __post_init__(self):
|
488
|
+
def __post_init__(self) -> None:
|
588
489
|
self._expressions_by_file_type_schema: dict[
|
589
|
-
tuple[BundleFileType,
|
490
|
+
tuple[BundleFileType, str | None], list[PathExpression]
|
590
491
|
] = defaultdict(list)
|
591
492
|
self._change_detectors: list[ChangeDetector] = []
|
592
493
|
self._context_expansions: list[ContextExpansion] = []
|
494
|
+
self._heritage: set[str] = set()
|
593
495
|
|
594
496
|
@property
|
595
497
|
def change_detectors(self) -> Sequence[ChangeDetector]:
|
@@ -597,10 +499,8 @@ class ChangeTypeProcessor:
|
|
597
499
|
|
598
500
|
def find_context_file_refs(
|
599
501
|
self,
|
600
|
-
|
601
|
-
|
602
|
-
new_data: Optional[dict[str, Any]],
|
603
|
-
expansion_trail: Set[Tuple[str, FileRef]],
|
502
|
+
change: FileChange,
|
503
|
+
expansion_trail: Set[tuple[str, FileRef]],
|
604
504
|
) -> list[ResolvedContext]:
|
605
505
|
"""
|
606
506
|
ChangeTypeV1 are attached to bundle files, react to changes within
|
@@ -659,31 +559,31 @@ class ChangeTypeProcessor:
|
|
659
559
|
|
660
560
|
# prevent infinite ownership resolution
|
661
561
|
expansion_trail_copy = set(expansion_trail)
|
662
|
-
if (self.name, file_ref) in expansion_trail_copy:
|
562
|
+
if (self.name, change.file_ref) in expansion_trail_copy:
|
663
563
|
return contexts
|
664
564
|
|
665
|
-
expansion_trail_copy.add((self.name, file_ref))
|
565
|
+
expansion_trail_copy.add((self.name, change.file_ref))
|
666
566
|
|
667
567
|
# direct context extraction
|
668
568
|
# the changed file itself is giving the context for approver extraction
|
669
569
|
# see doc string for more details
|
670
|
-
if self.context_schema is None or self.context_schema == file_ref.schema:
|
570
|
+
if self.context_schema is None or self.context_schema == change.file_ref.schema:
|
671
571
|
contexts.append(
|
672
572
|
ResolvedContext(
|
673
|
-
owned_file_ref=file_ref,
|
674
|
-
context_file_ref=file_ref,
|
573
|
+
owned_file_ref=change.file_ref,
|
574
|
+
context_file_ref=change.file_ref,
|
675
575
|
change_type=self,
|
676
576
|
)
|
677
577
|
)
|
678
578
|
|
679
579
|
# expand context based on change-type composition
|
680
580
|
for ce in self._context_expansions:
|
681
|
-
for ec in ce.expand(
|
581
|
+
for ec in ce.expand(change, expansion_trail_copy):
|
682
582
|
# add expanded contexts (derived owned files)
|
683
583
|
contexts.append(
|
684
584
|
ResolvedContext(
|
685
585
|
owned_file_ref=ec.owned_file_ref,
|
686
|
-
context_file_ref=file_ref,
|
586
|
+
context_file_ref=change.file_ref,
|
687
587
|
change_type=ec.change_type,
|
688
588
|
)
|
689
589
|
)
|
@@ -693,8 +593,8 @@ class ChangeTypeProcessor:
|
|
693
593
|
# file with a `context.selector`
|
694
594
|
# see doc string for more details
|
695
595
|
for c in self.change_detectors:
|
696
|
-
if c.change_schema == file_ref.schema:
|
697
|
-
for ctx_file_ref in c.find_context_file_refs(
|
596
|
+
if c.change_schema == change.file_ref.schema:
|
597
|
+
for ctx_file_ref in c.find_context_file_refs(change):
|
698
598
|
contexts.append(
|
699
599
|
ResolvedContext(
|
700
600
|
owned_file_ref=ctx_file_ref,
|
@@ -740,7 +640,7 @@ class ChangeTypeProcessor:
|
|
740
640
|
def _allowed_changed_paths_for_file_type_and_schema(
|
741
641
|
self,
|
742
642
|
file_type: BundleFileType,
|
743
|
-
file_schema:
|
643
|
+
file_schema: str | None,
|
744
644
|
file_content: Any,
|
745
645
|
ctx: "ChangeTypeContext",
|
746
646
|
) -> list[jsonpath_ng.JSONPath]:
|
@@ -750,16 +650,14 @@ class ChangeTypeProcessor:
|
|
750
650
|
file_schema,
|
751
651
|
) in self._expressions_by_file_type_schema:
|
752
652
|
for change_type_path_expression in self._expressions_by_file_type_schema[
|
753
|
-
|
653
|
+
file_type, file_schema
|
754
654
|
]:
|
755
|
-
paths.extend(
|
756
|
-
|
757
|
-
|
758
|
-
|
759
|
-
|
760
|
-
|
761
|
-
]
|
762
|
-
)
|
655
|
+
paths.extend([
|
656
|
+
p.full_path
|
657
|
+
for p in change_type_path_expression.jsonpath_for_context(ctx).find(
|
658
|
+
file_content
|
659
|
+
)
|
660
|
+
])
|
763
661
|
return paths
|
764
662
|
|
765
663
|
def add_change_detector(
|
@@ -770,7 +668,7 @@ class ChangeTypeProcessor:
|
|
770
668
|
self._change_detectors.append(detector)
|
771
669
|
change_schema = detector.change_schema or self.context_schema
|
772
670
|
expressions = self._expressions_by_file_type_schema[
|
773
|
-
|
671
|
+
self.context_type, change_schema
|
774
672
|
]
|
775
673
|
for path_expression in detector.json_path_expressions:
|
776
674
|
if path_expression not in expressions:
|
@@ -780,9 +678,34 @@ class ChangeTypeProcessor:
|
|
780
678
|
f"{type(detector)} is not a supported change detection provider within ChangeTypes"
|
781
679
|
)
|
782
680
|
|
783
|
-
def add_context_expansion(self, context_expansion: ContextExpansion):
|
681
|
+
def add_context_expansion(self, context_expansion: ContextExpansion) -> None:
|
784
682
|
self._context_expansions.append(context_expansion)
|
785
683
|
|
684
|
+
def inherit_from(self, other: "ChangeTypeProcessor") -> None:
|
685
|
+
for detector in other.change_detectors:
|
686
|
+
self.add_change_detector(detector)
|
687
|
+
other._heritage = self.lineage.union(other._heritage)
|
688
|
+
|
689
|
+
@property
|
690
|
+
def lineage(self) -> set[str]:
|
691
|
+
return self._heritage.union({self.name})
|
692
|
+
|
693
|
+
|
694
|
+
def build_ownership_context(
|
695
|
+
file_diff_resolver: FileDiffResolver,
|
696
|
+
selector: jsonpath_ng.JSONPath,
|
697
|
+
when: str | None = None,
|
698
|
+
where: str | None = None,
|
699
|
+
) -> OwnershipContext:
|
700
|
+
"""
|
701
|
+
create an OwnershipContext object based on the provided parameters
|
702
|
+
"""
|
703
|
+
if where == "backrefs":
|
704
|
+
return BackrefOwnershipContext(
|
705
|
+
file_diff_resolver=file_diff_resolver, selector=selector, when=when
|
706
|
+
)
|
707
|
+
return ForwardrefOwnershipContext(selector=selector, when=when)
|
708
|
+
|
786
709
|
|
787
710
|
def init_change_type_processors(
|
788
711
|
change_types: Sequence[ChangeTypeV1], file_diff_resolver: FileDiffResolver
|
@@ -795,11 +718,13 @@ def init_change_type_processors(
|
|
795
718
|
# build raw change-type-processor
|
796
719
|
processors[change_type.name] = ChangeTypeProcessor(
|
797
720
|
name=change_type.name,
|
721
|
+
labels=change_type.labels,
|
798
722
|
description=change_type.description,
|
799
723
|
priority=ChangeTypePriority(change_type.priority),
|
800
724
|
context_type=BundleFileType[change_type.context_type.upper()],
|
801
725
|
context_schema=change_type.context_schema,
|
802
726
|
disabled=bool(change_type.disabled),
|
727
|
+
restrictive=bool(change_type.restrictive),
|
803
728
|
implicit_ownership=change_type.implicit_ownership or [],
|
804
729
|
)
|
805
730
|
# register inheritance edges for cycle detection
|
@@ -814,9 +739,11 @@ def init_change_type_processors(
|
|
814
739
|
if isinstance(change_detector, ChangeTypeChangeDetectorJsonPathProviderV1):
|
815
740
|
ownership_context = None
|
816
741
|
if change_detector.context:
|
817
|
-
ownership_context =
|
742
|
+
ownership_context = build_ownership_context(
|
743
|
+
file_diff_resolver=file_diff_resolver,
|
818
744
|
selector=parse_jsonpath(change_detector.context.selector),
|
819
745
|
when=change_detector.context.when,
|
746
|
+
where=change_detector.context.where,
|
820
747
|
)
|
821
748
|
processor.add_change_detector(
|
822
749
|
JsonPathChangeDetector(
|
@@ -840,11 +767,13 @@ def init_change_type_processors(
|
|
840
767
|
processors[ct.name].add_context_expansion(
|
841
768
|
ContextExpansion(
|
842
769
|
change_type=processor,
|
843
|
-
context=
|
770
|
+
context=build_ownership_context(
|
771
|
+
file_diff_resolver=file_diff_resolver,
|
844
772
|
selector=parse_jsonpath(
|
845
773
|
change_detector.ownership_context.selector
|
846
774
|
),
|
847
775
|
when=change_detector.ownership_context.when,
|
776
|
+
where=change_detector.ownership_context.where,
|
848
777
|
),
|
849
778
|
file_diff_resolver=file_diff_resolver,
|
850
779
|
)
|
@@ -875,8 +804,13 @@ def init_change_type_processors(
|
|
875
804
|
f"change-type '{ctp.name}' inherits from '{d}' "
|
876
805
|
"but has a different context_schema"
|
877
806
|
)
|
878
|
-
|
879
|
-
|
807
|
+
|
808
|
+
# the higher level change type adopts the change detectors from his decentents
|
809
|
+
ctp.inherit_from(processors[d])
|
810
|
+
|
811
|
+
# the decentents adopt the context expansions from the higher level change type
|
812
|
+
for ce in ctp._context_expansions:
|
813
|
+
processors[d].add_context_expansion(ce)
|
880
814
|
|
881
815
|
return processors
|
882
816
|
|
@@ -909,7 +843,8 @@ class ChangeTypeContext:
|
|
909
843
|
origin: str
|
910
844
|
context_file: FileRef
|
911
845
|
approvers: list[Approver]
|
912
|
-
approver_reachability:
|
846
|
+
approver_reachability: list[ApproverReachability] | None = None
|
847
|
+
change_owner_labels: set[str] | None = None
|
913
848
|
|
914
849
|
@property
|
915
850
|
def disabled(self) -> bool:
|
@@ -927,20 +862,3 @@ JSON_PATH_ROOT = "$"
|
|
927
862
|
|
928
863
|
def change_path_covered_by_allowed_path(changed_path: str, allowed_path: str) -> bool:
|
929
864
|
return changed_path.startswith(allowed_path) or allowed_path == JSON_PATH_ROOT
|
930
|
-
|
931
|
-
|
932
|
-
def get_priority_for_changes(
|
933
|
-
bundle_file_changes: list[BundleFileChange],
|
934
|
-
) -> Optional[ChangeTypePriority]:
|
935
|
-
"""
|
936
|
-
Finds the lowest priority of all change types involved in the provided bundle file changes.
|
937
|
-
"""
|
938
|
-
priorities: set[ChangeTypePriority] = set()
|
939
|
-
for bfc in bundle_file_changes:
|
940
|
-
for ct in bfc.involved_change_types():
|
941
|
-
priorities.add(ct.priority)
|
942
|
-
# get the lowest priority
|
943
|
-
for p in reversed(ChangeTypePriority):
|
944
|
-
if p in priorities:
|
945
|
-
return p
|
946
|
-
return None
|