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
@@ -0,0 +1,160 @@
|
|
1
|
+
import logging
|
2
|
+
|
3
|
+
from gitlab.exceptions import GitlabGetError
|
4
|
+
from pydantic import BaseModel
|
5
|
+
|
6
|
+
from reconcile.aws_version_sync.merge_request_manager.merge_request import (
|
7
|
+
AVS_LABEL,
|
8
|
+
AVSInfo,
|
9
|
+
Parser,
|
10
|
+
Renderer,
|
11
|
+
)
|
12
|
+
from reconcile.utils.gitlab_api import GitLabApi
|
13
|
+
from reconcile.utils.merge_request_manager.merge_request_manager import (
|
14
|
+
MergeRequestManagerBase,
|
15
|
+
)
|
16
|
+
from reconcile.utils.mr.base import MergeRequestBase
|
17
|
+
from reconcile.utils.mr.labels import AUTO_MERGE
|
18
|
+
from reconcile.utils.vcs import VCS
|
19
|
+
|
20
|
+
|
21
|
+
class AVSMR(MergeRequestBase):
|
22
|
+
name = "AVS"
|
23
|
+
|
24
|
+
def __init__(
|
25
|
+
self, title: str, description: str, path: str, content: str, labels: list[str]
|
26
|
+
):
|
27
|
+
super().__init__()
|
28
|
+
self._title = title
|
29
|
+
self._description = description
|
30
|
+
self._path = path
|
31
|
+
self._content = content
|
32
|
+
self.labels = labels
|
33
|
+
|
34
|
+
@property
|
35
|
+
def title(self) -> str:
|
36
|
+
return self._title
|
37
|
+
|
38
|
+
@property
|
39
|
+
def description(self) -> str:
|
40
|
+
return self._description
|
41
|
+
|
42
|
+
def process(self, gitlab_cli: GitLabApi) -> None:
|
43
|
+
gitlab_cli.update_file(
|
44
|
+
branch_name=self.branch,
|
45
|
+
file_path=f"data{self._path}",
|
46
|
+
commit_message="aws version sync",
|
47
|
+
content=self._content,
|
48
|
+
)
|
49
|
+
|
50
|
+
|
51
|
+
class MrData(BaseModel):
|
52
|
+
namespace_file: str
|
53
|
+
provider: str
|
54
|
+
provisioner_ref: str
|
55
|
+
provisioner_uid: str
|
56
|
+
resource_provider: str
|
57
|
+
resource_identifier: str
|
58
|
+
resource_engine: str
|
59
|
+
resource_engine_version: str
|
60
|
+
|
61
|
+
|
62
|
+
class MergeRequestManager(MergeRequestManagerBase[AVSInfo]):
|
63
|
+
"""
|
64
|
+
Manager for AVS merge requests. This class
|
65
|
+
is responsible for housekeeping (closing old/bad MRs) and
|
66
|
+
opening new MRs for external resources that have new versions.
|
67
|
+
|
68
|
+
For each external resource, there are exist just one MR to update
|
69
|
+
the version number in the App-Interface. Old or obsolete MRs are
|
70
|
+
closed automatically.
|
71
|
+
"""
|
72
|
+
|
73
|
+
def __init__(
|
74
|
+
self, vcs: VCS, renderer: Renderer, parser: Parser, auto_merge_enabled: bool
|
75
|
+
):
|
76
|
+
super().__init__(vcs, parser, AVS_LABEL)
|
77
|
+
self._renderer = renderer
|
78
|
+
self._auto_merge_enabled = auto_merge_enabled
|
79
|
+
|
80
|
+
def create_merge_request(
|
81
|
+
self,
|
82
|
+
data: MrData,
|
83
|
+
) -> None:
|
84
|
+
"""Open new MR (if not already present) for an external resource and close any outdated before."""
|
85
|
+
if not self._housekeeping_ran:
|
86
|
+
self.housekeeping()
|
87
|
+
|
88
|
+
namespace_file = data.namespace_file
|
89
|
+
provider = data.provider
|
90
|
+
provisioner_ref = data.provisioner_ref
|
91
|
+
provisioner_uid = data.provisioner_uid
|
92
|
+
resource_provider = data.resource_provider
|
93
|
+
resource_identifier = data.resource_identifier
|
94
|
+
resource_engine = data.resource_engine
|
95
|
+
resource_engine_version = data.resource_engine_version
|
96
|
+
|
97
|
+
if mr := self._merge_request_already_exists({
|
98
|
+
"provider": provider,
|
99
|
+
"account_id": provisioner_uid,
|
100
|
+
"resource_provider": resource_provider,
|
101
|
+
"resource_identifier": resource_identifier,
|
102
|
+
"resource_engine": resource_engine,
|
103
|
+
}):
|
104
|
+
if mr.mr_info.resource_engine_version == resource_engine_version:
|
105
|
+
# an MR for this external resource already exists
|
106
|
+
return None
|
107
|
+
logging.info(
|
108
|
+
"Found an outdated MR for '%s' - closing it.", resource_identifier
|
109
|
+
)
|
110
|
+
self._vcs.close_app_interface_mr(
|
111
|
+
mr.raw, "Closing this MR because it's outdated."
|
112
|
+
)
|
113
|
+
# don't open a new MR right now, because the deletion of the old MRs could be
|
114
|
+
# disabled. In this case, we would end up with multiple open MRs for the
|
115
|
+
# same external resource.
|
116
|
+
return None
|
117
|
+
|
118
|
+
try:
|
119
|
+
content = self._vcs.get_file_content_from_app_interface_master(
|
120
|
+
file_path=namespace_file
|
121
|
+
)
|
122
|
+
except GitlabGetError as e:
|
123
|
+
if e.response_code == 404:
|
124
|
+
logging.error(
|
125
|
+
"The file %s does not exist anylonger. Most likely qontract-server data not in synch. This should resolve soon on its own.",
|
126
|
+
namespace_file,
|
127
|
+
)
|
128
|
+
return None
|
129
|
+
raise e
|
130
|
+
content = self._renderer.render_merge_request_content(
|
131
|
+
current_content=content,
|
132
|
+
provider=provider,
|
133
|
+
provisioner_ref=provisioner_ref,
|
134
|
+
resource_provider=resource_provider,
|
135
|
+
resource_identifier=resource_identifier,
|
136
|
+
resource_engine_version=resource_engine_version,
|
137
|
+
)
|
138
|
+
|
139
|
+
description = self._renderer.render_description(
|
140
|
+
provider=provider,
|
141
|
+
account_id=provisioner_uid,
|
142
|
+
resource_provider=resource_provider,
|
143
|
+
resource_identifier=resource_identifier,
|
144
|
+
resource_engine=resource_engine,
|
145
|
+
resource_engine_version=resource_engine_version,
|
146
|
+
)
|
147
|
+
title = self._renderer.render_title(resource_identifier=resource_identifier)
|
148
|
+
logging.info("Open MR for %s (%s)", resource_identifier, resource_engine)
|
149
|
+
mr_labels = [AVS_LABEL]
|
150
|
+
if self._auto_merge_enabled:
|
151
|
+
mr_labels.append(AUTO_MERGE)
|
152
|
+
self._vcs.open_app_interface_merge_request(
|
153
|
+
mr=AVSMR(
|
154
|
+
path=namespace_file,
|
155
|
+
title=title,
|
156
|
+
description=description,
|
157
|
+
content=content,
|
158
|
+
labels=mr_labels,
|
159
|
+
)
|
160
|
+
)
|
@@ -0,0 +1,64 @@
|
|
1
|
+
from collections.abc import (
|
2
|
+
Callable,
|
3
|
+
Iterable,
|
4
|
+
Mapping,
|
5
|
+
)
|
6
|
+
from typing import (
|
7
|
+
Any,
|
8
|
+
TypeVar,
|
9
|
+
)
|
10
|
+
from urllib.parse import urljoin
|
11
|
+
|
12
|
+
import anymarkup
|
13
|
+
import requests
|
14
|
+
|
15
|
+
from reconcile.utils.exceptions import FetchResourceError
|
16
|
+
from reconcile.utils.gql import GqlGetResourceError
|
17
|
+
|
18
|
+
|
19
|
+
def prom_get(
|
20
|
+
url: str,
|
21
|
+
params: Mapping[Any, Any] | None = None,
|
22
|
+
token: str | None = None,
|
23
|
+
ssl_verify: bool = True,
|
24
|
+
uri: str = "api/v1/query",
|
25
|
+
timeout: int = 60,
|
26
|
+
) -> list[dict[str, str]]:
|
27
|
+
url = urljoin(url, uri)
|
28
|
+
headers = {"accept": "application/json"}
|
29
|
+
if token:
|
30
|
+
headers["Authorization"] = f"Bearer {token}"
|
31
|
+
|
32
|
+
response = requests.get(
|
33
|
+
url, params=params, headers=headers, verify=ssl_verify, timeout=timeout
|
34
|
+
)
|
35
|
+
response.raise_for_status()
|
36
|
+
return [r["metric"] for r in response.json()["data"]["result"]]
|
37
|
+
|
38
|
+
|
39
|
+
Key = TypeVar("Key")
|
40
|
+
T = TypeVar("T")
|
41
|
+
|
42
|
+
|
43
|
+
def uniquify(key: Callable[[T], Key], items: Iterable[T]) -> list[T]:
|
44
|
+
return list({key(item): item for item in items}.values())
|
45
|
+
|
46
|
+
|
47
|
+
def get_values(gql_get_resource_func: Callable, path: str) -> dict[str, Any]:
|
48
|
+
try:
|
49
|
+
raw_values = gql_get_resource_func(path)
|
50
|
+
except GqlGetResourceError as e:
|
51
|
+
raise FetchResourceError(str(e)) from e
|
52
|
+
try:
|
53
|
+
values = anymarkup.parse(raw_values["content"], force_types=None)
|
54
|
+
values.pop("$schema", None)
|
55
|
+
except anymarkup.AnyMarkupError as e:
|
56
|
+
e_msg = "Could not parse data. Skipping resource: {}"
|
57
|
+
raise FetchResourceError(e_msg.format(path)) from e
|
58
|
+
return values
|
59
|
+
|
60
|
+
|
61
|
+
def override_values(values: Mapping, overrides: Mapping | None) -> dict:
|
62
|
+
if overrides is None:
|
63
|
+
return {**values}
|
64
|
+
return {**values, **overrides}
|
@@ -1,9 +1,6 @@
|
|
1
1
|
import logging
|
2
2
|
import sys
|
3
|
-
from typing import
|
4
|
-
Any,
|
5
|
-
Optional,
|
6
|
-
)
|
3
|
+
from typing import Any
|
7
4
|
|
8
5
|
from reconcile import queries
|
9
6
|
from reconcile.closedbox_endpoint_monitoring_base import (
|
@@ -69,7 +66,7 @@ def get_blackbox_providers() -> list[EndpointMonitoringProvider]:
|
|
69
66
|
|
70
67
|
def build_probe(
|
71
68
|
provider: EndpointMonitoringProvider, endpoints: list[Endpoint]
|
72
|
-
) ->
|
69
|
+
) -> OpenshiftResource | None:
|
73
70
|
blackbox_exporter = provider.blackboxExporter
|
74
71
|
if blackbox_exporter:
|
75
72
|
prober_url = parse_prober_url(blackbox_exporter.exporterUrl)
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# Integration change-owners
|
2
|
+
|
3
|
+
`change-owners` uses change-type declarations from `app-interface` to grant self-service change permissions to `app-interface` tenants.
|
4
|
+
|
5
|
+
|
6
|
+
## Module structure
|
7
|
+
|
8
|
+
* `reconcile.change_owners.diff` contains all functionality for low-level diffing on file content. It can be used to extract differences from files as `Diff` dataclasses.
|
9
|
+
* `reconcile.change_owners.change_types` uses the `diff` module to extract relevant changes and tries to cover them with `change-types` from `app-interface`. The results are `BundleFileChange` dataclasses that contain all the found changes along with the `change-types` covering them. A change is considered `covered` when at least one `change-type` allows the changes in a context that provides approvers.
|
10
|
+
* `reconcile.change_owners.self_service_roles` is a change coverage implementation that uses `RoleV1.self_service` configurations from `app-interface` to bring changes, change-types and approvers together in a `ChangeTypeContext`.
|
11
|
+
* `reconcile.change_owners.decision` handles MR decision command parsing from eligible change approvers.
|
12
|
+
* `reconcile.change_owners.change_owners` is the entry point for the integrations and acts mostly as a coordinator between the other modules.
|
13
|
+
|
14
|
+
## Functionality
|
15
|
+
|
16
|
+
`change_owners` uses the `qontract-server` diff endpoint to get a highlevel overview what changed in an MR. It leverages `change_types` to find fine grained differences in datafiles and resourcefiles and build `BundleFileChange` objects that hold the state of diffs and diff coverage.
|
17
|
+
|
18
|
+
`change_owners` checks `BundleFileChange` objects for `change-types` that are `restrictive`. If the MR was created by a user, that has this `change-type` not assigned, the integration will fail. A user with this role assigned could issue an `/good-to-test` command to override this restriction.
|
19
|
+
|
20
|
+
`change_owners` reachs out to pluggable functionality to find out which `change-types` can be applied to which changes with a set of approvers. Currently, the only module to provide such `ChangeTypeContext` is `self_service_roles` which looks for explicitly bound `change-types` and files in the context of a `Role` with users and bots will can act as approvers.
|
21
|
+
|
22
|
+
The functionality provided by `self_service_roles` is very explicit because it sets up the self-service relationship by listing all involved components. Other mechanisms to provide `ChangeTypeContexts` based on other explicit or implicit ownership information can be added easily and plugged into the `change_owners.cover_changes()` function.
|
23
|
+
|
24
|
+
The result of this coverage process is a list of `BundleFileChange` objects, each of them having a list of `DiffCoverage` objects, listing all differences and how (and if) they are covered by `ChangeTypeContexts`. That way every change has a list of `Approvers` provided by the context of the `ChangeType`.
|
25
|
+
|
26
|
+
Next, `change_owners` reaches out to the `app-interface MR` it processes, to find the decisions of the approvers. Decisions are given as `/` command comments on the MR. The `decision` module parses those comments and applies them to the `BundleFileChanges` and their `DiffCoverage` objects. The result is a list of `ChangeDecisions` where every change is `approved` and/or on `hold`.
|
27
|
+
|
28
|
+
The `change_owners` module inspects those `ChangeDecisions` to find out if all changes have been approved. If that is the case, it adds the `bot/approved` label to the MR so that `gitlab-housekeeper` can act on the MR and will try to merge it.
|
29
|
+
|
30
|
+
If at least one `ChangeDecision` is on `hold`, the `bot/hold` label is applied, which prevents `gitlab-housekeeper` from merging.
|
31
|
+
|
32
|
+
If at least one `ChangeDecision` is not `approved`, the the MR can not proceed without further approvals or without AppSRE intervention.
|
33
|
+
|
34
|
+
In the case of changes not having a `ChangeTypeContext` attached allowing approvers to decide, the MR is considered `non-self-serviceable` and can't proceed without AppSRE intervention.
|
@@ -1,6 +1,5 @@
|
|
1
1
|
from dataclasses import dataclass
|
2
2
|
from typing import (
|
3
|
-
Optional,
|
4
3
|
Protocol,
|
5
4
|
)
|
6
5
|
|
@@ -17,26 +16,25 @@ class Approver:
|
|
17
16
|
"""
|
18
17
|
|
19
18
|
org_username: str
|
20
|
-
tag_on_merge_requests:
|
19
|
+
tag_on_merge_requests: bool | None = False
|
21
20
|
|
22
21
|
|
23
22
|
class ApproverResolver(Protocol):
|
24
|
-
def lookup_approver_by_path(self, path: str) ->
|
25
|
-
...
|
23
|
+
def lookup_approver_by_path(self, path: str) -> Approver | None: ...
|
26
24
|
|
27
25
|
|
28
26
|
class GqlApproverResolver:
|
29
27
|
def __init__(self, gqlapis: list[GqlApi]):
|
30
28
|
self.gqlapis = gqlapis
|
31
29
|
|
32
|
-
def lookup_approver_by_path(self, path: str) ->
|
30
|
+
def lookup_approver_by_path(self, path: str) -> Approver | None:
|
33
31
|
for gqlapi in self.gqlapis:
|
34
32
|
approver = self._lookup_approver_by_path(gqlapi, path)
|
35
33
|
if approver:
|
36
34
|
return approver
|
37
35
|
return None
|
38
36
|
|
39
|
-
def _lookup_approver_by_path(self, gqlapi: GqlApi, path: str) ->
|
37
|
+
def _lookup_approver_by_path(self, gqlapi: GqlApi, path: str) -> Approver | None:
|
40
38
|
approvers = gqlapi.query(
|
41
39
|
"""
|
42
40
|
query Approvers($path: String) {
|
@@ -62,17 +60,17 @@ class GqlApproverResolver:
|
|
62
60
|
|
63
61
|
|
64
62
|
class ApproverReachability(Protocol):
|
65
|
-
def render_for_mr_report(self) -> str:
|
66
|
-
...
|
63
|
+
def render_for_mr_report(self) -> str: ...
|
67
64
|
|
68
65
|
|
69
66
|
@dataclass
|
70
67
|
class SlackGroupApproverReachability:
|
71
68
|
slack_group: str
|
72
69
|
workspace: str
|
70
|
+
channel: str
|
73
71
|
|
74
72
|
def render_for_mr_report(self) -> str:
|
75
|
-
return f"Slack group {self.slack_group}
|
73
|
+
return f"Slack group @{self.slack_group} in channel #{self.channel} (workspace {self.workspace})"
|
76
74
|
|
77
75
|
|
78
76
|
@dataclass
|
@@ -1,31 +1,157 @@
|
|
1
1
|
from abc import abstractmethod
|
2
2
|
from dataclasses import dataclass
|
3
|
-
from enum import
|
3
|
+
from enum import StrEnum
|
4
4
|
from typing import (
|
5
5
|
Any,
|
6
|
-
Optional,
|
7
6
|
Protocol,
|
8
|
-
|
7
|
+
)
|
8
|
+
|
9
|
+
from pydantic import (
|
10
|
+
BaseModel,
|
11
|
+
Field,
|
9
12
|
)
|
10
13
|
|
11
14
|
from reconcile.utils.gql import get_diff
|
12
15
|
|
16
|
+
DATAFILE_PATH_FIELD_NAME = "path"
|
17
|
+
DATAFILE_SHA256SUM_FIELD_NAME = "$file_sha256sum"
|
18
|
+
DATAFILE_SCHEMA_FIELD_NAME = "$schema"
|
13
19
|
|
14
|
-
|
20
|
+
|
21
|
+
class BundleFileType(StrEnum):
|
15
22
|
DATAFILE = "datafile"
|
16
23
|
RESOURCEFILE = "resourcefile"
|
17
24
|
|
18
25
|
|
19
26
|
@dataclass(frozen=True)
|
20
27
|
class FileRef:
|
28
|
+
"""
|
29
|
+
A reference to a file in a bundle.
|
30
|
+
"""
|
31
|
+
|
21
32
|
file_type: BundleFileType
|
22
33
|
path: str
|
23
|
-
schema:
|
34
|
+
schema: str | None
|
35
|
+
json_path: str | None = None
|
24
36
|
|
25
37
|
def __str__(self) -> str:
|
26
38
|
return f"{self.file_type.value}:{self.path}"
|
27
39
|
|
28
40
|
|
41
|
+
DATAFILE_CONTENT_CLEANUP_FIELDS = [
|
42
|
+
DATAFILE_SHA256SUM_FIELD_NAME,
|
43
|
+
DATAFILE_PATH_FIELD_NAME,
|
44
|
+
DATAFILE_SCHEMA_FIELD_NAME,
|
45
|
+
]
|
46
|
+
"""
|
47
|
+
Datafile metadata fields that should be removed from the datafile content
|
48
|
+
during BundleFileChange initialization.
|
49
|
+
"""
|
50
|
+
|
51
|
+
|
52
|
+
#
|
53
|
+
# The following dataclasses represent the data returned by the
|
54
|
+
# qontract-server /diff endpoint.
|
55
|
+
#
|
56
|
+
|
57
|
+
|
58
|
+
class QontractServerDatafileDiff(BaseModel):
|
59
|
+
"""
|
60
|
+
Represents a datafile diff of an individual datafile returned by the qontract-server /diff endpoint.
|
61
|
+
"""
|
62
|
+
|
63
|
+
datafilepath: str
|
64
|
+
datafileschema: str
|
65
|
+
old: dict[str, Any] | None
|
66
|
+
new: dict[str, Any] | None
|
67
|
+
|
68
|
+
@property
|
69
|
+
def old_datafilepath(self) -> str | None:
|
70
|
+
return self.old.get(DATAFILE_PATH_FIELD_NAME) if self.old else None
|
71
|
+
|
72
|
+
@property
|
73
|
+
def new_datafilepath(self) -> str | None:
|
74
|
+
return self.new.get(DATAFILE_PATH_FIELD_NAME) if self.new else None
|
75
|
+
|
76
|
+
@property
|
77
|
+
def old_data_sha(self) -> str | None:
|
78
|
+
return self.old.get(DATAFILE_SHA256SUM_FIELD_NAME) if self.old else None
|
79
|
+
|
80
|
+
@property
|
81
|
+
def new_data_sha(self) -> str | None:
|
82
|
+
return self.new.get(DATAFILE_SHA256SUM_FIELD_NAME) if self.new else None
|
83
|
+
|
84
|
+
@property
|
85
|
+
def cleaned_old_data(self) -> dict[str, Any] | None:
|
86
|
+
return _clean_datafile_content(self.old)
|
87
|
+
|
88
|
+
@property
|
89
|
+
def cleaned_new_data(self) -> dict[str, Any] | None:
|
90
|
+
return _clean_datafile_content(self.new)
|
91
|
+
|
92
|
+
|
93
|
+
def _clean_datafile_content(data: dict[str, Any] | None) -> dict[str, Any] | None:
|
94
|
+
"""
|
95
|
+
Sadly, datafiles mix and match data and metadata in the same file. This
|
96
|
+
function removes some metadata that is otherwise annoying to deal with.
|
97
|
+
"""
|
98
|
+
if data is None:
|
99
|
+
return None
|
100
|
+
return {k: v for k, v in data.items() if k not in DATAFILE_CONTENT_CLEANUP_FIELDS}
|
101
|
+
|
102
|
+
|
103
|
+
class QontractServerResourcefileBackref(BaseModel):
|
104
|
+
"""
|
105
|
+
Represents a backref from a resourcefile to a datafile
|
106
|
+
"""
|
107
|
+
|
108
|
+
path: str
|
109
|
+
datafileschema: str = Field(..., alias="datafileSchema")
|
110
|
+
jsonpath: str = Field(..., alias="jsonpath")
|
111
|
+
|
112
|
+
|
113
|
+
class QontractServerResourcefileDiffState(BaseModel):
|
114
|
+
"""
|
115
|
+
Represents the old or new state of a resourcefile returned by the qontract-server /diff endpoint.
|
116
|
+
"""
|
117
|
+
|
118
|
+
path: str
|
119
|
+
content: str
|
120
|
+
resourcefileschema: str | None = Field(..., alias="$schema")
|
121
|
+
sha256sum: str
|
122
|
+
backrefs: list[QontractServerResourcefileBackref] | None
|
123
|
+
|
124
|
+
|
125
|
+
class QontractServerResourcefileDiff(BaseModel):
|
126
|
+
"""
|
127
|
+
Represents a resourcefile diff of an individual resourcefile returned by the qontract-server /diff endpoint.
|
128
|
+
"""
|
129
|
+
|
130
|
+
resourcepath: str
|
131
|
+
old: QontractServerResourcefileDiffState | None = None
|
132
|
+
new: QontractServerResourcefileDiffState | None = None
|
133
|
+
|
134
|
+
@property
|
135
|
+
def resourcefileschema(self) -> str | None:
|
136
|
+
old_schema = self.old.resourcefileschema if self.old else None
|
137
|
+
new_schema = self.new.resourcefileschema if self.new else None
|
138
|
+
return new_schema or old_schema
|
139
|
+
|
140
|
+
|
141
|
+
class QontractServerDiff(BaseModel):
|
142
|
+
"""
|
143
|
+
Top level datastructure for datafile and resourcefile diffs returned by the qontract-server /diff endpoint.
|
144
|
+
"""
|
145
|
+
|
146
|
+
datafiles: dict[str, QontractServerDatafileDiff]
|
147
|
+
resources: dict[str, QontractServerResourcefileDiff]
|
148
|
+
|
149
|
+
|
150
|
+
#
|
151
|
+
# File diff resolver help finding differences between two versions of a file.
|
152
|
+
#
|
153
|
+
|
154
|
+
|
29
155
|
class FileDiffResolver(Protocol):
|
30
156
|
"""
|
31
157
|
A protocol to lookup the diff of a file given its FileRef.
|
@@ -34,8 +160,7 @@ class FileDiffResolver(Protocol):
|
|
34
160
|
@abstractmethod
|
35
161
|
def lookup_file_diff(
|
36
162
|
self, file_ref: FileRef
|
37
|
-
) ->
|
38
|
-
...
|
163
|
+
) -> tuple[dict[str, Any] | None, dict[str, Any] | None]: ...
|
39
164
|
|
40
165
|
|
41
166
|
@dataclass
|
@@ -49,7 +174,7 @@ class QontractServerFileDiffResolver:
|
|
49
174
|
|
50
175
|
def lookup_file_diff(
|
51
176
|
self, file_ref: FileRef
|
52
|
-
) ->
|
177
|
+
) -> tuple[dict[str, Any] | None, dict[str, Any] | None]:
|
53
178
|
data = get_diff(
|
54
179
|
old_sha=self.comparison_sha,
|
55
180
|
file_type=file_ref.file_type.value,
|
@@ -66,7 +191,7 @@ class NoOpFileDiffResolver:
|
|
66
191
|
|
67
192
|
def lookup_file_diff(
|
68
193
|
self, file_ref: FileRef
|
69
|
-
) ->
|
194
|
+
) -> tuple[dict[str, Any] | None, dict[str, Any] | None]:
|
70
195
|
raise Exception(
|
71
196
|
"NoOpFileDiffResolver is not supposed to be used in "
|
72
197
|
"runtime contexts where lookups are needed"
|