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
from typing import NoReturn
import requests
from orchestrator import inputstep
from orchestrator import inputstep, conditional, step
from orchestrator.config.assignee import Assignee
from orchestrator.domain import SubscriptionModel
from orchestrator.forms import FormPage, ReadOnlyField
from orchestrator.forms.validators import Accept, Label, LongText
from orchestrator.types import FormGenerator, State, UUIDstr, strEnum
from orchestrator.utils.json import json_dumps
from orchestrator.workflow import Step, StepList
from pydantic import validator
from gso import settings
......@@ -162,8 +163,15 @@ def await_pp_results(subscription: SubscriptionModel, label_text: str = DEFAULT_
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"))
def confirm_pp_results(state: State) -> FormGenerator:
successful_run = state["pp_run_results"]["return_code"] == 0
class ConfirmRunPage(FormPage):
class Config:
title = (
......@@ -174,9 +182,21 @@ def confirm_pp_results(state: State) -> FormGenerator:
run_status: str = ReadOnlyField(state["pp_run_results"]["status"])
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")
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 @@
"confirm_info": "Please verify this form looks correct.",
"pp_run_results": "Provisioning proxy results are not ready yet.",
"pp_result_good_enough": "Provisioning Proxy results look good (enough).",
"pp_result_good_enough_info": "If set to false, this will retry the provisioning up to two times.",
"pp_retry_label": "Playbook execution failure",
"site_bgp_community_id": "Site BGP community ID",
"site_internal_id": "Site internal ID",
......
......@@ -9,7 +9,7 @@ from orchestrator.forms import FormPage
from orchestrator.forms.validators import Choice
from orchestrator.targets import Target
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.utils import wrap_create_initial_input_form
......@@ -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.site import Site
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:
......@@ -118,7 +118,7 @@ def initialize_subscription(
subscription = device.DeviceProvisioning.from_other_lifecycle(subscription, SubscriptionLifecycle.PROVISIONING)
return {"subscription": subscription, "pp_did_succeed": False}
return {"subscription": subscription}
@step("Provision device [DRY RUN]")
......@@ -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(
"Create device",
initial_input_form=wrap_create_initial_input_form(initial_input_form_generator),
target=Target.CREATE,
)
def create_device() -> StepList:
should_retry_pp_steps = conditional(lambda state: not state.get("pp_did_succeed"))
return (
init
>> create_subscription
>> store_process_subscription(Target.CREATE)
>> initialize_subscription
>> get_info_from_ipam
# First attempt at dry run
>> should_retry_pp_steps(provision_device_dry)
>> should_retry_pp_steps(await_pp_results)
>> should_retry_pp_steps(confirm_pp_results)
# Second attempt
>> 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
>> pp_interaction(provision_device_dry)
>> pp_interaction(provision_device_dry)
>> pp_interaction(provision_device_dry)
>> reset_pp_success_state
# First attempt at provisioning
>> should_retry_pp_steps(provision_device_real)
>> should_retry_pp_steps(await_pp_results)
>> 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)
>> pp_interaction(provision_device_real)
>> pp_interaction(provision_device_real)
>> pp_interaction(provision_device_real)
>> set_status(SubscriptionLifecycle.ACTIVE)
>> resync
>> done
......
......@@ -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.iptrunk import IptrunkInactive, IptrunkProvisioning
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:
......@@ -245,30 +245,47 @@ def create_iptrunk() -> StepList:
>> store_process_subscription(Target.CREATE)
>> initialize_subscription
>> get_info_from_ipam
>> provision_ip_trunk_iface_dry
>> await_pp_results
>> confirm_pp_results
>> provision_ip_trunk_iface_real
>> await_pp_results
>> confirm_pp_results
>> provision_ip_trunk_isis_iface_dry
>> await_pp_results
>> confirm_pp_results
>> provision_ip_trunk_isis_iface_real
>> await_pp_results
>> confirm_pp_results
>> provision_ip_trunk_ldp_iface_dry
>> await_pp_results
>> confirm_pp_results
>> provision_ip_trunk_ldp_iface_real
>> await_pp_results
>> confirm_pp_results
>> provision_ip_trunk_lldp_iface_dry
>> await_pp_results
>> confirm_pp_results
>> provision_ip_trunk_lldp_iface_real
>> await_pp_results
>> confirm_pp_results
>> reset_pp_success_state
>> pp_interaction(provision_ip_trunk_iface_dry)
>> pp_interaction(provision_ip_trunk_iface_dry)
>> pp_interaction(provision_ip_trunk_iface_dry)
>> reset_pp_success_state
>> pp_interaction(provision_ip_trunk_iface_real)
>> pp_interaction(provision_ip_trunk_iface_real)
>> pp_interaction(provision_ip_trunk_iface_real)
>> reset_pp_success_state
>> pp_interaction(provision_ip_trunk_isis_iface_dry)
>> pp_interaction(provision_ip_trunk_isis_iface_dry)
>> pp_interaction(provision_ip_trunk_isis_iface_dry)
>> 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)
>> reset_pp_success_state
>> pp_interaction(provision_ip_trunk_ldp_iface_dry)
>> 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)
>> resync
>> done
......
......@@ -12,7 +12,7 @@ from gso.products.product_blocks import PhyPortCapacity
from gso.products.product_blocks.iptrunk import IptrunkType
from gso.products.product_types.iptrunk import Iptrunk
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:
......@@ -153,18 +153,27 @@ def modify_generic() -> StepList:
>> store_process_subscription(Target.MODIFY)
>> unsync
>> modify_iptrunk_subscription
>> provision_ip_trunk_iface_dry
>> await_pp_results
>> confirm_pp_results
>> provision_ip_trunk_iface_real
>> await_pp_results
>> confirm_pp_results
>> provision_ip_trunk_lldp_iface_dry
>> await_pp_results
>> confirm_pp_results
>> provision_ip_trunk_lldp_iface_real
>> await_pp_results
>> confirm_pp_results
>> reset_pp_success_state
>> pp_interaction(provision_ip_trunk_iface_dry)
>> pp_interaction(provision_ip_trunk_iface_dry)
>> pp_interaction(provision_ip_trunk_iface_dry)
>> reset_pp_success_state
>> pp_interaction(provision_ip_trunk_iface_real)
>> pp_interaction(provision_ip_trunk_iface_real)
>> pp_interaction(provision_ip_trunk_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)
>> resync
>> done
)
......@@ -7,7 +7,7 @@ from orchestrator.workflows.utils import wrap_modify_initial_input_form
from gso.products.product_types.iptrunk import Iptrunk
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:
......@@ -71,12 +71,17 @@ def modify_isis_metric() -> StepList:
>> store_process_subscription(Target.MODIFY)
>> unsync
>> modify_iptrunk_subscription
>> provision_ip_trunk_isis_iface_dry
>> await_pp_results
>> confirm_pp_results
>> provision_ip_trunk_isis_iface_real
>> await_pp_results
>> confirm_pp_results
>> reset_pp_success_state
>> pp_interaction(provision_ip_trunk_isis_iface_dry)
>> pp_interaction(provision_ip_trunk_isis_iface_dry)
>> pp_interaction(provision_ip_trunk_isis_iface_dry)
>> 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
>> done
)
......@@ -12,7 +12,7 @@ from orchestrator.workflows.utils import wrap_modify_initial_input_form
from gso.products.product_types.iptrunk import Iptrunk
from gso.services import ipam, provisioning_proxy
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:
......@@ -92,15 +92,22 @@ def terminate_iptrunk() -> StepList:
>> store_process_subscription(Target.TERMINATE)
>> unsync
>> modify_iptrunk_subscription
>> drain_traffic_from_ip_trunk
>> await_pp_results
>> confirm_pp_results
>> deprovision_ip_trunk_dry
>> await_pp_results
>> confirm_pp_results
>> deprovision_ip_trunk_real
>> await_pp_results
>> confirm_pp_results
>> reset_pp_success_state
>> pp_interaction(drain_traffic_from_ip_trunk)
>> pp_interaction(drain_traffic_from_ip_trunk)
>> pp_interaction(drain_traffic_from_ip_trunk)
>> reset_pp_success_state
>> pp_interaction(deprovision_ip_trunk_dry)
>> 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_ipv6
>> set_status(SubscriptionLifecycle.TERMINATED)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment