Skip to content
Snippets Groups Projects
Commit 4fa0140f authored by Simone Spinelli's avatar Simone Spinelli
Browse files

Create Iptrunk workflow

parent 0747b3ff
No related branches found
No related tags found
1 merge request!8Feature/iptrunks prototype
"""add Iptrunk create workflow.
Revision ID: d3616a686094
Revises: 42d52099c7da
Create Date: 2023-04-21 12:22:18.243625
"""
import sqlalchemy as sa
from alembic import op
# revision identifiers, used by Alembic.
revision = 'd3616a686094'
down_revision = '42d52099c7da'
branch_labels = None
depends_on = None
from orchestrator.migrations.helpers import create_workflow, delete_workflow
new_workflows = [
{
"name": "create_iptrunk",
"target": "CREATE",
"description": "Create Iptrunk",
"product_type": "Iptrunk"
}
]
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"])
......@@ -3,3 +3,4 @@ from orchestrator.workflows import LazyWorkflowInstance
LazyWorkflowInstance("workflows.device.create_device", "create_device")
LazyWorkflowInstance("workflows.device.terminate_device", "terminate_device")
LazyWorkflowInstance("workflows.device.get_facts", "get_facts")
LazyWorkflowInstance("workflows.iptrunk.create_iptrunk", "create_iptrunk")
import ipaddress
from uuid import uuid4
from orchestrator.forms import FormPage
from orchestrator.targets import Target
from orchestrator.workflow import inputstep
from orchestrator.forms.validators import Accept
from orchestrator.types import FormGenerator, State
from orchestrator.types import SubscriptionLifecycle, UUIDstr
from orchestrator.workflow import done, init, step, workflow
from orchestrator.workflows.steps import resync, set_status
from orchestrator.workflows.steps import store_process_subscription
from orchestrator.workflows.utils import wrap_create_initial_input_form
from gso.products.product_types import iptrunk
from gso.services import ipam, provisioning_proxy
def initial_input_form_generator(product_name: str) -> FormGenerator:
class CreateIptrunkForm(FormPage):
class Config:
title = product_name
fqdn: str
user_input = yield CreateIptrunkForm
return user_input.dict()
@step("Create subscription")
def create_subscription(product: UUIDstr) -> State:
subscription = iptrunk.IptrunkInactive.from_product_id(product, uuid4())
return {
"subscription": subscription,
"subscription_id": subscription.subscription_id,
}
@step("Get information from IPAM ")
def get_info_from_ipam(subscription: iptrunk.IptrunkInactive) -> State:
lo = ipam.new_iptrunk_lo_address()
subscription.iptrunk.lo_ipv4_address = lo.v4
subscription.iptrunk.lo_ipv6_address = lo.v6
# TODO: get info about how these should be generated
subscription.iptrunk.lo_iso_address = "49.51e5.0001.0620.4009.6047.00"
subscription.iptrunk.si_ipv4_network = "192.168.0.0/31"
subscription.iptrunk.ias_lt_ipv4_network = "192.168.1.0/31"
subscription.iptrunk.ias_lt_ipv6_network = "fc00:798:1::150/126"
return {"subscription": subscription}
@step("get information about SNMP")
def get_snmp_info(subscription: iptrunk.IptrunkInactive) -> State:
country = 'Spain'
city = 'Barcelona'
country_code = 'ES'
latitude = '41.3743'
longitude = '2.1328'
subscription.iptrunk.site_country = country
subscription.iptrunk.site_city = city
subscription.iptrunk.site_country_code = country_code
subscription.iptrunk.site_latitude = latitude
subscription.iptrunk.site_longitude = longitude
subscription.iptrunk.snmp_location = (
f'{city.upper()},{country.upper()}[{latitude},{longitude}]'
)
return {"subscription": subscription}
@step("Initialize subscription")
def initialize_subscription(
subscription: iptrunk.IptrunkInactive,
fqdn: str,
ts_address: ipaddress.IPv4Address,
ts_port: str
) -> State:
subscription.iptrunk.fqdn = fqdn
subscription.iptrunk.ts_address = str(ts_address)
subscription.iptrunk.ts_port = str(ts_port)
subscription.iptrunk_vendor = iptrunk_vendor
subscription.description = f"Iptrunk {fqdn} type \
({subscription.iptrunk_type})"
subscription = iptrunk.IptrunkProvisioning.from_other_lifecycle(
subscription, SubscriptionLifecycle.PROVISIONING
)
return {"subscription": subscription}
@step("Provision iptrunk [DRY RUN]")
def provision_iptrunk_dry(
subscription: iptrunk.IptrunkProvisioning,
fqdn: str,
ts_address: str,
ts_port: str
) -> State:
# import ansible_runner
#
# r = ansible_runner.run(
# private_data_dir="/opt/geant-gap-ansible",
# playbook="base_config.yaml",
# inventory=subscription.iptrunk.fqdn,
# extravars={
# "lo_ipv4_address": str(subscription.iptrunk.lo_ipv4_address),
# "lo_ipv6_address": str(subscription.iptrunk.lo_ipv6_address),
# "lo_iso_address": subscription.iptrunk.lo_iso_address,
# "snmp_location": subscription.iptrunk.snmp_location,
# "si_ipv4_network": str(subscription.iptrunk.si_ipv4_network),
# "lt_ipv4_network": str(subscription.iptrunk.ias_lt_ipv4_network),
# "lt_ipv6_network": str(subscription.iptrunk.ias_lt_ipv6_network),
# "site_country_code": subscription.iptrunk.site_country_code,
# "verb": "deploy",
# },
# )
# out = r.stdout.read()
# out_splitted = out.splitlines()
# # if r.rc != 0:
# # raise ValueError("Ansible has failed")
# return {"dry_run_output": out_splitted, "return_code": r.rc}
provisioning_proxy.provision_node(
node_subscription_params=subscription,
dry_run=True)
# TODO: figure out what to return when we are suspending & waiting
# for the provisioning-proxy to call back
return {"return_code": 0}
@inputstep("Confirm step", assignee="CHANGES")
def confirm_step() -> FormGenerator:
class ConfirmForm(FormPage):
confirm: Accept
user_input = yield ConfirmForm
return {"confirm": user_input.confirm}
@step("Provision iptrunk [FOR REAL]")
def provision_iptrunk_real(
subscription: iptrunk.IptrunkProvisioning,
fqdn: str,
ts_address: str,
ts_port: str
) -> State:
# import ansible_runner
#
# r = ansible_runner.run(
# private_data_dir="/opt/geant-gap-ansible",
# playbook="base_config.yaml",
# inventory=subscription.iptrunk.fqdn,
# extravars={
# "lo_ipv4_address": str(subscription.iptrunk.lo_ipv4_address),
# "lo_ipv6_address": str(subscription.iptrunk.lo_ipv6_address),
# "lo_iso_address": subscription.iptrunk.lo_iso_address,
# "snmp_location": subscription.iptrunk.snmp_location,
# "si_ipv4_network": str(subscription.iptrunk.si_ipv4_network),
# "lt_ipv4_network": str(subscription.iptrunk.ias_lt_ipv4_network),
# "lt_ipv6_network": str(subscription.iptrunk.ias_lt_ipv6_network),
# "site_country_code": subscription.iptrunk.site_country_code,
# "verb": "deploy",
# },
# )
# out = r.stdout.read()
# out_splitted = out.splitlines()
#
# return {"real_run_output": out_splitted, "return_code": r.rc}
provisioning_proxy.provision_node(
node_subscription_params=subscription)
# TODO: figure out what to return when we are suspending & waiting
# for the provisioning-proxy to call back
return {"return_code": 0}
@workflow(
"Create Iptrunk",
initial_input_form=wrap_create_initial_input_form(
initial_input_form_generator),
target=Target.CREATE,
)
def create_iptrunk():
return (
init
>> create_subscription
>> store_process_subscription(Target.CREATE)
>> get_info_from_ipam
>> get_snmp_info
>> initialize_subscription
>> provision_iptrunk_dry
>> confirm_step
>> provision_iptrunk_real
>> set_status(SubscriptionLifecycle.ACTIVE)
>> resync
>> done
)
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