qontract-reconcile 0.10.2.dev394__py3-none-any.whl → 0.10.2.dev427__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.dev394.dist-info → qontract_reconcile-0.10.2.dev427.dist-info}/METADATA +5 -4
- {qontract_reconcile-0.10.2.dev394.dist-info → qontract_reconcile-0.10.2.dev427.dist-info}/RECORD +316 -315
- reconcile/acs_rbac.py +2 -2
- reconcile/aus/advanced_upgrade_service.py +18 -12
- reconcile/aus/base.py +117 -18
- 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 +6 -6
- reconcile/aws_account_manager/reconciler.py +3 -3
- reconcile/aws_ami_cleanup/integration.py +2 -5
- reconcile/aws_ami_share.py +69 -62
- reconcile/aws_saml_idp/integration.py +5 -3
- reconcile/aws_saml_roles/integration.py +23 -22
- 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/cli.py +62 -4
- reconcile/dashdotdb_dora.py +1 -1
- reconcile/dashdotdb_slo.py +1 -1
- reconcile/database_access_manager.py +8 -9
- 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 +1 -1
- reconcile/external_resources/integration.py +1 -1
- reconcile/external_resources/manager.py +3 -2
- reconcile/external_resources/metrics.py +1 -1
- reconcile/external_resources/model.py +13 -13
- reconcile/external_resources/reconciler.py +7 -4
- reconcile/external_resources/secrets_sync.py +2 -2
- reconcile/external_resources/state.py +22 -13
- reconcile/fleet_labeler/integration.py +1 -1
- reconcile/gcp_image_mirror.py +2 -2
- reconcile/github_org.py +1 -1
- reconcile/github_owners.py +4 -0
- reconcile/gitlab_members.py +6 -12
- 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 +5 -5
- reconcile/gql_definitions/aws_cloudwatch_log_retention/aws_accounts.py +5 -5
- reconcile/gql_definitions/aws_saml_idp/aws_accounts.py +5 -5
- reconcile/gql_definitions/aws_saml_roles/aws_accounts.py +5 -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 +5 -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 +5 -5
- 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 +5 -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 +5 -5
- reconcile/gql_definitions/fragments/aws_vpc.py +5 -5
- reconcile/gql_definitions/fragments/aws_vpc_request.py +5 -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 +231 -0
- 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 +5 -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 +24 -79
- reconcile/gql_definitions/rhcs/openshift_resource_rhcs_cert.py +42 -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 +5 -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 +5 -5
- reconcile/gql_definitions/terraform_tgw_attachments/aws_accounts.py +5 -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 +9 -8
- reconcile/jira_permissions_validator.py +2 -2
- 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 +27 -29
- reconcile/openshift_rolebindings.py +7 -11
- reconcile/openshift_saas_deploy.py +4 -5
- reconcile/openshift_saas_deploy_change_tester.py +9 -7
- reconcile/openshift_serviceaccount_tokens.py +2 -2
- reconcile/openshift_upgrade_watcher.py +1 -1
- 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 +6 -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/skupper_network/integration.py +2 -2
- reconcile/slack_usergroups.py +31 -11
- reconcile/status_board.py +6 -6
- reconcile/statuspage/atlassian.py +7 -7
- reconcile/statuspage/page.py +4 -9
- reconcile/templating/lib/rendering.py +3 -3
- reconcile/templating/renderer.py +2 -2
- 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 +2 -2
- reconcile/terraform_repo.py +16 -12
- reconcile/terraform_resources.py +6 -6
- reconcile/terraform_tgw_attachments.py +20 -18
- reconcile/terraform_vpc_resources/integration.py +3 -1
- 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/organization.py +4 -2
- reconcile/utils/binary.py +7 -12
- reconcile/utils/deadmanssnitch_api.py +1 -1
- reconcile/utils/early_exit_cache.py +8 -10
- 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/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 +2 -5
- 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 +1 -1
- reconcile/utils/merge_request_manager/parser.py +4 -4
- reconcile/utils/metrics.py +5 -5
- reconcile/utils/models.py +304 -82
- reconcile/utils/mr/notificator.py +1 -1
- reconcile/utils/mr/user_maintenance.py +3 -2
- reconcile/utils/oc.py +246 -201
- 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/service_log.py +1 -1
- reconcile/utils/ocm/sre_capability_labels.py +20 -13
- reconcile/utils/openshift_resource.py +5 -0
- reconcile/utils/pagerduty_api.py +5 -2
- reconcile/utils/promotion_state.py +6 -11
- reconcile/utils/raw_github_api.py +1 -1
- reconcile/utils/rhcsv2_certs.py +1 -4
- reconcile/utils/rosa/session.py +16 -0
- reconcile/utils/runtime/integration.py +1 -1
- reconcile/utils/saasherder/interfaces.py +13 -20
- reconcile/utils/saasherder/models.py +23 -20
- reconcile/utils/saasherder/saasherder.py +46 -24
- reconcile/utils/slack_api.py +2 -2
- reconcile/utils/structs.py +1 -1
- reconcile/utils/terraform_client.py +1 -1
- reconcile/utils/terrascript_aws_client.py +47 -43
- reconcile/utils/unleash/server.py +2 -8
- reconcile/utils/vault.py +5 -12
- reconcile/utils/vcs.py +8 -8
- reconcile/vault_replication.py +1 -1
- 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 +6 -5
- tools/template_validation.py +3 -1
- {qontract_reconcile-0.10.2.dev394.dist-info → qontract_reconcile-0.10.2.dev427.dist-info}/WHEEL +0 -0
- {qontract_reconcile-0.10.2.dev394.dist-info → qontract_reconcile-0.10.2.dev427.dist-info}/entry_points.txt +0 -0
|
@@ -7,7 +7,7 @@ from collections.abc import (
|
|
|
7
7
|
from typing import Any
|
|
8
8
|
|
|
9
9
|
import yaml
|
|
10
|
-
from kubernetes.client import (
|
|
10
|
+
from kubernetes.client import (
|
|
11
11
|
ApiClient,
|
|
12
12
|
V1ConfigMap,
|
|
13
13
|
V1ObjectMeta,
|
|
@@ -20,6 +20,7 @@ from reconcile.gql_definitions.automated_actions.instance import (
|
|
|
20
20
|
AutomatedActionExternalResourceFlushElastiCacheV1,
|
|
21
21
|
AutomatedActionExternalResourceRdsRebootV1,
|
|
22
22
|
AutomatedActionExternalResourceRdsSnapshotV1,
|
|
23
|
+
AutomatedActionOpenshiftTriggerCronjobV1,
|
|
23
24
|
AutomatedActionOpenshiftWorkloadDeleteV1,
|
|
24
25
|
AutomatedActionOpenshiftWorkloadRestartArgumentV1,
|
|
25
26
|
AutomatedActionOpenshiftWorkloadRestartV1,
|
|
@@ -82,7 +83,7 @@ class AutomatedActionsConfigIntegration(
|
|
|
82
83
|
query_func = gql.get_api().query
|
|
83
84
|
return {
|
|
84
85
|
"automated_actions_instances": [
|
|
85
|
-
c.
|
|
86
|
+
c.model_dump() for c in self.get_automated_actions_instances(query_func)
|
|
86
87
|
]
|
|
87
88
|
}
|
|
88
89
|
|
|
@@ -167,7 +168,7 @@ class AutomatedActionsConfigIntegration(
|
|
|
167
168
|
case AutomatedActionActionListV1():
|
|
168
169
|
# no special handling needed, just dump the values
|
|
169
170
|
parameters.extend(
|
|
170
|
-
arg.
|
|
171
|
+
arg.model_dump(exclude_none=True, exclude_defaults=True)
|
|
171
172
|
for arg in action.action_list_arguments or []
|
|
172
173
|
)
|
|
173
174
|
case AutomatedActionExternalResourceFlushElastiCacheV1():
|
|
@@ -205,6 +206,17 @@ class AutomatedActionsConfigIntegration(
|
|
|
205
206
|
"account": f"^{rds_snapshot_er.provisioner.name}$",
|
|
206
207
|
"identifier": rds_snapshot_arg.identifier,
|
|
207
208
|
})
|
|
209
|
+
case AutomatedActionOpenshiftTriggerCronjobV1():
|
|
210
|
+
parameters.extend(
|
|
211
|
+
{
|
|
212
|
+
# all parameter values are regexes in the OPA policy
|
|
213
|
+
# therefore, cluster and namespace must be fixed to the current strings
|
|
214
|
+
"cluster": f"^{arg.namespace.cluster.name}$",
|
|
215
|
+
"namespace": f"^{arg.namespace.name}$",
|
|
216
|
+
"cronjob": arg.cronjob,
|
|
217
|
+
}
|
|
218
|
+
for arg in action.openshift_trigger_cronjob_arguments
|
|
219
|
+
)
|
|
208
220
|
case AutomatedActionOpenshiftWorkloadDeleteV1():
|
|
209
221
|
parameters.extend(
|
|
210
222
|
{
|
|
@@ -257,7 +269,7 @@ class AutomatedActionsConfigIntegration(
|
|
|
257
269
|
{
|
|
258
270
|
"users": {user.username: sorted(user.roles) for user in users},
|
|
259
271
|
"roles": {
|
|
260
|
-
role: [policy.
|
|
272
|
+
role: [policy.model_dump() for policy in policies]
|
|
261
273
|
for role, policies in roles.items()
|
|
262
274
|
},
|
|
263
275
|
},
|
|
@@ -42,14 +42,14 @@ QONTRACT_INTEGRATION_VERSION = make_semver(1, 0, 0)
|
|
|
42
42
|
|
|
43
43
|
|
|
44
44
|
class AwsAccountMgmtIntegrationParams(PydanticRunParams):
|
|
45
|
-
account_name: str | None
|
|
45
|
+
account_name: str | None = None
|
|
46
46
|
flavor: str
|
|
47
47
|
organization_account_role: str = "OrganizationAccountAccessRole"
|
|
48
48
|
default_tags: dict[str, str] = {}
|
|
49
49
|
initial_user_name: str = "terraform"
|
|
50
50
|
initial_user_policy_arn: str = "arn:aws:iam::aws:policy/AdministratorAccess"
|
|
51
51
|
initial_user_secret_vault_path: str = (
|
|
52
|
-
"app-sre-v2/creds/terraform/{account_name}/config"
|
|
52
|
+
"app-sre-v2/creds/terraform/{account_name}/config" # noqa: RUF027
|
|
53
53
|
)
|
|
54
54
|
# To avoid the accidental deletion of the resource file, explicitly set the
|
|
55
55
|
# qontract.cli option in the integration extraArgs!
|
|
@@ -76,9 +76,9 @@ class AwsAccountMgmtIntegration(
|
|
|
76
76
|
query_func, account_name=self.params.account_name
|
|
77
77
|
)
|
|
78
78
|
return {
|
|
79
|
-
"payer_accounts": [account.
|
|
79
|
+
"payer_accounts": [account.model_dump() for account in payer_accounts],
|
|
80
80
|
"non_organization_accounts": [
|
|
81
|
-
account.
|
|
81
|
+
account.model_dump() for account in non_organization_accounts
|
|
82
82
|
],
|
|
83
83
|
}
|
|
84
84
|
|
|
@@ -98,7 +98,7 @@ class AwsAccountMgmtIntegration(
|
|
|
98
98
|
lstrip_blocks=True,
|
|
99
99
|
keep_trailing_newline=True,
|
|
100
100
|
).render({
|
|
101
|
-
"accountRequest": account_request.
|
|
101
|
+
"accountRequest": account_request.model_dump(by_alias=True),
|
|
102
102
|
"uid": uid,
|
|
103
103
|
"settings": settings,
|
|
104
104
|
"timestamp": int(utc_now().timestamp()),
|
|
@@ -187,7 +187,7 @@ class AwsAccountMgmtIntegration(
|
|
|
187
187
|
template=account_template,
|
|
188
188
|
account_request=account_request,
|
|
189
189
|
uid=uid,
|
|
190
|
-
settings=self.params.
|
|
190
|
+
settings=self.params.model_dump(),
|
|
191
191
|
),
|
|
192
192
|
account_request_file_path=f"data/{account_request.path.strip('/')}",
|
|
193
193
|
)
|
|
@@ -35,7 +35,7 @@ class Quota(Protocol):
|
|
|
35
35
|
quota_code: str
|
|
36
36
|
value: float
|
|
37
37
|
|
|
38
|
-
def
|
|
38
|
+
def model_dump(self) -> dict[str, Any]: ...
|
|
39
39
|
|
|
40
40
|
|
|
41
41
|
class Contact(Protocol):
|
|
@@ -44,7 +44,7 @@ class Contact(Protocol):
|
|
|
44
44
|
email: str
|
|
45
45
|
phone_number: str
|
|
46
46
|
|
|
47
|
-
def
|
|
47
|
+
def model_dump(self) -> dict[str, Any]: ...
|
|
48
48
|
|
|
49
49
|
|
|
50
50
|
class AWSReconciler:
|
|
@@ -167,7 +167,7 @@ class AWSReconciler:
|
|
|
167
167
|
self, aws_api: AWSApi, name: str, quotas: Iterable[Quota]
|
|
168
168
|
) -> list[str] | None:
|
|
169
169
|
"""Request service quota changes."""
|
|
170
|
-
quotas_dict = [q.
|
|
170
|
+
quotas_dict = [q.model_dump() for q in quotas]
|
|
171
171
|
with self.state.transaction(
|
|
172
172
|
state_key(name, TASK_REQUEST_SERVICE_QUOTA)
|
|
173
173
|
) as _state:
|
|
@@ -40,15 +40,12 @@ QONTRACT_INTEGRATION = "aws_ami_cleanup"
|
|
|
40
40
|
MANAGED_TAG = {"Key": "managed_by_integration", "Value": QONTRACT_INTEGRATION}
|
|
41
41
|
|
|
42
42
|
|
|
43
|
-
class AWSAmi(BaseModel):
|
|
43
|
+
class AWSAmi(BaseModel, frozen=True):
|
|
44
44
|
name: str
|
|
45
45
|
image_id: str
|
|
46
46
|
creation_date: datetime
|
|
47
47
|
snapshot_ids: list[str]
|
|
48
48
|
|
|
49
|
-
class Config:
|
|
50
|
-
frozen = True
|
|
51
|
-
|
|
52
49
|
|
|
53
50
|
def get_aws_amis_from_launch_templates(ec2_client: EC2Client) -> set[str]:
|
|
54
51
|
amis = set()
|
|
@@ -176,7 +173,7 @@ def run(dry_run: bool, thread_pool_size: int, defer: Callable | None = None) ->
|
|
|
176
173
|
# Build AWSApi object. We will use all those accounts listed in ami_accounts since
|
|
177
174
|
# we will also need to look for used AMIs.
|
|
178
175
|
accounts_dicted = [
|
|
179
|
-
account.
|
|
176
|
+
account.model_dump(by_alias=True)
|
|
180
177
|
for account in aws_accounts or []
|
|
181
178
|
if account.name in ami_accounts
|
|
182
179
|
]
|
reconcile/aws_ami_share.py
CHANGED
|
@@ -1,17 +1,19 @@
|
|
|
1
1
|
import logging
|
|
2
|
+
import re
|
|
2
3
|
from collections.abc import (
|
|
3
|
-
Callable,
|
|
4
4
|
Iterable,
|
|
5
5
|
Mapping,
|
|
6
6
|
)
|
|
7
7
|
from typing import Any
|
|
8
8
|
|
|
9
9
|
from reconcile import queries
|
|
10
|
+
from reconcile.typed_queries.aws_account_tags import get_aws_account_tags
|
|
11
|
+
from reconcile.typed_queries.external_resources import get_settings
|
|
10
12
|
from reconcile.utils.aws_api import AWSApi
|
|
11
|
-
from reconcile.utils.defer import defer
|
|
12
13
|
|
|
13
14
|
QONTRACT_INTEGRATION = "aws-ami-share"
|
|
14
|
-
|
|
15
|
+
|
|
16
|
+
MANAGED_TAG = {"managed_by_integration": QONTRACT_INTEGRATION}
|
|
15
17
|
|
|
16
18
|
|
|
17
19
|
def filter_accounts(accounts: Iterable[dict[str, Any]]) -> list[dict[str, Any]]:
|
|
@@ -37,65 +39,70 @@ def get_region(
|
|
|
37
39
|
return region
|
|
38
40
|
|
|
39
41
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
+
def share_ami(
|
|
43
|
+
dry_run: bool,
|
|
44
|
+
src_account: Mapping[str, Any],
|
|
45
|
+
share: Mapping[str, Any],
|
|
46
|
+
default_tags: dict[str, str],
|
|
47
|
+
aws_api: AWSApi,
|
|
48
|
+
) -> None:
|
|
49
|
+
dst_account = share["account"]
|
|
50
|
+
regex = re.compile(share["regex"])
|
|
51
|
+
region = get_region(share, src_account, dst_account)
|
|
52
|
+
src_amis = aws_api.get_amis_details(src_account, src_account, regex, region)
|
|
53
|
+
dst_amis = aws_api.get_amis_details(dst_account, src_account, regex, region)
|
|
54
|
+
|
|
55
|
+
for ami_id, src_ami_tags in src_amis.items():
|
|
56
|
+
dst_ami_tags = dst_amis.get(ami_id)
|
|
57
|
+
if dst_ami_tags is None:
|
|
58
|
+
logging.info([
|
|
59
|
+
"share_ami",
|
|
60
|
+
src_account["name"],
|
|
61
|
+
dst_account["name"],
|
|
62
|
+
ami_id,
|
|
63
|
+
])
|
|
64
|
+
if not dry_run:
|
|
65
|
+
aws_api.share_ami(src_account, dst_account["uid"], ami_id, region)
|
|
66
|
+
dst_account_tags = default_tags | get_aws_account_tags(
|
|
67
|
+
dst_account.get("organization", None)
|
|
68
|
+
)
|
|
69
|
+
desired_tags = src_ami_tags | dst_account_tags | MANAGED_TAG
|
|
70
|
+
current_tags = dst_ami_tags or {}
|
|
71
|
+
|
|
72
|
+
if desired_tags != current_tags:
|
|
73
|
+
logging.info([
|
|
74
|
+
"tag_shared_ami",
|
|
75
|
+
dst_account["name"],
|
|
76
|
+
ami_id,
|
|
77
|
+
desired_tags,
|
|
78
|
+
])
|
|
79
|
+
if not dry_run:
|
|
80
|
+
aws_api.create_tags(dst_account, ami_id, desired_tags)
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
def run(dry_run: bool) -> None:
|
|
42
84
|
accounts = queries.get_aws_accounts(sharing=True)
|
|
43
85
|
sharing_accounts = filter_accounts(accounts)
|
|
44
86
|
settings = queries.get_app_interface_settings()
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
"share_ami",
|
|
68
|
-
src_account["name"],
|
|
69
|
-
dst_account["name"],
|
|
70
|
-
src_ami_id,
|
|
71
|
-
])
|
|
72
|
-
if not dry_run:
|
|
73
|
-
aws_api.share_ami(
|
|
74
|
-
src_account, dst_account["uid"], src_ami_id, region
|
|
75
|
-
)
|
|
76
|
-
# we assume an unshared ami does not have tags
|
|
77
|
-
found_dst_amis = [{"image_id": src_ami_id, "tags": []}]
|
|
78
|
-
|
|
79
|
-
dst_ami = found_dst_amis[0]
|
|
80
|
-
dst_ami_id = dst_ami["image_id"]
|
|
81
|
-
dst_ami_tags = dst_ami["tags"]
|
|
82
|
-
if MANAGED_TAG not in dst_ami_tags:
|
|
83
|
-
logging.info([
|
|
84
|
-
"tag_shared_ami",
|
|
85
|
-
dst_account["name"],
|
|
86
|
-
dst_ami_id,
|
|
87
|
-
MANAGED_TAG,
|
|
88
|
-
])
|
|
89
|
-
if not dry_run:
|
|
90
|
-
aws_api.create_tag(dst_account, dst_ami_id, MANAGED_TAG)
|
|
91
|
-
src_ami_tags = src_ami["tags"]
|
|
92
|
-
for src_tag in src_ami_tags:
|
|
93
|
-
if src_tag not in dst_ami_tags:
|
|
94
|
-
logging.info([
|
|
95
|
-
"tag_shared_ami",
|
|
96
|
-
dst_account["name"],
|
|
97
|
-
dst_ami_id,
|
|
98
|
-
src_tag,
|
|
99
|
-
])
|
|
100
|
-
if not dry_run:
|
|
101
|
-
aws_api.create_tag(dst_account, dst_ami_id, src_tag)
|
|
87
|
+
try:
|
|
88
|
+
default_tags = get_settings().default_tags
|
|
89
|
+
except ValueError:
|
|
90
|
+
# no external resources settings found
|
|
91
|
+
default_tags = {}
|
|
92
|
+
|
|
93
|
+
with AWSApi(
|
|
94
|
+
1,
|
|
95
|
+
sharing_accounts,
|
|
96
|
+
settings=settings,
|
|
97
|
+
init_users=False,
|
|
98
|
+
) as aws_api:
|
|
99
|
+
for src_account in sharing_accounts:
|
|
100
|
+
for share in src_account.get("sharing") or []:
|
|
101
|
+
if share["provider"] == "ami":
|
|
102
|
+
share_ami(
|
|
103
|
+
dry_run=dry_run,
|
|
104
|
+
src_account=src_account,
|
|
105
|
+
share=share,
|
|
106
|
+
default_tags=default_tags,
|
|
107
|
+
aws_api=aws_api,
|
|
108
|
+
)
|
|
@@ -82,7 +82,7 @@ class AwsSamlIdpIntegration(QontractReconcileIntegration[AwsSamlIdpIntegrationPa
|
|
|
82
82
|
if not query_func:
|
|
83
83
|
query_func = gql.get_api().query
|
|
84
84
|
return {
|
|
85
|
-
"accounts": [c.
|
|
85
|
+
"accounts": [c.model_dump() for c in self.get_aws_accounts(query_func)],
|
|
86
86
|
}
|
|
87
87
|
|
|
88
88
|
def get_aws_accounts(
|
|
@@ -125,7 +125,9 @@ class AwsSamlIdpIntegration(QontractReconcileIntegration[AwsSamlIdpIntegrationPa
|
|
|
125
125
|
aws_accounts = self.get_aws_accounts(
|
|
126
126
|
gql_api.query, account_name=self.params.account_name
|
|
127
127
|
)
|
|
128
|
-
aws_accounts_dict = [
|
|
128
|
+
aws_accounts_dict = [
|
|
129
|
+
account.model_dump(by_alias=True) for account in aws_accounts
|
|
130
|
+
]
|
|
129
131
|
try:
|
|
130
132
|
default_tags = get_settings().default_tags
|
|
131
133
|
except ValueError:
|
|
@@ -143,7 +145,7 @@ class AwsSamlIdpIntegration(QontractReconcileIntegration[AwsSamlIdpIntegrationPa
|
|
|
143
145
|
for saml_idp_config in self.build_saml_idp_config(
|
|
144
146
|
aws_accounts,
|
|
145
147
|
saml_idp_name=self.params.saml_idp_name,
|
|
146
|
-
saml_metadata=self.get_saml_metadata(self.params.saml_metadata_url),
|
|
148
|
+
saml_metadata=self.get_saml_metadata(str(self.params.saml_metadata_url)),
|
|
147
149
|
):
|
|
148
150
|
ts.populate_saml_idp(
|
|
149
151
|
account_name=saml_idp_config.account_name,
|
|
@@ -6,10 +6,11 @@ from collections.abc import (
|
|
|
6
6
|
)
|
|
7
7
|
from typing import (
|
|
8
8
|
Any,
|
|
9
|
+
Self,
|
|
9
10
|
TypedDict,
|
|
10
11
|
)
|
|
11
12
|
|
|
12
|
-
from pydantic import BaseModel,
|
|
13
|
+
from pydantic import BaseModel, field_validator, model_validator
|
|
13
14
|
|
|
14
15
|
from reconcile.gql_definitions.aws_saml_roles.aws_accounts import (
|
|
15
16
|
AWSAccountV1,
|
|
@@ -59,7 +60,8 @@ class AwsSamlRolesIntegrationParams(PydanticRunParams):
|
|
|
59
60
|
extended_early_exit_cache_ttl_seconds: int = 3600
|
|
60
61
|
log_cached_log_output: bool = False
|
|
61
62
|
|
|
62
|
-
@
|
|
63
|
+
@field_validator("max_session_duration_hours")
|
|
64
|
+
@classmethod
|
|
63
65
|
def max_session_duration_range(cls, v: str | int) -> int:
|
|
64
66
|
if 1 <= int(v) <= 12:
|
|
65
67
|
return int(v)
|
|
@@ -70,7 +72,8 @@ class CustomPolicy(BaseModel):
|
|
|
70
72
|
name: str
|
|
71
73
|
policy: dict[str, Any]
|
|
72
74
|
|
|
73
|
-
@
|
|
75
|
+
@field_validator("name")
|
|
76
|
+
@classmethod
|
|
74
77
|
def name_size(cls, v: str) -> str:
|
|
75
78
|
"""Check the policy name size.
|
|
76
79
|
|
|
@@ -82,7 +85,8 @@ class CustomPolicy(BaseModel):
|
|
|
82
85
|
)
|
|
83
86
|
return v
|
|
84
87
|
|
|
85
|
-
@
|
|
88
|
+
@field_validator("policy")
|
|
89
|
+
@classmethod
|
|
86
90
|
def policy_size(cls, v: dict[str, Any]) -> dict[str, Any]:
|
|
87
91
|
"""Check the policy size.
|
|
88
92
|
|
|
@@ -105,7 +109,8 @@ class AwsRole(BaseModel):
|
|
|
105
109
|
custom_policies: list[CustomPolicy]
|
|
106
110
|
managed_policies: list[ManagedPolicy]
|
|
107
111
|
|
|
108
|
-
@
|
|
112
|
+
@field_validator("name")
|
|
113
|
+
@classmethod
|
|
109
114
|
def name_size(cls, v: str) -> str:
|
|
110
115
|
"""Check the role name size.
|
|
111
116
|
|
|
@@ -117,29 +122,23 @@ class AwsRole(BaseModel):
|
|
|
117
122
|
)
|
|
118
123
|
return v
|
|
119
124
|
|
|
120
|
-
@
|
|
121
|
-
def validate_policies(
|
|
125
|
+
@model_validator(mode="after")
|
|
126
|
+
def validate_policies(self) -> Self:
|
|
122
127
|
"""Check the policies.
|
|
123
128
|
|
|
124
129
|
See https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_iam-quotas.html
|
|
125
130
|
"""
|
|
126
|
-
custom_policies
|
|
127
|
-
managed_policies = values.get("managed_policies", [])
|
|
128
|
-
if len(custom_policies) + len(managed_policies) > 20:
|
|
131
|
+
if len(self.custom_policies) + len(self.managed_policies) > 20:
|
|
129
132
|
raise ValueError(
|
|
130
|
-
f"The role '{
|
|
133
|
+
f"The role '{self.name}' has too many policies. AWS roles can have at most 20 policies (via quota increase). Please consider consolidating the policies."
|
|
131
134
|
)
|
|
132
|
-
cp_names = [cp.name for cp in custom_policies]
|
|
135
|
+
cp_names = [cp.name for cp in self.custom_policies]
|
|
133
136
|
if len(set(cp_names)) != len(cp_names):
|
|
134
|
-
raise ValueError(
|
|
135
|
-
|
|
136
|
-
)
|
|
137
|
-
mp_names = [mp.name for mp in managed_policies]
|
|
137
|
+
raise ValueError(f"The role '{self.name}' has duplicate custom policies.")
|
|
138
|
+
mp_names = [mp.name for mp in self.managed_policies]
|
|
138
139
|
if len(set(mp_names)) != len(mp_names):
|
|
139
|
-
raise ValueError(
|
|
140
|
-
|
|
141
|
-
)
|
|
142
|
-
return values
|
|
140
|
+
raise ValueError(f"The role '{self.name}' has duplicate managed policies.")
|
|
141
|
+
return self
|
|
143
142
|
|
|
144
143
|
|
|
145
144
|
class RunnerParams(TypedDict):
|
|
@@ -164,7 +163,7 @@ class AwsSamlRolesIntegration(
|
|
|
164
163
|
if not query_func:
|
|
165
164
|
query_func = gql.get_api().query
|
|
166
165
|
return {
|
|
167
|
-
"roles": [c.
|
|
166
|
+
"roles": [c.model_dump() for c in self.get_roles(query_func)],
|
|
168
167
|
}
|
|
169
168
|
|
|
170
169
|
def get_aws_accounts(
|
|
@@ -252,7 +251,9 @@ class AwsSamlRolesIntegration(
|
|
|
252
251
|
aws_accounts = self.get_aws_accounts(
|
|
253
252
|
gql_api.query, account_name=self.params.account_name
|
|
254
253
|
)
|
|
255
|
-
aws_accounts_dict = [
|
|
254
|
+
aws_accounts_dict = [
|
|
255
|
+
account.model_dump(by_alias=True) for account in aws_accounts
|
|
256
|
+
]
|
|
256
257
|
aws_roles = self.get_roles(gql_api.query, account_name=self.params.account_name)
|
|
257
258
|
try:
|
|
258
259
|
default_tags = get_settings().default_tags
|
|
@@ -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 (
|
|
@@ -106,7 +98,8 @@ class ExternalResource(BaseModel):
|
|
|
106
98
|
self.resource_identifier,
|
|
107
99
|
)
|
|
108
100
|
|
|
109
|
-
@
|
|
101
|
+
@field_validator("resource_engine_version", mode="before")
|
|
102
|
+
@classmethod
|
|
110
103
|
def parse_resource_engine_version(
|
|
111
104
|
cls, v: str | semver.VersionInfo
|
|
112
105
|
) -> semver.VersionInfo:
|
|
@@ -114,7 +107,8 @@ class ExternalResource(BaseModel):
|
|
|
114
107
|
return v
|
|
115
108
|
return parse_semver(str(v), optional_minor_and_patch=True)
|
|
116
109
|
|
|
117
|
-
@
|
|
110
|
+
@model_validator(mode="before")
|
|
111
|
+
@classmethod
|
|
118
112
|
def set_resource_engine_version_format(cls, values: dict) -> dict:
|
|
119
113
|
resource_engine_version, resource_engine_version_format = (
|
|
120
114
|
str(values.get("resource_engine_version")),
|
|
@@ -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/cli.py
CHANGED
|
@@ -50,8 +50,8 @@ from reconcile.utils.unleash import get_feature_toggle_state
|
|
|
50
50
|
TERRAFORM_VERSION = ["1.6.6"]
|
|
51
51
|
TERRAFORM_VERSION_REGEX = r"^Terraform\sv([\d]+\.[\d]+\.[\d]+)$"
|
|
52
52
|
|
|
53
|
-
OC_VERSIONS = ["4.
|
|
54
|
-
OC_VERSION_REGEX = r"^Client\sVersion:\s([\d]+\.[\d]+\.[\d]+)
|
|
53
|
+
OC_VERSIONS = ["4.19.0", "4.16.2"]
|
|
54
|
+
OC_VERSION_REGEX = r"^Client\sVersion:\s([\d]+\.[\d]+\.[\d]+)"
|
|
55
55
|
|
|
56
56
|
HELM_VERSIONS = ["3.11.1"]
|
|
57
57
|
HELM_VERSION_REGEX = r"^version.BuildInfo{Version:\"v([\d]+\.[\d]+\.[\d]+)\".*$"
|
|
@@ -2855,6 +2855,36 @@ def ocm_addons_upgrade_scheduler_org(
|
|
|
2855
2855
|
default=bool(os.environ.get("IGNORE_STS_CLUSTERS")),
|
|
2856
2856
|
help="Ignore STS clusters",
|
|
2857
2857
|
)
|
|
2858
|
+
@click.option(
|
|
2859
|
+
"--job-controller-cluster",
|
|
2860
|
+
help="The cluster holding the job-controller namepsace",
|
|
2861
|
+
required=False,
|
|
2862
|
+
envvar="JOB_CONTROLLER_CLUSTER",
|
|
2863
|
+
)
|
|
2864
|
+
@click.option(
|
|
2865
|
+
"--job-controller-namespace",
|
|
2866
|
+
help="The namespace used for ROSA jobs",
|
|
2867
|
+
required=False,
|
|
2868
|
+
envvar="JOB_CONTROLLER_NAMESPACE",
|
|
2869
|
+
)
|
|
2870
|
+
@click.option(
|
|
2871
|
+
"--rosa-job-service-account",
|
|
2872
|
+
help="The service-account used for ROSA jobs",
|
|
2873
|
+
required=False,
|
|
2874
|
+
envvar="ROSA_JOB_SERVICE_ACCOUNT",
|
|
2875
|
+
)
|
|
2876
|
+
@click.option(
|
|
2877
|
+
"--rosa-job-image",
|
|
2878
|
+
help="The container image to use to run ROSA cli command jobs",
|
|
2879
|
+
required=False,
|
|
2880
|
+
envvar="ROSA_JOB_IMAGE",
|
|
2881
|
+
)
|
|
2882
|
+
@click.option(
|
|
2883
|
+
"--rosa-role",
|
|
2884
|
+
help="The role to assume in the ROSA cluster account",
|
|
2885
|
+
required=False,
|
|
2886
|
+
envvar="ROSA_ROLE",
|
|
2887
|
+
)
|
|
2858
2888
|
@click.pass_context
|
|
2859
2889
|
def advanced_upgrade_scheduler(
|
|
2860
2890
|
ctx: click.Context,
|
|
@@ -2862,9 +2892,21 @@ def advanced_upgrade_scheduler(
|
|
|
2862
2892
|
org_id: Iterable[str],
|
|
2863
2893
|
exclude_org_id: Iterable[str],
|
|
2864
2894
|
ignore_sts_clusters: bool,
|
|
2895
|
+
job_controller_cluster: str | None,
|
|
2896
|
+
job_controller_namespace: str | None,
|
|
2897
|
+
rosa_job_service_account: str | None,
|
|
2898
|
+
rosa_role: str | None,
|
|
2899
|
+
rosa_job_image: str | None,
|
|
2865
2900
|
) -> None:
|
|
2866
|
-
from reconcile.aus.advanced_upgrade_service import
|
|
2867
|
-
|
|
2901
|
+
from reconcile.aus.advanced_upgrade_service import (
|
|
2902
|
+
QONTRACT_INTEGRATION,
|
|
2903
|
+
QONTRACT_INTEGRATION_VERSION,
|
|
2904
|
+
AdvancedUpgradeServiceIntegration,
|
|
2905
|
+
)
|
|
2906
|
+
from reconcile.aus.base import (
|
|
2907
|
+
AdvancedUpgradeSchedulerBaseIntegrationParams,
|
|
2908
|
+
RosaRoleUpgradeHandlerParams,
|
|
2909
|
+
)
|
|
2868
2910
|
|
|
2869
2911
|
run_class_integration(
|
|
2870
2912
|
integration=AdvancedUpgradeServiceIntegration(
|
|
@@ -2873,6 +2915,22 @@ def advanced_upgrade_scheduler(
|
|
|
2873
2915
|
ocm_organization_ids=set(org_id),
|
|
2874
2916
|
excluded_ocm_organization_ids=set(exclude_org_id),
|
|
2875
2917
|
ignore_sts_clusters=ignore_sts_clusters,
|
|
2918
|
+
rosa_role_upgrade_handler_params=RosaRoleUpgradeHandlerParams(
|
|
2919
|
+
job_controller_cluster=job_controller_cluster,
|
|
2920
|
+
job_controller_namespace=job_controller_namespace,
|
|
2921
|
+
rosa_job_service_account=rosa_job_service_account,
|
|
2922
|
+
rosa_role=rosa_role,
|
|
2923
|
+
rosa_job_image=rosa_job_image,
|
|
2924
|
+
integration_name=QONTRACT_INTEGRATION,
|
|
2925
|
+
integration_version=QONTRACT_INTEGRATION_VERSION,
|
|
2926
|
+
)
|
|
2927
|
+
if all([
|
|
2928
|
+
job_controller_cluster,
|
|
2929
|
+
job_controller_namespace,
|
|
2930
|
+
rosa_job_service_account,
|
|
2931
|
+
rosa_role,
|
|
2932
|
+
])
|
|
2933
|
+
else None,
|
|
2876
2934
|
)
|
|
2877
2935
|
),
|
|
2878
2936
|
ctx=ctx,
|
reconcile/dashdotdb_dora.py
CHANGED
reconcile/dashdotdb_slo.py
CHANGED