qontract-reconcile 0.9.1rc298__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.9.1rc298.dist-info → qontract_reconcile-0.10.1.dev1203.dist-info}/WHEEL +1 -2
- {qontract_reconcile-0.9.1rc298.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.9.1rc298.dist-info/METADATA +0 -63
- qontract_reconcile-0.9.1rc298.dist-info/RECORD +0 -585
- qontract_reconcile-0.9.1rc298.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
reconcile/oum/base.py
ADDED
@@ -0,0 +1,387 @@
|
|
1
|
+
import logging
|
2
|
+
from abc import (
|
3
|
+
ABC,
|
4
|
+
abstractmethod,
|
5
|
+
)
|
6
|
+
from collections import defaultdict
|
7
|
+
|
8
|
+
from reconcile.gql_definitions.common.ocm_environments import (
|
9
|
+
query as ocm_environment_query,
|
10
|
+
)
|
11
|
+
from reconcile.gql_definitions.fragments.ocm_environment import OCMEnvironment
|
12
|
+
from reconcile.oum.metrics import (
|
13
|
+
OCMUserManagementOrganizationActionCounter as ReconcileActionCounter,
|
14
|
+
)
|
15
|
+
from reconcile.oum.metrics import (
|
16
|
+
OCMUserManagementOrganizationReconcileCounter as ReconcileCounter,
|
17
|
+
)
|
18
|
+
from reconcile.oum.metrics import (
|
19
|
+
OCMUserManagementOrganizationReconcileErrorCounter as ReconcileErrorCounter,
|
20
|
+
)
|
21
|
+
from reconcile.oum.metrics import (
|
22
|
+
OCMUserManagementOrganizationValidationErrorsGauge as ValidationErrorsGauge,
|
23
|
+
)
|
24
|
+
from reconcile.oum.models import (
|
25
|
+
ClusterError,
|
26
|
+
ClusterRoleReconcileResult,
|
27
|
+
ClusterUserManagementSpec,
|
28
|
+
OrganizationUserManagementConfiguration,
|
29
|
+
)
|
30
|
+
from reconcile.oum.providers import (
|
31
|
+
GroupMemberProvider,
|
32
|
+
init_ldap_group_member_provider,
|
33
|
+
)
|
34
|
+
from reconcile.utils import (
|
35
|
+
gql,
|
36
|
+
metrics,
|
37
|
+
)
|
38
|
+
from reconcile.utils.ocm.base import (
|
39
|
+
CAPABILITY_MANAGE_CLUSTER_ADMIN,
|
40
|
+
OCMClusterGroupId,
|
41
|
+
)
|
42
|
+
from reconcile.utils.ocm.cluster_groups import (
|
43
|
+
add_user_to_cluster_group,
|
44
|
+
delete_user_from_cluster_group,
|
45
|
+
get_cluster_groups,
|
46
|
+
)
|
47
|
+
from reconcile.utils.ocm_base_client import (
|
48
|
+
OCMBaseClient,
|
49
|
+
init_ocm_base_client,
|
50
|
+
)
|
51
|
+
from reconcile.utils.runtime.integration import (
|
52
|
+
PydanticRunParams,
|
53
|
+
QontractReconcileIntegration,
|
54
|
+
)
|
55
|
+
|
56
|
+
|
57
|
+
class OCMUserManagementIntegrationParams(PydanticRunParams):
|
58
|
+
ocm_environment: str | None = None
|
59
|
+
ocm_organization_ids: set[str] | None = None
|
60
|
+
group_provider_specs: list[str]
|
61
|
+
|
62
|
+
|
63
|
+
class OCMUserManagementIntegration(
|
64
|
+
QontractReconcileIntegration[OCMUserManagementIntegrationParams], ABC
|
65
|
+
):
|
66
|
+
def run(self, dry_run: bool) -> None:
|
67
|
+
with metrics.transactional_metrics(self.name):
|
68
|
+
# init group providers
|
69
|
+
self.group_member_providers = get_group_providers(
|
70
|
+
self.params.group_provider_specs
|
71
|
+
)
|
72
|
+
|
73
|
+
for ocm_env in self.get_ocm_environments():
|
74
|
+
self.reconcile_ocm_environment(dry_run, ocm_env)
|
75
|
+
|
76
|
+
@property
|
77
|
+
def group_member_provider_ids(self) -> set[str]:
|
78
|
+
return set(self.group_member_providers.keys())
|
79
|
+
|
80
|
+
def get_ocm_environments(self) -> list[OCMEnvironment]:
|
81
|
+
return ocm_environment_query(
|
82
|
+
gql.get_api().query,
|
83
|
+
variables={"name": self.params.ocm_environment}
|
84
|
+
if self.params.ocm_environment
|
85
|
+
else None,
|
86
|
+
).environments
|
87
|
+
|
88
|
+
@abstractmethod
|
89
|
+
def get_user_mgmt_config_for_ocm_env(
|
90
|
+
self, ocm_env: OCMEnvironment, org_ids: set[str] | None
|
91
|
+
) -> dict[str, OrganizationUserManagementConfiguration]:
|
92
|
+
"""
|
93
|
+
Discover cluster user mgmt configurations in the given OCM environment.
|
94
|
+
If org_ids are provided, only return configurations for the given organizations.
|
95
|
+
|
96
|
+
To be implemented by subclasses.
|
97
|
+
"""
|
98
|
+
|
99
|
+
def reconcile_ocm_environment(self, dry_run: bool, ocm_env: OCMEnvironment) -> None:
|
100
|
+
"""
|
101
|
+
Processes user management configuration for all OCM organizations
|
102
|
+
within the given OCM environment.
|
103
|
+
"""
|
104
|
+
org_configs = self.get_user_mgmt_config_for_ocm_env(
|
105
|
+
ocm_env, self.params.ocm_organization_ids
|
106
|
+
)
|
107
|
+
|
108
|
+
ocm_api = init_ocm_base_client(ocm_env, self.secret_reader)
|
109
|
+
for org_id, org_config in org_configs.items():
|
110
|
+
specs = build_specs_from_config(org_config, self.group_member_providers)
|
111
|
+
self.reconcile_ocm_organization(
|
112
|
+
dry_run, ocm_api, org_id, ocm_env.name, specs
|
113
|
+
)
|
114
|
+
|
115
|
+
def reconcile_ocm_organization(
|
116
|
+
self,
|
117
|
+
dry_run: bool,
|
118
|
+
ocm_api: OCMBaseClient,
|
119
|
+
org_id: str,
|
120
|
+
ocm_env: str,
|
121
|
+
cluster_specs: list[ClusterUserManagementSpec],
|
122
|
+
) -> None:
|
123
|
+
"""
|
124
|
+
Process user management configuration for all clusters in the
|
125
|
+
given OCM organization.
|
126
|
+
"""
|
127
|
+
metrics.inc_counter(
|
128
|
+
ReconcileCounter(
|
129
|
+
integration=self.name,
|
130
|
+
ocm_env=ocm_env,
|
131
|
+
org_id=org_id,
|
132
|
+
)
|
133
|
+
)
|
134
|
+
|
135
|
+
validation_errors = 0
|
136
|
+
errors: list[Exception] = []
|
137
|
+
for spec in cluster_specs:
|
138
|
+
if spec.errors:
|
139
|
+
validation_errors += 1
|
140
|
+
validation_msg = "\n".join([m.message for m in spec.errors])
|
141
|
+
self.signal_cluster_validation_error(
|
142
|
+
dry_run, ocm_api, spec, Exception(validation_msg)
|
143
|
+
)
|
144
|
+
continue
|
145
|
+
reconcile_result = reconcile_cluster_roles(
|
146
|
+
dry_run=dry_run,
|
147
|
+
ocm_api=ocm_api,
|
148
|
+
org_id=org_id,
|
149
|
+
spec=spec,
|
150
|
+
)
|
151
|
+
|
152
|
+
# expose action metrics
|
153
|
+
# we do this also in error situations to signal partial work
|
154
|
+
# that has been done on a cluster
|
155
|
+
metrics.inc_counter(
|
156
|
+
ReconcileActionCounter(
|
157
|
+
integration=self.name,
|
158
|
+
ocm_env=ocm_env,
|
159
|
+
org_id=org_id,
|
160
|
+
action=ReconcileActionCounter.Action.AddUser,
|
161
|
+
),
|
162
|
+
by=reconcile_result.users_added,
|
163
|
+
)
|
164
|
+
metrics.inc_counter(
|
165
|
+
ReconcileActionCounter(
|
166
|
+
integration=self.name,
|
167
|
+
ocm_env=ocm_env,
|
168
|
+
org_id=org_id,
|
169
|
+
action=ReconcileActionCounter.Action.RemoveUser,
|
170
|
+
),
|
171
|
+
by=reconcile_result.users_removed,
|
172
|
+
)
|
173
|
+
|
174
|
+
# signal errors
|
175
|
+
if reconcile_result.error:
|
176
|
+
self.signal_cluster_reconcile_error(
|
177
|
+
dry_run, ocm_api, spec, reconcile_result.error
|
178
|
+
)
|
179
|
+
errors.append(reconcile_result.error)
|
180
|
+
|
181
|
+
# expose organization level metrics
|
182
|
+
metrics.inc_counter(
|
183
|
+
ReconcileErrorCounter(
|
184
|
+
integration=self.name,
|
185
|
+
ocm_env=ocm_env,
|
186
|
+
org_id=org_id,
|
187
|
+
),
|
188
|
+
by=1 if len(errors) > 0 else 0,
|
189
|
+
)
|
190
|
+
metrics.set_gauge(
|
191
|
+
ValidationErrorsGauge(
|
192
|
+
integration=self.name,
|
193
|
+
ocm_env=ocm_env,
|
194
|
+
org_id=org_id,
|
195
|
+
),
|
196
|
+
validation_errors,
|
197
|
+
)
|
198
|
+
|
199
|
+
@abstractmethod
|
200
|
+
def signal_cluster_reconcile_success(
|
201
|
+
self,
|
202
|
+
dry_run: bool,
|
203
|
+
ocm_api: OCMBaseClient,
|
204
|
+
spec: ClusterUserManagementSpec,
|
205
|
+
message: str,
|
206
|
+
) -> None:
|
207
|
+
"""
|
208
|
+
This method is called when the cluster reconcile operation was successful.
|
209
|
+
"""
|
210
|
+
|
211
|
+
@abstractmethod
|
212
|
+
def signal_cluster_validation_error(
|
213
|
+
self,
|
214
|
+
dry_run: bool,
|
215
|
+
ocm_api: OCMBaseClient,
|
216
|
+
spec: ClusterUserManagementSpec,
|
217
|
+
error: Exception,
|
218
|
+
) -> None:
|
219
|
+
"""
|
220
|
+
This method is called when the configuration for a cluster is invalid.
|
221
|
+
|
222
|
+
If this method throws an exception, reconciliation on the rest of the clusters
|
223
|
+
of an organization will stop.
|
224
|
+
"""
|
225
|
+
|
226
|
+
@abstractmethod
|
227
|
+
def signal_cluster_reconcile_error(
|
228
|
+
self,
|
229
|
+
dry_run: bool,
|
230
|
+
ocm_api: OCMBaseClient,
|
231
|
+
spec: ClusterUserManagementSpec,
|
232
|
+
error: Exception,
|
233
|
+
) -> None:
|
234
|
+
"""
|
235
|
+
This method is called when the cluster reconcile operation failed.
|
236
|
+
|
237
|
+
If this method throws an exception, reconciliation on the rest of the clusters
|
238
|
+
of an organization will stop.
|
239
|
+
"""
|
240
|
+
|
241
|
+
|
242
|
+
def reconcile_cluster_roles(
|
243
|
+
dry_run: bool,
|
244
|
+
ocm_api: OCMBaseClient,
|
245
|
+
org_id: str,
|
246
|
+
spec: ClusterUserManagementSpec,
|
247
|
+
) -> ClusterRoleReconcileResult:
|
248
|
+
"""
|
249
|
+
Make sure that the cluster roles and given users are synced onto the cluster.
|
250
|
+
This implies adding missing users and removing stale ones.
|
251
|
+
Cluster roles not mentioned in the spec are not touched.
|
252
|
+
"""
|
253
|
+
result = ClusterRoleReconcileResult()
|
254
|
+
|
255
|
+
try:
|
256
|
+
org_id = spec.cluster.organization_id
|
257
|
+
cluster = spec.cluster.ocm_cluster
|
258
|
+
desired_groups: dict[OCMClusterGroupId, set[str]] = spec.roles
|
259
|
+
current_groups: dict[OCMClusterGroupId, set[str]] = {
|
260
|
+
role_id: {u.id for u in group.users.items}
|
261
|
+
for role_id, group in get_cluster_groups(
|
262
|
+
ocm_api=ocm_api, cluster_id=cluster.id
|
263
|
+
).items()
|
264
|
+
if group.users
|
265
|
+
}
|
266
|
+
# only process roles present in the desired state and ignore the ones that are not
|
267
|
+
# this way a role can still be managed manually while another one is managed by this integration
|
268
|
+
for group in desired_groups:
|
269
|
+
desired_members = desired_groups.get(group, set())
|
270
|
+
current_members = current_groups.get(group, set())
|
271
|
+
|
272
|
+
# add missing users
|
273
|
+
for missing_user in desired_members - current_members:
|
274
|
+
logging.info(
|
275
|
+
f"add user {missing_user} to {group.value} - cluster id={cluster.id}, name={cluster.name}, org={org_id}"
|
276
|
+
)
|
277
|
+
if not dry_run:
|
278
|
+
add_user_to_cluster_group(
|
279
|
+
ocm_api=ocm_api,
|
280
|
+
cluster_id=cluster.id,
|
281
|
+
user_name=missing_user,
|
282
|
+
group=group,
|
283
|
+
)
|
284
|
+
result.users_added += 1
|
285
|
+
# remove obsolete users
|
286
|
+
for obsolete_user in current_members - desired_members:
|
287
|
+
logging.info(
|
288
|
+
f"remove user {obsolete_user} from {group.value} - cluster id={cluster.id}, name={cluster.name}, org={org_id}"
|
289
|
+
)
|
290
|
+
if not dry_run:
|
291
|
+
delete_user_from_cluster_group(
|
292
|
+
ocm_api=ocm_api,
|
293
|
+
cluster_id=cluster.id,
|
294
|
+
user_name=obsolete_user,
|
295
|
+
group=group,
|
296
|
+
)
|
297
|
+
result.users_removed += 1
|
298
|
+
except Exception as e:
|
299
|
+
result.error = e
|
300
|
+
|
301
|
+
return result
|
302
|
+
|
303
|
+
|
304
|
+
def build_specs_from_config(
|
305
|
+
org_config: OrganizationUserManagementConfiguration,
|
306
|
+
group_member_providers: dict[str, GroupMemberProvider],
|
307
|
+
) -> list[ClusterUserManagementSpec]:
|
308
|
+
"""
|
309
|
+
Transforms the external provider/group references into actual user names.
|
310
|
+
"""
|
311
|
+
# collect external group refs by provider so we can do a bulk resolve
|
312
|
+
external_group_refs_by_provider: dict[str, set[str]] = defaultdict(set)
|
313
|
+
for cluster_config in org_config.cluster_configs:
|
314
|
+
for role_external_group_ref in cluster_config.roles.values():
|
315
|
+
for external_group_ref in role_external_group_ref:
|
316
|
+
external_group_refs_by_provider[external_group_ref.provider].add(
|
317
|
+
external_group_ref.group_id
|
318
|
+
)
|
319
|
+
|
320
|
+
# resolve all groups using the provider implementations
|
321
|
+
external_group_members_by_provider: dict[str, dict[str, set[str]]] = {}
|
322
|
+
for provider, group_ids in external_group_refs_by_provider.items():
|
323
|
+
external_group_members_by_provider[provider] = group_member_providers[
|
324
|
+
provider
|
325
|
+
].resolve_groups(group_ids)
|
326
|
+
|
327
|
+
# build specs
|
328
|
+
cluster_specs: list[ClusterUserManagementSpec] = []
|
329
|
+
for cluster_config in org_config.cluster_configs:
|
330
|
+
spec = ClusterUserManagementSpec(
|
331
|
+
cluster=cluster_config.cluster,
|
332
|
+
roles={},
|
333
|
+
errors=cluster_config.errors,
|
334
|
+
)
|
335
|
+
cluster_specs.append(spec)
|
336
|
+
|
337
|
+
# fill roles
|
338
|
+
for (
|
339
|
+
role_id,
|
340
|
+
external_group_refs,
|
341
|
+
) in cluster_config.roles.items():
|
342
|
+
spec.roles[role_id] = set()
|
343
|
+
if (
|
344
|
+
cluster_config.cluster.ocm_cluster.is_osd()
|
345
|
+
and role_id == OCMClusterGroupId.CLUSTER_ADMINS
|
346
|
+
and not cluster_config.cluster.is_capability_set(
|
347
|
+
CAPABILITY_MANAGE_CLUSTER_ADMIN, "true"
|
348
|
+
)
|
349
|
+
):
|
350
|
+
spec.errors.append(
|
351
|
+
ClusterError(
|
352
|
+
message="This cluster does not have the capability to manage the cluster-admins role. Go to https://red.ht/ohss-incident and request cluster-admin access."
|
353
|
+
)
|
354
|
+
)
|
355
|
+
for group_ref in external_group_refs:
|
356
|
+
members = external_group_members_by_provider[group_ref.provider].get(
|
357
|
+
group_ref.group_id
|
358
|
+
)
|
359
|
+
if members is None:
|
360
|
+
spec.errors.append(
|
361
|
+
ClusterError(
|
362
|
+
message=f"{group_ref.provider} group {group_ref.group_id} for {role_id.value} not found"
|
363
|
+
)
|
364
|
+
)
|
365
|
+
continue
|
366
|
+
spec.roles[role_id].update(members)
|
367
|
+
|
368
|
+
if spec.errors:
|
369
|
+
spec.roles = {}
|
370
|
+
|
371
|
+
return cluster_specs
|
372
|
+
|
373
|
+
|
374
|
+
def get_group_providers(
|
375
|
+
group_provider_specs: list[str],
|
376
|
+
) -> dict[str, GroupMemberProvider]:
|
377
|
+
"""
|
378
|
+
Initialize the group member providers.
|
379
|
+
"""
|
380
|
+
providers: dict[str, GroupMemberProvider] = {}
|
381
|
+
for provider_spec in group_provider_specs:
|
382
|
+
provider_name, provider_type, provider_args = provider_spec.split(":")
|
383
|
+
if provider_type == "ldap":
|
384
|
+
providers[provider_name] = init_ldap_group_member_provider(provider_args)
|
385
|
+
else:
|
386
|
+
raise ValueError(f"unknown group member provider type {provider_type}")
|
387
|
+
return providers
|
@@ -0,0 +1,55 @@
|
|
1
|
+
from collections import defaultdict
|
2
|
+
|
3
|
+
from pydantic import BaseModel
|
4
|
+
|
5
|
+
from reconcile.oum.models import ExternalGroupRef
|
6
|
+
from reconcile.utils.models import CSV
|
7
|
+
from reconcile.utils.ocm import sre_capability_labels
|
8
|
+
from reconcile.utils.ocm.cluster_groups import OCMClusterGroupId
|
9
|
+
from reconcile.utils.ocm.labels import LabelContainer
|
10
|
+
|
11
|
+
|
12
|
+
class _GroupMappingLabelset(BaseModel):
|
13
|
+
"""
|
14
|
+
Parses, represents and validates a set of provider labels for the user management SRE capability.
|
15
|
+
|
16
|
+
The full qualified label names supported by the standalone user management are defined as follows:
|
17
|
+
|
18
|
+
* sre-capabilities.user-mgmt.$provider.authz.dedicated-admins: group1,group2
|
19
|
+
* sre-capabilities.user-mgmt.$provider.authz.cluster-admins: group3,group4
|
20
|
+
|
21
|
+
This labelset is processed per provider so it defines labelnames without
|
22
|
+
the sre-capabilities.user-mgmt.$provider prefix.
|
23
|
+
"""
|
24
|
+
|
25
|
+
authz_roles: dict[str, CSV] | None = sre_capability_labels.labelset_groupfield(
|
26
|
+
group_prefix="authz."
|
27
|
+
)
|
28
|
+
|
29
|
+
|
30
|
+
def build_cluster_config_from_labels(
|
31
|
+
provider: str,
|
32
|
+
org_labels: LabelContainer,
|
33
|
+
subscription_labels: LabelContainer,
|
34
|
+
) -> dict[OCMClusterGroupId, list[ExternalGroupRef]]:
|
35
|
+
"""
|
36
|
+
Extract the role-group mappings from the given organization and subscription label.
|
37
|
+
|
38
|
+
The label keys are expected to be stripped of the capability prefix and
|
39
|
+
external group provider prefix, resulting in the key names used in the
|
40
|
+
GroupMappingLabelset model.
|
41
|
+
"""
|
42
|
+
role_group_mapping: dict[OCMClusterGroupId, list[ExternalGroupRef]] = defaultdict(
|
43
|
+
list
|
44
|
+
)
|
45
|
+
|
46
|
+
# turn org labels and subscription labels individually into a labelset
|
47
|
+
for labels in [org_labels, subscription_labels]:
|
48
|
+
labelset = sre_capability_labels.build_labelset(labels, _GroupMappingLabelset)
|
49
|
+
for ocm_group_name, external_groups in (labelset.authz_roles or {}).items():
|
50
|
+
for external_group_id in external_groups:
|
51
|
+
role_group_mapping[OCMClusterGroupId(ocm_group_name)].append(
|
52
|
+
ExternalGroupRef(provider=provider, group_id=external_group_id)
|
53
|
+
)
|
54
|
+
|
55
|
+
return role_group_mapping
|
reconcile/oum/metrics.py
ADDED
@@ -0,0 +1,71 @@
|
|
1
|
+
from enum import StrEnum
|
2
|
+
|
3
|
+
from pydantic import BaseModel
|
4
|
+
|
5
|
+
from reconcile.utils.metrics import (
|
6
|
+
CounterMetric,
|
7
|
+
GaugeMetric,
|
8
|
+
)
|
9
|
+
|
10
|
+
|
11
|
+
class OCMUserManagementBaseMetric(BaseModel):
|
12
|
+
"Base class for OCM user management metrics"
|
13
|
+
|
14
|
+
integration: str
|
15
|
+
ocm_env: str
|
16
|
+
|
17
|
+
|
18
|
+
class OCMUserManagementOrganizationValidationErrorsGauge(
|
19
|
+
OCMUserManagementBaseMetric, GaugeMetric
|
20
|
+
):
|
21
|
+
"Current validation errors within an OCM organization"
|
22
|
+
|
23
|
+
org_id: str
|
24
|
+
|
25
|
+
@classmethod
|
26
|
+
def name(cls) -> str:
|
27
|
+
return "oum_organization_validation_errors"
|
28
|
+
|
29
|
+
|
30
|
+
class OCMUserManagementOrganizationReconcileCounter(
|
31
|
+
OCMUserManagementBaseMetric, CounterMetric
|
32
|
+
):
|
33
|
+
"Counter for the number of times an OCM organization was reconciled"
|
34
|
+
|
35
|
+
org_id: str
|
36
|
+
|
37
|
+
@classmethod
|
38
|
+
def name(cls) -> str:
|
39
|
+
return "oum_organization_reconciled"
|
40
|
+
|
41
|
+
|
42
|
+
class OCMUserManagementOrganizationReconcileErrorCounter(
|
43
|
+
OCMUserManagementBaseMetric, CounterMetric
|
44
|
+
):
|
45
|
+
"Counter for the failed reconcile runs for an OCM organization"
|
46
|
+
|
47
|
+
org_id: str
|
48
|
+
|
49
|
+
@classmethod
|
50
|
+
def name(cls) -> str:
|
51
|
+
return "oum_organization_reconcile_errors"
|
52
|
+
|
53
|
+
|
54
|
+
class OCMUserManagementOrganizationActionCounter(
|
55
|
+
OCMUserManagementBaseMetric, CounterMetric
|
56
|
+
):
|
57
|
+
"Counter for the number of actions taken for an OCM organization"
|
58
|
+
|
59
|
+
class Action(StrEnum):
|
60
|
+
AddUser = "add-user"
|
61
|
+
RemoveUser = "remove-user"
|
62
|
+
|
63
|
+
def __str__(self) -> str:
|
64
|
+
return self.value
|
65
|
+
|
66
|
+
org_id: str
|
67
|
+
action: Action
|
68
|
+
|
69
|
+
@classmethod
|
70
|
+
def name(cls) -> str:
|
71
|
+
return "oum_organization_actions"
|
reconcile/oum/models.py
ADDED
@@ -0,0 +1,69 @@
|
|
1
|
+
from collections import defaultdict
|
2
|
+
|
3
|
+
from pydantic import (
|
4
|
+
BaseModel,
|
5
|
+
Field,
|
6
|
+
)
|
7
|
+
|
8
|
+
from reconcile.utils.ocm.cluster_groups import OCMClusterGroupId
|
9
|
+
from reconcile.utils.ocm.clusters import ClusterDetails
|
10
|
+
|
11
|
+
|
12
|
+
class ClusterError(BaseModel):
|
13
|
+
"""
|
14
|
+
Represents an error that occurred while processing a cluster.
|
15
|
+
"""
|
16
|
+
|
17
|
+
message: str
|
18
|
+
|
19
|
+
|
20
|
+
class ExternalGroupRef(BaseModel):
|
21
|
+
"""
|
22
|
+
A reference to a group in an external identity provider.
|
23
|
+
"""
|
24
|
+
|
25
|
+
provider: str
|
26
|
+
group_id: str
|
27
|
+
|
28
|
+
|
29
|
+
class ClusterUserManagementConfiguration(BaseModel):
|
30
|
+
"""
|
31
|
+
Provider neutral representation of cluster user management configuration.
|
32
|
+
"""
|
33
|
+
|
34
|
+
cluster: ClusterDetails
|
35
|
+
roles: dict[OCMClusterGroupId, list[ExternalGroupRef]] = defaultdict(list)
|
36
|
+
errors: list[ClusterError] = Field(default_factory=list)
|
37
|
+
|
38
|
+
|
39
|
+
class OrganizationUserManagementConfiguration(BaseModel):
|
40
|
+
org_id: str
|
41
|
+
cluster_configs: list[ClusterUserManagementConfiguration] = Field(
|
42
|
+
default_factory=list
|
43
|
+
)
|
44
|
+
|
45
|
+
|
46
|
+
class ClusterUserManagementSpec(BaseModel):
|
47
|
+
"""
|
48
|
+
Contains the resolved usernames for cluster roles and notifications.
|
49
|
+
ClusterUserManagementSpec objects are derived from ClusterUserManagementConfiguration
|
50
|
+
objects by resolving the ExternalGroupRef objects using the provider
|
51
|
+
implementations.
|
52
|
+
"""
|
53
|
+
|
54
|
+
cluster: ClusterDetails
|
55
|
+
roles: dict[OCMClusterGroupId, set[str]]
|
56
|
+
errors: list[ClusterError] = Field(default_factory=list)
|
57
|
+
|
58
|
+
|
59
|
+
class ClusterRoleReconcileResult(BaseModel):
|
60
|
+
"""
|
61
|
+
Holds the result of a cluster role reconciliation.
|
62
|
+
"""
|
63
|
+
|
64
|
+
users_added: int = 0
|
65
|
+
users_removed: int = 0
|
66
|
+
error: Exception | None = None
|
67
|
+
|
68
|
+
class Config:
|
69
|
+
arbitrary_types_allowed = True
|
@@ -0,0 +1,59 @@
|
|
1
|
+
from abc import (
|
2
|
+
ABC,
|
3
|
+
abstractmethod,
|
4
|
+
)
|
5
|
+
|
6
|
+
from reconcile.ldap_users import get_ldap_settings
|
7
|
+
from reconcile.utils.ldap_client import LdapClient
|
8
|
+
|
9
|
+
|
10
|
+
class GroupMemberProvider(ABC):
|
11
|
+
"""
|
12
|
+
The base class for all group member providers.
|
13
|
+
"""
|
14
|
+
|
15
|
+
@abstractmethod
|
16
|
+
def resolve_groups(self, group_ids: set[str]) -> dict[str, set[str]]:
|
17
|
+
"""
|
18
|
+
Resolve the set of members for each given group ID.
|
19
|
+
"""
|
20
|
+
|
21
|
+
|
22
|
+
class LdapGroupMemberProvider(GroupMemberProvider):
|
23
|
+
"""
|
24
|
+
Resolve group members using the LDAP groups.
|
25
|
+
"""
|
26
|
+
|
27
|
+
def __init__(self, ldap_client: LdapClient, group_base_dn: str):
|
28
|
+
self.ldap_client = ldap_client
|
29
|
+
self.group_base_dn = group_base_dn
|
30
|
+
|
31
|
+
def resolve_groups(self, group_ids: set[str]) -> dict[str, set[str]]:
|
32
|
+
group_dn_mapping = {f"cn={cn},{self.group_base_dn}": cn for cn in group_ids}
|
33
|
+
if len(group_ids) == 0:
|
34
|
+
return {}
|
35
|
+
with self.ldap_client as lc:
|
36
|
+
groups_members_by_dn = lc.get_group_members(group_dn_mapping.keys())
|
37
|
+
return {
|
38
|
+
group_dn_mapping[dn]: members
|
39
|
+
for dn, members in groups_members_by_dn.items()
|
40
|
+
}
|
41
|
+
|
42
|
+
|
43
|
+
def init_ldap_group_member_provider(group_base_dn: str) -> LdapGroupMemberProvider:
|
44
|
+
"""
|
45
|
+
Initialize a LDAPGroupMemberProvider using the available settings.
|
46
|
+
Right now, it depends on the app-interface settings.
|
47
|
+
|
48
|
+
The group_base_dn is used to find groups by their CN. It is extended as folows
|
49
|
+
to find a group by name:
|
50
|
+
cn={name},{group_base_dn}
|
51
|
+
"""
|
52
|
+
|
53
|
+
settings = get_ldap_settings()
|
54
|
+
return LdapGroupMemberProvider(
|
55
|
+
LdapClient.from_params(
|
56
|
+
settings["ldap"]["serverUrl"], None, None, settings["ldap"]["baseDn"]
|
57
|
+
),
|
58
|
+
group_base_dn,
|
59
|
+
)
|