Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
GÉANT Service Orchestrator
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Jira
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package registry
Container registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
GÉANT Orchestration and Automation Team
GAP
GÉANT Service Orchestrator
Commits
f83780eb
Verified
Commit
f83780eb
authored
1 year ago
by
Karel van Klink
Browse files
Options
Downloads
Patches
Plain Diff
use conditionals and reformat some code in modify iptrunk interface workflow
parent
8280d82d
No related branches found
No related tags found
No related merge requests found
Pipeline
#85180
canceled
1 year ago
Stage: tox
Stage: documentation
Stage: sonarqube
Changes
2
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
gso/workflows/iptrunk/modify_trunk_interface.py
+115
-67
115 additions, 67 deletions
gso/workflows/iptrunk/modify_trunk_interface.py
test/workflows/iptrunk/test_modify_trunk_interface.py
+1
-1
1 addition, 1 deletion
test/workflows/iptrunk/test_modify_trunk_interface.py
with
116 additions
and
68 deletions
gso/workflows/iptrunk/modify_trunk_interface.py
+
115
−
67
View file @
f83780eb
"""
A modification workflow that updates the :term:`LAG` interfaces that are part of an existing IP trunk.
"""
"""
A modification workflow that updates the :term:`LAG` interfaces that are part of an existing IP trunk.
"""
import
ipaddress
import
ipaddress
from
uuid
import
uuid4
from
uuid
import
UUID
,
uuid4
from
orchestrator.forms
import
FormPage
,
ReadOnlyField
from
orchestrator.forms
import
FormPage
,
ReadOnlyField
from
orchestrator.forms.validators
import
UniqueConstrainedList
from
orchestrator.forms.validators
import
UniqueConstrainedList
from
orchestrator.targets
import
Target
from
orchestrator.targets
import
Target
from
orchestrator.types
import
FormGenerator
,
State
,
UUIDstr
from
orchestrator.types
import
FormGenerator
,
State
,
UUIDstr
from
orchestrator.workflow
import
StepList
,
done
,
init
,
step
,
workflow
from
orchestrator.workflow
import
StepList
,
conditional
,
done
,
init
,
step
,
workflow
from
orchestrator.workflows.steps
import
resync
,
store_process_subscription
,
unsync
from
orchestrator.workflows.steps
import
resync
,
store_process_subscription
,
unsync
from
orchestrator.workflows.utils
import
wrap_modify_initial_input_form
from
orchestrator.workflows.utils
import
wrap_modify_initial_input_form
from
pydantic
import
validator
from
pydantic
import
validator
...
@@ -15,6 +15,7 @@ from pydantic_forms.validators import Label
...
@@ -15,6 +15,7 @@ from pydantic_forms.validators import Label
from
gso.products.product_blocks.iptrunk
import
(
from
gso.products.product_blocks.iptrunk
import
(
IptrunkInterfaceBlock
,
IptrunkInterfaceBlock
,
IptrunkSideBlock
,
IptrunkType
,
IptrunkType
,
PhyPortCapacity
,
PhyPortCapacity
,
)
)
...
@@ -159,22 +160,23 @@ def modify_iptrunk_subscription(
...
@@ -159,22 +160,23 @@ def modify_iptrunk_subscription(
)
->
State
:
)
->
State
:
"""
Modify the subscription in the service database, reflecting the changes to the newly selected interfaces.
"""
"""
Modify the subscription in the service database, reflecting the changes to the newly selected interfaces.
"""
# Prepare the list of removed AE members
# Prepare the list of removed AE members
previous_ae_members
=
{}
previous_ae_members
=
[
removed_ae_members
=
{}
[
for
side_index
in
range
(
2
):
previous_ae_members
[
side_index
]
=
[
{
{
"
interface_name
"
:
member
.
interface_name
,
"
interface_name
"
:
member
.
interface_name
,
"
interface_description
"
:
member
.
interface_description
,
"
interface_description
"
:
member
.
interface_description
,
}
}
for
member
in
s
ubscription
.
iptrunk
.
iptrunk_sides
[
side_index
]
.
iptrunk_side_ae_members
for
member
in
s
ide
.
iptrunk_side_ae_members
]
]
for
side
in
subscription
.
iptrunk
.
iptrunk_sides
]
removed_ae_members
=
[]
for
side_index
in
range
(
2
):
for
side_index
in
range
(
2
):
previous_members
=
previous_ae_members
[
side_index
]
previous_members
=
previous_ae_members
[
side_index
]
current_members
=
side_a_ae_members
if
side_index
==
0
else
side_b_ae_members
current_members
=
side_a_ae_members
if
side_index
==
0
else
side_b_ae_members
removed_ae_members
[
side_index
]
=
[
removed_ae_members
.
append
([
ae_member
for
ae_member
in
previous_members
if
ae_member
not
in
current_members
])
ae_member
for
ae_member
in
previous_members
if
ae_member
not
in
current_members
]
subscription
.
iptrunk
.
geant_s_sid
=
geant_s_sid
subscription
.
iptrunk
.
geant_s_sid
=
geant_s_sid
subscription
.
iptrunk
.
iptrunk_description
=
iptrunk_description
subscription
.
iptrunk
.
iptrunk_description
=
iptrunk_description
subscription
.
iptrunk
.
iptrunk_type
=
iptrunk_type
subscription
.
iptrunk
.
iptrunk_type
=
iptrunk_type
...
@@ -250,67 +252,99 @@ def provision_ip_trunk_iface_real(
...
@@ -250,67 +252,99 @@ def provision_ip_trunk_iface_real(
return
{
"
subscription
"
:
subscription
}
return
{
"
subscription
"
:
subscription
}
@step
(
"
Update interfaces in Netbox. Reserving interfaces.
"
)
def
_netbox_update_interfaces
(
def
update_interfaces_in_netbox
(
subscription
:
Iptrunk
,
removed_ae_members
:
dict
,
previous_ae_members
:
dict
)
->
State
:
subscription_id
:
UUID
,
"""
Update Netbox such that it contains the new interfaces.
"""
side_block
:
IptrunkSideBlock
,
removed_ae_members
:
list
[
dict
],
previous_ae_members
:
list
[
dict
],
)
->
None
:
nbclient
=
NetboxClient
()
nbclient
=
NetboxClient
()
for
index
,
side
in
enumerate
(
subscription
.
iptrunk
.
iptrunk_sides
):
if
get_router_vendor
(
side
.
iptrunk_side_node
.
owner_subscription_id
)
==
RouterVendor
.
NOKIA
:
# Free removed interfaces
lag_interface
=
side
.
iptrunk_side_ae_iface
for
member
in
removed_ae_members
:
router_name
=
side
.
iptrunk_side_node
.
router_fqdn
nbclient
.
free_interface
(
side_block
.
iptrunk_side_node
.
router_fqdn
,
member
[
"
interface_name
"
])
# Free removed interfaces
for
member
in
removed_ae_members
[
str
(
index
)]:
# Attach physical interfaces to :term:`LAG`
nbclient
.
free_interface
(
router_name
,
member
[
"
interface_name
"
])
# Update interface description to subscription ID
# Attach physical interfaces to :term:`LAG`
# Reserve interfaces
# Update interface description to subscription ID
for
interface
in
side_block
.
iptrunk_side_ae_members
:
# Reserve interfaces
if
any
(
ae_member
[
"
interface_name
"
]
==
interface
.
interface_name
for
ae_member
in
previous_ae_members
):
for
interface
in
side
.
iptrunk_side_ae_members
:
continue
if
any
(
if
side_block
.
iptrunk_side_ae_iface
:
ae_member
.
get
(
"
interface_name
"
)
==
interface
.
interface_name
nbclient
.
attach_interface_to_lag
(
for
ae_member
in
previous_ae_members
[
str
(
index
)]
device_name
=
side_block
.
iptrunk_side_node
.
router_fqdn
,
):
lag_name
=
side_block
.
iptrunk_side_ae_iface
,
continue
iface_name
=
interface
.
interface_name
,
nbclient
.
attach_interface_to_lag
(
description
=
str
(
subscription_id
),
device_name
=
side
.
iptrunk_side_node
.
router_fqdn
,
)
lag_name
=
lag_interface
,
iface_name
=
interface
.
interface_name
,
nbclient
.
reserve_interface
(
description
=
str
(
subscription
.
subscription_id
),
device_name
=
side_block
.
iptrunk_side_node
.
router_fqdn
,
)
iface_name
=
interface
.
interface_name
,
nbclient
.
reserve_interface
(
)
device_name
=
side
.
iptrunk_side_node
.
router_fqdn
,
iface_name
=
interface
.
interface_name
,
)
@step
(
"
Netbox: Reserve side A interfaces
"
)
return
{
def
netbox_update_interfaces_side_a
(
"
subscription
"
:
subscription
,
subscription
:
Iptrunk
,
removed_ae_members
:
list
[
list
[
dict
]],
previous_ae_members
:
list
[
list
[
dict
]]
}
)
->
None
:
"""
Update Netbox such that it contains the new interfaces on side A.
"""
_netbox_update_interfaces
(
subscription
.
subscription_id
,
subscription
.
iptrunk
.
iptrunk_sides
[
0
],
removed_ae_members
[
0
],
previous_ae_members
[
0
],
)
@step
(
"
Netbox: Reserve side B interfaces
"
)
def
netbox_update_interfaces_side_b
(
subscription
:
Iptrunk
,
removed_ae_members
:
list
[
list
[
dict
]],
previous_ae_members
:
list
[
list
[
dict
]]
)
->
None
:
"""
Update Netbox such that it contains the new interfaces on side B.
"""
_netbox_update_interfaces
(
subscription
.
subscription_id
,
subscription
.
iptrunk
.
iptrunk_sides
[
1
],
removed_ae_members
[
1
],
previous_ae_members
[
1
],
)
@step
(
"
Allocate interfaces in Netbox
"
)
def
_netbox_allocate_interfaces
(
side_block
:
IptrunkSideBlock
,
previous_ae_members
:
list
[
dict
])
->
None
:
def
allocate_interfaces_in_netbox
(
subscription
:
Iptrunk
,
previous_ae_members
:
dict
)
->
State
:
nbclient
=
NetboxClient
()
"""
Allocate the :term:`LAG` interfaces in NetBox.
Attach the :term:`LAG` interfaces to the physical interfaces detach old ones from the :term:`LAG`.
for
interface
in
side_block
.
iptrunk_side_ae_members
:
if
any
(
ae_member
[
"
interface_name
"
]
==
interface
.
interface_name
for
ae_member
in
previous_ae_members
):
continue
nbclient
.
allocate_interface
(
device_name
=
side_block
.
iptrunk_side_node
.
router_fqdn
,
iface_name
=
interface
.
interface_name
,
)
# detach the old interfaces from lag
if
side_block
.
iptrunk_side_ae_iface
:
nbclient
.
detach_interfaces_from_lag
(
device_name
=
side_block
.
iptrunk_side_node
.
router_fqdn
,
lag_name
=
side_block
.
iptrunk_side_ae_iface
,
)
@step
(
"
Netbox: Allocate side A interfaces
"
)
def
allocate_interfaces_in_netbox_side_a
(
subscription
:
Iptrunk
,
previous_ae_members
:
list
[
list
[
dict
]])
->
None
:
"""
Allocate the :term:`LAG` interfaces on side A in Netbox.
Attach the :term:`LAG` interface to the physical interface detach old one from the :term:`LAG`.
"""
"""
for
index
,
side
in
enumerate
(
subscription
.
iptrunk
.
iptrunk_sides
):
_netbox_allocate_interfaces
(
subscription
.
iptrunk
.
iptrunk_sides
[
0
],
previous_ae_members
[
0
])
nbclient
=
NetboxClient
()
if
get_router_vendor
(
side
.
iptrunk_side_node
.
owner_subscription_id
)
==
RouterVendor
.
NOKIA
:
for
interface
in
side
.
iptrunk_side_ae_members
:
if
any
(
ae_member
.
get
(
"
interface_name
"
)
==
interface
.
interface_name
for
ae_member
in
previous_ae_members
[
str
(
index
)]
):
continue
nbclient
.
allocate_interface
(
device_name
=
side
.
iptrunk_side_node
.
router_fqdn
,
iface_name
=
interface
.
interface_name
,
)
# detach the old interfaces from lag
nbclient
.
detach_interfaces_from_lag
(
device_name
=
side
.
iptrunk_side_node
.
router_fqdn
,
lag_name
=
side
.
iptrunk_side_ae_iface
,
)
return
{
"
subscription
"
:
subscription
}
@step
(
"
Netbox: Allocate side B interfaces
"
)
def
allocate_interfaces_in_netbox_side_b
(
subscription
:
Iptrunk
,
previous_ae_members
:
list
[
list
[
dict
]])
->
None
:
"""
Allocate the :term:`LAG` interface on side B in Netbox.
Attach the :term:`LAG` interface to the physical interface detach old one from the :term:`LAG`.
"""
_netbox_allocate_interfaces
(
subscription
.
iptrunk
.
iptrunk_sides
[
1
],
previous_ae_members
[
1
])
@workflow
(
@workflow
(
...
@@ -326,15 +360,29 @@ def modify_trunk_interface() -> StepList:
...
@@ -326,15 +360,29 @@ def modify_trunk_interface() -> StepList:
* Provision the updated version of the IP trunk, first as a dry run
* Provision the updated version of the IP trunk, first as a dry run
* Allocate the reserved interfaces in Netbox
* Allocate the reserved interfaces in Netbox
"""
"""
side_a_is_nokia
=
conditional
(
lambda
state
:
get_router_vendor
(
state
[
"
subscription
"
][
"
iptrunk
"
][
"
iptrunk_sides
"
][
0
][
"
iptrunk_side_node
"
][
"
owner_subscription_id
"
]
)
==
RouterVendor
.
NOKIA
)
side_b_is_nokia
=
conditional
(
lambda
state
:
get_router_vendor
(
state
[
"
subscription
"
][
"
iptrunk
"
][
"
iptrunk_sides
"
][
1
][
"
iptrunk_side_node
"
][
"
owner_subscription_id
"
]
)
==
RouterVendor
.
NOKIA
)
return
(
return
(
init
init
>>
store_process_subscription
(
Target
.
MODIFY
)
>>
store_process_subscription
(
Target
.
MODIFY
)
>>
unsync
>>
unsync
>>
modify_iptrunk_subscription
>>
modify_iptrunk_subscription
>>
update_interfaces_in_netbox
>>
side_a_is_nokia
(
netbox_update_interfaces_side_a
)
>>
side_b_is_nokia
(
netbox_update_interfaces_side_b
)
>>
pp_interaction
(
provision_ip_trunk_iface_dry
)
>>
pp_interaction
(
provision_ip_trunk_iface_dry
)
>>
pp_interaction
(
provision_ip_trunk_iface_real
)
>>
pp_interaction
(
provision_ip_trunk_iface_real
)
>>
allocate_interfaces_in_netbox
>>
side_a_is_nokia
(
allocate_interfaces_in_netbox_side_a
)
>>
side_b_is_nokia
(
allocate_interfaces_in_netbox_side_b
)
>>
resync
>>
resync
>>
done
>>
done
)
)
This diff is collapsed.
Click to expand it.
test/workflows/iptrunk/test_modify_trunk_interface.py
+
1
−
1
View file @
f83780eb
...
@@ -138,7 +138,7 @@ def test_iptrunk_modify_trunk_interface_success(
...
@@ -138,7 +138,7 @@ def test_iptrunk_modify_trunk_interface_success(
new_side_b_sid
=
input_form_iptrunk_data
[
3
][
"
side_b_ae_geant_a_sid
"
]
new_side_b_sid
=
input_form_iptrunk_data
[
3
][
"
side_b_ae_geant_a_sid
"
]
new_side_b_ae_members
=
input_form_iptrunk_data
[
3
][
"
side_b_ae_members
"
]
new_side_b_ae_members
=
input_form_iptrunk_data
[
3
][
"
side_b_ae_members
"
]
# Only Nokia interfaces will checked
# Only Nokia interfaces will
be
checked
vendor_side_a
=
subscription
.
iptrunk
.
iptrunk_sides
[
0
].
iptrunk_side_node
.
vendor
vendor_side_a
=
subscription
.
iptrunk
.
iptrunk_sides
[
0
].
iptrunk_side_node
.
vendor
vendor_side_b
=
subscription
.
iptrunk
.
iptrunk_sides
[
1
].
iptrunk_side_node
.
vendor
vendor_side_b
=
subscription
.
iptrunk
.
iptrunk_sides
[
1
].
iptrunk_side_node
.
vendor
num_ifaces
=
(
len
(
new_side_a_ae_members
)
if
vendor_side_a
==
RouterVendor
.
NOKIA
else
0
)
+
(
num_ifaces
=
(
len
(
new_side_a_ae_members
)
if
vendor_side_a
==
RouterVendor
.
NOKIA
else
0
)
+
(
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment