qontract-reconcile 0.10.2.dev310__py3-none-any.whl → 0.10.2.dev439__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.
Potentially problematic release.
This version of qontract-reconcile might be problematic. Click here for more details.
- {qontract_reconcile-0.10.2.dev310.dist-info → qontract_reconcile-0.10.2.dev439.dist-info}/METADATA +13 -12
- {qontract_reconcile-0.10.2.dev310.dist-info → qontract_reconcile-0.10.2.dev439.dist-info}/RECORD +396 -391
- reconcile/acs_rbac.py +2 -2
- reconcile/aus/advanced_upgrade_service.py +18 -12
- reconcile/aus/base.py +134 -32
- reconcile/aus/cluster_version_data.py +15 -5
- reconcile/aus/models.py +3 -1
- reconcile/aus/ocm_addons_upgrade_scheduler_org.py +1 -0
- reconcile/aus/ocm_upgrade_scheduler.py +8 -1
- reconcile/aus/ocm_upgrade_scheduler_org.py +20 -5
- reconcile/aus/version_gates/sts_version_gate_handler.py +54 -1
- reconcile/automated_actions/config/integration.py +16 -4
- reconcile/aws_account_manager/integration.py +8 -8
- reconcile/aws_account_manager/reconciler.py +3 -3
- reconcile/aws_ami_cleanup/integration.py +8 -12
- reconcile/aws_ami_share.py +69 -62
- reconcile/aws_cloudwatch_log_retention/integration.py +155 -126
- reconcile/aws_ecr_image_pull_secrets.py +5 -5
- reconcile/aws_iam_keys.py +1 -0
- reconcile/aws_saml_idp/integration.py +12 -4
- reconcile/aws_saml_roles/integration.py +32 -25
- reconcile/aws_version_sync/integration.py +125 -84
- reconcile/change_owners/bundle.py +3 -3
- reconcile/change_owners/change_log_tracking.py +3 -2
- reconcile/change_owners/change_owners.py +1 -1
- reconcile/change_owners/diff.py +2 -4
- reconcile/checkpoint.py +12 -4
- reconcile/cli.py +111 -18
- reconcile/cluster_deployment_mapper.py +2 -3
- reconcile/dashdotdb_dora.py +5 -12
- reconcile/dashdotdb_slo.py +1 -1
- reconcile/database_access_manager.py +125 -121
- reconcile/deadmanssnitch.py +1 -5
- reconcile/dynatrace_token_provider/integration.py +1 -1
- reconcile/endpoints_discovery/integration.py +4 -1
- reconcile/endpoints_discovery/merge_request.py +1 -1
- reconcile/endpoints_discovery/merge_request_manager.py +9 -11
- reconcile/external_resources/factories.py +5 -12
- reconcile/external_resources/integration.py +1 -1
- reconcile/external_resources/manager.py +8 -5
- reconcile/external_resources/meta.py +0 -1
- reconcile/external_resources/metrics.py +1 -1
- reconcile/external_resources/model.py +20 -20
- reconcile/external_resources/reconciler.py +7 -4
- reconcile/external_resources/secrets_sync.py +10 -14
- reconcile/external_resources/state.py +26 -16
- reconcile/fleet_labeler/integration.py +1 -1
- reconcile/gabi_authorized_users.py +8 -5
- reconcile/gcp_image_mirror.py +2 -2
- reconcile/github_org.py +1 -1
- reconcile/github_owners.py +4 -0
- reconcile/gitlab_housekeeping.py +13 -15
- reconcile/gitlab_members.py +6 -12
- reconcile/gitlab_mr_sqs_consumer.py +2 -2
- reconcile/gitlab_owners.py +15 -11
- reconcile/gitlab_permissions.py +8 -12
- reconcile/glitchtip_project_alerts/integration.py +3 -1
- reconcile/gql_definitions/acs/acs_instances.py +10 -10
- reconcile/gql_definitions/acs/acs_policies.py +5 -5
- reconcile/gql_definitions/acs/acs_rbac.py +6 -6
- reconcile/gql_definitions/advanced_upgrade_service/aus_clusters.py +32 -32
- reconcile/gql_definitions/advanced_upgrade_service/aus_organization.py +26 -26
- reconcile/gql_definitions/app_interface_metrics_exporter/onboarding_status.py +6 -7
- reconcile/gql_definitions/app_sre_tekton_access_revalidation/roles.py +5 -5
- reconcile/gql_definitions/app_sre_tekton_access_revalidation/users.py +5 -5
- reconcile/gql_definitions/automated_actions/instance.py +51 -12
- reconcile/gql_definitions/aws_account_manager/aws_accounts.py +11 -11
- reconcile/gql_definitions/aws_ami_cleanup/aws_accounts.py +20 -10
- reconcile/gql_definitions/aws_cloudwatch_log_retention/aws_accounts.py +28 -68
- reconcile/gql_definitions/aws_saml_idp/aws_accounts.py +20 -10
- reconcile/gql_definitions/aws_saml_roles/aws_accounts.py +20 -10
- reconcile/gql_definitions/aws_saml_roles/roles.py +5 -5
- reconcile/gql_definitions/aws_version_sync/clusters.py +10 -10
- reconcile/gql_definitions/aws_version_sync/namespaces.py +5 -5
- reconcile/gql_definitions/change_owners/queries/change_types.py +5 -5
- reconcile/gql_definitions/change_owners/queries/self_service_roles.py +9 -9
- reconcile/gql_definitions/cluster_auth_rhidp/clusters.py +18 -18
- reconcile/gql_definitions/common/alerting_services_settings.py +9 -9
- reconcile/gql_definitions/common/app_code_component_repos.py +5 -5
- reconcile/gql_definitions/common/app_interface_custom_messages.py +5 -5
- reconcile/gql_definitions/common/app_interface_dms_settings.py +5 -5
- reconcile/gql_definitions/common/app_interface_repo_settings.py +5 -5
- reconcile/gql_definitions/common/app_interface_roles.py +120 -0
- reconcile/gql_definitions/common/app_interface_state_settings.py +10 -10
- reconcile/gql_definitions/common/app_interface_vault_settings.py +5 -5
- reconcile/gql_definitions/common/app_quay_repos_escalation_policies.py +5 -5
- reconcile/gql_definitions/common/apps.py +5 -5
- reconcile/gql_definitions/common/aws_vpc_requests.py +22 -9
- reconcile/gql_definitions/common/aws_vpcs.py +11 -11
- reconcile/gql_definitions/common/clusters.py +37 -35
- reconcile/gql_definitions/common/clusters_minimal.py +14 -14
- reconcile/gql_definitions/common/clusters_with_dms.py +6 -6
- reconcile/gql_definitions/common/clusters_with_peering.py +29 -30
- reconcile/gql_definitions/common/github_orgs.py +10 -10
- reconcile/gql_definitions/common/jira_settings.py +10 -10
- reconcile/gql_definitions/common/jiralert_settings.py +5 -5
- reconcile/gql_definitions/common/ldap_settings.py +5 -5
- reconcile/gql_definitions/common/namespaces.py +42 -44
- reconcile/gql_definitions/common/namespaces_minimal.py +15 -13
- reconcile/gql_definitions/common/ocm_env_telemeter.py +12 -12
- reconcile/gql_definitions/common/ocm_environments.py +19 -19
- reconcile/gql_definitions/common/pagerduty_instances.py +9 -9
- reconcile/gql_definitions/common/pgp_reencryption_settings.py +6 -6
- reconcile/gql_definitions/common/pipeline_providers.py +29 -29
- reconcile/gql_definitions/common/quay_instances.py +5 -5
- reconcile/gql_definitions/common/quay_orgs.py +5 -5
- reconcile/gql_definitions/common/reserved_networks.py +5 -5
- reconcile/gql_definitions/common/rhcs_provider_settings.py +5 -5
- reconcile/gql_definitions/common/saas_files.py +44 -44
- reconcile/gql_definitions/common/saas_target_namespaces.py +10 -10
- reconcile/gql_definitions/common/saasherder_settings.py +5 -5
- reconcile/gql_definitions/common/slack_workspaces.py +5 -5
- reconcile/gql_definitions/common/smtp_client_settings.py +19 -19
- reconcile/gql_definitions/common/state_aws_account.py +7 -8
- reconcile/gql_definitions/common/users.py +5 -5
- reconcile/gql_definitions/common/users_with_paths.py +5 -5
- reconcile/gql_definitions/cost_report/app_names.py +5 -5
- reconcile/gql_definitions/cost_report/cost_namespaces.py +5 -5
- reconcile/gql_definitions/cost_report/settings.py +9 -9
- reconcile/gql_definitions/dashdotdb_slo/slo_documents_query.py +43 -43
- reconcile/gql_definitions/dynatrace_token_provider/dynatrace_bootstrap_tokens.py +10 -10
- reconcile/gql_definitions/dynatrace_token_provider/token_specs.py +5 -5
- reconcile/gql_definitions/email_sender/apps.py +5 -5
- reconcile/gql_definitions/email_sender/emails.py +8 -8
- reconcile/gql_definitions/email_sender/users.py +6 -6
- reconcile/gql_definitions/endpoints_discovery/apps.py +10 -10
- reconcile/gql_definitions/external_resources/aws_accounts.py +9 -9
- reconcile/gql_definitions/external_resources/external_resources_modules.py +23 -23
- reconcile/gql_definitions/external_resources/external_resources_namespaces.py +494 -410
- reconcile/gql_definitions/external_resources/external_resources_settings.py +28 -26
- reconcile/gql_definitions/external_resources/fragments/external_resources_module_overrides.py +5 -5
- reconcile/gql_definitions/fleet_labeler/fleet_labels.py +40 -40
- reconcile/gql_definitions/fragments/aus_organization.py +5 -5
- reconcile/gql_definitions/fragments/aws_account_common.py +7 -5
- reconcile/gql_definitions/fragments/aws_account_managed.py +5 -5
- reconcile/gql_definitions/fragments/aws_account_sso.py +5 -5
- reconcile/gql_definitions/fragments/aws_infra_management_account.py +5 -5
- reconcile/gql_definitions/fragments/{aws_vpc_request_subnet.py → aws_organization.py} +12 -8
- reconcile/gql_definitions/fragments/aws_vpc.py +5 -5
- reconcile/gql_definitions/fragments/aws_vpc_request.py +12 -5
- reconcile/gql_definitions/fragments/container_image_mirror.py +5 -5
- reconcile/gql_definitions/fragments/deploy_resources.py +5 -5
- reconcile/gql_definitions/fragments/disable.py +5 -5
- reconcile/gql_definitions/fragments/email_service.py +5 -5
- reconcile/gql_definitions/fragments/email_user.py +5 -5
- reconcile/gql_definitions/fragments/jumphost_common_fields.py +5 -5
- reconcile/gql_definitions/fragments/membership_source.py +5 -5
- reconcile/gql_definitions/fragments/minimal_ocm_organization.py +5 -5
- reconcile/gql_definitions/fragments/oc_connection_cluster.py +5 -5
- reconcile/gql_definitions/fragments/ocm_environment.py +5 -5
- reconcile/gql_definitions/fragments/pipeline_provider_retention.py +5 -5
- reconcile/gql_definitions/fragments/prometheus_instance.py +5 -5
- reconcile/gql_definitions/fragments/resource_limits_requirements.py +5 -5
- reconcile/gql_definitions/fragments/resource_requests_requirements.py +5 -5
- reconcile/gql_definitions/fragments/resource_values.py +5 -5
- reconcile/gql_definitions/fragments/saas_slo_document.py +5 -5
- reconcile/gql_definitions/fragments/saas_target_namespace.py +5 -5
- reconcile/gql_definitions/fragments/serviceaccount_token.py +5 -5
- reconcile/gql_definitions/fragments/terraform_state.py +5 -5
- reconcile/gql_definitions/fragments/upgrade_policy.py +5 -5
- reconcile/gql_definitions/fragments/user.py +5 -5
- reconcile/gql_definitions/fragments/vault_secret.py +5 -5
- reconcile/gql_definitions/gcp/gcp_docker_repos.py +9 -9
- reconcile/gql_definitions/gcp/gcp_projects.py +9 -9
- reconcile/gql_definitions/gitlab_members/gitlab_instances.py +9 -9
- reconcile/gql_definitions/gitlab_members/permissions.py +9 -9
- reconcile/gql_definitions/glitchtip/glitchtip_instance.py +9 -9
- reconcile/gql_definitions/glitchtip/glitchtip_project.py +11 -11
- reconcile/gql_definitions/glitchtip_project_alerts/glitchtip_project.py +9 -9
- reconcile/gql_definitions/integrations/integrations.py +48 -51
- reconcile/gql_definitions/introspection.json +3510 -1865
- reconcile/gql_definitions/jenkins_configs/jenkins_configs.py +11 -11
- reconcile/gql_definitions/jenkins_configs/jenkins_instances.py +10 -10
- reconcile/gql_definitions/jira/jira_servers.py +5 -5
- reconcile/gql_definitions/jira_permissions_validator/jira_boards_for_permissions_validator.py +14 -10
- reconcile/gql_definitions/jumphosts/jumphosts.py +13 -13
- reconcile/gql_definitions/ldap_groups/roles.py +5 -5
- reconcile/gql_definitions/ldap_groups/settings.py +9 -9
- reconcile/gql_definitions/maintenance/maintenances.py +5 -5
- reconcile/gql_definitions/membershipsources/roles.py +5 -5
- reconcile/gql_definitions/ocm_labels/clusters.py +18 -19
- reconcile/gql_definitions/ocm_labels/organizations.py +5 -5
- reconcile/gql_definitions/openshift_cluster_bots/clusters.py +22 -22
- reconcile/gql_definitions/openshift_groups/managed_groups.py +5 -5
- reconcile/gql_definitions/openshift_groups/managed_roles.py +6 -6
- reconcile/gql_definitions/openshift_serviceaccount_tokens/tokens.py +10 -10
- reconcile/gql_definitions/quay_membership/quay_membership.py +6 -6
- reconcile/gql_definitions/rhcs/certs.py +33 -87
- reconcile/gql_definitions/rhcs/openshift_resource_rhcs_cert.py +43 -0
- reconcile/gql_definitions/rhidp/organizations.py +18 -18
- reconcile/gql_definitions/service_dependencies/jenkins_instance_fragment.py +5 -5
- reconcile/gql_definitions/service_dependencies/service_dependencies.py +8 -8
- reconcile/gql_definitions/sharding/aws_accounts.py +10 -10
- reconcile/gql_definitions/sharding/ocm_organization.py +8 -8
- reconcile/gql_definitions/skupper_network/site_controller_template.py +5 -5
- reconcile/gql_definitions/skupper_network/skupper_networks.py +10 -10
- reconcile/gql_definitions/slack_usergroups/clusters.py +5 -5
- reconcile/gql_definitions/slack_usergroups/permissions.py +9 -9
- reconcile/gql_definitions/slack_usergroups/users.py +5 -5
- reconcile/gql_definitions/slo_documents/slo_documents.py +5 -5
- reconcile/gql_definitions/status_board/status_board.py +6 -7
- reconcile/gql_definitions/statuspage/statuspages.py +9 -9
- reconcile/gql_definitions/templating/template_collection.py +5 -5
- reconcile/gql_definitions/templating/templates.py +5 -5
- reconcile/gql_definitions/terraform_cloudflare_dns/app_interface_cloudflare_dns_settings.py +6 -6
- reconcile/gql_definitions/terraform_cloudflare_dns/terraform_cloudflare_zones.py +11 -11
- reconcile/gql_definitions/terraform_cloudflare_resources/terraform_cloudflare_accounts.py +11 -11
- reconcile/gql_definitions/terraform_cloudflare_resources/terraform_cloudflare_resources.py +20 -25
- reconcile/gql_definitions/terraform_cloudflare_users/app_interface_setting_cloudflare_and_vault.py +6 -6
- reconcile/gql_definitions/terraform_cloudflare_users/terraform_cloudflare_roles.py +12 -12
- reconcile/gql_definitions/terraform_init/aws_accounts.py +23 -9
- reconcile/gql_definitions/terraform_repo/terraform_repo.py +9 -9
- reconcile/gql_definitions/terraform_resources/database_access_manager.py +5 -5
- reconcile/gql_definitions/terraform_resources/terraform_resources_namespaces.py +450 -402
- reconcile/gql_definitions/terraform_tgw_attachments/aws_accounts.py +23 -17
- reconcile/gql_definitions/unleash_feature_toggles/feature_toggles.py +9 -9
- reconcile/gql_definitions/vault_instances/vault_instances.py +61 -61
- reconcile/gql_definitions/vault_policies/vault_policies.py +11 -11
- reconcile/gql_definitions/vpc_peerings_validator/vpc_peerings_validator.py +8 -8
- reconcile/gql_definitions/vpc_peerings_validator/vpc_peerings_validator_peered_cluster_fragment.py +5 -5
- reconcile/integrations_manager.py +3 -3
- reconcile/jenkins_job_builder.py +1 -1
- reconcile/jenkins_worker_fleets.py +80 -11
- reconcile/jira_permissions_validator.py +237 -122
- reconcile/ldap_groups/integration.py +1 -1
- reconcile/ocm/types.py +35 -56
- reconcile/ocm_aws_infrastructure_access.py +1 -1
- reconcile/ocm_clusters.py +4 -4
- reconcile/ocm_labels/integration.py +3 -2
- reconcile/ocm_machine_pools.py +33 -27
- reconcile/openshift_base.py +122 -10
- reconcile/openshift_cluster_bots.py +5 -5
- reconcile/openshift_groups.py +5 -0
- reconcile/openshift_limitranges.py +1 -1
- reconcile/openshift_namespace_labels.py +1 -1
- reconcile/openshift_namespaces.py +97 -101
- reconcile/openshift_resources_base.py +10 -5
- reconcile/openshift_rhcs_certs.py +77 -40
- reconcile/openshift_rolebindings.py +230 -130
- reconcile/openshift_saas_deploy.py +6 -7
- reconcile/openshift_saas_deploy_change_tester.py +9 -7
- reconcile/openshift_saas_deploy_trigger_cleaner.py +3 -5
- reconcile/openshift_serviceaccount_tokens.py +8 -7
- reconcile/openshift_tekton_resources.py +1 -1
- reconcile/openshift_upgrade_watcher.py +4 -4
- reconcile/openshift_users.py +5 -3
- reconcile/oum/labelset.py +5 -3
- reconcile/oum/models.py +1 -4
- reconcile/oum/providers.py +1 -1
- reconcile/prometheus_rules_tester/integration.py +4 -4
- reconcile/quay_mirror.py +1 -1
- reconcile/queries.py +131 -0
- reconcile/requests_sender.py +8 -3
- reconcile/resource_scraper.py +1 -5
- reconcile/rhidp/common.py +3 -5
- reconcile/rhidp/sso_client/base.py +19 -10
- reconcile/saas_auto_promotions_manager/merge_request_manager/renderer.py +1 -1
- reconcile/saas_auto_promotions_manager/subscriber.py +4 -3
- reconcile/sendgrid_teammates.py +20 -9
- reconcile/skupper_network/integration.py +2 -2
- reconcile/slack_usergroups.py +35 -14
- reconcile/sql_query.py +1 -0
- reconcile/status.py +2 -2
- reconcile/status_board.py +6 -6
- reconcile/statuspage/atlassian.py +7 -7
- reconcile/statuspage/integrations/maintenances.py +4 -3
- reconcile/statuspage/page.py +4 -9
- reconcile/statuspage/status.py +5 -8
- reconcile/templates/rosa-classic-cluster-creation.sh.j2 +5 -1
- reconcile/templates/rosa-hcp-cluster-creation.sh.j2 +4 -1
- reconcile/templating/lib/merge_request_manager.py +2 -2
- reconcile/templating/lib/rendering.py +3 -3
- reconcile/templating/renderer.py +12 -13
- reconcile/terraform_aws_route53.py +18 -8
- reconcile/terraform_cloudflare_dns.py +3 -3
- reconcile/terraform_cloudflare_resources.py +12 -13
- reconcile/terraform_cloudflare_users.py +3 -2
- reconcile/terraform_init/integration.py +187 -23
- reconcile/terraform_repo.py +16 -12
- reconcile/terraform_resources.py +18 -10
- reconcile/terraform_tgw_attachments.py +28 -20
- reconcile/terraform_users.py +27 -22
- reconcile/terraform_vpc_peerings.py +15 -3
- reconcile/terraform_vpc_resources/integration.py +23 -8
- reconcile/typed_queries/app_interface_roles.py +10 -0
- reconcile/typed_queries/aws_account_tags.py +41 -0
- reconcile/typed_queries/cost_report/app_names.py +1 -1
- reconcile/typed_queries/cost_report/cost_namespaces.py +2 -2
- reconcile/typed_queries/saas_files.py +13 -13
- reconcile/typed_queries/status_board.py +2 -2
- reconcile/unleash_feature_toggles/integration.py +4 -2
- reconcile/utils/acs/base.py +6 -3
- reconcile/utils/acs/policies.py +2 -2
- reconcile/utils/aggregated_list.py +4 -3
- reconcile/utils/aws_api.py +51 -20
- reconcile/utils/aws_api_typed/api.py +38 -9
- reconcile/utils/aws_api_typed/cloudformation.py +149 -0
- reconcile/utils/aws_api_typed/logs.py +73 -0
- reconcile/utils/aws_api_typed/organization.py +4 -2
- reconcile/utils/binary.py +7 -12
- reconcile/utils/datetime_util.py +67 -0
- reconcile/utils/deadmanssnitch_api.py +1 -1
- reconcile/utils/differ.py +2 -3
- reconcile/utils/early_exit_cache.py +11 -12
- reconcile/utils/expiration.py +7 -3
- reconcile/utils/external_resource_spec.py +24 -1
- reconcile/utils/filtering.py +1 -1
- reconcile/utils/gitlab_api.py +7 -5
- reconcile/utils/glitchtip/client.py +6 -2
- reconcile/utils/glitchtip/models.py +25 -28
- reconcile/utils/gpg.py +5 -3
- reconcile/utils/gql.py +4 -7
- reconcile/utils/helm.py +2 -1
- reconcile/utils/helpers.py +1 -1
- reconcile/utils/imap_client.py +1 -1
- reconcile/utils/instrumented_wrappers.py +1 -1
- reconcile/utils/internal_groups/client.py +2 -2
- reconcile/utils/internal_groups/models.py +8 -17
- reconcile/utils/jenkins_api.py +24 -1
- reconcile/utils/jinja2/utils.py +6 -8
- reconcile/utils/jira_client.py +82 -63
- reconcile/utils/jjb_client.py +78 -46
- reconcile/utils/jobcontroller/controller.py +2 -2
- reconcile/utils/jobcontroller/models.py +17 -1
- reconcile/utils/json.py +74 -0
- reconcile/utils/ldap_client.py +4 -3
- reconcile/utils/lean_terraform_client.py +3 -1
- reconcile/utils/membershipsources/app_interface_resolver.py +4 -2
- reconcile/utils/membershipsources/models.py +16 -23
- reconcile/utils/membershipsources/resolver.py +4 -2
- reconcile/utils/merge_request_manager/merge_request_manager.py +4 -4
- reconcile/utils/merge_request_manager/parser.py +6 -6
- reconcile/utils/metrics.py +5 -5
- reconcile/utils/models.py +304 -82
- reconcile/utils/mr/__init__.py +3 -1
- reconcile/utils/mr/app_interface_reporter.py +6 -3
- reconcile/utils/mr/aws_access.py +1 -1
- reconcile/utils/mr/base.py +7 -13
- reconcile/utils/mr/clusters_updates.py +4 -2
- reconcile/utils/mr/notificator.py +3 -3
- reconcile/utils/mr/ocm_upgrade_scheduler_org_updates.py +4 -1
- reconcile/utils/mr/promote_qontract.py +28 -12
- reconcile/utils/mr/update_access_report_base.py +3 -4
- reconcile/utils/mr/user_maintenance.py +7 -6
- reconcile/utils/oc.py +445 -336
- reconcile/utils/oc_filters.py +3 -3
- reconcile/utils/ocm/addons.py +0 -1
- reconcile/utils/ocm/base.py +18 -21
- reconcile/utils/ocm/cluster_groups.py +1 -1
- reconcile/utils/ocm/identity_providers.py +2 -2
- reconcile/utils/ocm/labels.py +1 -1
- reconcile/utils/ocm/ocm.py +81 -71
- reconcile/utils/ocm/products.py +9 -3
- reconcile/utils/ocm/search_filters.py +3 -6
- reconcile/utils/ocm/service_log.py +4 -6
- reconcile/utils/ocm/sre_capability_labels.py +20 -13
- reconcile/utils/ocm_base_client.py +4 -4
- reconcile/utils/openshift_resource.py +83 -52
- reconcile/utils/openssl.py +2 -2
- reconcile/utils/output.py +3 -2
- reconcile/utils/pagerduty_api.py +10 -7
- reconcile/utils/promotion_state.py +6 -11
- reconcile/utils/raw_github_api.py +11 -8
- reconcile/utils/repo_owners.py +21 -29
- reconcile/utils/rhcsv2_certs.py +138 -35
- reconcile/utils/rosa/session.py +16 -0
- reconcile/utils/runtime/integration.py +2 -3
- reconcile/utils/runtime/meta.py +2 -1
- reconcile/utils/runtime/runner.py +2 -2
- reconcile/utils/saasherder/interfaces.py +13 -20
- reconcile/utils/saasherder/models.py +25 -21
- reconcile/utils/saasherder/saasherder.py +60 -32
- reconcile/utils/secret_reader.py +6 -6
- reconcile/utils/sharding.py +1 -1
- reconcile/utils/slack_api.py +26 -4
- reconcile/utils/sloth.py +224 -0
- reconcile/utils/sqs_gateway.py +16 -11
- reconcile/utils/state.py +2 -1
- reconcile/utils/structs.py +1 -1
- reconcile/utils/terraform_client.py +29 -26
- reconcile/utils/terrascript_aws_client.py +200 -116
- reconcile/utils/three_way_diff_strategy.py +1 -1
- reconcile/utils/unleash/server.py +2 -8
- reconcile/utils/vault.py +44 -41
- reconcile/utils/vcs.py +8 -8
- reconcile/vault_replication.py +119 -58
- tools/app_interface_reporter.py +4 -4
- tools/cli_commands/cost_report/cost_management_api.py +3 -3
- tools/cli_commands/cost_report/view.py +7 -6
- tools/cli_commands/erv2.py +1 -1
- tools/cli_commands/gpg_encrypt.py +4 -1
- tools/cli_commands/systems_and_tools.py +5 -1
- tools/qontract_cli.py +36 -21
- tools/template_validation.py +3 -1
- reconcile/gql_definitions/ocm_oidc_idp/__init__.py +0 -0
- reconcile/gql_definitions/ocm_subscription_labels/__init__.py +0 -0
- reconcile/jenkins/__init__.py +0 -0
- reconcile/jenkins/types.py +0 -77
- {qontract_reconcile-0.10.2.dev310.dist-info → qontract_reconcile-0.10.2.dev439.dist-info}/WHEEL +0 -0
- {qontract_reconcile-0.10.2.dev310.dist-info → qontract_reconcile-0.10.2.dev439.dist-info}/entry_points.txt +0 -0
|
@@ -7,12 +7,7 @@ from enum import StrEnum
|
|
|
7
7
|
from typing import Any
|
|
8
8
|
|
|
9
9
|
import semver
|
|
10
|
-
from pydantic import
|
|
11
|
-
BaseModel,
|
|
12
|
-
ValidationError,
|
|
13
|
-
root_validator,
|
|
14
|
-
validator,
|
|
15
|
-
)
|
|
10
|
+
from pydantic import BaseModel, ValidationError, field_validator, model_validator
|
|
16
11
|
|
|
17
12
|
from reconcile.aws_version_sync.merge_request_manager.merge_request import (
|
|
18
13
|
Renderer,
|
|
@@ -81,7 +76,7 @@ class SupportedResourceProvider(StrEnum):
|
|
|
81
76
|
ELASTICACHE = "elasticache"
|
|
82
77
|
|
|
83
78
|
|
|
84
|
-
class ExternalResource(BaseModel):
|
|
79
|
+
class ExternalResource(BaseModel, arbitrary_types_allowed=True):
|
|
85
80
|
namespace_file: str | None = None
|
|
86
81
|
provider: str = "aws"
|
|
87
82
|
provisioner: ExternalResourceProvisioner
|
|
@@ -94,9 +89,6 @@ class ExternalResource(BaseModel):
|
|
|
94
89
|
# used to map AWS cache name to resource_identifier
|
|
95
90
|
redis_replication_group_id: str | None = None
|
|
96
91
|
|
|
97
|
-
class Config:
|
|
98
|
-
arbitrary_types_allowed = True
|
|
99
|
-
|
|
100
92
|
@property
|
|
101
93
|
def key(self) -> tuple:
|
|
102
94
|
return (
|
|
@@ -104,10 +96,10 @@ class ExternalResource(BaseModel):
|
|
|
104
96
|
self.provisioner.uid,
|
|
105
97
|
self.resource_provider,
|
|
106
98
|
self.resource_identifier,
|
|
107
|
-
self.resource_engine,
|
|
108
99
|
)
|
|
109
100
|
|
|
110
|
-
@
|
|
101
|
+
@field_validator("resource_engine_version", mode="before")
|
|
102
|
+
@classmethod
|
|
111
103
|
def parse_resource_engine_version(
|
|
112
104
|
cls, v: str | semver.VersionInfo
|
|
113
105
|
) -> semver.VersionInfo:
|
|
@@ -115,7 +107,8 @@ class ExternalResource(BaseModel):
|
|
|
115
107
|
return v
|
|
116
108
|
return parse_semver(str(v), optional_minor_and_patch=True)
|
|
117
109
|
|
|
118
|
-
@
|
|
110
|
+
@model_validator(mode="before")
|
|
111
|
+
@classmethod
|
|
119
112
|
def set_resource_engine_version_format(cls, values: dict) -> dict:
|
|
120
113
|
resource_engine_version, resource_engine_version_format = (
|
|
121
114
|
str(values.get("resource_engine_version")),
|
|
@@ -220,6 +213,7 @@ class AVSIntegration(QontractReconcileIntegration[AVSIntegrationParams]):
|
|
|
220
213
|
clusters: Iterable[ClusterV1],
|
|
221
214
|
timeout: int,
|
|
222
215
|
elasticache_replication_group_id_to_identifier: ReplicationGroupIdToIdentifier,
|
|
216
|
+
supported_providers: Iterable[str],
|
|
223
217
|
prom_get_func: Callable = prom_get,
|
|
224
218
|
) -> list[ExternalResource]:
|
|
225
219
|
metrics: list[ExternalResource] = []
|
|
@@ -232,81 +226,123 @@ class AVSIntegration(QontractReconcileIntegration[AVSIntegrationParams]):
|
|
|
232
226
|
)
|
|
233
227
|
|
|
234
228
|
# RDS resources
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
params={"query": "aws_resources_exporter_rds_engineversion"},
|
|
239
|
-
token=token,
|
|
240
|
-
timeout=timeout,
|
|
229
|
+
if SupportedResourceProvider.RDS in supported_providers:
|
|
230
|
+
metrics.extend(
|
|
231
|
+
self._fetch_rds_metrics(cluster, token, timeout, prom_get_func)
|
|
241
232
|
)
|
|
242
233
|
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
234
|
+
# ElastiCache resources
|
|
235
|
+
if SupportedResourceProvider.ELASTICACHE in supported_providers:
|
|
236
|
+
metrics.extend(
|
|
237
|
+
self._fetch_elasticache_metrics(
|
|
238
|
+
cluster,
|
|
239
|
+
token,
|
|
240
|
+
timeout,
|
|
241
|
+
elasticache_replication_group_id_to_identifier,
|
|
242
|
+
prom_get_func,
|
|
243
|
+
)
|
|
244
|
+
)
|
|
245
|
+
|
|
246
|
+
return metrics
|
|
247
|
+
|
|
248
|
+
def _fetch_rds_metrics(
|
|
249
|
+
self,
|
|
250
|
+
cluster: ClusterV1,
|
|
251
|
+
token: str | None,
|
|
252
|
+
timeout: int,
|
|
253
|
+
prom_get_func: Callable,
|
|
254
|
+
) -> list[ExternalResource]:
|
|
255
|
+
"""Fetch RDS metrics from the AWS resource exporter."""
|
|
256
|
+
metrics: list[ExternalResource] = []
|
|
257
|
+
try:
|
|
258
|
+
rds_metrics = prom_get_func(
|
|
259
|
+
url=cluster.prometheus_url,
|
|
260
|
+
params={"query": "aws_resources_exporter_rds_engineversion"},
|
|
261
|
+
token=token,
|
|
262
|
+
timeout=timeout,
|
|
263
|
+
)
|
|
264
|
+
except Exception as e:
|
|
265
|
+
logging.error(
|
|
266
|
+
f"Failed to get 'aws_resources_exporter_rds_engineversion' metrics for cluster {cluster.name}: {e}"
|
|
267
|
+
)
|
|
268
|
+
return []
|
|
269
|
+
|
|
270
|
+
for m in rds_metrics:
|
|
271
|
+
try:
|
|
272
|
+
metrics.append(
|
|
273
|
+
ExternalResource(
|
|
274
|
+
provider="aws",
|
|
275
|
+
provisioner=ExternalResourceProvisioner(
|
|
276
|
+
uid=m["aws_account_id"]
|
|
277
|
+
),
|
|
278
|
+
resource_provider=SupportedResourceProvider.RDS,
|
|
279
|
+
resource_identifier=m["dbinstance_identifier"],
|
|
280
|
+
resource_engine=m["engine"],
|
|
281
|
+
resource_engine_version=m["engine_version"],
|
|
282
|
+
)
|
|
283
|
+
)
|
|
284
|
+
except ValidationError as e:
|
|
285
|
+
if EXTENDED_SUPPORT_VERSION_INDICATOR in m["engine_version"]:
|
|
286
|
+
# don't try to parse AWS extended support version numbers
|
|
287
|
+
# See https://aws.amazon.com/about-aws/whats-new/2025/04/amazon-rds-postgresql-extended-support-11-22-rds-20250220-12-22-rds-20250220/ for more info
|
|
288
|
+
pass
|
|
289
|
+
else:
|
|
290
|
+
logging.error(
|
|
291
|
+
f"Failed to parse RDS metric for {m['dbinstance_identifier']}: {e}"
|
|
292
|
+
)
|
|
293
|
+
except KeyError as e:
|
|
270
294
|
logging.error(
|
|
271
|
-
f"Failed to
|
|
295
|
+
f"Failed to parse RDS metric for {m['dbinstance_identifier']}: {e}"
|
|
272
296
|
)
|
|
297
|
+
return metrics
|
|
273
298
|
|
|
274
|
-
|
|
299
|
+
def _fetch_elasticache_metrics(
|
|
300
|
+
self,
|
|
301
|
+
cluster: ClusterV1,
|
|
302
|
+
token: str | None,
|
|
303
|
+
timeout: int,
|
|
304
|
+
elasticache_replication_group_id_to_identifier: ReplicationGroupIdToIdentifier,
|
|
305
|
+
prom_get_func: Callable,
|
|
306
|
+
) -> list[ExternalResource]:
|
|
307
|
+
"""Fetch ElastiCache metrics from the AWS resource exporter."""
|
|
308
|
+
metrics: list[ExternalResource] = []
|
|
309
|
+
try:
|
|
310
|
+
elasticache_metrics = prom_get_func(
|
|
311
|
+
url=cluster.prometheus_url,
|
|
312
|
+
params={"query": "aws_resources_exporter_elasticache_redisversion"},
|
|
313
|
+
token=token,
|
|
314
|
+
timeout=timeout,
|
|
315
|
+
)
|
|
316
|
+
except Exception as e:
|
|
317
|
+
logging.error(
|
|
318
|
+
f"Failed to get 'aws_resources_exporter_elasticache_redisversion' metrics for cluster {cluster.name}: {e}"
|
|
319
|
+
)
|
|
320
|
+
return []
|
|
321
|
+
|
|
322
|
+
for m in elasticache_metrics:
|
|
275
323
|
try:
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
324
|
+
metrics.append(
|
|
325
|
+
ExternalResource(
|
|
326
|
+
provider="aws",
|
|
327
|
+
provisioner=ExternalResourceProvisioner(
|
|
328
|
+
uid=m["aws_account_id"]
|
|
329
|
+
),
|
|
330
|
+
resource_provider=SupportedResourceProvider.ELASTICACHE,
|
|
331
|
+
# replication_group_id != resource_identifier!
|
|
332
|
+
resource_identifier=elasticache_replication_group_id_to_identifier.get(
|
|
333
|
+
(
|
|
334
|
+
m["aws_account_id"],
|
|
335
|
+
m["replication_group_id"],
|
|
336
|
+
),
|
|
337
|
+
m["replication_group_id"],
|
|
338
|
+
),
|
|
339
|
+
resource_engine=m["engine"],
|
|
340
|
+
resource_engine_version=m["engine_version"],
|
|
341
|
+
)
|
|
281
342
|
)
|
|
282
|
-
|
|
283
|
-
try:
|
|
284
|
-
metrics.append(
|
|
285
|
-
ExternalResource(
|
|
286
|
-
provider="aws",
|
|
287
|
-
provisioner=ExternalResourceProvisioner(
|
|
288
|
-
uid=m["aws_account_id"]
|
|
289
|
-
),
|
|
290
|
-
resource_provider=SupportedResourceProvider.ELASTICACHE,
|
|
291
|
-
# replication_group_id != resource_identifier!
|
|
292
|
-
resource_identifier=elasticache_replication_group_id_to_identifier.get(
|
|
293
|
-
(
|
|
294
|
-
m["aws_account_id"],
|
|
295
|
-
m["replication_group_id"],
|
|
296
|
-
),
|
|
297
|
-
m["replication_group_id"],
|
|
298
|
-
),
|
|
299
|
-
resource_engine=m["engine"],
|
|
300
|
-
resource_engine_version=m["engine_version"],
|
|
301
|
-
)
|
|
302
|
-
)
|
|
303
|
-
except Exception as e:
|
|
304
|
-
logging.error(
|
|
305
|
-
f"Failed to parse ElastiCache metrics for {m['replication_group_id']}: {e}"
|
|
306
|
-
)
|
|
307
|
-
except Exception as e:
|
|
343
|
+
except (ValidationError, KeyError) as e:
|
|
308
344
|
logging.error(
|
|
309
|
-
f"Failed to
|
|
345
|
+
f"Failed to parse ElastiCache metrics for {m['replication_group_id']}: {e}"
|
|
310
346
|
)
|
|
311
347
|
|
|
312
348
|
return metrics
|
|
@@ -353,8 +389,8 @@ class AVSIntegration(QontractReconcileIntegration[AVSIntegrationParams]):
|
|
|
353
389
|
resource.provider == SupportedResourceProvider.ELASTICACHE
|
|
354
390
|
and str(values["engine_version"]).lower().endswith("x")
|
|
355
391
|
):
|
|
356
|
-
# AWS ElastiCache Redis 6 could use a version like 6.x.
|
|
357
|
-
|
|
392
|
+
# AWS ElastiCache Redis 6 could use a version like 6.x. Let's patch it to a fix version
|
|
393
|
+
values["engine_version"] = "6.2"
|
|
358
394
|
|
|
359
395
|
if (
|
|
360
396
|
resource.provider == SupportedResourceProvider.RDS
|
|
@@ -400,7 +436,9 @@ class AVSIntegration(QontractReconcileIntegration[AVSIntegrationParams]):
|
|
|
400
436
|
key=lambda r: r.key,
|
|
401
437
|
equal=lambda external_resources_app_interface,
|
|
402
438
|
external_resources_aws: external_resources_app_interface.resource_engine_version_string
|
|
403
|
-
== external_resources_aws.resource_engine_version_string
|
|
439
|
+
== external_resources_aws.resource_engine_version_string
|
|
440
|
+
and external_resources_app_interface.resource_engine
|
|
441
|
+
== external_resources_aws.resource_engine,
|
|
404
442
|
)
|
|
405
443
|
for diff_pair in diff.change.values():
|
|
406
444
|
aws_resource = diff_pair.desired
|
|
@@ -408,6 +446,8 @@ class AVSIntegration(QontractReconcileIntegration[AVSIntegrationParams]):
|
|
|
408
446
|
if (
|
|
409
447
|
aws_resource.resource_engine_version
|
|
410
448
|
<= app_interface_resource.resource_engine_version
|
|
449
|
+
and aws_resource.resource_engine
|
|
450
|
+
== app_interface_resource.resource_engine
|
|
411
451
|
):
|
|
412
452
|
# do not downgrade the version
|
|
413
453
|
continue
|
|
@@ -422,7 +462,7 @@ class AVSIntegration(QontractReconcileIntegration[AVSIntegrationParams]):
|
|
|
422
462
|
provisioner_uid=app_interface_resource.provisioner.uid,
|
|
423
463
|
resource_provider=app_interface_resource.resource_provider,
|
|
424
464
|
resource_identifier=app_interface_resource.resource_identifier,
|
|
425
|
-
resource_engine=
|
|
465
|
+
resource_engine=aws_resource.resource_engine,
|
|
426
466
|
resource_engine_version=aws_resource.resource_engine_version_string,
|
|
427
467
|
)
|
|
428
468
|
)
|
|
@@ -475,6 +515,7 @@ class AVSIntegration(QontractReconcileIntegration[AVSIntegrationParams]):
|
|
|
475
515
|
for external_resource in external_resources_app_interface
|
|
476
516
|
if external_resource.redis_replication_group_id
|
|
477
517
|
},
|
|
518
|
+
supported_providers=self.params.supported_providers,
|
|
478
519
|
)
|
|
479
520
|
|
|
480
521
|
self.reconcile(
|
|
@@ -62,8 +62,8 @@ class QontractServerDatafileDiff(BaseModel):
|
|
|
62
62
|
|
|
63
63
|
datafilepath: str
|
|
64
64
|
datafileschema: str
|
|
65
|
-
old: dict[str, Any] | None
|
|
66
|
-
new: dict[str, Any] | None
|
|
65
|
+
old: dict[str, Any] | None = None
|
|
66
|
+
new: dict[str, Any] | None = None
|
|
67
67
|
|
|
68
68
|
@property
|
|
69
69
|
def old_datafilepath(self) -> str | None:
|
|
@@ -119,7 +119,7 @@ class QontractServerResourcefileDiffState(BaseModel):
|
|
|
119
119
|
content: str
|
|
120
120
|
resourcefileschema: str | None = Field(..., alias="$schema")
|
|
121
121
|
sha256sum: str
|
|
122
|
-
backrefs: list[QontractServerResourcefileBackref] | None
|
|
122
|
+
backrefs: list[QontractServerResourcefileBackref] | None = None
|
|
123
123
|
|
|
124
124
|
|
|
125
125
|
class QontractServerResourcefileDiff(BaseModel):
|
|
@@ -155,7 +155,8 @@ class ChangeLogIntegration(QontractReconcileIntegration[ChangeLogIntegrationPara
|
|
|
155
155
|
changes = aggregate_resource_changes(
|
|
156
156
|
bundle_changes=aggregate_file_moves(parse_bundle_changes(diff)),
|
|
157
157
|
content_store={
|
|
158
|
-
c.path: c.
|
|
158
|
+
c.path: c.model_dump(by_alias=True)
|
|
159
|
+
for c in namespaces + jenkins_configs
|
|
159
160
|
},
|
|
160
161
|
supported_schemas={
|
|
161
162
|
"/openshift/namespace-1.yml",
|
|
@@ -239,4 +240,4 @@ class ChangeLogIntegration(QontractReconcileIntegration[ChangeLogIntegrationPara
|
|
|
239
240
|
change_log.items, key=lambda i: i.merged_at, reverse=True
|
|
240
241
|
)
|
|
241
242
|
if not dry_run:
|
|
242
|
-
integration_state.add(BUNDLE_DIFFS_OBJ, change_log.
|
|
243
|
+
integration_state.add(BUNDLE_DIFFS_OBJ, change_log.model_dump(), force=True)
|
|
@@ -140,7 +140,7 @@ def write_coverage_report_to_mr(
|
|
|
140
140
|
approver_reachability = set()
|
|
141
141
|
for d in change_decisions:
|
|
142
142
|
approvers = [
|
|
143
|
-
f"{cr.context} - {' '.join([f'@{a.org_username}' if a.tag_on_merge_requests else a.org_username for a in cr.approvers])}"
|
|
143
|
+
f"{cr.context} - {' '.join([f'@{a.org_username}' if (a.tag_on_merge_requests or len(cr.approvers) == 1) else a.org_username for a in cr.approvers])}"
|
|
144
144
|
for cr in d.change_responsibles
|
|
145
145
|
]
|
|
146
146
|
if d.coverable_by_fragment_decisions:
|
reconcile/change_owners/diff.py
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import copy
|
|
2
|
-
import json
|
|
3
2
|
from dataclasses import dataclass
|
|
4
3
|
from enum import Enum
|
|
5
4
|
from functools import reduce
|
|
@@ -11,6 +10,7 @@ from deepdiff.helper import CannotCompare
|
|
|
11
10
|
from deepdiff.model import DiffLevel
|
|
12
11
|
from deepdiff.path import parse_path
|
|
13
12
|
|
|
13
|
+
from reconcile.utils.json import json_dumps
|
|
14
14
|
from reconcile.utils.jsonpath import parse_jsonpath
|
|
15
15
|
|
|
16
16
|
|
|
@@ -75,7 +75,7 @@ class Diff:
|
|
|
75
75
|
def _value_repr(self, value: Any | None) -> str | None:
|
|
76
76
|
if value:
|
|
77
77
|
if isinstance(value, dict | list):
|
|
78
|
-
return
|
|
78
|
+
return json_dumps(value, indent=2)
|
|
79
79
|
return str(value)
|
|
80
80
|
return value
|
|
81
81
|
|
|
@@ -251,8 +251,6 @@ def deepdiff_path_to_jsonpath(deep_diff_path: str) -> jsonpath_ng.JSONPath:
|
|
|
251
251
|
case int():
|
|
252
252
|
return jsonpath_ng.Index(element)
|
|
253
253
|
case str():
|
|
254
|
-
if "." in element:
|
|
255
|
-
return jsonpath_ng.Fields(f"'{element}'")
|
|
256
254
|
return jsonpath_ng.Fields(element)
|
|
257
255
|
|
|
258
256
|
path_parts = [build_jsonpath_part(p) for p in parse_path(deep_diff_path)]
|
reconcile/checkpoint.py
CHANGED
|
@@ -26,6 +26,7 @@ from jira import Issue
|
|
|
26
26
|
|
|
27
27
|
from reconcile.utils.constants import PROJ_ROOT
|
|
28
28
|
from reconcile.utils.jira_client import JiraClient
|
|
29
|
+
from reconcile.utils.secret_reader import SecretReaderBase
|
|
29
30
|
|
|
30
31
|
DEFAULT_CHECKPOINT_LABELS = ("sre-checkpoint",)
|
|
31
32
|
|
|
@@ -61,7 +62,7 @@ def url_makes_sense(url: str) -> bool:
|
|
|
61
62
|
return rs.status_code < HTTPStatus.NOT_FOUND
|
|
62
63
|
|
|
63
64
|
|
|
64
|
-
def valid_owners(owners: Iterable[Mapping[str, str]]) -> bool:
|
|
65
|
+
def valid_owners(owners: Iterable[Mapping[str, str | None]]) -> bool:
|
|
65
66
|
"""Confirm whether all the owners have a name and a valid email address."""
|
|
66
67
|
return all(
|
|
67
68
|
o["name"]
|
|
@@ -118,8 +119,8 @@ def file_ticket(
|
|
|
118
119
|
def report_invalid_metadata(
|
|
119
120
|
app: Mapping[str, Any],
|
|
120
121
|
path: str,
|
|
121
|
-
board: Mapping[str,
|
|
122
|
-
|
|
122
|
+
board: Mapping[str, Any],
|
|
123
|
+
secret_reader: SecretReaderBase,
|
|
123
124
|
parent: str,
|
|
124
125
|
dry_run: bool = False,
|
|
125
126
|
) -> None:
|
|
@@ -150,7 +151,14 @@ def report_invalid_metadata(
|
|
|
150
151
|
path=path,
|
|
151
152
|
)
|
|
152
153
|
else:
|
|
153
|
-
jira = JiraClient(
|
|
154
|
+
jira = JiraClient.create(
|
|
155
|
+
project_name=board["name"],
|
|
156
|
+
token=secret_reader.read_secret(board["server"]["token"]),
|
|
157
|
+
email=secret_reader.read_secret(board["server"]["email"])
|
|
158
|
+
if board["server"]["email"]
|
|
159
|
+
else None,
|
|
160
|
+
server_url=board["server"]["server_url"],
|
|
161
|
+
)
|
|
154
162
|
do_cut = partial(
|
|
155
163
|
file_ticket, # type: ignore
|
|
156
164
|
jira=jira,
|