diff --git a/gso/migrations/versions/2025-06-20_24858fd1d805_add_modify_note_workflow_to_existing_.py b/gso/migrations/versions/2025-06-20_24858fd1d805_add_modify_note_workflow_to_existing_.py new file mode 100644 index 0000000000000000000000000000000000000000..7414647ef21f79530bef8db6e0f022605f218c74 --- /dev/null +++ b/gso/migrations/versions/2025-06-20_24858fd1d805_add_modify_note_workflow_to_existing_.py @@ -0,0 +1,70 @@ +"""Add modify note workflow to existing products. + +Revision ID: 24858fd1d805 +Revises: 550e3aebc1c5 +Create Date: 2025-06-20 10:51:57.321841 + +""" +import sqlalchemy as sa +from alembic import op + +# revision identifiers, used by Alembic. +revision = '24858fd1d805' +down_revision = '550e3aebc1c5' +branch_labels = None +depends_on = None + + +from orchestrator.migrations.helpers import create_workflow, delete_workflow, add_products_to_workflow_by_product_tag, \ + remove_products_from_workflow_by_product_tag + +product_tags = [ + "ER", + "COP", + "EP", + "G_IP", + "G_PLUS", + "IAS", + "IMP_ER", + "IMP_COP", + "IMP_EP", + "IMP_G_IP", + "IMP_G_PLUS", + "IMP_IAS", + "IMP_IP_TRUNK", + "IMP_LSI", + "IMP_LHC", + "IMP_OFFICE_RTR", + "IMPORTED_OPENGEAR", + "IMP_RE_LHCONE", + "IMP_RE_PEER", + "IMP_RTR", + "IMP_SITE", + "IMP_SPOP_SWITCH", + "IMP_SWITCH", + "IPTRUNK", + "LSI", + "LHC", + "OFFICE_ROUTER", + "OPENGEAR", + "POP_VLAN", + "RE_LHCONE", + "RE_PEER", + "RTR", + "SITE", + "Super_POP_SWITCH", + "SWITCH", + "VRF", +] + + +def upgrade() -> None: + conn = op.get_bind() + for product in product_tags: + add_products_to_workflow_by_product_tag(conn, "modify_note", product) + + +def downgrade() -> None: + conn = op.get_bind() + for product in product_tags: + remove_products_from_workflow_by_product_tag(conn, "modify_note", product) diff --git a/gso/migrations/versions/2025-06-20_7c3094cd282a_remove_obsolete_validation_task.py b/gso/migrations/versions/2025-06-20_7c3094cd282a_remove_obsolete_validation_task.py new file mode 100644 index 0000000000000000000000000000000000000000..9efde60deb819ba3da8fe4a2b46629000aaa0f7d --- /dev/null +++ b/gso/migrations/versions/2025-06-20_7c3094cd282a_remove_obsolete_validation_task.py @@ -0,0 +1,35 @@ +"""Remove obsolete validation task. + +Revision ID: 7c3094cd282a +Revises: 24858fd1d805 +Create Date: 2025-06-20 11:34:08.439370 + +""" +import sqlalchemy as sa +from alembic import op + +# revision identifiers, used by Alembic. +revision = '7c3094cd282a' +down_revision = '24858fd1d805' +branch_labels = None +depends_on = None + + +from orchestrator.migrations.helpers import create_task, delete_workflow + +old_task = { + "name": "task_validate_geant_products", + "description": "Validate GEANT products" +} + +def upgrade() -> None: + conn = op.get_bind() + conn.execute(sa.text(f""" +DELETE FROM processes WHERE workflow_id = (SELECT workflow_id FROM workflows WHERE name = '{old_task["name"]}') + """)) + delete_workflow(conn, old_task["name"]) + + +def downgrade() -> None: + conn = op.get_bind() + create_task(conn, old_task) diff --git a/gso/schedules/validate_products.py b/gso/schedules/validate_products.py index efc441ad21f3a4894b82a030e99fd7f0653e0a99..1e693fe3ac48458741710d6a46be65bf548d5c25 100644 --- a/gso/schedules/validate_products.py +++ b/gso/schedules/validate_products.py @@ -4,12 +4,10 @@ from celery import shared_task from orchestrator.services.processes import start_process from gso.schedules.scheduling import CronScheduleConfig, scheduler -from gso.services.processes import count_incomplete_validate_products @shared_task @scheduler(CronScheduleConfig(name="Validate Products and inactive subscriptions", minute="30", hour="2")) def validate_products() -> None: """Validate all products.""" - if count_incomplete_validate_products() == 0: - start_process("task_validate_geant_products") + start_process("task_validate_products") diff --git a/gso/services/processes.py b/gso/services/processes.py index 30caa96fddf3d997fa9ac91254d5934f5707a830..22bfe4e0d7cdcf4aa08141d2a3bce5c78c07ff8d 100644 --- a/gso/services/processes.py +++ b/gso/services/processes.py @@ -18,19 +18,6 @@ def get_processes_by_workflow_name(workflow_name: str) -> Query: return ProcessTable.query.join(WorkflowTable).filter(WorkflowTable.name == workflow_name) -def count_incomplete_validate_products() -> int: - """Count the number of incomplete validate_geant_products processes. - - Returns: - The count of incomplete 'validate_geant_products' processes. - """ - return ( - get_processes_by_workflow_name("validate_geant_products") - .filter(ProcessTable.last_status != ProcessStatus.COMPLETED) - .count() - ) - - def get_failed_tasks() -> list[ProcessTable]: """Get all tasks that have failed.""" return ProcessTable.query.filter( diff --git a/gso/translations/en-GB.json b/gso/translations/en-GB.json index e3ea7bc6c1dd75b253f09bbec50844103087f84b..bbb37da1baca708717536a15f24de22603cdd3fd 100644 --- a/gso/translations/en-GB.json +++ b/gso/translations/en-GB.json @@ -163,7 +163,6 @@ "task_modify_partners": "Modify partner task", "task_redeploy_base_config": "Redeploy base config on multiple routers", "task_send_email_notifications": "Send email notifications for failed tasks", - "task_validate_geant_products": "Validation task for GEANT products", "terminate_edge_port": "Terminate Edge Port", "terminate_iptrunk": "Terminate IP Trunk", "terminate_geant_ip": "Terminate GÉANT IP", diff --git a/gso/workflows/__init__.py b/gso/workflows/__init__.py index 3456115a4439eb0bdfe98e2291b9bcb65bde0952..827d2a07c5db07c4e000c94b27fb982a496a90f2 100644 --- a/gso/workflows/__init__.py +++ b/gso/workflows/__init__.py @@ -104,7 +104,6 @@ LazyWorkflowInstance("gso.workflows.opengear.import_opengear", "import_opengear" # Tasks LazyWorkflowInstance("gso.workflows.tasks.send_email_notifications", "task_send_email_notifications") -LazyWorkflowInstance("gso.workflows.tasks.validate_geant_products", "task_validate_geant_products") LazyWorkflowInstance("gso.workflows.tasks.create_partners", "task_create_partners") LazyWorkflowInstance("gso.workflows.tasks.modify_partners", "task_modify_partners") LazyWorkflowInstance("gso.workflows.tasks.delete_partners", "task_delete_partners") diff --git a/gso/workflows/tasks/validate_geant_products.py b/gso/workflows/tasks/validate_geant_products.py deleted file mode 100644 index 8fe39f61b762f46683336f802af1885d447ab339..0000000000000000000000000000000000000000 --- a/gso/workflows/tasks/validate_geant_products.py +++ /dev/null @@ -1,46 +0,0 @@ -"""A task that checks for all products in the database to be well-kept.""" - -# <!-- vale off --> -# Copyright 2019-2020 SURF. -# Copyright 2024 GÉANT Vereniging. -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# <!-- vale on --> - -from orchestrator.targets import Target -from orchestrator.workflow import StepList, done, init, workflow -from orchestrator.workflows.tasks.validate_products import ( - check_all_workflows_are_in_db, - check_db_fixed_input_config, - check_subscription_models, - check_that_products_have_create_modify_and_terminate_workflows, - check_workflows_for_matching_targets_and_descriptions, -) - - -@workflow("Validate GEANT products", target=Target.SYSTEM) -def task_validate_geant_products() -> StepList: - """Validate products in the database. - - This task is based on the ``task_validate_products`` present in ``orchestrator-core`` but it does not check for the - existence of the ``modify_note`` workflow on all products, since this workflow is currently not used in GEANT. - """ - return ( - init - >> check_all_workflows_are_in_db - >> check_workflows_for_matching_targets_and_descriptions - # >> check_that_products_have_at_least_one_workflow FIXME: Uncomment as soon as this would pass again - >> check_db_fixed_input_config - >> check_that_products_have_create_modify_and_terminate_workflows - >> check_subscription_models - >> done - ) diff --git a/test/tasks/test_masssive_redeploy_base_config.py b/test/tasks/test_massive_redeploy_base_config.py similarity index 100% rename from test/tasks/test_masssive_redeploy_base_config.py rename to test/tasks/test_massive_redeploy_base_config.py diff --git a/test/workflows/tasks/test_task_validate_products.py b/test/workflows/tasks/test_task_validate_products.py index 66853d257d838b423cd7595e2a8ee2b015d94ecf..6c7398b920d392fb86b688d105efd49b01006ae1 100644 --- a/test/workflows/tasks/test_task_validate_products.py +++ b/test/workflows/tasks/test_task_validate_products.py @@ -4,14 +4,15 @@ from test.workflows import assert_complete, extract_state, run_workflow @pytest.mark.workflow() -def test_task_validate_geant_products(): - result, _, _ = run_workflow("task_validate_geant_products", [{}]) +def test_task_validate_products(): + result, _, _ = run_workflow("task_validate_products", [{}]) assert_complete(result) state = extract_state(result) assert state["check_all_workflows_are_in_db"] assert state["check_workflows_for_matching_targets_and_descriptions"] - # assert state["check_that_products_have_at_least_one_workflow"] FIXME: Uncomment when the task is reverted again + assert state["check_that_products_have_at_least_one_workflow"] + assert state["check_that_active_products_have_a_modify_note"] assert state["check_db_fixed_input_config"] assert state["check_that_products_have_create_modify_and_terminate_workflows"] assert state["check_subscription_models"]