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
reconcile/utils/ocm/ocm.py
CHANGED
@@ -1,41 +1,23 @@
|
|
1
1
|
from __future__ import annotations
|
2
2
|
|
3
3
|
import functools
|
4
|
-
import logging
|
5
|
-
import random
|
6
4
|
import re
|
7
|
-
import
|
8
|
-
from
|
9
|
-
from collections.abc import (
|
10
|
-
Iterable,
|
11
|
-
Mapping,
|
12
|
-
)
|
13
|
-
from dataclasses import (
|
14
|
-
dataclass,
|
15
|
-
field,
|
16
|
-
)
|
17
|
-
from typing import (
|
18
|
-
Any,
|
19
|
-
Optional,
|
20
|
-
Union,
|
21
|
-
)
|
5
|
+
from collections.abc import Mapping
|
6
|
+
from typing import Any
|
22
7
|
|
23
8
|
from sretoolbox.utils import retry
|
24
9
|
|
25
10
|
import reconcile.utils.aws_helper as awsh
|
26
11
|
from reconcile.gql_definitions.fragments.vault_secret import VaultSecret
|
27
12
|
from reconcile.ocm.types import (
|
28
|
-
OCMClusterAutoscale,
|
29
|
-
OCMClusterNetwork,
|
30
|
-
OCMClusterSpec,
|
31
|
-
OCMOidcIdp,
|
32
13
|
OCMSpec,
|
33
|
-
OSDClusterSpec,
|
34
|
-
ROSAClusterAWSAccount,
|
35
|
-
ROSAClusterSpec,
|
36
|
-
ROSAOcmAwsAttrs,
|
37
14
|
)
|
38
|
-
from reconcile.utils.
|
15
|
+
from reconcile.utils.ocm.clusters import get_node_pools
|
16
|
+
from reconcile.utils.ocm.products import (
|
17
|
+
OCMProduct,
|
18
|
+
OCMProductPortfolio,
|
19
|
+
build_product_portfolio,
|
20
|
+
)
|
39
21
|
from reconcile.utils.ocm_base_client import (
|
40
22
|
OCMAPIClientConfiguration,
|
41
23
|
OCMBaseClient,
|
@@ -49,11 +31,24 @@ STATUS_DELETING = "deleting"
|
|
49
31
|
|
50
32
|
AMS_API_BASE = "/api/accounts_mgmt"
|
51
33
|
CS_API_BASE = "/api/clusters_mgmt"
|
52
|
-
KAS_API_BASE = "/api/kafkas_mgmt"
|
53
34
|
|
54
|
-
MACHINE_POOL_DESIRED_KEYS = {
|
35
|
+
MACHINE_POOL_DESIRED_KEYS = {
|
36
|
+
"id",
|
37
|
+
"instance_type",
|
38
|
+
"replicas",
|
39
|
+
"autoscaling",
|
40
|
+
"labels",
|
41
|
+
"taints",
|
42
|
+
}
|
55
43
|
UPGRADE_CHANNELS = {"stable", "fast", "candidate"}
|
56
|
-
UPGRADE_POLICY_DESIRED_KEYS = {
|
44
|
+
UPGRADE_POLICY_DESIRED_KEYS = {
|
45
|
+
"id",
|
46
|
+
"schedule_type",
|
47
|
+
"schedule",
|
48
|
+
"next_run",
|
49
|
+
"version",
|
50
|
+
"state",
|
51
|
+
}
|
57
52
|
ADDON_UPGRADE_POLICY_DESIRED_KEYS = {
|
58
53
|
"id",
|
59
54
|
"addon_id",
|
@@ -68,511 +63,8 @@ CLUSTER_ADDON_DESIRED_KEYS = {"id", "parameters"}
|
|
68
63
|
|
69
64
|
DISABLE_UWM_ATTR = "disable_user_workload_monitoring"
|
70
65
|
CLUSTER_ADMIN_LABEL_KEY = "capability.cluster.manage_cluster_admin"
|
71
|
-
BYTES_IN_GIGABYTE = 1024**3
|
72
66
|
REQUEST_TIMEOUT_SEC = 60
|
73
67
|
|
74
|
-
SPEC_ATTR_ACCOUNT = "account"
|
75
|
-
SPEC_ATTR_DISABLE_UWM = "disable_user_workload_monitoring"
|
76
|
-
SPEC_ATTR_AUTOSCALE = "autoscale"
|
77
|
-
SPEC_ATTR_INSTANCE_TYPE = "instance_type"
|
78
|
-
SPEC_ATTR_PRIVATE = "private"
|
79
|
-
SPEC_ATTR_CHANNEL = "channel"
|
80
|
-
SPEC_ATTR_NODES = "nodes"
|
81
|
-
SPEC_ATTR_LOAD_BALANCERS = "load_balancers"
|
82
|
-
SPEC_ATTR_STORAGE = "storage"
|
83
|
-
SPEC_ATTR_ID = "id"
|
84
|
-
SPEC_ATTR_EXTERNAL_ID = "external_id"
|
85
|
-
SPEC_ATTR_PROVISION_SHARD_ID = "provision_shard_id"
|
86
|
-
SPEC_ATTR_VERSION = "version"
|
87
|
-
SPEC_ATTR_INITIAL_VERSION = "initial_version"
|
88
|
-
SPEC_ATTR_MULTI_AZ = "multi_az"
|
89
|
-
SPEC_ATTR_HYPERSHIFT = "hypershift"
|
90
|
-
SPEC_ATTR_SUBNET_IDS = "subnet_ids"
|
91
|
-
SPEC_ATTR_AVAILABILITY_ZONES = "availability_zones"
|
92
|
-
|
93
|
-
SPEC_ATTR_NETWORK = "network"
|
94
|
-
|
95
|
-
SPEC_ATTR_CONSOLE_URL = "consoleUrl"
|
96
|
-
SPEC_ATTR_SERVER_URL = "serverUrl"
|
97
|
-
SPEC_ATTR_ELBFQDN = "elbFQDN"
|
98
|
-
SPEC_ATTR_PATH = "path"
|
99
|
-
|
100
|
-
OCM_PRODUCT_OSD = "osd"
|
101
|
-
OCM_PRODUCT_ROSA = "rosa"
|
102
|
-
|
103
|
-
|
104
|
-
class OCMProduct:
|
105
|
-
|
106
|
-
ALLOWED_SPEC_UPDATE_FIELDS: set[str]
|
107
|
-
EXCLUDED_SPEC_FIELDS: set[str]
|
108
|
-
|
109
|
-
@staticmethod
|
110
|
-
@abstractmethod
|
111
|
-
def create_cluster(ocm: OCM, name: str, cluster: OCMSpec, dry_run: bool):
|
112
|
-
pass
|
113
|
-
|
114
|
-
@staticmethod
|
115
|
-
@abstractmethod
|
116
|
-
def update_cluster(ocm: OCM, cluster_name: str, update_spec: Mapping[str, Any]):
|
117
|
-
pass
|
118
|
-
|
119
|
-
@staticmethod
|
120
|
-
@abstractmethod
|
121
|
-
def get_ocm_spec(
|
122
|
-
ocm: OCM, cluster: Mapping[str, Any], init_provision_shards: bool
|
123
|
-
) -> OCMSpec:
|
124
|
-
pass
|
125
|
-
|
126
|
-
|
127
|
-
class OCMProductOsd(OCMProduct):
|
128
|
-
ALLOWED_SPEC_UPDATE_FIELDS = {
|
129
|
-
SPEC_ATTR_STORAGE,
|
130
|
-
SPEC_ATTR_LOAD_BALANCERS,
|
131
|
-
SPEC_ATTR_PRIVATE,
|
132
|
-
SPEC_ATTR_CHANNEL,
|
133
|
-
SPEC_ATTR_AUTOSCALE,
|
134
|
-
SPEC_ATTR_NODES,
|
135
|
-
SPEC_ATTR_DISABLE_UWM,
|
136
|
-
}
|
137
|
-
|
138
|
-
EXCLUDED_SPEC_FIELDS = {
|
139
|
-
SPEC_ATTR_ID,
|
140
|
-
SPEC_ATTR_EXTERNAL_ID,
|
141
|
-
SPEC_ATTR_PROVISION_SHARD_ID,
|
142
|
-
SPEC_ATTR_VERSION,
|
143
|
-
SPEC_ATTR_INITIAL_VERSION,
|
144
|
-
SPEC_ATTR_HYPERSHIFT,
|
145
|
-
}
|
146
|
-
|
147
|
-
@staticmethod
|
148
|
-
def create_cluster(ocm: OCM, name: str, cluster: OCMSpec, dry_run: bool):
|
149
|
-
ocm_spec = OCMProductOsd._get_create_cluster_spec(name, cluster)
|
150
|
-
api = f"{CS_API_BASE}/v1/clusters"
|
151
|
-
params = {}
|
152
|
-
if dry_run:
|
153
|
-
params["dryRun"] = "true"
|
154
|
-
|
155
|
-
ocm._post(api, ocm_spec, params)
|
156
|
-
|
157
|
-
@staticmethod
|
158
|
-
def update_cluster(ocm: OCM, cluster_name: str, update_spec: Mapping[str, Any]):
|
159
|
-
ocm_spec = OCMProductOsd._get_update_cluster_spec(update_spec)
|
160
|
-
cluster_id = ocm.cluster_ids.get(cluster_name)
|
161
|
-
api = f"{CS_API_BASE}/v1/clusters/{cluster_id}"
|
162
|
-
params: dict[str, Any] = {}
|
163
|
-
ocm._patch(api, ocm_spec, params)
|
164
|
-
|
165
|
-
@staticmethod
|
166
|
-
def get_ocm_spec(
|
167
|
-
ocm: OCM, cluster: Mapping[str, Any], init_provision_shards: bool
|
168
|
-
) -> OCMSpec:
|
169
|
-
if init_provision_shards:
|
170
|
-
provision_shard_id = ocm.get_provision_shard(cluster["id"])["id"]
|
171
|
-
else:
|
172
|
-
provision_shard_id = None
|
173
|
-
|
174
|
-
autoscale = cluster["nodes"].get("autoscale_compute")
|
175
|
-
autoscale_spec = (
|
176
|
-
OCMClusterAutoscale(
|
177
|
-
max_replicas=autoscale.get("max_replicas"),
|
178
|
-
min_replicas=autoscale.get("min_replicas"),
|
179
|
-
)
|
180
|
-
if autoscale
|
181
|
-
else None
|
182
|
-
)
|
183
|
-
|
184
|
-
spec = OCMClusterSpec(
|
185
|
-
product=cluster["product"]["id"],
|
186
|
-
id=cluster["id"],
|
187
|
-
external_id=cluster["external_id"],
|
188
|
-
provider=cluster["cloud_provider"]["id"],
|
189
|
-
region=cluster["region"]["id"],
|
190
|
-
channel=cluster["version"]["channel_group"],
|
191
|
-
version=cluster["version"]["raw_id"],
|
192
|
-
multi_az=cluster["multi_az"],
|
193
|
-
instance_type=cluster["nodes"]["compute_machine_type"]["id"],
|
194
|
-
private=cluster["api"]["listening"] == "internal",
|
195
|
-
disable_user_workload_monitoring=cluster[
|
196
|
-
"disable_user_workload_monitoring"
|
197
|
-
],
|
198
|
-
provision_shard_id=provision_shard_id,
|
199
|
-
nodes=cluster["nodes"].get("compute"),
|
200
|
-
autoscale=autoscale_spec,
|
201
|
-
hypershift=cluster["hypershift"]["enabled"],
|
202
|
-
)
|
203
|
-
|
204
|
-
if not cluster["ccs"]["enabled"]:
|
205
|
-
cluster_spec_data = spec.dict()
|
206
|
-
cluster_spec_data["storage"] = (
|
207
|
-
cluster["storage_quota"]["value"] // BYTES_IN_GIGABYTE
|
208
|
-
)
|
209
|
-
cluster_spec_data["load_balancers"] = cluster["load_balancer_quota"]
|
210
|
-
spec = OSDClusterSpec(**cluster_spec_data)
|
211
|
-
|
212
|
-
network = OCMClusterNetwork(
|
213
|
-
type=cluster["network"].get("type") or "OVNKubernetes",
|
214
|
-
vpc=cluster["network"]["machine_cidr"],
|
215
|
-
service=cluster["network"]["service_cidr"],
|
216
|
-
pod=cluster["network"]["pod_cidr"],
|
217
|
-
)
|
218
|
-
|
219
|
-
ocm_spec = OCMSpec(
|
220
|
-
console_url=cluster["console"]["url"],
|
221
|
-
server_url=cluster["api"]["url"],
|
222
|
-
domain=cluster["dns"]["base_domain"],
|
223
|
-
spec=spec,
|
224
|
-
network=network,
|
225
|
-
)
|
226
|
-
|
227
|
-
return ocm_spec
|
228
|
-
|
229
|
-
@staticmethod
|
230
|
-
def _get_create_cluster_spec(cluster_name: str, cluster: OCMSpec) -> dict[str, Any]:
|
231
|
-
ocm_spec: dict[str, Any] = {
|
232
|
-
"name": cluster_name,
|
233
|
-
"cloud_provider": {"id": cluster.spec.provider},
|
234
|
-
"region": {"id": cluster.spec.region},
|
235
|
-
"version": {
|
236
|
-
"id": f"openshift-v{cluster.spec.initial_version}",
|
237
|
-
"channel_group": cluster.spec.channel,
|
238
|
-
},
|
239
|
-
"multi_az": cluster.spec.multi_az,
|
240
|
-
"nodes": {"compute_machine_type": {"id": cluster.spec.instance_type}},
|
241
|
-
"network": {
|
242
|
-
"type": cluster.network.type or "OVNKubernetes",
|
243
|
-
"machine_cidr": cluster.network.vpc,
|
244
|
-
"service_cidr": cluster.network.service,
|
245
|
-
"pod_cidr": cluster.network.pod,
|
246
|
-
},
|
247
|
-
"api": {"listening": "internal" if cluster.spec.private else "external"},
|
248
|
-
"disable_user_workload_monitoring": cluster.spec.disable_user_workload_monitoring
|
249
|
-
or True,
|
250
|
-
}
|
251
|
-
|
252
|
-
# Workaround to enable type checks.
|
253
|
-
# cluster.spec is a Union of pydantic models Union[OSDClusterSpec, RosaClusterSpec].
|
254
|
-
# In this case, cluster.spec will always be an OSDClusterSpec because the type
|
255
|
-
# assignment is managed by pydantic, however, mypy complains if OSD attributes are set
|
256
|
-
# outside the isinstance check because it checks all the types set in the Union.
|
257
|
-
if isinstance(cluster.spec, OSDClusterSpec):
|
258
|
-
ocm_spec["storage_quota"] = {
|
259
|
-
"value": float(cluster.spec.storage * BYTES_IN_GIGABYTE),
|
260
|
-
}
|
261
|
-
ocm_spec["load_balancer_quota"] = cluster.spec.load_balancers
|
262
|
-
|
263
|
-
provision_shard_id = cluster.spec.provision_shard_id
|
264
|
-
if provision_shard_id:
|
265
|
-
ocm_spec.setdefault("properties", {})
|
266
|
-
ocm_spec["properties"]["provision_shard_id"] = provision_shard_id
|
267
|
-
|
268
|
-
autoscale = cluster.spec.autoscale
|
269
|
-
if autoscale is not None:
|
270
|
-
ocm_spec["nodes"]["autoscale_compute"] = autoscale.dict()
|
271
|
-
else:
|
272
|
-
ocm_spec["nodes"]["compute"] = cluster.spec.nodes
|
273
|
-
return ocm_spec
|
274
|
-
|
275
|
-
@staticmethod
|
276
|
-
def _get_update_cluster_spec(update_spec: Mapping[str, Any]) -> dict[str, Any]:
|
277
|
-
ocm_spec: dict[str, Any] = {}
|
278
|
-
|
279
|
-
storage = update_spec.get("storage")
|
280
|
-
if storage is not None:
|
281
|
-
ocm_spec["storage_quota"] = {"value": float(storage * 1073741824)} # 1024^3
|
282
|
-
|
283
|
-
load_balancers = update_spec.get("load_balancers")
|
284
|
-
if load_balancers is not None:
|
285
|
-
ocm_spec["load_balancer_quota"] = load_balancers
|
286
|
-
|
287
|
-
private = update_spec.get("private")
|
288
|
-
if private is not None:
|
289
|
-
ocm_spec["api"] = {"listening": "internal" if private else "external"}
|
290
|
-
|
291
|
-
channel = update_spec.get("channel")
|
292
|
-
if channel is not None:
|
293
|
-
ocm_spec["version"] = {"channel_group": channel}
|
294
|
-
|
295
|
-
autoscale = update_spec.get("autoscale")
|
296
|
-
if autoscale is not None:
|
297
|
-
ocm_spec["nodes"] = {"autoscale_compute": autoscale}
|
298
|
-
|
299
|
-
nodes = update_spec.get("nodes")
|
300
|
-
if nodes:
|
301
|
-
ocm_spec["nodes"] = {"compute": update_spec["nodes"]}
|
302
|
-
|
303
|
-
disable_uwm = update_spec.get("disable_user_workload_monitoring")
|
304
|
-
if disable_uwm is not None:
|
305
|
-
ocm_spec["disable_user_workload_monitoring"] = disable_uwm
|
306
|
-
|
307
|
-
return ocm_spec
|
308
|
-
|
309
|
-
|
310
|
-
class OCMProductRosa(OCMProduct):
|
311
|
-
ALLOWED_SPEC_UPDATE_FIELDS = {
|
312
|
-
SPEC_ATTR_CHANNEL,
|
313
|
-
SPEC_ATTR_AUTOSCALE,
|
314
|
-
SPEC_ATTR_NODES,
|
315
|
-
SPEC_ATTR_DISABLE_UWM,
|
316
|
-
}
|
317
|
-
|
318
|
-
EXCLUDED_SPEC_FIELDS = {
|
319
|
-
SPEC_ATTR_ID,
|
320
|
-
SPEC_ATTR_EXTERNAL_ID,
|
321
|
-
SPEC_ATTR_PROVISION_SHARD_ID,
|
322
|
-
SPEC_ATTR_VERSION,
|
323
|
-
SPEC_ATTR_INITIAL_VERSION,
|
324
|
-
SPEC_ATTR_ACCOUNT,
|
325
|
-
SPEC_ATTR_HYPERSHIFT,
|
326
|
-
SPEC_ATTR_SUBNET_IDS,
|
327
|
-
SPEC_ATTR_AVAILABILITY_ZONES,
|
328
|
-
}
|
329
|
-
|
330
|
-
@staticmethod
|
331
|
-
def create_cluster(ocm: OCM, name: str, cluster: OCMSpec, dry_run: bool):
|
332
|
-
ocm_spec = OCMProductRosa._get_create_cluster_spec(name, cluster)
|
333
|
-
api = f"{CS_API_BASE}/v1/clusters"
|
334
|
-
params = {}
|
335
|
-
if dry_run:
|
336
|
-
params["dryRun"] = "true"
|
337
|
-
if cluster.spec.hypershift:
|
338
|
-
logging.info(
|
339
|
-
"Dry-Run is not yet implemented for Hosted clusters. Here is the payload:"
|
340
|
-
)
|
341
|
-
logging.info(ocm_spec)
|
342
|
-
return
|
343
|
-
ocm._post(api, ocm_spec, params)
|
344
|
-
|
345
|
-
@staticmethod
|
346
|
-
def update_cluster(ocm: OCM, cluster_name: str, update_spec: Mapping[str, Any]):
|
347
|
-
ocm_spec = OCMProductRosa._get_update_cluster_spec(update_spec)
|
348
|
-
cluster_id = ocm.cluster_ids.get(cluster_name)
|
349
|
-
api = f"{CS_API_BASE}/v1/clusters/{cluster_id}"
|
350
|
-
params: dict[str, Any] = {}
|
351
|
-
ocm._patch(api, ocm_spec, params)
|
352
|
-
|
353
|
-
@staticmethod
|
354
|
-
def get_ocm_spec(
|
355
|
-
ocm: OCM, cluster: Mapping[str, Any], init_provision_shards: bool
|
356
|
-
) -> OCMSpec:
|
357
|
-
|
358
|
-
if init_provision_shards:
|
359
|
-
provision_shard_id = ocm.get_provision_shard(cluster["id"])["id"]
|
360
|
-
else:
|
361
|
-
provision_shard_id = None
|
362
|
-
|
363
|
-
autoscale = cluster["nodes"].get("autoscale_compute")
|
364
|
-
autoscale_spec = (
|
365
|
-
OCMClusterAutoscale(
|
366
|
-
max_replicas=autoscale.get("max_replicas"),
|
367
|
-
min_replicas=autoscale.get("min_replicas"),
|
368
|
-
)
|
369
|
-
if autoscale
|
370
|
-
else None
|
371
|
-
)
|
372
|
-
|
373
|
-
account = ROSAClusterAWSAccount(
|
374
|
-
uid=cluster["properties"]["rosa_creator_arn"].split(":")[4],
|
375
|
-
rosa=ROSAOcmAwsAttrs(
|
376
|
-
creator_role_arn=cluster["properties"]["rosa_creator_arn"],
|
377
|
-
installer_role_arn=cluster["aws"]["sts"]["role_arn"],
|
378
|
-
support_role_arn=cluster["aws"]["sts"]["support_role_arn"],
|
379
|
-
controlplane_role_arn=cluster["aws"]["sts"]["instance_iam_roles"][
|
380
|
-
"master_role_arn"
|
381
|
-
],
|
382
|
-
worker_role_arn=cluster["aws"]["sts"]["instance_iam_roles"][
|
383
|
-
"worker_role_arn"
|
384
|
-
],
|
385
|
-
),
|
386
|
-
)
|
387
|
-
|
388
|
-
spec = ROSAClusterSpec(
|
389
|
-
product=cluster["product"]["id"],
|
390
|
-
account=account,
|
391
|
-
id=cluster["id"],
|
392
|
-
external_id=cluster.get("external_id"),
|
393
|
-
provider=cluster["cloud_provider"]["id"],
|
394
|
-
region=cluster["region"]["id"],
|
395
|
-
channel=cluster["version"]["channel_group"],
|
396
|
-
version=cluster["version"]["raw_id"],
|
397
|
-
multi_az=cluster["multi_az"],
|
398
|
-
instance_type=cluster["nodes"]["compute_machine_type"]["id"],
|
399
|
-
private=cluster["api"]["listening"] == "internal",
|
400
|
-
disable_user_workload_monitoring=cluster[
|
401
|
-
"disable_user_workload_monitoring"
|
402
|
-
],
|
403
|
-
provision_shard_id=provision_shard_id,
|
404
|
-
nodes=cluster["nodes"].get("compute"),
|
405
|
-
autoscale=autoscale_spec,
|
406
|
-
hypershift=cluster["hypershift"]["enabled"],
|
407
|
-
subnet_ids=cluster["aws"].get("subnet_ids"),
|
408
|
-
availability_zones=cluster["nodes"].get("availability_zones"),
|
409
|
-
)
|
410
|
-
|
411
|
-
network = OCMClusterNetwork(
|
412
|
-
type=cluster["network"].get("type") or "OVNKubernetes",
|
413
|
-
vpc=cluster["network"]["machine_cidr"],
|
414
|
-
service=cluster["network"]["service_cidr"],
|
415
|
-
pod=cluster["network"]["pod_cidr"],
|
416
|
-
)
|
417
|
-
|
418
|
-
ocm_spec = OCMSpec(
|
419
|
-
console_url=cluster["console"]["url"],
|
420
|
-
server_url=cluster["api"]["url"],
|
421
|
-
domain=cluster["dns"]["base_domain"],
|
422
|
-
spec=spec,
|
423
|
-
network=network,
|
424
|
-
)
|
425
|
-
|
426
|
-
return ocm_spec
|
427
|
-
|
428
|
-
@staticmethod
|
429
|
-
def _get_create_cluster_spec(cluster_name: str, cluster: OCMSpec) -> dict[str, Any]:
|
430
|
-
operator_roles_prefix = "".join(
|
431
|
-
"".join(random.choices(string.ascii_lowercase + string.digits, k=4))
|
432
|
-
)
|
433
|
-
|
434
|
-
ocm_spec: dict[str, Any] = {
|
435
|
-
"api": {"listening": "internal" if cluster.spec.private else "external"},
|
436
|
-
"name": cluster_name,
|
437
|
-
"cloud_provider": {"id": cluster.spec.provider},
|
438
|
-
"region": {"id": cluster.spec.region},
|
439
|
-
"version": {
|
440
|
-
"id": f"openshift-v{cluster.spec.initial_version}",
|
441
|
-
"channel_group": cluster.spec.channel,
|
442
|
-
},
|
443
|
-
"hypershift": {"enabled": cluster.spec.hypershift},
|
444
|
-
"multi_az": cluster.spec.multi_az,
|
445
|
-
"nodes": {"compute_machine_type": {"id": cluster.spec.instance_type}},
|
446
|
-
"network": {
|
447
|
-
"type": cluster.network.type or "OVNKubernetes",
|
448
|
-
"machine_cidr": cluster.network.vpc,
|
449
|
-
"service_cidr": cluster.network.service,
|
450
|
-
"pod_cidr": cluster.network.pod,
|
451
|
-
},
|
452
|
-
"disable_user_workload_monitoring": cluster.spec.disable_user_workload_monitoring
|
453
|
-
or True,
|
454
|
-
}
|
455
|
-
|
456
|
-
provision_shard_id = cluster.spec.provision_shard_id
|
457
|
-
if provision_shard_id:
|
458
|
-
ocm_spec.setdefault("properties", {})
|
459
|
-
ocm_spec["properties"]["provision_shard_id"] = provision_shard_id
|
460
|
-
|
461
|
-
autoscale = cluster.spec.autoscale
|
462
|
-
if autoscale is not None:
|
463
|
-
ocm_spec["nodes"]["autoscale_compute"] = autoscale.dict()
|
464
|
-
else:
|
465
|
-
ocm_spec["nodes"]["compute"] = cluster.spec.nodes
|
466
|
-
|
467
|
-
if isinstance(cluster.spec, ROSAClusterSpec):
|
468
|
-
ocm_spec.setdefault("properties", {})
|
469
|
-
ocm_spec["properties"][
|
470
|
-
"rosa_creator_arn"
|
471
|
-
] = cluster.spec.account.rosa.creator_role_arn
|
472
|
-
|
473
|
-
rosa_spec: dict[str, Any] = {
|
474
|
-
"product": {"id": "rosa"},
|
475
|
-
"ccs": {"enabled": True},
|
476
|
-
"aws": {
|
477
|
-
"account_id": cluster.spec.account.uid,
|
478
|
-
"sts": {
|
479
|
-
"enabled": True,
|
480
|
-
"auto_mode": True,
|
481
|
-
"role_arn": cluster.spec.account.rosa.installer_role_arn,
|
482
|
-
"support_role_arn": cluster.spec.account.rosa.support_role_arn,
|
483
|
-
"instance_iam_roles": {
|
484
|
-
"master_role_arn": cluster.spec.account.rosa.controlplane_role_arn,
|
485
|
-
"worker_role_arn": cluster.spec.account.rosa.worker_role_arn,
|
486
|
-
},
|
487
|
-
"operator_role_prefix": f"{cluster_name}-{operator_roles_prefix}",
|
488
|
-
},
|
489
|
-
},
|
490
|
-
}
|
491
|
-
|
492
|
-
if cluster.spec.hypershift:
|
493
|
-
ocm_spec["nodes"][
|
494
|
-
"availability_zones"
|
495
|
-
] = cluster.spec.availability_zones
|
496
|
-
rosa_spec["aws"]["subnet_ids"] = cluster.spec.subnet_ids
|
497
|
-
|
498
|
-
ocm_spec.update(rosa_spec)
|
499
|
-
return ocm_spec
|
500
|
-
|
501
|
-
@staticmethod
|
502
|
-
def _get_update_cluster_spec(update_spec: Mapping[str, Any]) -> dict[str, Any]:
|
503
|
-
ocm_spec: dict[str, Any] = {}
|
504
|
-
|
505
|
-
channel = update_spec.get(SPEC_ATTR_CHANNEL)
|
506
|
-
if channel is not None:
|
507
|
-
ocm_spec["version"] = {"channel_group": channel}
|
508
|
-
|
509
|
-
autoscale = update_spec.get(SPEC_ATTR_AUTOSCALE)
|
510
|
-
if autoscale is not None:
|
511
|
-
ocm_spec["nodes"] = {"autoscale_compute": autoscale}
|
512
|
-
|
513
|
-
nodes = update_spec.get(SPEC_ATTR_NODES)
|
514
|
-
if nodes:
|
515
|
-
ocm_spec["nodes"] = {"compute": update_spec["nodes"]}
|
516
|
-
|
517
|
-
disable_uwm = update_spec.get(SPEC_ATTR_DISABLE_UWM)
|
518
|
-
if disable_uwm is not None:
|
519
|
-
ocm_spec["disable_user_workload_monitoring"] = disable_uwm
|
520
|
-
|
521
|
-
return ocm_spec
|
522
|
-
|
523
|
-
|
524
|
-
OCM_PRODUCTS_IMPL = {
|
525
|
-
OCM_PRODUCT_OSD: OCMProductOsd,
|
526
|
-
OCM_PRODUCT_ROSA: OCMProductRosa,
|
527
|
-
}
|
528
|
-
|
529
|
-
|
530
|
-
class SectorConfigError(Exception):
|
531
|
-
pass
|
532
|
-
|
533
|
-
|
534
|
-
@dataclass
|
535
|
-
class Sector:
|
536
|
-
name: str
|
537
|
-
ocm: OCM
|
538
|
-
dependencies: list[Sector] = field(default_factory=lambda: [])
|
539
|
-
cluster_infos: list[dict[Any, Any]] = field(default_factory=lambda: [])
|
540
|
-
_validated_dependencies: Optional[set[Sector]] = None
|
541
|
-
|
542
|
-
def __key(self):
|
543
|
-
return (self.ocm.name, self.name)
|
544
|
-
|
545
|
-
def __hash__(self) -> int:
|
546
|
-
return hash(self.__key())
|
547
|
-
|
548
|
-
def __str__(self) -> str:
|
549
|
-
return f"{self.ocm.name}/{self.name}"
|
550
|
-
|
551
|
-
def ocmspec(self, cluster_name: str) -> OCMSpec:
|
552
|
-
return self.ocm.clusters[cluster_name]
|
553
|
-
|
554
|
-
def _iter_dependencies(self) -> Iterable[Sector]:
|
555
|
-
"""
|
556
|
-
iterate reccursively over all the sector dependencies
|
557
|
-
"""
|
558
|
-
logging.debug(f"[{self}] checking dependencies")
|
559
|
-
for dep in self.dependencies or []:
|
560
|
-
if self == dep:
|
561
|
-
raise SectorConfigError(
|
562
|
-
f"[{self}] infinite sector dependency loop detected: depending on itself"
|
563
|
-
)
|
564
|
-
yield dep
|
565
|
-
for d in dep._iter_dependencies():
|
566
|
-
if self == d:
|
567
|
-
raise SectorConfigError(
|
568
|
-
f"[{self}] infinite sector dependency loop detected under {dep} dependencies"
|
569
|
-
)
|
570
|
-
yield d
|
571
|
-
|
572
|
-
def validate_dependencies(self) -> bool:
|
573
|
-
list(self._iter_dependencies())
|
574
|
-
return True
|
575
|
-
|
576
68
|
|
577
69
|
class OCM: # pylint: disable=too-many-public-methods
|
578
70
|
"""
|
@@ -595,18 +87,24 @@ class OCM: # pylint: disable=too-many-public-methods
|
|
595
87
|
self,
|
596
88
|
name,
|
597
89
|
org_id,
|
90
|
+
ocm_env: str,
|
598
91
|
ocm_client: OCMBaseClient,
|
599
92
|
init_provision_shards=False,
|
600
93
|
init_addons=False,
|
601
94
|
init_version_gates=False,
|
602
95
|
blocked_versions=None,
|
603
|
-
|
604
|
-
|
96
|
+
inheritVersionData: list[dict[str, Any]] | None = None,
|
97
|
+
product_portfolio: OCMProductPortfolio | None = None,
|
605
98
|
):
|
606
99
|
"""Initiates access token and gets clusters information."""
|
607
100
|
self.name = name
|
608
101
|
self._ocm_client = ocm_client
|
609
102
|
self.org_id = org_id
|
103
|
+
self.ocm_env = ocm_env
|
104
|
+
if product_portfolio is None:
|
105
|
+
self.product_portfolio = build_product_portfolio()
|
106
|
+
else:
|
107
|
+
self.product_portfolio = product_portfolio
|
610
108
|
self._init_clusters(init_provision_shards=init_provision_shards)
|
611
109
|
|
612
110
|
if init_addons:
|
@@ -614,8 +112,6 @@ class OCM: # pylint: disable=too-many-public-methods
|
|
614
112
|
|
615
113
|
self._init_blocked_versions(blocked_versions)
|
616
114
|
|
617
|
-
self.inheritVersionData = inheritVersionData or []
|
618
|
-
|
619
115
|
self.init_version_gates = init_version_gates
|
620
116
|
self.version_gates: list[Any] = []
|
621
117
|
if init_version_gates:
|
@@ -629,29 +125,25 @@ class OCM: # pylint: disable=too-many-public-methods
|
|
629
125
|
self.get_aws_infrastructure_access_role_grants
|
630
126
|
)
|
631
127
|
|
632
|
-
|
633
|
-
|
634
|
-
|
635
|
-
sector_name = sector["name"]
|
636
|
-
self.sectors[sector_name] = Sector(name=sector_name, ocm=self)
|
637
|
-
for sector in sectors or []:
|
638
|
-
s = self.sectors[sector["name"]]
|
639
|
-
for dep in sector.get("dependencies") or []:
|
640
|
-
s.dependencies.append(self.sectors[dep["name"]])
|
128
|
+
@property
|
129
|
+
def ocm_api(self) -> OCMBaseClient:
|
130
|
+
return self._ocm_client
|
641
131
|
|
642
|
-
|
643
|
-
def _ready_for_app_interface(cluster: dict[str, Any]) -> bool:
|
132
|
+
def _ready_for_app_interface(self, cluster: dict[str, Any]) -> bool:
|
644
133
|
return (
|
645
134
|
cluster["managed"]
|
646
135
|
and cluster["state"] == STATUS_READY
|
647
|
-
and cluster["product"]["id"] in
|
136
|
+
and cluster["product"]["id"] in self.product_portfolio.product_names
|
648
137
|
)
|
649
138
|
|
650
139
|
def _init_clusters(self, init_provision_shards: bool):
|
651
140
|
api = f"{CS_API_BASE}/v1/clusters"
|
652
|
-
|
141
|
+
product_csv = ",".join([f"'{p}'" for p in self.product_portfolio.product_names])
|
142
|
+
params = {
|
143
|
+
"search": f"organization.id='{self.org_id}' and managed='true' and product.id in ({product_csv})"
|
144
|
+
}
|
653
145
|
clusters = self._get_json(api, params=params).get("items", [])
|
654
|
-
self.cluster_ids = {c["name"]: c["id"] for c in clusters}
|
146
|
+
self.cluster_ids: dict[str, str] = {c["name"]: c["id"] for c in clusters}
|
655
147
|
|
656
148
|
self.clusters: dict[str, OCMSpec] = {}
|
657
149
|
self.available_cluster_upgrades: dict[str, list[str]] = {}
|
@@ -668,30 +160,41 @@ class OCM: # pylint: disable=too-many-public-methods
|
|
668
160
|
else:
|
669
161
|
self.not_ready_clusters.add(cluster_name)
|
670
162
|
|
163
|
+
@property
|
164
|
+
def non_blocked_cluster_upgrades(self) -> dict[str, list[str]]:
|
165
|
+
return {
|
166
|
+
cluster: [v for v in versions or [] if not self.version_blocked(v)]
|
167
|
+
for cluster, versions in self.available_cluster_upgrades.items()
|
168
|
+
}
|
169
|
+
|
671
170
|
def is_ready(self, cluster):
|
672
171
|
return cluster in self.clusters
|
673
172
|
|
674
|
-
def
|
675
|
-
|
173
|
+
def get_product_impl(
|
174
|
+
self, product: str, hypershift: bool | None = False
|
175
|
+
) -> OCMProduct:
|
176
|
+
return self.product_portfolio.get_product_impl(product, hypershift)
|
676
177
|
|
677
178
|
def _get_cluster_ocm_spec(
|
678
179
|
self, cluster: Mapping[str, Any], init_provision_shards: bool
|
679
180
|
) -> OCMSpec:
|
680
|
-
|
681
|
-
|
682
|
-
|
181
|
+
impl = self.get_product_impl(
|
182
|
+
cluster["product"]["id"], cluster["hypershift"]["enabled"]
|
183
|
+
)
|
184
|
+
spec = impl.get_ocm_spec(self.ocm_api, cluster, init_provision_shards)
|
683
185
|
return spec
|
684
186
|
|
685
187
|
def create_cluster(self, name: str, cluster: OCMSpec, dry_run: bool):
|
686
|
-
impl = self.
|
687
|
-
impl.create_cluster(self, name, cluster, dry_run)
|
188
|
+
impl = self.get_product_impl(cluster.spec.product, cluster.spec.hypershift)
|
189
|
+
impl.create_cluster(self.ocm_api, self.org_id, name, cluster, dry_run)
|
688
190
|
|
689
191
|
def update_cluster(
|
690
192
|
self, cluster_name: str, update_spec: Mapping[str, Any], dry_run=False
|
691
193
|
):
|
692
194
|
cluster = self.clusters[cluster_name]
|
693
|
-
|
694
|
-
impl.
|
195
|
+
cluster_id = self.cluster_ids[cluster_name]
|
196
|
+
impl = self.get_product_impl(cluster.spec.product, cluster.spec.hypershift)
|
197
|
+
impl.update_cluster(self.ocm_api, cluster_id, update_spec, dry_run)
|
695
198
|
|
696
199
|
def get_group_if_exists(self, cluster, group_id):
|
697
200
|
"""Returns a list of users in a group in a cluster.
|
@@ -749,7 +252,7 @@ class OCM: # pylint: disable=too-many-public-methods
|
|
749
252
|
)
|
750
253
|
self._delete(api)
|
751
254
|
|
752
|
-
def get_cluster_aws_account_id(self, cluster: str) ->
|
255
|
+
def get_cluster_aws_account_id(self, cluster: str) -> str | None:
|
753
256
|
"""Returns the AWS account id of the cluster.
|
754
257
|
Since there is no direct API to get this information,
|
755
258
|
we hack our way by relying on existing role grants
|
@@ -870,8 +373,6 @@ class OCM: # pylint: disable=too-many-public-methods
|
|
870
373
|
for idp in idps:
|
871
374
|
if idp["type"] != "GithubIdentityProvider":
|
872
375
|
continue
|
873
|
-
if idp["mapping_method"] != "claim":
|
874
|
-
continue
|
875
376
|
idp_name = idp["name"]
|
876
377
|
idp_github = idp["github"]
|
877
378
|
|
@@ -899,7 +400,7 @@ class OCM: # pylint: disable=too-many-public-methods
|
|
899
400
|
api = f"{CS_API_BASE}/v1/clusters/{cluster_id}/identity_providers"
|
900
401
|
payload = {
|
901
402
|
"type": "GithubIdentityProvider",
|
902
|
-
"mapping_method": "
|
403
|
+
"mapping_method": "add",
|
903
404
|
"name": spec["name"],
|
904
405
|
"github": {
|
905
406
|
"client_id": spec["client_id"],
|
@@ -909,98 +410,18 @@ class OCM: # pylint: disable=too-many-public-methods
|
|
909
410
|
}
|
910
411
|
self._post(api, payload)
|
911
412
|
|
912
|
-
def
|
913
|
-
|
914
|
-
|
915
|
-
|
916
|
-
f"{attrs} are mandatory parameters cannot be empty."
|
917
|
-
)
|
413
|
+
def get_kubeconfig(self, cluster: str) -> str | None:
|
414
|
+
"""Returns the cluster credentials (kubeconfig)
|
415
|
+
|
416
|
+
:param cluster: cluster name
|
918
417
|
|
919
|
-
|
920
|
-
"""
|
418
|
+
:type cluster: string
|
419
|
+
"""
|
921
420
|
cluster_id = self.cluster_ids.get(cluster)
|
922
421
|
if not cluster_id:
|
923
|
-
return
|
924
|
-
api = f"{CS_API_BASE}/v1/clusters/{cluster_id}/
|
925
|
-
|
926
|
-
if not idps:
|
927
|
-
return []
|
928
|
-
|
929
|
-
results = []
|
930
|
-
for idp in idps:
|
931
|
-
if idp["type"] != "OpenIDIdentityProvider":
|
932
|
-
continue
|
933
|
-
claims = idp["open_id"].get("claims", {})
|
934
|
-
results.append(
|
935
|
-
OCMOidcIdp(
|
936
|
-
cluster=cluster,
|
937
|
-
id=idp["id"],
|
938
|
-
name=idp["name"],
|
939
|
-
client_id=idp["open_id"]["client_id"],
|
940
|
-
issuer=idp["open_id"]["issuer"],
|
941
|
-
email_claims=claims.get("email", []),
|
942
|
-
name_claims=claims.get("name", []),
|
943
|
-
username_claims=claims.get("preferred_username", []),
|
944
|
-
groups_claims=claims.get("groups", []),
|
945
|
-
)
|
946
|
-
)
|
947
|
-
return results
|
948
|
-
|
949
|
-
def create_oidc_idp(self, oidc_idp: OCMOidcIdp) -> None:
|
950
|
-
"""Creates a new OpenID Connect IDP."""
|
951
|
-
cluster_id = self.cluster_ids[oidc_idp.cluster]
|
952
|
-
api = f"{CS_API_BASE}/v1/clusters/{cluster_id}/identity_providers"
|
953
|
-
self._check_oidc_idp_params(
|
954
|
-
oidc_idp,
|
955
|
-
attrs=["email_claims", "name_claims", "username_claims", "client_secret"],
|
956
|
-
)
|
957
|
-
payload = {
|
958
|
-
"type": "OpenIDIdentityProvider",
|
959
|
-
"name": oidc_idp.name,
|
960
|
-
"mapping_method": "claim",
|
961
|
-
"open_id": {
|
962
|
-
"claims": {
|
963
|
-
"email": oidc_idp.email_claims,
|
964
|
-
"name": oidc_idp.name_claims,
|
965
|
-
"preferred_username": oidc_idp.username_claims,
|
966
|
-
"groups": oidc_idp.groups_claims,
|
967
|
-
},
|
968
|
-
"client_id": oidc_idp.client_id,
|
969
|
-
"client_secret": oidc_idp.client_secret,
|
970
|
-
"issuer": oidc_idp.issuer,
|
971
|
-
},
|
972
|
-
}
|
973
|
-
self._post(api, payload)
|
974
|
-
|
975
|
-
def update_oidc_idp(self, id: str, oidc_idp: OCMOidcIdp) -> None:
|
976
|
-
"""Update an existing OpenID Connect IDP."""
|
977
|
-
cluster_id = self.cluster_ids[oidc_idp.cluster]
|
978
|
-
self._check_oidc_idp_params(
|
979
|
-
oidc_idp,
|
980
|
-
attrs=["email_claims", "name_claims", "username_claims", "client_secret"],
|
981
|
-
)
|
982
|
-
api = f"{CS_API_BASE}/v1/clusters/{cluster_id}/identity_providers/{id}"
|
983
|
-
payload = {
|
984
|
-
"type": "OpenIDIdentityProvider",
|
985
|
-
"open_id": {
|
986
|
-
"claims": {
|
987
|
-
"email": oidc_idp.email_claims,
|
988
|
-
"name": oidc_idp.name_claims,
|
989
|
-
"preferred_username": oidc_idp.username_claims,
|
990
|
-
"groups": oidc_idp.groups_claims,
|
991
|
-
},
|
992
|
-
"client_id": oidc_idp.client_id,
|
993
|
-
"client_secret": oidc_idp.client_secret,
|
994
|
-
"issuer": oidc_idp.issuer,
|
995
|
-
},
|
996
|
-
}
|
997
|
-
self._patch(api, payload)
|
998
|
-
|
999
|
-
def delete_idp(self, cluster: str, idp_id: str) -> None:
|
1000
|
-
"""Delete an IDP."""
|
1001
|
-
cluster_id = self.cluster_ids[cluster]
|
1002
|
-
api = f"{CS_API_BASE}/v1/clusters/{cluster_id}/identity_providers/{idp_id}"
|
1003
|
-
self._delete(api)
|
422
|
+
return None
|
423
|
+
api = f"{CS_API_BASE}/v1/clusters/{cluster_id}/credentials"
|
424
|
+
return self._get_json(api).get("kubeconfig")
|
1004
425
|
|
1005
426
|
def get_external_configuration_labels(self, cluster: str) -> dict[str, str]:
|
1006
427
|
"""Returns details of External Configurations
|
@@ -1066,32 +487,6 @@ class OCM: # pylint: disable=too-many-public-methods
|
|
1066
487
|
)
|
1067
488
|
self._delete(api)
|
1068
489
|
|
1069
|
-
def _get_subscription_labels_api(self, cluster: str) -> str:
|
1070
|
-
cluster_id = self.cluster_ids[cluster]
|
1071
|
-
api = f"{CS_API_BASE}/v1/clusters/{cluster_id}"
|
1072
|
-
subscription_api = self._get_json(api)["subscription"]["href"]
|
1073
|
-
return f"{subscription_api}/labels"
|
1074
|
-
|
1075
|
-
def is_cluster_admin_enabled(self, cluster: str) -> bool:
|
1076
|
-
api = self._get_subscription_labels_api(cluster)
|
1077
|
-
subcription_labels = self._get_json(api).get("items")
|
1078
|
-
|
1079
|
-
for sl in subcription_labels or []:
|
1080
|
-
if sl["key"] == CLUSTER_ADMIN_LABEL_KEY and sl["value"] == "true":
|
1081
|
-
return True
|
1082
|
-
|
1083
|
-
return False
|
1084
|
-
|
1085
|
-
def enable_cluster_admin(self, cluster: str):
|
1086
|
-
api = self._get_subscription_labels_api(cluster)
|
1087
|
-
data = {
|
1088
|
-
"key": CLUSTER_ADMIN_LABEL_KEY,
|
1089
|
-
"value": "true",
|
1090
|
-
"internal": True,
|
1091
|
-
}
|
1092
|
-
|
1093
|
-
self._post(api, data)
|
1094
|
-
|
1095
490
|
def get_machine_pools(self, cluster):
|
1096
491
|
"""Returns a list of details of Machine Pools
|
1097
492
|
|
@@ -1163,6 +558,63 @@ class OCM: # pylint: disable=too-many-public-methods
|
|
1163
558
|
)
|
1164
559
|
self._delete(api)
|
1165
560
|
|
561
|
+
def get_node_pools(self, cluster):
|
562
|
+
"""Returns a list of details of Node Pools
|
563
|
+
|
564
|
+
:param cluster: cluster name
|
565
|
+
|
566
|
+
:type cluster: string
|
567
|
+
"""
|
568
|
+
results = []
|
569
|
+
cluster_id = self.cluster_ids.get(cluster)
|
570
|
+
if not cluster_id:
|
571
|
+
return results
|
572
|
+
|
573
|
+
return get_node_pools(self._ocm_client, cluster_id)
|
574
|
+
|
575
|
+
def delete_node_pool(self, cluster, spec):
|
576
|
+
"""Deletes an existing Node Pool
|
577
|
+
|
578
|
+
:param cluster: cluster name
|
579
|
+
:param spec: required information for node pool update
|
580
|
+
|
581
|
+
:type cluster: string
|
582
|
+
:type spec: dictionary
|
583
|
+
"""
|
584
|
+
cluster_id = self.cluster_ids[cluster]
|
585
|
+
node_pool_id = spec["id"]
|
586
|
+
api = f"{CS_API_BASE}/v1/clusters/{cluster_id}/node_pools/" + f"{node_pool_id}"
|
587
|
+
self._delete(api)
|
588
|
+
|
589
|
+
def create_node_pool(self, cluster, spec):
|
590
|
+
"""Creates a new Node Pool
|
591
|
+
|
592
|
+
:param cluster: cluster name
|
593
|
+
:param spec: required information for node pool creation
|
594
|
+
|
595
|
+
:type cluster: string
|
596
|
+
:type spec: dictionary
|
597
|
+
"""
|
598
|
+
cluster_id = self.cluster_ids[cluster]
|
599
|
+
api = f"{CS_API_BASE}/v1/clusters/{cluster_id}/node_pools"
|
600
|
+
self._post(api, spec)
|
601
|
+
|
602
|
+
def update_node_pool(self, cluster, spec):
|
603
|
+
"""Updates an existing Node Pool
|
604
|
+
|
605
|
+
:param cluster: cluster name
|
606
|
+
:param spec: required information for node pool update
|
607
|
+
|
608
|
+
:type cluster: string
|
609
|
+
:type spec: dictionary
|
610
|
+
"""
|
611
|
+
cluster_id = self.cluster_ids[cluster]
|
612
|
+
node_pool_id = spec["id"]
|
613
|
+
labels = spec.get("labels", {})
|
614
|
+
spec["labels"] = labels
|
615
|
+
api = f"{CS_API_BASE}/v1/clusters/{cluster_id}/node_pools/" + f"{node_pool_id}"
|
616
|
+
self._patch(api, spec)
|
617
|
+
|
1166
618
|
def addon_version_blocked(self, version: str, addon_id: str) -> bool:
|
1167
619
|
"""Check if an addon version is blocked
|
1168
620
|
|
@@ -1191,81 +643,16 @@ class OCM: # pylint: disable=too-many-public-methods
|
|
1191
643
|
"""
|
1192
644
|
return any(re.search(b, version) for b in self.blocked_versions)
|
1193
645
|
|
1194
|
-
def get_available_upgrades(self,
|
1195
|
-
"""Get available versions to upgrade
|
1196
|
-
in the specified channel
|
646
|
+
def get_available_upgrades(self, cluster_name: str) -> list[str]:
|
647
|
+
"""Get available versions to upgrade for a specific cluster.
|
1197
648
|
|
1198
649
|
Args:
|
1199
|
-
|
1200
|
-
channel (string): Upgrade channel
|
1201
|
-
|
1202
|
-
Raises:
|
1203
|
-
KeyError: if specified channel is not valid
|
650
|
+
cluster_name (string): cluster display name to get available upgrades for
|
1204
651
|
|
1205
652
|
Returns:
|
1206
|
-
list: available versions to upgrade to
|
1207
|
-
"""
|
1208
|
-
if channel not in UPGRADE_CHANNELS:
|
1209
|
-
raise KeyError(f"channel should be one of {UPGRADE_CHANNELS}")
|
1210
|
-
version_id = f"openshift-v{version}"
|
1211
|
-
if channel != "stable":
|
1212
|
-
version_id = f"{version_id}-{channel}"
|
1213
|
-
api = f"{CS_API_BASE}/v1/versions/{version_id}"
|
1214
|
-
return self._get_json(api).get("available_upgrades", [])
|
1215
|
-
|
1216
|
-
def get_upgrade_policies(self, cluster, schedule_type=None) -> list[dict[str, Any]]:
|
1217
|
-
"""Returns a list of details of Upgrade Policies
|
1218
|
-
|
1219
|
-
:param cluster: cluster name
|
1220
|
-
|
1221
|
-
:type cluster: string
|
1222
|
-
"""
|
1223
|
-
results: list[dict[str, Any]] = []
|
1224
|
-
cluster_id = self.cluster_ids.get(cluster)
|
1225
|
-
if not cluster_id:
|
1226
|
-
return results
|
1227
|
-
api = f"{CS_API_BASE}/v1/clusters/{cluster_id}/upgrade_policies"
|
1228
|
-
items = self._get_json(api).get("items")
|
1229
|
-
if not items:
|
1230
|
-
return results
|
1231
|
-
|
1232
|
-
for item in items:
|
1233
|
-
if schedule_type and item["schedule_type"] != schedule_type:
|
1234
|
-
continue
|
1235
|
-
result = {k: v for k, v in item.items() if k in UPGRADE_POLICY_DESIRED_KEYS}
|
1236
|
-
results.append(result)
|
1237
|
-
|
1238
|
-
return results
|
1239
|
-
|
1240
|
-
def create_upgrade_policy(self, cluster, spec):
|
1241
|
-
"""Creates a new Upgrade Policy
|
1242
|
-
|
1243
|
-
:param cluster: cluster name
|
1244
|
-
:param spec: required information for creation
|
1245
|
-
|
1246
|
-
:type cluster: string
|
1247
|
-
:type spec: dictionary
|
1248
|
-
"""
|
1249
|
-
cluster_id = self.cluster_ids[cluster]
|
1250
|
-
api = f"{CS_API_BASE}/v1/clusters/{cluster_id}/upgrade_policies"
|
1251
|
-
self._post(api, spec)
|
1252
|
-
|
1253
|
-
def delete_upgrade_policy(self, cluster, spec):
|
1254
|
-
"""Deletes an existing Upgrade Policy
|
1255
|
-
|
1256
|
-
:param cluster: cluster name
|
1257
|
-
:param spec: required information for update
|
1258
|
-
|
1259
|
-
:type cluster: string
|
1260
|
-
:type spec: dictionary
|
653
|
+
list: a non-null but potentially empty list of available versions to upgrade to
|
1261
654
|
"""
|
1262
|
-
|
1263
|
-
upgrade_policy_id = spec["id"]
|
1264
|
-
api = (
|
1265
|
-
f"{CS_API_BASE}/v1/clusters/{cluster_id}/"
|
1266
|
-
+ f"upgrade_policies/{upgrade_policy_id}"
|
1267
|
-
)
|
1268
|
-
self._delete(api)
|
655
|
+
return self.available_cluster_upgrades.get(cluster_name) or []
|
1269
656
|
|
1270
657
|
def get_additional_routers(self, cluster):
|
1271
658
|
"""Returns a list of Additional Application Routers
|
@@ -1319,16 +706,6 @@ class OCM: # pylint: disable=too-many-public-methods
|
|
1319
706
|
api = f"{CS_API_BASE}/v1/clusters/{cluster_id}/" + f"ingresses/{router_id}"
|
1320
707
|
self._delete(api)
|
1321
708
|
|
1322
|
-
def get_provision_shard(self, cluster_id):
|
1323
|
-
"""Returns details of the provision shard
|
1324
|
-
|
1325
|
-
:param cluster: cluster id
|
1326
|
-
|
1327
|
-
:type cluster: string
|
1328
|
-
"""
|
1329
|
-
api = f"{CS_API_BASE}/v1/clusters/{cluster_id}/provision_shard"
|
1330
|
-
return self._get_json(api)
|
1331
|
-
|
1332
709
|
@staticmethod
|
1333
710
|
def _get_autoscale(cluster):
|
1334
711
|
autoscale = cluster["nodes"].get("autoscale_compute", None)
|
@@ -1346,45 +723,6 @@ class OCM: # pylint: disable=too-many-public-methods
|
|
1346
723
|
api = f"{AMS_API_BASE}/v1/access_token"
|
1347
724
|
return self._post(api)
|
1348
725
|
|
1349
|
-
def get_kafka_clusters(self, fields=None):
|
1350
|
-
"""Returns details of the Kafka clusters"""
|
1351
|
-
api = f"{KAS_API_BASE}/v1/kafkas"
|
1352
|
-
clusters = self._get_json(api)["items"]
|
1353
|
-
if fields:
|
1354
|
-
clusters = [
|
1355
|
-
{k: v for k, v in cluster.items() if k in fields}
|
1356
|
-
for cluster in clusters
|
1357
|
-
]
|
1358
|
-
return clusters
|
1359
|
-
|
1360
|
-
def get_kafka_service_accounts(self, fields=None):
|
1361
|
-
"""Returns details of the Kafka service accounts"""
|
1362
|
-
results = []
|
1363
|
-
api = f"{KAS_API_BASE}/v1/service_accounts"
|
1364
|
-
service_accounts = self._get_json(api)["items"]
|
1365
|
-
for sa in service_accounts:
|
1366
|
-
sa_id = sa["id"]
|
1367
|
-
id_api = f"{api}/{sa_id}"
|
1368
|
-
sa_details = self._get_json(id_api)
|
1369
|
-
if fields:
|
1370
|
-
sa_details = {k: v for k, v in sa_details.items() if k in fields}
|
1371
|
-
results.append(sa_details)
|
1372
|
-
return results
|
1373
|
-
|
1374
|
-
def create_kafka_cluster(self, data):
|
1375
|
-
"""Creates (async) a Kafka cluster"""
|
1376
|
-
api = f"{KAS_API_BASE}/v1/kafkas"
|
1377
|
-
params = {"async": "true"}
|
1378
|
-
self._post(api, data, params)
|
1379
|
-
|
1380
|
-
def create_kafka_service_account(self, name, fields=None):
|
1381
|
-
"""Creates a Kafka service account"""
|
1382
|
-
api = f"{KAS_API_BASE}/v1/service_accounts"
|
1383
|
-
result = self._post(api, {"name": name})
|
1384
|
-
if fields:
|
1385
|
-
result = {k: v for k, v in result.items() if k in fields}
|
1386
|
-
return result
|
1387
|
-
|
1388
726
|
def _init_addons(self):
|
1389
727
|
"""Returns a list of Addons"""
|
1390
728
|
api = f"{CS_API_BASE}/v1/addons"
|
@@ -1411,58 +749,6 @@ class OCM: # pylint: disable=too-many-public-methods
|
|
1411
749
|
return addon["version"]["id"]
|
1412
750
|
return None
|
1413
751
|
|
1414
|
-
def get_addon_upgrade_policies(
|
1415
|
-
self, cluster_name: str, addon_id: str = ""
|
1416
|
-
) -> list[dict[str, Any]]:
|
1417
|
-
results: list[dict[str, Any]] = []
|
1418
|
-
cluster_id = self.cluster_ids.get(cluster_name)
|
1419
|
-
if not cluster_id:
|
1420
|
-
return results
|
1421
|
-
api = f"{CS_API_BASE}/v1/clusters/{cluster_id}/addon_upgrade_policies"
|
1422
|
-
items = self._get_json(api).get("items")
|
1423
|
-
if not items:
|
1424
|
-
return results
|
1425
|
-
|
1426
|
-
for item in items:
|
1427
|
-
if addon_id and item["addon_id"] != addon_id:
|
1428
|
-
continue
|
1429
|
-
result = {
|
1430
|
-
k: v for k, v in item.items() if k in ADDON_UPGRADE_POLICY_DESIRED_KEYS
|
1431
|
-
}
|
1432
|
-
results.append(result)
|
1433
|
-
|
1434
|
-
return results
|
1435
|
-
|
1436
|
-
def create_addon_upgrade_policy(self, cluster_name: str, spec: dict) -> None:
|
1437
|
-
"""Creates a new Addon Upgrade Policy
|
1438
|
-
|
1439
|
-
:param cluster: cluster name
|
1440
|
-
:param spec: required information for creation
|
1441
|
-
|
1442
|
-
:type cluster: string
|
1443
|
-
:type spec: dictionary
|
1444
|
-
"""
|
1445
|
-
cluster_id = self.cluster_ids[cluster_name]
|
1446
|
-
api = f"{CS_API_BASE}/v1/clusters/{cluster_id}/addon_upgrade_policies"
|
1447
|
-
self._post(api, spec)
|
1448
|
-
|
1449
|
-
def delete_addon_upgrade_policy(self, cluster_name: str, spec: dict) -> None:
|
1450
|
-
"""Deletes an existing Addon Upgrade Policy
|
1451
|
-
|
1452
|
-
:param cluster: cluster name
|
1453
|
-
:param spec: required information for delete
|
1454
|
-
|
1455
|
-
:type cluster: string
|
1456
|
-
:type spec: dictionary
|
1457
|
-
"""
|
1458
|
-
cluster_id = self.cluster_ids[cluster_name]
|
1459
|
-
upgrade_policy_id = spec["id"]
|
1460
|
-
api = (
|
1461
|
-
f"{CS_API_BASE}/v1/clusters/{cluster_id}/"
|
1462
|
-
+ f"addon_upgrade_policies/{upgrade_policy_id}"
|
1463
|
-
)
|
1464
|
-
self._delete(api)
|
1465
|
-
|
1466
752
|
def get_version_gates(
|
1467
753
|
self, version_prefix: str, sts_only: bool = False
|
1468
754
|
) -> list[dict[str, Any]]:
|
@@ -1475,31 +761,17 @@ class OCM: # pylint: disable=too-many-public-methods
|
|
1475
761
|
and g["sts_only"] == sts_only
|
1476
762
|
]
|
1477
763
|
|
1478
|
-
def get_version_agreement(self, cluster: str) -> list[dict[str, Any]]:
|
1479
|
-
cluster_id = self.cluster_ids.get(cluster)
|
1480
|
-
if not cluster_id:
|
1481
|
-
return []
|
1482
|
-
api = f"{CS_API_BASE}/v1/clusters/{cluster_id}/gate_agreements"
|
1483
|
-
agreements = self._get_json(api).get("items")
|
1484
|
-
if agreements:
|
1485
|
-
return agreements
|
1486
|
-
return []
|
1487
|
-
|
1488
|
-
def create_version_agreement(
|
1489
|
-
self, gate_id: str, cluster: str
|
1490
|
-
) -> dict[str, Union[str, bool]]:
|
1491
|
-
cluster_id = self.cluster_ids.get(cluster)
|
1492
|
-
if not cluster_id:
|
1493
|
-
return {}
|
1494
|
-
api = f"{CS_API_BASE}/v1/clusters/{cluster_id}/gate_agreements"
|
1495
|
-
return self._post(api, {"version_gate": {"id": gate_id}})
|
1496
|
-
|
1497
764
|
def get_cluster_addons(
|
1498
|
-
self,
|
765
|
+
self,
|
766
|
+
cluster: str,
|
767
|
+
with_version: bool = False,
|
768
|
+
required_state: str | None = None,
|
1499
769
|
) -> list[dict[str, str]]:
|
1500
770
|
"""Returns a list of Addons installed on a cluster
|
1501
771
|
|
1502
772
|
:param cluster: cluster name
|
773
|
+
:param with_version: include addon version
|
774
|
+
:param required_state: add search parameter to filter by specified state
|
1503
775
|
|
1504
776
|
:type cluster: string
|
1505
777
|
"""
|
@@ -1508,7 +780,12 @@ class OCM: # pylint: disable=too-many-public-methods
|
|
1508
780
|
if not cluster_id:
|
1509
781
|
return results
|
1510
782
|
api = f"{CS_API_BASE}/v1/clusters/{cluster_id}/addons"
|
1511
|
-
|
783
|
+
|
784
|
+
p: dict[str, Any] | None = None
|
785
|
+
if required_state:
|
786
|
+
p = {"search": f"state='{required_state}'"}
|
787
|
+
|
788
|
+
items = self._get_json(api, params=p).get("items")
|
1512
789
|
if not items:
|
1513
790
|
return results
|
1514
791
|
|
@@ -1551,7 +828,9 @@ class OCM: # pylint: disable=too-many-public-methods
|
|
1551
828
|
try:
|
1552
829
|
re.compile(b)
|
1553
830
|
except re.error:
|
1554
|
-
raise TypeError(
|
831
|
+
raise TypeError(
|
832
|
+
f"blocked version is not a valid regex expression: {b}"
|
833
|
+
) from None
|
1555
834
|
|
1556
835
|
@retry(max_attempts=10)
|
1557
836
|
def _do_get_request(self, api: str, params: Mapping[str, str]) -> dict[str, Any]:
|
@@ -1565,7 +844,7 @@ class OCM: # pylint: disable=too-many-public-methods
|
|
1565
844
|
return rs["kind"].endswith("List")
|
1566
845
|
|
1567
846
|
def _get_json(
|
1568
|
-
self, api: str, params:
|
847
|
+
self, api: str, params: dict[str, Any] | None = None, page_size: int = 100
|
1569
848
|
) -> dict[str, Any]:
|
1570
849
|
responses = []
|
1571
850
|
if not params:
|
@@ -1653,11 +932,11 @@ class OCMMap: # pylint: disable=too-many-public-methods
|
|
1653
932
|
init_provision_shards=False,
|
1654
933
|
init_addons=False,
|
1655
934
|
init_version_gates=False,
|
1656
|
-
|
935
|
+
product_portfolio: OCMProductPortfolio | None = None,
|
936
|
+
) -> None:
|
1657
937
|
"""Initiates OCM instances for each OCM referenced in a cluster."""
|
1658
|
-
self.clusters_map = {}
|
1659
|
-
self.ocm_map = {}
|
1660
|
-
self.sector_map = {}
|
938
|
+
self.clusters_map: dict[str, str] = {}
|
939
|
+
self.ocm_map: dict[str, OCM] = {}
|
1661
940
|
self.calling_integration = integration
|
1662
941
|
self.settings = settings
|
1663
942
|
|
@@ -1671,6 +950,7 @@ class OCMMap: # pylint: disable=too-many-public-methods
|
|
1671
950
|
init_provision_shards,
|
1672
951
|
init_addons,
|
1673
952
|
init_version_gates=init_version_gates,
|
953
|
+
product_portfolio=product_portfolio,
|
1674
954
|
)
|
1675
955
|
elif namespaces:
|
1676
956
|
for namespace_info in namespaces:
|
@@ -1680,6 +960,7 @@ class OCMMap: # pylint: disable=too-many-public-methods
|
|
1680
960
|
init_provision_shards,
|
1681
961
|
init_addons,
|
1682
962
|
init_version_gates=init_version_gates,
|
963
|
+
product_portfolio=product_portfolio,
|
1683
964
|
)
|
1684
965
|
elif ocms:
|
1685
966
|
for ocm in ocms:
|
@@ -1688,20 +969,21 @@ class OCMMap: # pylint: disable=too-many-public-methods
|
|
1688
969
|
init_provision_shards,
|
1689
970
|
init_addons,
|
1690
971
|
init_version_gates=init_version_gates,
|
972
|
+
product_portfolio=product_portfolio,
|
1691
973
|
)
|
1692
974
|
else:
|
1693
975
|
raise KeyError("expected one of clusters, namespaces or ocm.")
|
1694
976
|
|
1695
|
-
|
1696
|
-
for ocm in self.ocm_map.values():
|
1697
|
-
for sector in ocm.sectors.values():
|
1698
|
-
sector.validate_dependencies()
|
1699
|
-
|
1700
|
-
def __getitem__(self, ocm_name) -> OCM:
|
977
|
+
def __getitem__(self, ocm_name: str) -> OCM:
|
1701
978
|
return self.ocm_map[ocm_name]
|
1702
979
|
|
1703
980
|
def init_ocm_client_from_cluster(
|
1704
|
-
self,
|
981
|
+
self,
|
982
|
+
cluster_info,
|
983
|
+
init_provision_shards,
|
984
|
+
init_addons,
|
985
|
+
init_version_gates,
|
986
|
+
product_portfolio: OCMProductPortfolio | None = None,
|
1705
987
|
):
|
1706
988
|
if self.cluster_disabled(cluster_info):
|
1707
989
|
return
|
@@ -1713,22 +995,20 @@ class OCMMap: # pylint: disable=too-many-public-methods
|
|
1713
995
|
|
1714
996
|
if ocm_name not in self.ocm_map:
|
1715
997
|
self.init_ocm_client(
|
1716
|
-
ocm_info,
|
998
|
+
ocm_info,
|
999
|
+
init_provision_shards,
|
1000
|
+
init_addons,
|
1001
|
+
init_version_gates,
|
1002
|
+
product_portfolio,
|
1717
1003
|
)
|
1718
1004
|
|
1719
|
-
if (
|
1720
|
-
cluster_info.get("upgradePolicy") is not None
|
1721
|
-
and cluster_info["upgradePolicy"].get("conditions") is not None
|
1722
|
-
):
|
1723
|
-
sector_name = cluster_info["upgradePolicy"]["conditions"].get("sector")
|
1724
|
-
if sector_name:
|
1725
|
-
ocm = self.ocm_map.get(ocm_name)
|
1726
|
-
# ensure our cluster actually runs in an OCM org we have access to
|
1727
|
-
if ocm and ocm.is_ready(cluster_name):
|
1728
|
-
ocm.sectors[sector_name].cluster_infos.append(cluster_info)
|
1729
|
-
|
1730
1005
|
def init_ocm_client(
|
1731
|
-
self,
|
1006
|
+
self,
|
1007
|
+
ocm_info,
|
1008
|
+
init_provision_shards,
|
1009
|
+
init_addons,
|
1010
|
+
init_version_gates,
|
1011
|
+
product_portfolio: OCMProductPortfolio | None = None,
|
1732
1012
|
):
|
1733
1013
|
"""
|
1734
1014
|
Initiate OCM client.
|
@@ -1771,18 +1051,19 @@ class OCMMap: # pylint: disable=too-many-public-methods
|
|
1771
1051
|
self.ocm_map[ocm_name] = OCM(
|
1772
1052
|
name,
|
1773
1053
|
org_id,
|
1054
|
+
ocm_environment["name"],
|
1774
1055
|
ocm_client,
|
1775
1056
|
init_provision_shards=init_provision_shards,
|
1776
1057
|
init_addons=init_addons,
|
1777
1058
|
blocked_versions=ocm_info.get("blockedVersions"),
|
1778
1059
|
init_version_gates=init_version_gates,
|
1779
|
-
sectors=ocm_info.get("sectors"),
|
1780
1060
|
inheritVersionData=ocm_info.get("inheritVersionData"),
|
1061
|
+
product_portfolio=product_portfolio,
|
1781
1062
|
)
|
1782
1063
|
|
1783
1064
|
def instances(self) -> list[str]:
|
1784
1065
|
"""Get list of OCM instance names initiated in the OCM map."""
|
1785
|
-
return self.ocm_map.keys()
|
1066
|
+
return list(self.ocm_map.keys())
|
1786
1067
|
|
1787
1068
|
def cluster_disabled(self, cluster_info):
|
1788
1069
|
"""
|
@@ -1810,46 +1091,19 @@ class OCMMap: # pylint: disable=too-many-public-methods
|
|
1810
1091
|
:type cluster: string
|
1811
1092
|
"""
|
1812
1093
|
ocm = self.clusters_map[cluster]
|
1813
|
-
return self.ocm_map
|
1094
|
+
return self.ocm_map[ocm]
|
1814
1095
|
|
1815
1096
|
def clusters(self) -> list[str]:
|
1816
1097
|
"""Get list of cluster names initiated in the OCM map."""
|
1817
1098
|
return [k for k, v in self.clusters_map.items() if v]
|
1818
1099
|
|
1819
|
-
def cluster_specs(self) -> tuple[dict[str, OCMSpec], list]:
|
1100
|
+
def cluster_specs(self) -> tuple[dict[str, OCMSpec], list[str]]:
|
1820
1101
|
"""Get dictionary of cluster names and specs in the OCM map."""
|
1821
1102
|
cluster_specs = {}
|
1822
1103
|
for v in self.ocm_map.values():
|
1823
1104
|
cluster_specs.update(v.clusters)
|
1824
1105
|
|
1825
|
-
not_ready_cluster_names = []
|
1106
|
+
not_ready_cluster_names: list[str] = []
|
1826
1107
|
for v in self.ocm_map.values():
|
1827
1108
|
not_ready_cluster_names.extend(v.not_ready_clusters)
|
1828
1109
|
return cluster_specs, not_ready_cluster_names
|
1829
|
-
|
1830
|
-
def kafka_cluster_specs(self):
|
1831
|
-
"""Get dictionary of Kafka cluster names and specs in the OCM map."""
|
1832
|
-
fields = [
|
1833
|
-
"id",
|
1834
|
-
"status",
|
1835
|
-
"cloud_provider",
|
1836
|
-
"region",
|
1837
|
-
"multi_az",
|
1838
|
-
"name",
|
1839
|
-
"bootstrap_server_host",
|
1840
|
-
"failed_reason",
|
1841
|
-
]
|
1842
|
-
cluster_specs = []
|
1843
|
-
for ocm in self.ocm_map.values():
|
1844
|
-
clusters = ocm.get_kafka_clusters(fields=fields)
|
1845
|
-
cluster_specs.extend(clusters)
|
1846
|
-
return cluster_specs
|
1847
|
-
|
1848
|
-
def kafka_service_account_specs(self):
|
1849
|
-
"""Get dictionary of Kafka service account specs in the OCM map."""
|
1850
|
-
fields = ["name", "client_id"]
|
1851
|
-
service_account_specs = []
|
1852
|
-
for ocm in self.ocm_map.values():
|
1853
|
-
service_accounts = ocm.get_kafka_service_accounts(fields=fields)
|
1854
|
-
service_account_specs.extend(service_accounts)
|
1855
|
-
return service_account_specs
|