Skip to content
Snippets Groups Projects
Commit c47f9166 authored by geant-release-service's avatar geant-release-service
Browse files

Finished release 2.32.

parents b8d47270 eb0ba5de
Branches
Tags
No related merge requests found
Pipeline #91429 failed
# Changelog
## [2.32] - 2025-01-17
- Add environment variables for Python logging and UTF-8 support in Alpine image
- add custom customer type and resolver to the graphq
- Add task for checking NETCONF connectivity of a Site
- `promote_p_to_pe`: PE static routes as a separate step
- Add custom_service_name to EdgePort, L2Circuit and AccessPort blocks.
- Update edge port WF to include custom_service_name as a optional field
- Add migration to remove old GS and GA sequences and add a shared one
- Add the ability of generating or filled-in GS/GA ids in EdgePort
- Add the ability of generating or filled-in GS/GA ids in L3CoreServices
- Make use for submitformpage where appropriate
- Add SharePoint list to L3 core service creation workflow
- Fix a bug in the L3 creation workflow input form
- Add validation workflow for L3 Core Service subscriptions
## [2.28] - 2024-12-13
- Fix an issue where LSO could receive special characters from a workflow state.
- Unify GÉANT service ID resource type naming, and add sequence to the database for generating them.
......
"""Add L3 Core Service validation workflow.
Revision ID: c56862da5ab1
Revises: cd077973121e
Create Date: 2025-01-16 14:17:43.633474
"""
import sqlalchemy as sa
from alembic import op
# revision identifiers, used by Alembic.
revision = 'c56862da5ab1'
down_revision = 'cd077973121e'
branch_labels = None
depends_on = None
from orchestrator.migrations.helpers import create_workflow, delete_workflow
new_workflows = [
{
"name": "validate_l3_core_service",
"target": "SYSTEM",
"description": "Validate L3 Core Service",
"product_type": "L3CoreService"
}
]
def upgrade() -> None:
conn = op.get_bind()
for workflow in new_workflows:
create_workflow(conn, workflow)
def downgrade() -> None:
conn = op.get_bind()
for workflow in new_workflows:
delete_workflow(conn, workflow["name"])
......@@ -97,6 +97,7 @@
"validate_switch": "Validate Switch configuration",
"validate_edge_port": "Validate Edge Port",
"validate_lan_switch_interconnect": "Validate LAN Switch Interconnect",
"validate_l3_core_service": "Validate L3 Core Service",
"task_validate_geant_products": "Validation task for GEANT products",
"task_send_email_notifications": "Send email notifications for failed tasks",
"task_create_partners": "Create partner task",
......
......@@ -123,6 +123,7 @@ LazyWorkflowInstance("gso.workflows.l3_core_service.modify_l3_core_service", "mo
LazyWorkflowInstance("gso.workflows.l3_core_service.create_imported_l3_core_service", "create_imported_l3_core_service")
LazyWorkflowInstance("gso.workflows.l3_core_service.import_l3_core_service", "import_l3_core_service")
LazyWorkflowInstance("gso.workflows.l3_core_service.migrate_l3_core_service", "migrate_l3_core_service")
LazyWorkflowInstance("gso.workflows.l3_core_service.validate_l3_core_service", "validate_l3_core_service")
# Layer 2 Circuit workflows
LazyWorkflowInstance("gso.workflows.l2_circuit.create_layer_2_circuit", "create_layer_2_circuit")
......
......@@ -184,8 +184,11 @@ def initialize_subscription(
for session in binding_port_input["bgp_peers"]
]
sbp_gs_id = (
generate_unique_id(prefix="GS") if binding_port_input.pop("generate_gs_id") else binding_port_input.pop("gs_id")
generate_unique_id(prefix="GS")
if binding_port_input.pop("generate_gs_id", False)
else binding_port_input.pop("gs_id")
)
binding_port_input.pop("gs_id", None)
service_binding_port = ServiceBindingPortInactive.new(
subscription_id=uuid4(),
v4_bfd_settings=BFDSettings.new(subscription_id=uuid4(), **(binding_port_input.pop("v4_bfd_settings"))),
......
"""Validation workflow for L3 Core Service subscription objects."""
from typing import Any
from orchestrator.targets import Target
from orchestrator.workflow import StepList, begin, done, step, workflow
from orchestrator.workflows.steps import resync, store_process_subscription, unsync
from orchestrator.workflows.utils import wrap_modify_initial_input_form
from pydantic_forms.types import State, UUIDstr
from gso.products.product_types.l3_core_service import L3CoreService
from gso.services.lso_client import LSOState, anonymous_lso_interaction
from gso.services.partners import get_partner_by_id
@step("Prepare list of all Access Ports")
def build_fqdn_list(subscription: L3CoreService) -> State:
"""Build the list of all FQDNs that are in the list of access ports of a L3 Core Service subscription."""
ap_fqdn_list = [ap.sbp.edge_port.node.router_fqdn for ap in subscription.l3_core_service.ap_list]
return {"ap_fqdn_list": ap_fqdn_list}
@step("Check SBP config for drift")
def validate_sbp_config(subscription: dict[str, Any], process_id: UUIDstr, ap_fqdn_list: list[str]) -> LSOState:
"""Workflow step for running a playbook that checks whether SBP config has drifted."""
extra_vars = {
"subscription": subscription,
"partner_name": get_partner_by_id(subscription["customer_id"]).name,
"dry_run": True,
"verb": "deploy",
"object": "sbp",
"is_verification_workflow": "true",
"commit_comment": f"GSO_PROCESS_ID: {process_id} - Validate config for {subscription["description"]}",
}
return {
"playbook_name": "gap_ansible/playbooks/l3_core_service.yaml",
"inventory": {"all": {"hosts": dict.fromkeys(ap_fqdn_list)}},
"extra_vars": extra_vars,
}
@step("Check BGP peer config for drift")
def validate_bgp_peers(subscription: dict[str, Any], process_id: UUIDstr, ap_fqdn_list: list[str]) -> LSOState:
"""Workflow step for running a playbook that checks whether BGP peer config has drifted."""
extra_vars = {
"subscription": subscription,
"partner_name": get_partner_by_id(subscription["customer_id"]).name,
"verb": "deploy",
"object": "bgp",
"dry_run": True,
"is_verification_workflow": "true",
"commit_comment": f"GSO_PROCESS_ID: {process_id} - Validate BGP peer config for {subscription["description"]}",
}
return {
"playbook_name": "gap_ansible/playbooks/l3_core_service.yaml",
"inventory": {"all": {"hosts": dict.fromkeys(ap_fqdn_list)}},
"extra_vars": extra_vars,
}
@step("Validate DNS records")
def validate_dns_records() -> None:
"""Validate DNS records in Infoblox."""
# TODO: implement
@workflow("Validate L3 Core Service", target=Target.SYSTEM, initial_input_form=(wrap_modify_initial_input_form(None)))
def validate_l3_core_service() -> StepList:
"""Validate an existing L3 Core Service subscription."""
return (
begin
>> store_process_subscription(Target.SYSTEM)
>> unsync
>> anonymous_lso_interaction(validate_sbp_config)
>> anonymous_lso_interaction(validate_bgp_peers)
>> validate_dns_records
>> resync
>> done
)
......@@ -4,7 +4,7 @@ from setuptools import find_packages, setup
setup(
name="geant-service-orchestrator",
version="2.31",
version="2.32",
author="GÉANT Orchestration and Automation Team",
author_email="goat@geant.org",
description="GÉANT Service Orchestrator",
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment