qontract-reconcile 0.10.2.dev361__py3-none-any.whl → 0.10.2.dev430__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.2.dev361.dist-info → qontract_reconcile-0.10.2.dev430.dist-info}/METADATA +13 -12
- {qontract_reconcile-0.10.2.dev361.dist-info → qontract_reconcile-0.10.2.dev430.dist-info}/RECORD +351 -345
- 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_iam_keys.py +1 -0
- reconcile/aws_saml_idp/integration.py +12 -4
- reconcile/aws_saml_roles/integration.py +30 -23
- reconcile/aws_version_sync/integration.py +6 -12
- 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 +0 -2
- reconcile/checkpoint.py +11 -3
- reconcile/cli.py +93 -10
- reconcile/dashdotdb_dora.py +5 -12
- reconcile/dashdotdb_slo.py +1 -1
- reconcile/database_access_manager.py +123 -117
- 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 +8 -8
- reconcile/external_resources/factories.py +4 -6
- reconcile/external_resources/integration.py +1 -1
- reconcile/external_resources/manager.py +8 -6
- reconcile/external_resources/meta.py +0 -1
- reconcile/external_resources/metrics.py +1 -1
- reconcile/external_resources/model.py +19 -15
- reconcile/external_resources/reconciler.py +7 -4
- reconcile/external_resources/secrets_sync.py +4 -7
- reconcile/external_resources/state.py +26 -16
- reconcile/fleet_labeler/integration.py +1 -1
- reconcile/gabi_authorized_users.py +5 -2
- 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_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 +5 -5
- reconcile/gql_definitions/acs/acs_policies.py +5 -5
- reconcile/gql_definitions/acs/acs_rbac.py +5 -5
- reconcile/gql_definitions/advanced_upgrade_service/aus_clusters.py +5 -5
- reconcile/gql_definitions/advanced_upgrade_service/aus_organization.py +5 -5
- reconcile/gql_definitions/app_interface_metrics_exporter/onboarding_status.py +5 -5
- 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 +46 -7
- reconcile/gql_definitions/aws_account_manager/aws_accounts.py +5 -5
- reconcile/gql_definitions/aws_ami_cleanup/aws_accounts.py +15 -5
- reconcile/gql_definitions/aws_cloudwatch_log_retention/aws_accounts.py +27 -66
- reconcile/gql_definitions/aws_saml_idp/aws_accounts.py +15 -5
- reconcile/gql_definitions/aws_saml_roles/aws_accounts.py +15 -5
- reconcile/gql_definitions/aws_saml_roles/roles.py +5 -5
- reconcile/gql_definitions/aws_version_sync/clusters.py +5 -5
- 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 +5 -5
- reconcile/gql_definitions/cluster_auth_rhidp/clusters.py +5 -5
- reconcile/gql_definitions/common/alerting_services_settings.py +5 -5
- 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 +5 -5
- reconcile/gql_definitions/common/app_interface_state_settings.py +5 -5
- 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 +15 -5
- reconcile/gql_definitions/common/aws_vpcs.py +5 -5
- reconcile/gql_definitions/common/clusters.py +5 -5
- reconcile/gql_definitions/common/clusters_minimal.py +5 -5
- reconcile/gql_definitions/common/clusters_with_dms.py +5 -5
- reconcile/gql_definitions/common/clusters_with_peering.py +5 -5
- reconcile/gql_definitions/common/github_orgs.py +5 -5
- reconcile/gql_definitions/common/jira_settings.py +5 -5
- reconcile/gql_definitions/common/jiralert_settings.py +5 -5
- reconcile/gql_definitions/common/ldap_settings.py +5 -5
- reconcile/gql_definitions/common/namespaces.py +5 -5
- reconcile/gql_definitions/common/namespaces_minimal.py +7 -5
- reconcile/gql_definitions/common/ocm_env_telemeter.py +5 -5
- reconcile/gql_definitions/common/ocm_environments.py +5 -5
- reconcile/gql_definitions/common/pagerduty_instances.py +5 -5
- reconcile/gql_definitions/common/pgp_reencryption_settings.py +5 -5
- reconcile/gql_definitions/common/pipeline_providers.py +5 -5
- 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 +5 -5
- reconcile/gql_definitions/common/saas_target_namespaces.py +5 -5
- 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 +5 -5
- reconcile/gql_definitions/common/state_aws_account.py +5 -5
- 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 +5 -5
- reconcile/gql_definitions/dashdotdb_slo/slo_documents_query.py +5 -5
- reconcile/gql_definitions/dynatrace_token_provider/dynatrace_bootstrap_tokens.py +5 -5
- 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 +5 -5
- reconcile/gql_definitions/email_sender/users.py +5 -5
- reconcile/gql_definitions/endpoints_discovery/apps.py +5 -5
- reconcile/gql_definitions/external_resources/aws_accounts.py +5 -5
- reconcile/gql_definitions/external_resources/external_resources_modules.py +5 -5
- reconcile/gql_definitions/external_resources/external_resources_namespaces.py +33 -6
- reconcile/gql_definitions/external_resources/external_resources_settings.py +5 -5
- reconcile/gql_definitions/external_resources/fragments/external_resources_module_overrides.py +5 -5
- reconcile/gql_definitions/fleet_labeler/fleet_labels.py +5 -5
- 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_organization.py +33 -0
- reconcile/gql_definitions/fragments/aws_vpc.py +5 -5
- reconcile/gql_definitions/fragments/aws_vpc_request.py +7 -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 +5 -5
- reconcile/gql_definitions/gcp/gcp_projects.py +5 -5
- reconcile/gql_definitions/gitlab_members/gitlab_instances.py +5 -5
- reconcile/gql_definitions/gitlab_members/permissions.py +5 -5
- reconcile/gql_definitions/glitchtip/glitchtip_instance.py +5 -5
- reconcile/gql_definitions/glitchtip/glitchtip_project.py +5 -5
- reconcile/gql_definitions/glitchtip_project_alerts/glitchtip_project.py +5 -5
- reconcile/gql_definitions/integrations/integrations.py +5 -5
- reconcile/gql_definitions/introspection.json +724 -129
- reconcile/gql_definitions/jenkins_configs/jenkins_configs.py +5 -5
- reconcile/gql_definitions/jenkins_configs/jenkins_instances.py +5 -5
- reconcile/gql_definitions/jira/jira_servers.py +5 -5
- reconcile/gql_definitions/jira_permissions_validator/jira_boards_for_permissions_validator.py +9 -5
- reconcile/gql_definitions/jumphosts/jumphosts.py +5 -5
- reconcile/gql_definitions/ldap_groups/roles.py +5 -5
- reconcile/gql_definitions/ldap_groups/settings.py +5 -5
- reconcile/gql_definitions/maintenance/maintenances.py +5 -5
- reconcile/gql_definitions/membershipsources/roles.py +5 -5
- reconcile/gql_definitions/ocm_labels/clusters.py +5 -5
- reconcile/gql_definitions/ocm_labels/organizations.py +5 -5
- reconcile/gql_definitions/openshift_cluster_bots/clusters.py +5 -5
- reconcile/gql_definitions/openshift_groups/managed_groups.py +5 -5
- reconcile/gql_definitions/openshift_groups/managed_roles.py +5 -5
- reconcile/gql_definitions/openshift_serviceaccount_tokens/tokens.py +5 -5
- reconcile/gql_definitions/quay_membership/quay_membership.py +5 -5
- reconcile/gql_definitions/rhcs/certs.py +25 -79
- reconcile/gql_definitions/rhcs/openshift_resource_rhcs_cert.py +43 -0
- reconcile/gql_definitions/rhidp/organizations.py +5 -5
- reconcile/gql_definitions/service_dependencies/jenkins_instance_fragment.py +5 -5
- reconcile/gql_definitions/service_dependencies/service_dependencies.py +5 -5
- reconcile/gql_definitions/sharding/aws_accounts.py +5 -5
- reconcile/gql_definitions/sharding/ocm_organization.py +5 -5
- reconcile/gql_definitions/skupper_network/site_controller_template.py +5 -5
- reconcile/gql_definitions/skupper_network/skupper_networks.py +5 -5
- reconcile/gql_definitions/slack_usergroups/clusters.py +5 -5
- reconcile/gql_definitions/slack_usergroups/permissions.py +5 -5
- 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 +5 -5
- reconcile/gql_definitions/statuspage/statuspages.py +5 -5
- 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 +5 -5
- reconcile/gql_definitions/terraform_cloudflare_dns/terraform_cloudflare_zones.py +5 -5
- reconcile/gql_definitions/terraform_cloudflare_resources/terraform_cloudflare_accounts.py +5 -5
- reconcile/gql_definitions/terraform_cloudflare_resources/terraform_cloudflare_resources.py +5 -5
- reconcile/gql_definitions/terraform_cloudflare_users/app_interface_setting_cloudflare_and_vault.py +5 -5
- reconcile/gql_definitions/terraform_cloudflare_users/terraform_cloudflare_roles.py +5 -5
- reconcile/gql_definitions/terraform_init/aws_accounts.py +19 -5
- reconcile/gql_definitions/terraform_repo/terraform_repo.py +5 -5
- reconcile/gql_definitions/terraform_resources/database_access_manager.py +5 -5
- reconcile/gql_definitions/terraform_resources/terraform_resources_namespaces.py +30 -6
- reconcile/gql_definitions/terraform_tgw_attachments/aws_accounts.py +15 -5
- reconcile/gql_definitions/unleash_feature_toggles/feature_toggles.py +5 -5
- reconcile/gql_definitions/vault_instances/vault_instances.py +5 -5
- reconcile/gql_definitions/vault_policies/vault_policies.py +5 -5
- reconcile/gql_definitions/vpc_peerings_validator/vpc_peerings_validator.py +5 -5
- reconcile/gql_definitions/vpc_peerings_validator/vpc_peerings_validator_peered_cluster_fragment.py +5 -5
- reconcile/integrations_manager.py +3 -3
- reconcile/jenkins_worker_fleets.py +10 -8
- reconcile/jira_permissions_validator.py +237 -122
- reconcile/ldap_groups/integration.py +1 -1
- reconcile/ocm/types.py +35 -57
- 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 +113 -4
- reconcile/openshift_cluster_bots.py +1 -1
- reconcile/openshift_namespace_labels.py +1 -1
- reconcile/openshift_namespaces.py +97 -101
- reconcile/openshift_resources_base.py +6 -2
- reconcile/openshift_rhcs_certs.py +74 -37
- reconcile/openshift_rolebindings.py +7 -11
- reconcile/openshift_saas_deploy.py +4 -5
- reconcile/openshift_saas_deploy_change_tester.py +9 -7
- reconcile/openshift_saas_deploy_trigger_cleaner.py +3 -5
- reconcile/openshift_serviceaccount_tokens.py +2 -2
- reconcile/openshift_upgrade_watcher.py +4 -4
- reconcile/oum/labelset.py +5 -3
- reconcile/oum/models.py +1 -4
- reconcile/prometheus_rules_tester/integration.py +3 -3
- reconcile/quay_mirror.py +1 -1
- reconcile/queries.py +131 -0
- reconcile/rhidp/common.py +3 -5
- reconcile/rhidp/sso_client/base.py +16 -5
- reconcile/saas_auto_promotions_manager/merge_request_manager/renderer.py +1 -1
- reconcile/saas_auto_promotions_manager/subscriber.py +4 -3
- reconcile/skupper_network/integration.py +2 -2
- reconcile/slack_usergroups.py +35 -14
- reconcile/sql_query.py +1 -0
- 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/templating/lib/rendering.py +3 -3
- reconcile/templating/renderer.py +2 -2
- reconcile/terraform_aws_route53.py +7 -1
- reconcile/terraform_cloudflare_dns.py +3 -3
- reconcile/terraform_cloudflare_resources.py +5 -5
- reconcile/terraform_cloudflare_users.py +3 -2
- reconcile/terraform_init/integration.py +187 -23
- reconcile/terraform_repo.py +16 -12
- reconcile/terraform_resources.py +6 -6
- reconcile/terraform_tgw_attachments.py +27 -19
- reconcile/terraform_users.py +7 -0
- reconcile/terraform_vpc_peerings.py +14 -3
- reconcile/terraform_vpc_resources/integration.py +10 -1
- 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 +11 -11
- 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/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/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/gql.py +4 -7
- reconcile/utils/helpers.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/jinja2/utils.py +6 -101
- reconcile/utils/jira_client.py +82 -63
- reconcile/utils/jjb_client.py +7 -10
- reconcile/utils/jobcontroller/controller.py +2 -2
- reconcile/utils/jobcontroller/models.py +17 -1
- reconcile/utils/json.py +43 -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/app_interface_reporter.py +2 -2
- reconcile/utils/mr/notificator.py +3 -3
- reconcile/utils/mr/update_access_report_base.py +3 -4
- reconcile/utils/mr/user_maintenance.py +3 -2
- reconcile/utils/oc.py +246 -201
- reconcile/utils/oc_filters.py +3 -3
- reconcile/utils/ocm/addons.py +0 -1
- reconcile/utils/ocm/base.py +17 -20
- 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/products.py +8 -8
- 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/openshift_resource.py +8 -3
- reconcile/utils/pagerduty_api.py +10 -7
- reconcile/utils/promotion_state.py +6 -11
- reconcile/utils/raw_github_api.py +1 -1
- reconcile/utils/rhcsv2_certs.py +86 -23
- reconcile/utils/rosa/session.py +16 -0
- reconcile/utils/runtime/integration.py +2 -3
- reconcile/utils/runtime/runner.py +2 -2
- reconcile/utils/saasherder/interfaces.py +13 -20
- reconcile/utils/saasherder/models.py +23 -20
- reconcile/utils/saasherder/saasherder.py +50 -27
- reconcile/utils/slack_api.py +2 -2
- reconcile/utils/sloth.py +171 -2
- reconcile/utils/structs.py +1 -1
- reconcile/utils/terraform_client.py +5 -4
- reconcile/utils/terrascript_aws_client.py +134 -74
- reconcile/utils/unleash/server.py +2 -8
- reconcile/utils/vault.py +5 -12
- reconcile/utils/vcs.py +8 -8
- reconcile/vault_replication.py +107 -42
- 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/qontract_cli.py +28 -17
- tools/template_validation.py +3 -1
- {qontract_reconcile-0.10.2.dev361.dist-info → qontract_reconcile-0.10.2.dev430.dist-info}/WHEEL +0 -0
- {qontract_reconcile-0.10.2.dev361.dist-info → qontract_reconcile-0.10.2.dev430.dist-info}/entry_points.txt +0 -0
|
@@ -11,7 +11,7 @@ from typing import (
|
|
|
11
11
|
TypedDict,
|
|
12
12
|
)
|
|
13
13
|
|
|
14
|
-
from pydantic import BaseModel
|
|
14
|
+
from pydantic import BaseModel, Field
|
|
15
15
|
from sretoolbox.container.image import Image
|
|
16
16
|
|
|
17
17
|
from reconcile import openshift_base, queries
|
|
@@ -61,17 +61,19 @@ def get_database_access_namespaces(
|
|
|
61
61
|
return query(query_func).namespaces_v1 or []
|
|
62
62
|
|
|
63
63
|
|
|
64
|
-
class DatabaseConnectionParameters(
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
64
|
+
class DatabaseConnectionParameters(
|
|
65
|
+
BaseModel, validate_by_name=True, validate_by_alias=True
|
|
66
|
+
):
|
|
67
|
+
host: str = Field(..., alias="db.host")
|
|
68
|
+
port: str = Field(..., alias="db.port")
|
|
69
|
+
user: str = Field(..., alias="db.user")
|
|
70
|
+
password: str = Field(..., alias="db.password")
|
|
71
|
+
database: str = Field(..., alias="db.name")
|
|
70
72
|
|
|
71
73
|
|
|
72
74
|
class PSQLScriptGenerator(BaseModel):
|
|
73
75
|
db_access: DatabaseAccessV1
|
|
74
|
-
current_db_access: DatabaseAccessV1 | None
|
|
76
|
+
current_db_access: DatabaseAccessV1 | None = None
|
|
75
77
|
connection_parameter: DatabaseConnectionParameters
|
|
76
78
|
admin_connection_parameter: DatabaseConnectionParameters
|
|
77
79
|
engine: str
|
|
@@ -225,7 +227,7 @@ def get_db_engine(resource: NamespaceTerraformResourceRDSV1) -> str:
|
|
|
225
227
|
|
|
226
228
|
class JobData(BaseModel):
|
|
227
229
|
engine: str
|
|
228
|
-
|
|
230
|
+
name: str
|
|
229
231
|
image: str
|
|
230
232
|
service_account_name: str
|
|
231
233
|
rds_admin_secret_name: str
|
|
@@ -234,7 +236,7 @@ class JobData(BaseModel):
|
|
|
234
236
|
|
|
235
237
|
|
|
236
238
|
def get_job_spec(job_data: JobData) -> OpenshiftResource:
|
|
237
|
-
job_name =
|
|
239
|
+
job_name = job_data.name
|
|
238
240
|
|
|
239
241
|
image_tag = Image(job_data.image).tag
|
|
240
242
|
image_pull_policy = "Always" if image_tag == "latest" else "IfNotPresent"
|
|
@@ -391,14 +393,6 @@ def get_service_account_spec(name: str) -> OpenshiftResource:
|
|
|
391
393
|
)
|
|
392
394
|
|
|
393
395
|
|
|
394
|
-
class DBAMResource(BaseModel):
|
|
395
|
-
resource: OpenshiftResource
|
|
396
|
-
clean_up: bool
|
|
397
|
-
|
|
398
|
-
class Config:
|
|
399
|
-
arbitrary_types_allowed = True
|
|
400
|
-
|
|
401
|
-
|
|
402
396
|
class JobStatusCondition(BaseModel):
|
|
403
397
|
type: str
|
|
404
398
|
|
|
@@ -424,18 +418,12 @@ def _populate_resources(
|
|
|
424
418
|
user_connection: DatabaseConnectionParameters,
|
|
425
419
|
admin_connection: DatabaseConnectionParameters,
|
|
426
420
|
current_db_access: DatabaseAccessV1 | None = None,
|
|
427
|
-
) -> list[
|
|
421
|
+
) -> list[OpenshiftResource]:
|
|
428
422
|
if user_connection.database == admin_connection.database:
|
|
429
423
|
raise ValueError(f"Can not use default database {admin_connection.database}")
|
|
430
424
|
|
|
431
|
-
managed_resources: list[DBAMResource] = []
|
|
432
425
|
# create service account
|
|
433
|
-
|
|
434
|
-
DBAMResource(
|
|
435
|
-
resource=get_service_account_spec(resource_prefix),
|
|
436
|
-
clean_up=True,
|
|
437
|
-
)
|
|
438
|
-
)
|
|
426
|
+
service_account_resource = get_service_account_spec(resource_prefix)
|
|
439
427
|
|
|
440
428
|
# create script secret
|
|
441
429
|
generator = PSQLScriptGenerator(
|
|
@@ -446,74 +434,107 @@ def _populate_resources(
|
|
|
446
434
|
engine=engine,
|
|
447
435
|
)
|
|
448
436
|
script_secret_name = f"{resource_prefix}-script"
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
clean_up=False,
|
|
461
|
-
),
|
|
462
|
-
])
|
|
437
|
+
secret_script_resource = generate_script_secret_spec(
|
|
438
|
+
script_secret_name,
|
|
439
|
+
generator.generate_script(),
|
|
440
|
+
)
|
|
441
|
+
|
|
442
|
+
# create user secret
|
|
443
|
+
user_secret_resource = generate_user_secret_spec(
|
|
444
|
+
resource_prefix,
|
|
445
|
+
user_connection,
|
|
446
|
+
)
|
|
447
|
+
|
|
463
448
|
# create pull secret
|
|
464
|
-
|
|
465
|
-
pull_secret_resources = orb.fetch_provider_vault_secret(
|
|
449
|
+
pull_secret_resource = orb.fetch_provider_vault_secret(
|
|
466
450
|
path=pull_secret["path"],
|
|
467
451
|
version=pull_secret["version"],
|
|
468
452
|
name=f"{resource_prefix}-pull-secret",
|
|
469
|
-
labels=labels,
|
|
453
|
+
labels=pull_secret["labels"] or {},
|
|
470
454
|
annotations=pull_secret["annotations"] or {},
|
|
471
455
|
type=pull_secret["type"],
|
|
472
456
|
integration=QONTRACT_INTEGRATION,
|
|
473
457
|
integration_version=QONTRACT_INTEGRATION_VERSION,
|
|
474
458
|
settings=settings,
|
|
475
459
|
)
|
|
476
|
-
managed_resources.extend([
|
|
477
|
-
DBAMResource(resource=pull_secret_resources, clean_up=True),
|
|
478
|
-
# create job
|
|
479
|
-
DBAMResource(
|
|
480
|
-
resource=get_job_spec(
|
|
481
|
-
JobData(
|
|
482
|
-
engine=engine,
|
|
483
|
-
name_suffix=db_access.name,
|
|
484
|
-
image=job_image,
|
|
485
|
-
service_account_name=resource_prefix,
|
|
486
|
-
rds_admin_secret_name=admin_secret_name,
|
|
487
|
-
script_secret_name=script_secret_name,
|
|
488
|
-
pull_secret=f"{resource_prefix}-pull-secret",
|
|
489
|
-
)
|
|
490
|
-
),
|
|
491
|
-
clean_up=True,
|
|
492
|
-
),
|
|
493
|
-
])
|
|
494
460
|
|
|
495
|
-
|
|
461
|
+
job_resource = get_job_spec(
|
|
462
|
+
JobData(
|
|
463
|
+
engine=engine,
|
|
464
|
+
name=resource_prefix,
|
|
465
|
+
image=job_image,
|
|
466
|
+
service_account_name=resource_prefix,
|
|
467
|
+
rds_admin_secret_name=admin_secret_name,
|
|
468
|
+
script_secret_name=script_secret_name,
|
|
469
|
+
pull_secret=f"{resource_prefix}-pull-secret",
|
|
470
|
+
)
|
|
471
|
+
)
|
|
472
|
+
|
|
473
|
+
return [
|
|
474
|
+
service_account_resource,
|
|
475
|
+
secret_script_resource,
|
|
476
|
+
user_secret_resource,
|
|
477
|
+
pull_secret_resource,
|
|
478
|
+
job_resource,
|
|
479
|
+
]
|
|
496
480
|
|
|
497
481
|
|
|
498
482
|
def _generate_password() -> str:
|
|
499
483
|
return "".join(choices(ascii_letters + digits, k=32))
|
|
500
484
|
|
|
501
485
|
|
|
502
|
-
class
|
|
486
|
+
class DBConnections(TypedDict):
|
|
503
487
|
user: DatabaseConnectionParameters
|
|
504
488
|
admin: DatabaseConnectionParameters
|
|
505
489
|
|
|
506
490
|
|
|
491
|
+
def _decode_secret_value(value: str) -> str:
|
|
492
|
+
return base64.b64decode(value).decode("utf-8")
|
|
493
|
+
|
|
494
|
+
|
|
495
|
+
def _build_user_connection(
|
|
496
|
+
db_access: DatabaseAccessV1,
|
|
497
|
+
admin_secret: dict[str, Any],
|
|
498
|
+
user_secret: dict[str, Any],
|
|
499
|
+
) -> DatabaseConnectionParameters:
|
|
500
|
+
"""
|
|
501
|
+
Build user connection parameters.
|
|
502
|
+
|
|
503
|
+
If user secret exists, use values from it as that's the one used to provision new database user.
|
|
504
|
+
Otherwise, generate a new password, this info will be saved as cluster secret.
|
|
505
|
+
After job completes, the secret will be saved to vault then deleted from the cluster.
|
|
506
|
+
|
|
507
|
+
Args:
|
|
508
|
+
db_access (DatabaseAccessV1): Database access definition from app-interface.
|
|
509
|
+
admin_secret (dict[str, Any]): Admin secret fetched from the cluster.
|
|
510
|
+
user_secret (dict[str, Any]): User secret fetched from the cluster, may be empty if not exists.
|
|
511
|
+
Returns:
|
|
512
|
+
DatabaseConnectionParameters: Connection parameters for the database user.
|
|
513
|
+
"""
|
|
514
|
+
if user_secret:
|
|
515
|
+
return DatabaseConnectionParameters(
|
|
516
|
+
host=_decode_secret_value(user_secret["data"]["db.host"]),
|
|
517
|
+
port=_decode_secret_value(user_secret["data"]["db.port"]),
|
|
518
|
+
user=_decode_secret_value(user_secret["data"]["db.user"]),
|
|
519
|
+
password=_decode_secret_value(user_secret["data"]["db.password"]),
|
|
520
|
+
database=_decode_secret_value(user_secret["data"]["db.name"]),
|
|
521
|
+
)
|
|
522
|
+
return DatabaseConnectionParameters(
|
|
523
|
+
host=_decode_secret_value(admin_secret["data"]["db.host"]),
|
|
524
|
+
port=_decode_secret_value(admin_secret["data"]["db.port"]),
|
|
525
|
+
user=db_access.username,
|
|
526
|
+
password=_generate_password(),
|
|
527
|
+
database=db_access.database,
|
|
528
|
+
)
|
|
529
|
+
|
|
530
|
+
|
|
507
531
|
def _create_database_connection_parameter(
|
|
508
532
|
db_access: DatabaseAccessV1,
|
|
509
533
|
namespace_name: str,
|
|
510
534
|
oc: OCClient,
|
|
511
535
|
admin_secret_name: str,
|
|
512
536
|
user_secret_name: str,
|
|
513
|
-
) ->
|
|
514
|
-
def _decode_secret_value(value: str) -> str:
|
|
515
|
-
return base64.b64decode(value).decode("utf-8")
|
|
516
|
-
|
|
537
|
+
) -> DBConnections:
|
|
517
538
|
user_secret = oc.get(
|
|
518
539
|
namespace_name,
|
|
519
540
|
"Secret",
|
|
@@ -526,26 +547,11 @@ def _create_database_connection_parameter(
|
|
|
526
547
|
admin_secret_name,
|
|
527
548
|
allow_not_found=False,
|
|
528
549
|
)
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
port = _decode_secret_value(user_secret["data"]["db.port"])
|
|
535
|
-
database = _decode_secret_value(user_secret["data"]["db.name"])
|
|
536
|
-
else:
|
|
537
|
-
host = _decode_secret_value(admin_secret["data"]["db.host"])
|
|
538
|
-
port = _decode_secret_value(admin_secret["data"]["db.port"])
|
|
539
|
-
user = db_access.username
|
|
540
|
-
password = _generate_password()
|
|
541
|
-
database = db_access.database
|
|
542
|
-
return _DBDonnections(
|
|
543
|
-
user=DatabaseConnectionParameters(
|
|
544
|
-
host=host,
|
|
545
|
-
port=port,
|
|
546
|
-
user=user,
|
|
547
|
-
password=password,
|
|
548
|
-
database=database,
|
|
550
|
+
return DBConnections(
|
|
551
|
+
user=_build_user_connection(
|
|
552
|
+
db_access=db_access,
|
|
553
|
+
admin_secret=admin_secret,
|
|
554
|
+
user_secret=user_secret,
|
|
549
555
|
),
|
|
550
556
|
admin=DatabaseConnectionParameters(
|
|
551
557
|
host=_decode_secret_value(admin_secret["data"]["db.host"]),
|
|
@@ -557,10 +563,10 @@ def _create_database_connection_parameter(
|
|
|
557
563
|
)
|
|
558
564
|
|
|
559
565
|
|
|
560
|
-
def
|
|
566
|
+
def _db_access_access_is_valid(db_access: DatabaseAccessV1) -> bool:
|
|
561
567
|
found_schema: set[str] = set()
|
|
562
568
|
|
|
563
|
-
for schema in
|
|
569
|
+
for schema in db_access.access or []:
|
|
564
570
|
if schema.target.dbschema in found_schema:
|
|
565
571
|
return False
|
|
566
572
|
found_schema.add(schema.target.dbschema)
|
|
@@ -575,6 +581,7 @@ class JobFailedError(Exception):
|
|
|
575
581
|
def _process_db_access(
|
|
576
582
|
dry_run: bool,
|
|
577
583
|
state: State,
|
|
584
|
+
state_key: str,
|
|
578
585
|
db_access: DatabaseAccessV1,
|
|
579
586
|
namespace: NamespaceV1,
|
|
580
587
|
admin_secret_name: str,
|
|
@@ -583,13 +590,13 @@ def _process_db_access(
|
|
|
583
590
|
vault_output_path: str,
|
|
584
591
|
vault_client: VaultClient,
|
|
585
592
|
) -> None:
|
|
586
|
-
if not
|
|
593
|
+
if not _db_access_access_is_valid(db_access):
|
|
587
594
|
raise ValueError("Duplicate schema in access list.")
|
|
588
595
|
|
|
589
596
|
current_db_access: DatabaseAccessV1 | None = None
|
|
590
|
-
if state.exists(
|
|
591
|
-
current_state = state.get(
|
|
592
|
-
if current_state == db_access.
|
|
597
|
+
if state.exists(state_key):
|
|
598
|
+
current_state = state.get(state_key)
|
|
599
|
+
if current_state == db_access.model_dump(by_alias=True):
|
|
593
600
|
return
|
|
594
601
|
current_db_access = DatabaseAccessV1(**current_state)
|
|
595
602
|
if current_db_access.database != db_access.database:
|
|
@@ -600,9 +607,9 @@ def _process_db_access(
|
|
|
600
607
|
cluster_name = namespace.cluster.name
|
|
601
608
|
namespace_name = namespace.name
|
|
602
609
|
|
|
603
|
-
resource_prefix = f"dbam-{
|
|
610
|
+
resource_prefix = f"dbam-{state_key.replace('/', '-')}"
|
|
604
611
|
with OC_Map(
|
|
605
|
-
clusters=[namespace.cluster.
|
|
612
|
+
clusters=[namespace.cluster.model_dump(by_alias=True)],
|
|
606
613
|
integration=QONTRACT_INTEGRATION,
|
|
607
614
|
settings=settings,
|
|
608
615
|
) as oc_map:
|
|
@@ -613,7 +620,7 @@ def _process_db_access(
|
|
|
613
620
|
namespace_name,
|
|
614
621
|
oc,
|
|
615
622
|
admin_secret_name,
|
|
616
|
-
resource_prefix,
|
|
623
|
+
user_secret_name=resource_prefix,
|
|
617
624
|
)
|
|
618
625
|
|
|
619
626
|
sql_query_settings = settings.get("sqlQuery")
|
|
@@ -642,7 +649,7 @@ def _process_db_access(
|
|
|
642
649
|
job = oc.get(
|
|
643
650
|
namespace_name,
|
|
644
651
|
"Job",
|
|
645
|
-
|
|
652
|
+
resource_prefix,
|
|
646
653
|
allow_not_found=True,
|
|
647
654
|
)
|
|
648
655
|
if not job:
|
|
@@ -652,8 +659,8 @@ def _process_db_access(
|
|
|
652
659
|
oc_map=oc_map,
|
|
653
660
|
cluster=cluster_name,
|
|
654
661
|
namespace=namespace_name,
|
|
655
|
-
resource_type=r.
|
|
656
|
-
resource=r
|
|
662
|
+
resource_type=r.kind,
|
|
663
|
+
resource=r,
|
|
657
664
|
wait_for_namespace=False,
|
|
658
665
|
)
|
|
659
666
|
return
|
|
@@ -665,34 +672,31 @@ def _process_db_access(
|
|
|
665
672
|
)
|
|
666
673
|
if job_status.is_complete():
|
|
667
674
|
if job_status.has_errors():
|
|
668
|
-
raise JobFailedError(
|
|
669
|
-
f"Job dbam-{db_access.name} failed, please check logs"
|
|
670
|
-
)
|
|
675
|
+
raise JobFailedError(f"Job {resource_prefix} failed, please check logs")
|
|
671
676
|
if not dry_run and not db_access.delete:
|
|
672
677
|
secret = {
|
|
673
|
-
"path": f"{vault_output_path}/{QONTRACT_INTEGRATION}/{
|
|
674
|
-
"data": connections["user"].
|
|
678
|
+
"path": f"{vault_output_path}/{QONTRACT_INTEGRATION}/{state_key}",
|
|
679
|
+
"data": connections["user"].model_dump(by_alias=True),
|
|
675
680
|
}
|
|
676
681
|
vault_client.write(secret, decode_base64=False)
|
|
677
682
|
logging.debug("job completed, cleaning up")
|
|
678
683
|
for r in managed_resources:
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
)
|
|
684
|
+
openshift_base.delete(
|
|
685
|
+
dry_run=dry_run,
|
|
686
|
+
oc_map=oc_map,
|
|
687
|
+
cluster=cluster_name,
|
|
688
|
+
namespace=namespace_name,
|
|
689
|
+
resource_type=r.kind,
|
|
690
|
+
name=r.name,
|
|
691
|
+
enable_deletion=True,
|
|
692
|
+
)
|
|
689
693
|
state.add(
|
|
690
|
-
|
|
691
|
-
value=db_access.
|
|
694
|
+
state_key,
|
|
695
|
+
value=db_access.model_dump(by_alias=True),
|
|
692
696
|
force=True,
|
|
693
697
|
)
|
|
694
698
|
else:
|
|
695
|
-
logging.info(f"Job
|
|
699
|
+
logging.info(f"Job {resource_prefix} appears to be still running")
|
|
696
700
|
|
|
697
701
|
|
|
698
702
|
class DBAMIntegrationParams(PydanticRunParams):
|
|
@@ -734,9 +738,11 @@ class DatabaseAccessManagerIntegration(QontractReconcileIntegration):
|
|
|
734
738
|
|
|
735
739
|
for db_access in resource.database_access or []:
|
|
736
740
|
try:
|
|
741
|
+
state_key = f"{external_resource.provisioner.name}/{resource.identifier}/{db_access.name}"
|
|
737
742
|
_process_db_access(
|
|
738
743
|
dry_run,
|
|
739
744
|
state,
|
|
745
|
+
state_key,
|
|
740
746
|
db_access,
|
|
741
747
|
namespace,
|
|
742
748
|
admin_secret_name,
|
|
@@ -82,7 +82,7 @@ class DynatraceTokenProviderIntegration(QontractReconcileIntegration[NoParams]):
|
|
|
82
82
|
return {
|
|
83
83
|
"version": QONTRACT_INTEGRATION_VERSION,
|
|
84
84
|
"specs": {
|
|
85
|
-
spec.name: spec.
|
|
85
|
+
spec.name: spec.model_dump()
|
|
86
86
|
for spec in get_dynatrace_token_provider_token_specs()
|
|
87
87
|
},
|
|
88
88
|
}
|
|
@@ -150,7 +150,10 @@ class EndpointsDiscoveryIntegration(
|
|
|
150
150
|
return []
|
|
151
151
|
|
|
152
152
|
routes = defaultdict(list)
|
|
153
|
-
for item in oc.get_items(
|
|
153
|
+
for item in oc.get_items(
|
|
154
|
+
kind="Route.route.openshift.io",
|
|
155
|
+
namespace=namespace.name,
|
|
156
|
+
):
|
|
154
157
|
tls = bool(item["spec"].get("tls"))
|
|
155
158
|
host = item["spec"]["host"]
|
|
156
159
|
# group all routes with the same hostname/tls
|
|
@@ -89,7 +89,7 @@ class Renderer:
|
|
|
89
89
|
|
|
90
90
|
def render_description(self, hash: str) -> str:
|
|
91
91
|
"""Render the description for a merge request."""
|
|
92
|
-
return DESC.safe_substitute(EPDInfo(hash=hash).
|
|
92
|
+
return DESC.safe_substitute(EPDInfo(hash=hash).model_dump())
|
|
93
93
|
|
|
94
94
|
def render_title(self) -> str:
|
|
95
95
|
"""Render the title for a merge request."""
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import hashlib
|
|
2
2
|
import logging
|
|
3
3
|
from collections.abc import Sequence
|
|
4
|
-
from typing import Any
|
|
4
|
+
from typing import Any
|
|
5
5
|
|
|
6
6
|
from gitlab.exceptions import GitlabGetError
|
|
7
7
|
from pydantic import BaseModel
|
|
@@ -64,20 +64,20 @@ class Endpoint(BaseModel):
|
|
|
64
64
|
|
|
65
65
|
@property
|
|
66
66
|
def hash(self) -> str:
|
|
67
|
-
return hashlib.sha256(json_dumps(self.
|
|
67
|
+
return hashlib.sha256(json_dumps(self.model_dump()).encode()).hexdigest()
|
|
68
68
|
|
|
69
69
|
|
|
70
|
-
EndpointsToAdd
|
|
71
|
-
EndpointsToChange
|
|
72
|
-
EndpointsToDelete
|
|
70
|
+
EndpointsToAdd = list[Endpoint]
|
|
71
|
+
EndpointsToChange = list[Endpoint]
|
|
72
|
+
EndpointsToDelete = list[Endpoint]
|
|
73
73
|
|
|
74
74
|
|
|
75
75
|
class App(BaseModel):
|
|
76
76
|
name: str
|
|
77
77
|
path: str
|
|
78
|
-
endpoints_to_add: EndpointsToAdd =
|
|
79
|
-
endpoints_to_change: EndpointsToChange =
|
|
80
|
-
endpoints_to_delete: EndpointsToDelete =
|
|
78
|
+
endpoints_to_add: EndpointsToAdd = []
|
|
79
|
+
endpoints_to_change: EndpointsToChange = []
|
|
80
|
+
endpoints_to_delete: EndpointsToDelete = []
|
|
81
81
|
|
|
82
82
|
@property
|
|
83
83
|
def hash(self) -> str:
|
|
@@ -2,8 +2,7 @@ from abc import (
|
|
|
2
2
|
ABC,
|
|
3
3
|
abstractmethod,
|
|
4
4
|
)
|
|
5
|
-
from
|
|
6
|
-
from typing import Generic, TypeVar
|
|
5
|
+
from typing import TypeVar
|
|
7
6
|
|
|
8
7
|
from reconcile.external_resources.aws import (
|
|
9
8
|
AWSDefaultResourceFactory,
|
|
@@ -34,7 +33,7 @@ from reconcile.utils.secret_reader import SecretReaderBase
|
|
|
34
33
|
T = TypeVar("T")
|
|
35
34
|
|
|
36
35
|
|
|
37
|
-
class ObjectFactory
|
|
36
|
+
class ObjectFactory[T]:
|
|
38
37
|
def __init__(
|
|
39
38
|
self, factories: dict[str, T], default_factory: T | None = None
|
|
40
39
|
) -> None:
|
|
@@ -116,7 +115,7 @@ class AWSExternalResourceFactory(ExternalResourceFactory):
|
|
|
116
115
|
secret_reader: SecretReaderBase,
|
|
117
116
|
provision_factories: ObjectFactory[ModuleProvisionDataFactory],
|
|
118
117
|
resource_factories: ObjectFactory[AWSResourceFactory],
|
|
119
|
-
default_tags:
|
|
118
|
+
default_tags: dict[str, str],
|
|
120
119
|
):
|
|
121
120
|
self.provision_factories = provision_factories
|
|
122
121
|
self.resource_factories = resource_factories
|
|
@@ -132,8 +131,7 @@ class AWSExternalResourceFactory(ExternalResourceFactory):
|
|
|
132
131
|
) -> ExternalResource:
|
|
133
132
|
f = self.resource_factories.get_factory(spec.provider)
|
|
134
133
|
data = f.resolve(spec, module_conf)
|
|
135
|
-
data["tags"] = spec.tags(integration=QONTRACT_INTEGRATION)
|
|
136
|
-
data["default_tags"] = [{"tags": self.default_tags}]
|
|
134
|
+
data["tags"] = self.default_tags | spec.tags(integration=QONTRACT_INTEGRATION)
|
|
137
135
|
|
|
138
136
|
region = data.get("region")
|
|
139
137
|
if region:
|
|
@@ -45,7 +45,7 @@ from reconcile.utils.secret_reader import SecretReaderBase, create_secret_reader
|
|
|
45
45
|
def fetch_current_state(
|
|
46
46
|
ri: ResourceInventory, oc: OCCli, cluster: str, namespace: str
|
|
47
47
|
) -> None:
|
|
48
|
-
for item in oc.get_items("Job", namespace=namespace):
|
|
48
|
+
for item in oc.get_items("Job.batch", namespace=namespace):
|
|
49
49
|
r = OpenshiftResource(item, QONTRACT_INTEGRATION, QONTRACT_INTEGRATION_VERSION)
|
|
50
50
|
ri.add_current(cluster, namespace, "Job", r.name, r)
|
|
51
51
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import logging
|
|
2
2
|
from collections import Counter
|
|
3
3
|
from collections.abc import Iterable
|
|
4
|
-
from
|
|
4
|
+
from typing import cast
|
|
5
5
|
|
|
6
6
|
from sretoolbox.utils import threaded
|
|
7
7
|
|
|
@@ -41,6 +41,7 @@ from reconcile.external_resources.state import (
|
|
|
41
41
|
from reconcile.gql_definitions.external_resources.external_resources_settings import (
|
|
42
42
|
ExternalResourcesSettingsV1,
|
|
43
43
|
)
|
|
44
|
+
from reconcile.utils.datetime_util import utc_now
|
|
44
45
|
from reconcile.utils.external_resource_spec import (
|
|
45
46
|
ExternalResourceSpec,
|
|
46
47
|
)
|
|
@@ -67,7 +68,7 @@ def setup_factories(
|
|
|
67
68
|
resource_factories=setup_aws_resource_factories(
|
|
68
69
|
er_inventory, secret_reader
|
|
69
70
|
),
|
|
70
|
-
default_tags=settings.default_tags,
|
|
71
|
+
default_tags=cast("dict[str, str]", settings.default_tags),
|
|
71
72
|
)
|
|
72
73
|
}
|
|
73
74
|
)
|
|
@@ -142,7 +143,7 @@ class ExternalResourcesManager:
|
|
|
142
143
|
def _resource_drift_detection_ttl_expired(
|
|
143
144
|
self, reconciliation: Reconciliation, state: ExternalResourceState
|
|
144
145
|
) -> bool:
|
|
145
|
-
return (
|
|
146
|
+
return (utc_now() - state.ts).total_seconds() > (
|
|
146
147
|
reconciliation.module_configuration.reconcile_drift_interval_minutes * 60
|
|
147
148
|
)
|
|
148
149
|
|
|
@@ -243,7 +244,7 @@ class ExternalResourcesManager:
|
|
|
243
244
|
reconciliation = Reconciliation(
|
|
244
245
|
key=key,
|
|
245
246
|
resource_hash=resource.hash(),
|
|
246
|
-
input=resource.
|
|
247
|
+
input=resource.export(),
|
|
247
248
|
action=Action.APPLY,
|
|
248
249
|
module_configuration=module_conf,
|
|
249
250
|
linked_resources=self._find_linked_resources(spec),
|
|
@@ -356,7 +357,7 @@ class ExternalResourcesManager:
|
|
|
356
357
|
def _set_resource_reconciliation_in_progress(
|
|
357
358
|
self, r: Reconciliation, state: ExternalResourceState
|
|
358
359
|
) -> None:
|
|
359
|
-
state.ts =
|
|
360
|
+
state.ts = utc_now()
|
|
360
361
|
if r.action == Action.APPLY:
|
|
361
362
|
state.resource_status = ResourceStatus.IN_PROGRESS
|
|
362
363
|
elif r.action == Action.DESTROY:
|
|
@@ -449,7 +450,8 @@ class ExternalResourcesManager:
|
|
|
449
450
|
r
|
|
450
451
|
for r in desired_r.union(deleted_r)
|
|
451
452
|
if self._reconciliation_needs_dry_run_run(
|
|
452
|
-
r,
|
|
453
|
+
r,
|
|
454
|
+
self.state_mgr.get_external_resource_state(key=r.key),
|
|
453
455
|
)
|
|
454
456
|
}
|
|
455
457
|
|
|
@@ -10,7 +10,6 @@ SECRET_ANN_PROVISIONER = SECRET_ANN_PREFIX + "/provisioner_name"
|
|
|
10
10
|
SECRET_ANN_PROVIDER = SECRET_ANN_PREFIX + "/provider"
|
|
11
11
|
SECRET_ANN_IDENTIFIER = SECRET_ANN_PREFIX + "/identifier"
|
|
12
12
|
SECRET_UPDATED_AT = SECRET_ANN_PREFIX + "/updated_at"
|
|
13
|
-
SECRET_UPDATED_AT_TIMEFORMAT = "%Y-%m-%dT%H:%M:%SZ"
|
|
14
13
|
|
|
15
14
|
FLAG_RESOURCE_MANAGED_BY_ERV2 = "managed_by_erv2"
|
|
16
15
|
FLAG_DELETE_RESOURCE = "delete"
|
|
@@ -13,7 +13,7 @@ from reconcile.utils.metrics import (
|
|
|
13
13
|
|
|
14
14
|
|
|
15
15
|
class ExternalResourcesBaseMetric(BaseModel):
|
|
16
|
-
integration = normalize_integration_name(QONTRACT_INTEGRATION)
|
|
16
|
+
integration: str = normalize_integration_name(QONTRACT_INTEGRATION)
|
|
17
17
|
app: str
|
|
18
18
|
environment: str
|
|
19
19
|
provision_provider: str
|