Skip to content
Snippets Groups Projects
Verified Commit 6d265a95 authored by Karel van Klink's avatar Karel van Klink :smiley_cat:
Browse files

update workflows to make use of new provisioning proxy pattern with 3 retries

parent 070f4a7f
No related branches found
No related tags found
1 merge request!44update workflows to make use of new provisioning proxy pattern with 3 retries
...@@ -7,13 +7,14 @@ import logging ...@@ -7,13 +7,14 @@ import logging
from typing import NoReturn from typing import NoReturn
import requests import requests
from orchestrator import inputstep from orchestrator import inputstep, conditional, step
from orchestrator.config.assignee import Assignee from orchestrator.config.assignee import Assignee
from orchestrator.domain import SubscriptionModel from orchestrator.domain import SubscriptionModel
from orchestrator.forms import FormPage, ReadOnlyField from orchestrator.forms import FormPage, ReadOnlyField
from orchestrator.forms.validators import Accept, Label, LongText from orchestrator.forms.validators import Accept, Label, LongText
from orchestrator.types import FormGenerator, State, UUIDstr, strEnum from orchestrator.types import FormGenerator, State, UUIDstr, strEnum
from orchestrator.utils.json import json_dumps from orchestrator.utils.json import json_dumps
from orchestrator.workflow import Step, StepList
from pydantic import validator from pydantic import validator
from gso import settings from gso import settings
...@@ -162,8 +163,15 @@ def await_pp_results(subscription: SubscriptionModel, label_text: str = DEFAULT_ ...@@ -162,8 +163,15 @@ def await_pp_results(subscription: SubscriptionModel, label_text: str = DEFAULT_
return result_page.dict() return result_page.dict()
@step("Reset Provisioning Proxy state")
def reset_pp_success_state() -> State:
return {"pp_did_succeed": False}
@inputstep("Confirm provisioning proxy results", assignee=Assignee("SYSTEM")) @inputstep("Confirm provisioning proxy results", assignee=Assignee("SYSTEM"))
def confirm_pp_results(state: State) -> FormGenerator: def confirm_pp_results(state: State) -> FormGenerator:
successful_run = state["pp_run_results"]["return_code"] == 0
class ConfirmRunPage(FormPage): class ConfirmRunPage(FormPage):
class Config: class Config:
title = ( title = (
...@@ -174,9 +182,21 @@ def confirm_pp_results(state: State) -> FormGenerator: ...@@ -174,9 +182,21 @@ def confirm_pp_results(state: State) -> FormGenerator:
run_status: str = ReadOnlyField(state["pp_run_results"]["status"]) run_status: str = ReadOnlyField(state["pp_run_results"]["status"])
run_results: LongText = ReadOnlyField(f"{state['pp_run_results']['output']}") run_results: LongText = ReadOnlyField(f"{state['pp_run_results']['output']}")
pp_result_good_enough: bool = state["pp_run_results"]["return_code"] == 0 if not successful_run:
pp_retry_label: Label = "Provisioning Proxy has failed execution, the playbook will be retried " \
"(up to two times)."
confirm: Accept = Accept("INCOMPLETE") confirm: Accept = Accept("INCOMPLETE")
confirmation = yield ConfirmRunPage yield ConfirmRunPage
return {"pp_did_succeed": successful_run}
def pp_interaction(provisioning_step: Step) -> StepList:
should_retry_pp_steps = conditional(lambda state: not state.get("pp_did_succeed"))
return {"pp_did_succeed": confirmation.pp_result_good_enough} return (
should_retry_pp_steps(provisioning_step)
>> should_retry_pp_steps(await_pp_results)
>> should_retry_pp_steps(confirm_pp_results)
)
...@@ -5,8 +5,7 @@ ...@@ -5,8 +5,7 @@
"confirm_info": "Please verify this form looks correct.", "confirm_info": "Please verify this form looks correct.",
"pp_run_results": "Provisioning proxy results are not ready yet.", "pp_run_results": "Provisioning proxy results are not ready yet.",
"pp_result_good_enough": "Provisioning Proxy results look good (enough).", "pp_retry_label": "Playbook execution failure",
"pp_result_good_enough_info": "If set to false, this will retry the provisioning up to two times.",
"site_bgp_community_id": "Site BGP community ID", "site_bgp_community_id": "Site BGP community ID",
"site_internal_id": "Site internal ID", "site_internal_id": "Site internal ID",
......
...@@ -9,7 +9,7 @@ from orchestrator.forms import FormPage ...@@ -9,7 +9,7 @@ from orchestrator.forms import FormPage
from orchestrator.forms.validators import Choice from orchestrator.forms.validators import Choice
from orchestrator.targets import Target from orchestrator.targets import Target
from orchestrator.types import FormGenerator, State, SubscriptionLifecycle, UUIDstr from orchestrator.types import FormGenerator, State, SubscriptionLifecycle, UUIDstr
from orchestrator.workflow import StepList, conditional, done, init, step, workflow from orchestrator.workflow import StepList, done, init, step, workflow
from orchestrator.workflows.steps import resync, set_status, store_process_subscription from orchestrator.workflows.steps import resync, set_status, store_process_subscription
from orchestrator.workflows.utils import wrap_create_initial_input_form from orchestrator.workflows.utils import wrap_create_initial_input_form
...@@ -18,7 +18,7 @@ from gso.products.product_types import device ...@@ -18,7 +18,7 @@ from gso.products.product_types import device
from gso.products.product_types.device import DeviceInactive, DeviceProvisioning from gso.products.product_types.device import DeviceInactive, DeviceProvisioning
from gso.products.product_types.site import Site from gso.products.product_types.site import Site
from gso.services import _ipam, provisioning_proxy from gso.services import _ipam, provisioning_proxy
from gso.services.provisioning_proxy import await_pp_results, confirm_pp_results from gso.services.provisioning_proxy import reset_pp_success_state, pp_interaction
def site_selector() -> Choice: def site_selector() -> Choice:
...@@ -118,7 +118,7 @@ def initialize_subscription( ...@@ -118,7 +118,7 @@ def initialize_subscription(
subscription = device.DeviceProvisioning.from_other_lifecycle(subscription, SubscriptionLifecycle.PROVISIONING) subscription = device.DeviceProvisioning.from_other_lifecycle(subscription, SubscriptionLifecycle.PROVISIONING)
return {"subscription": subscription, "pp_did_succeed": False} return {"subscription": subscription}
@step("Provision device [DRY RUN]") @step("Provision device [DRY RUN]")
...@@ -153,50 +153,29 @@ def provision_device_real(subscription: DeviceProvisioning, process_id: UUIDstr) ...@@ -153,50 +153,29 @@ def provision_device_real(subscription: DeviceProvisioning, process_id: UUIDstr)
} }
@step("Reset Provisioning Proxy state")
def reset_pp_success_state() -> State:
return {"pp_did_succeed": False}
@workflow( @workflow(
"Create device", "Create device",
initial_input_form=wrap_create_initial_input_form(initial_input_form_generator), initial_input_form=wrap_create_initial_input_form(initial_input_form_generator),
target=Target.CREATE, target=Target.CREATE,
) )
def create_device() -> StepList: def create_device() -> StepList:
should_retry_pp_steps = conditional(lambda state: not state.get("pp_did_succeed"))
return ( return (
init init
>> create_subscription >> create_subscription
>> store_process_subscription(Target.CREATE) >> store_process_subscription(Target.CREATE)
>> initialize_subscription >> initialize_subscription
>> get_info_from_ipam >> get_info_from_ipam
# First attempt at dry run
>> should_retry_pp_steps(provision_device_dry) >> reset_pp_success_state
>> should_retry_pp_steps(await_pp_results) >> pp_interaction(provision_device_dry)
>> should_retry_pp_steps(confirm_pp_results) >> pp_interaction(provision_device_dry)
# Second attempt >> pp_interaction(provision_device_dry)
>> should_retry_pp_steps(provision_device_dry)
>> should_retry_pp_steps(await_pp_results)
>> should_retry_pp_steps(confirm_pp_results)
# Third and last try
>> should_retry_pp_steps(provision_device_dry)
>> should_retry_pp_steps(await_pp_results)
>> should_retry_pp_steps(confirm_pp_results)
>> reset_pp_success_state >> reset_pp_success_state
# First attempt at provisioning >> pp_interaction(provision_device_real)
>> should_retry_pp_steps(provision_device_real) >> pp_interaction(provision_device_real)
>> should_retry_pp_steps(await_pp_results) >> pp_interaction(provision_device_real)
>> should_retry_pp_steps(confirm_pp_results)
# Second attempt
>> should_retry_pp_steps(provision_device_real)
>> should_retry_pp_steps(await_pp_results)
>> should_retry_pp_steps(confirm_pp_results)
# Third and last try
>> should_retry_pp_steps(provision_device_real)
>> should_retry_pp_steps(await_pp_results)
>> should_retry_pp_steps(confirm_pp_results)
>> set_status(SubscriptionLifecycle.ACTIVE) >> set_status(SubscriptionLifecycle.ACTIVE)
>> resync >> resync
>> done >> done
......
...@@ -14,7 +14,7 @@ from gso.products.product_blocks.iptrunk import IptrunkType ...@@ -14,7 +14,7 @@ from gso.products.product_blocks.iptrunk import IptrunkType
from gso.products.product_types.device import Device from gso.products.product_types.device import Device
from gso.products.product_types.iptrunk import IptrunkInactive, IptrunkProvisioning from gso.products.product_types.iptrunk import IptrunkInactive, IptrunkProvisioning
from gso.services import _ipam, provisioning_proxy from gso.services import _ipam, provisioning_proxy
from gso.services.provisioning_proxy import await_pp_results, confirm_pp_results from gso.services.provisioning_proxy import await_pp_results, confirm_pp_results, pp_interaction, reset_pp_success_state
def initial_input_form_generator(product_name: str) -> FormGenerator: def initial_input_form_generator(product_name: str) -> FormGenerator:
...@@ -245,30 +245,47 @@ def create_iptrunk() -> StepList: ...@@ -245,30 +245,47 @@ def create_iptrunk() -> StepList:
>> store_process_subscription(Target.CREATE) >> store_process_subscription(Target.CREATE)
>> initialize_subscription >> initialize_subscription
>> get_info_from_ipam >> get_info_from_ipam
>> provision_ip_trunk_iface_dry
>> await_pp_results >> reset_pp_success_state
>> confirm_pp_results >> pp_interaction(provision_ip_trunk_iface_dry)
>> provision_ip_trunk_iface_real >> pp_interaction(provision_ip_trunk_iface_dry)
>> await_pp_results >> pp_interaction(provision_ip_trunk_iface_dry)
>> confirm_pp_results
>> provision_ip_trunk_isis_iface_dry >> reset_pp_success_state
>> await_pp_results >> pp_interaction(provision_ip_trunk_iface_real)
>> confirm_pp_results >> pp_interaction(provision_ip_trunk_iface_real)
>> provision_ip_trunk_isis_iface_real >> pp_interaction(provision_ip_trunk_iface_real)
>> await_pp_results
>> confirm_pp_results >> reset_pp_success_state
>> provision_ip_trunk_ldp_iface_dry >> pp_interaction(provision_ip_trunk_isis_iface_dry)
>> await_pp_results >> pp_interaction(provision_ip_trunk_isis_iface_dry)
>> confirm_pp_results >> pp_interaction(provision_ip_trunk_isis_iface_dry)
>> provision_ip_trunk_ldp_iface_real
>> await_pp_results >> reset_pp_success_state
>> confirm_pp_results >> pp_interaction(provision_ip_trunk_isis_iface_real)
>> provision_ip_trunk_lldp_iface_dry >> pp_interaction(provision_ip_trunk_isis_iface_real)
>> await_pp_results >> pp_interaction(provision_ip_trunk_isis_iface_real)
>> confirm_pp_results
>> provision_ip_trunk_lldp_iface_real >> reset_pp_success_state
>> await_pp_results >> pp_interaction(provision_ip_trunk_ldp_iface_dry)
>> confirm_pp_results >> pp_interaction(provision_ip_trunk_ldp_iface_dry)
>> pp_interaction(provision_ip_trunk_ldp_iface_dry)
>> reset_pp_success_state
>> pp_interaction(provision_ip_trunk_ldp_iface_real)
>> pp_interaction(provision_ip_trunk_ldp_iface_real)
>> pp_interaction(provision_ip_trunk_ldp_iface_real)
>> reset_pp_success_state
>> pp_interaction(provision_ip_trunk_lldp_iface_dry)
>> pp_interaction(provision_ip_trunk_lldp_iface_dry)
>> pp_interaction(provision_ip_trunk_lldp_iface_dry)
>> reset_pp_success_state
>> pp_interaction(provision_ip_trunk_lldp_iface_real)
>> pp_interaction(provision_ip_trunk_lldp_iface_real)
>> pp_interaction(provision_ip_trunk_lldp_iface_real)
>> set_status(SubscriptionLifecycle.ACTIVE) >> set_status(SubscriptionLifecycle.ACTIVE)
>> resync >> resync
>> done >> done
......
...@@ -12,7 +12,7 @@ from gso.products.product_blocks import PhyPortCapacity ...@@ -12,7 +12,7 @@ from gso.products.product_blocks import PhyPortCapacity
from gso.products.product_blocks.iptrunk import IptrunkType from gso.products.product_blocks.iptrunk import IptrunkType
from gso.products.product_types.iptrunk import Iptrunk from gso.products.product_types.iptrunk import Iptrunk
from gso.services import provisioning_proxy from gso.services import provisioning_proxy
from gso.services.provisioning_proxy import await_pp_results, confirm_pp_results from gso.services.provisioning_proxy import await_pp_results, confirm_pp_results, reset_pp_success_state, pp_interaction
def initial_input_form_generator(subscription_id: UUIDstr) -> FormGenerator: def initial_input_form_generator(subscription_id: UUIDstr) -> FormGenerator:
...@@ -153,18 +153,27 @@ def modify_generic() -> StepList: ...@@ -153,18 +153,27 @@ def modify_generic() -> StepList:
>> store_process_subscription(Target.MODIFY) >> store_process_subscription(Target.MODIFY)
>> unsync >> unsync
>> modify_iptrunk_subscription >> modify_iptrunk_subscription
>> provision_ip_trunk_iface_dry
>> await_pp_results >> reset_pp_success_state
>> confirm_pp_results >> pp_interaction(provision_ip_trunk_iface_dry)
>> provision_ip_trunk_iface_real >> pp_interaction(provision_ip_trunk_iface_dry)
>> await_pp_results >> pp_interaction(provision_ip_trunk_iface_dry)
>> confirm_pp_results
>> provision_ip_trunk_lldp_iface_dry >> reset_pp_success_state
>> await_pp_results >> pp_interaction(provision_ip_trunk_iface_real)
>> confirm_pp_results >> pp_interaction(provision_ip_trunk_iface_real)
>> provision_ip_trunk_lldp_iface_real >> pp_interaction(provision_ip_trunk_iface_real)
>> await_pp_results
>> confirm_pp_results >> reset_pp_success_state
>> pp_interaction(provision_ip_trunk_lldp_iface_dry)
>> pp_interaction(provision_ip_trunk_lldp_iface_dry)
>> pp_interaction(provision_ip_trunk_lldp_iface_dry)
>> reset_pp_success_state
>> pp_interaction(provision_ip_trunk_lldp_iface_real)
>> pp_interaction(provision_ip_trunk_lldp_iface_real)
>> pp_interaction(provision_ip_trunk_lldp_iface_real)
>> resync >> resync
>> done >> done
) )
...@@ -7,7 +7,7 @@ from orchestrator.workflows.utils import wrap_modify_initial_input_form ...@@ -7,7 +7,7 @@ from orchestrator.workflows.utils import wrap_modify_initial_input_form
from gso.products.product_types.iptrunk import Iptrunk from gso.products.product_types.iptrunk import Iptrunk
from gso.services import provisioning_proxy from gso.services import provisioning_proxy
from gso.services.provisioning_proxy import await_pp_results, confirm_pp_results from gso.services.provisioning_proxy import await_pp_results, confirm_pp_results, pp_interaction, reset_pp_success_state
def initial_input_form_generator(subscription_id: UUIDstr) -> FormGenerator: def initial_input_form_generator(subscription_id: UUIDstr) -> FormGenerator:
...@@ -71,12 +71,17 @@ def modify_isis_metric() -> StepList: ...@@ -71,12 +71,17 @@ def modify_isis_metric() -> StepList:
>> store_process_subscription(Target.MODIFY) >> store_process_subscription(Target.MODIFY)
>> unsync >> unsync
>> modify_iptrunk_subscription >> modify_iptrunk_subscription
>> provision_ip_trunk_isis_iface_dry
>> await_pp_results >> reset_pp_success_state
>> confirm_pp_results >> pp_interaction(provision_ip_trunk_isis_iface_dry)
>> provision_ip_trunk_isis_iface_real >> pp_interaction(provision_ip_trunk_isis_iface_dry)
>> await_pp_results >> pp_interaction(provision_ip_trunk_isis_iface_dry)
>> confirm_pp_results
>> reset_pp_success_state
>> pp_interaction(provision_ip_trunk_isis_iface_real)
>> pp_interaction(provision_ip_trunk_isis_iface_real)
>> pp_interaction(provision_ip_trunk_isis_iface_real)
>> resync >> resync
>> done >> done
) )
...@@ -12,7 +12,7 @@ from orchestrator.workflows.utils import wrap_modify_initial_input_form ...@@ -12,7 +12,7 @@ from orchestrator.workflows.utils import wrap_modify_initial_input_form
from gso.products.product_types.iptrunk import Iptrunk from gso.products.product_types.iptrunk import Iptrunk
from gso.services import ipam, provisioning_proxy from gso.services import ipam, provisioning_proxy
from gso.services.ipam import V4ServiceNetwork, V6ServiceNetwork from gso.services.ipam import V4ServiceNetwork, V6ServiceNetwork
from gso.services.provisioning_proxy import await_pp_results, confirm_pp_results from gso.services.provisioning_proxy import await_pp_results, confirm_pp_results, pp_interaction, reset_pp_success_state
def initial_input_form_generator(subscription_id: UUIDstr) -> FormGenerator: def initial_input_form_generator(subscription_id: UUIDstr) -> FormGenerator:
...@@ -92,15 +92,22 @@ def terminate_iptrunk() -> StepList: ...@@ -92,15 +92,22 @@ def terminate_iptrunk() -> StepList:
>> store_process_subscription(Target.TERMINATE) >> store_process_subscription(Target.TERMINATE)
>> unsync >> unsync
>> modify_iptrunk_subscription >> modify_iptrunk_subscription
>> drain_traffic_from_ip_trunk
>> await_pp_results >> reset_pp_success_state
>> confirm_pp_results >> pp_interaction(drain_traffic_from_ip_trunk)
>> deprovision_ip_trunk_dry >> pp_interaction(drain_traffic_from_ip_trunk)
>> await_pp_results >> pp_interaction(drain_traffic_from_ip_trunk)
>> confirm_pp_results
>> deprovision_ip_trunk_real >> reset_pp_success_state
>> await_pp_results >> pp_interaction(deprovision_ip_trunk_dry)
>> confirm_pp_results >> pp_interaction(deprovision_ip_trunk_dry)
>> pp_interaction(deprovision_ip_trunk_dry)
>> reset_pp_success_state
>> pp_interaction(deprovision_ip_trunk_real)
>> pp_interaction(deprovision_ip_trunk_real)
>> pp_interaction(deprovision_ip_trunk_real)
>> deprovision_ip_trunk_ipv4 >> deprovision_ip_trunk_ipv4
>> deprovision_ip_trunk_ipv6 >> deprovision_ip_trunk_ipv6
>> set_status(SubscriptionLifecycle.TERMINATED) >> set_status(SubscriptionLifecycle.TERMINATED)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment