@@ -56,13 +56,13 @@ Example workflow orchestrator implementation based on the
5656 - [ Validate workflows] ( #validate-workflows )
5757 - [ Services] ( #services-1 )
5858 - [ Subscription descriptions] ( #subscription-descriptions )
59- - [ Netbox ] ( #netbox )
59+ - [ NetBox ] ( #netbox )
6060 - [ Payload] ( #payload )
6161 - [ Create] ( #create )
6262 - [ Update] ( #update )
6363 - [ Get] ( #get )
6464 - [ Delete] ( #delete )
65- - [ Product block to Netbox object mapping] ( #product-block-to-netbox-object-mapping )
65+ - [ Product block to NetBox object mapping] ( #product-block-to-netbox-object-mapping )
6666 - [ Federation] ( #federation )
6767 - [ Requirements] ( #requirements )
6868 - [ Example queries] ( #example-queries )
@@ -113,26 +113,26 @@ http://localhost:4000
113113
114114Use the following steps to see the example orchestrator in action:
115115
116- 1 . bootstrap Netbox
116+ 1 . Bootstrap NetBox
117117 1 . from the ` Tasks ` page click ` New Task `
118- 2 . select ` Netbox Bootstrap` and click ` Start task `
118+ 2 . select ` NetBox Bootstrap` and click ` Start task `
119119 3 . select ` Expand all ` on the following page to see the step details
120- 2 . create a network node (need at least two to create a core link)
120+ 2 . Create a network node (need at least two to create a core link)
121121 1 . in the left-above corner, click on ` New subscription `
122122 2 . select either the ` Node Cisco ` or ` Node Nokia `
123123 3 . fill in the needed fields, click ` Start workflow ` and view the summary form
124124 4 . click ` Start workflow ` again to start the workflow, or click ` Previous ` to modify fields
125- 3 . add interfaces to a node (needed by the other products)
125+ 3 . Add interfaces to a node (needed by the other products)
126126 1 . on the ` Subscriptions ` page, click on the subscription description of the node to show the details
127127 2 . select ` Update node interfaces ` from the ` Actions ` pulldown
128- 4 . create a core link
128+ 4 . Create a core link
129129 1 . in the left-above corner, click on ` New subscription `
130130 2 . select either the ` core link 10G ` or ` core link 100G `
131131 3 . fill in the forms and finally click on ` Start workflow ` to start the workflow
132- 5 . create a customer port (need at least two ** tagged** ports to create a l2vpn)
132+ 5 . Create a customer port (need at least two ** tagged** ports to create a l2vpn)
133133 1 . use ` New subscription ` for either a ` port 10G ` or a ` port 100G `
134134 3 . fill in the forms and click on ` Start workflow ` to start the workflow
135- 6 . create a l2vpn
135+ 6 . Create a l2vpn
136136 1 . use ` New subscription ` for a ` l2vpn ` , fill in the forms, and ` Start workflow `
137137
138138While running the different workflows, have a look at the following
@@ -183,12 +183,12 @@ implementation of a service. A service can be as simple as the
183183generation of a description based on the product block domain model, or
184184a complete interface to query, create, update or delete objects in an
185185OSS or BSS. In the example orchestrator, a service is implemented to
186- interface with Netbox that is being used as IMS and IPAM. The mapping
187- between the product blocks and the objects in Netbox are described, and
186+ interface with NetBox that is being used as IMS and IPAM. The mapping
187+ between the product blocks and the objects in NetBox are described, and
188188the interface is fully implemented for the supported products.
189189
190190The example orchestrator is fully functional and showcases how the WFO
191- can be integrated with Netbox .
191+ can be integrated with NetBox .
192192
193193## Introduction
194194
@@ -436,11 +436,11 @@ orchestrator:
436436- IPv4 and IPv6 prefix for node loopback addresses
437437- IPv4 and IPv6 prefix for core link addressing
438438
439- The task Netbox Bootstrap takes care of initializing Netbox with a
440- default set of this information. For convenience, a task Netbox Wipe is
441- added as well, that will remove all object from Netbox again, including
439+ The task NetBox Bootstrap takes care of initializing NetBox with a
440+ default set of this information. For convenience, a task NetBox Wipe is
441+ added as well, that will remove all object from NetBox again, including
442442the ones that are created by the different workflows. Tasks can be found
443- in the orchestrator UI in the ` New tasks ` pulldown on the ` tasks ` page.
443+ in the orchestrator UI in the ` New task ` pulldown on the ` Tasks ` page.
444444
445445#### Node
446446
@@ -741,7 +741,7 @@ of the node are supplied by the user and stored on the
741741and a check is performed to ensure that both pieces of information are
742742present on the product block. During the provisioning phase the node is
743743administered in IMS and the handle to that information is stored on the
744- `NodeBlockProvsioning ` . Next, the node is provisioned in the NRM and the
744+ `NodeBlockProvisioning ` . Next, the node is provisioned in the NRM and the
745745handle is also stored. If both of these two actions were successful, the
746746subscription is transitioned to Active and it is checked that the type
747747and node name, and the IMS and NRM ID , are present on the product block.
@@ -826,7 +826,7 @@ interpretation are much less prone to happen.
826826@ step(" A Bad example of using input params" )
827827def my_ugly_step(state: State) -> State:
828828 variable_1 = int (state[" variable_1" ])
829- variable_2 = str (state[" varialble_2 " ])
829+ variable_2 = str (state[" variable_2 " ])
830830 subscription = SubscriptionModel.from_subscription_id(state[" subscription_id" ])
831831
832832 if variable_1 > 42 :
@@ -853,7 +853,7 @@ def my_beautiful_step(variable_1: int, variable_2: str, subscription: Subscripti
853853 subscription.product_block_model.variable_1 = variable_1
854854 subscription.product_block_model.variable_2 = variable_2
855855
856- return state | {" subscriotion " : subscription}
856+ return state | {" subscription " : subscription}
857857```
858858
859859As you can see the Orchestrator the orchestrator helps you a lot to condense the logic in your function. The `@ step`
@@ -985,7 +985,7 @@ Vlan = Annotated[int, Ge(2), Le(4094), doc("Allowed VLAN ID range.")]
985985
986986The node role is defined as type Choice and will be rendered as a
987987dropdown that is filled with a mapping between the role IDs and names as
988- defined in Netbox .
988+ defined in NetBox .
989989
990990```python
991991def node_role_selector() -> Choice:
@@ -1292,20 +1292,20 @@ def _(product: NodeProvisioning) -> str:
12921292 return f " node { product.node.node_name} ( { product.node.node_status} ) "
12931293```
12941294
1295- # ## Netbox
1295+ # ## NetBox
12961296
1297- The Netbox service is an interplay between several single dispatch
1297+ The NetBox service is an interplay between several single dispatch
12981298functions, one to generate the payload for a specific product block, and
1299- two others that create or modify an object in Netbox based on the type
1299+ two others that create or modify an object in NetBox based on the type
13001300of payload. The Pynetbox[^ 7 ] Python API client library is used to
1301- interface with Netbox .
1301+ interface with NetBox .
13021302
13031303# ### Payload
13041304
13051305The `build_payload()` single dispatch allows a first argument of type
13061306product block model, and a subscription model parameter that is used
13071307when related information is needed from other parts of the subscription.
1308- The specified return type is the base class that is used for all Netbox
1308+ The specified return type is the base class that is used for all NetBox
13091309payload definitions.
13101310
13111311```python
@@ -1317,7 +1317,7 @@ def build_payload(model: ProductBlockModel, subscription: SubscriptionModel, **k
13171317When the payload is generated from a product block, the correct mapping
13181318is made between the types used in the orchestrator and the types used in
13191319the OSS or BSS . For example, the Port product block maps on the
1320- Interface type in Netbox , as can be seen below.
1320+ Interface type in NetBox , as can be seen below.
13211321
13221322```python
13231323@ build_payload.register
@@ -1339,13 +1339,13 @@ def build_port_payload(model: PortBlockProvisioning, subscription: SubscriptionM
13391339
13401340The values from the product block are copied to the appropriate place in
13411341the Interface payload. The interface payload field names match the ones
1342- that are expected by Netbox . The speed of the interface is taken from
1342+ that are expected by NetBox . The speed of the interface is taken from
13431343the fixed input speed with the same name on the subscription, the
13441344multiplication by 1000 is to convert between Mbit/ s and Kbit/ s.
13451345
13461346# ### Create
13471347
1348- To create an object in Netbox based on the type of Netbox payload, the
1348+ To create an object in NetBox based on the type of NetBox payload, the
13491349single dispatch `create()` is used:
13501350
13511351```python
@@ -1355,7 +1355,7 @@ def create(payload: NetboxPayload, **kwargs: Any) -> int:
13551355```
13561356
13571357When registering the payload type , a keyword argument is used to inject
1358- the matching endpoint on the Netbox API that is used to create the
1358+ the matching endpoint on the NetBox API that is used to create the
13591359desired object . In the example below can be seen that interface payload
13601360is to be used against the `api.dcim.interfaces` endpoint.
13611361
@@ -1366,35 +1366,35 @@ def _(payload: InterfacePayload, **kwargs: Any) -> int:
13661366```
13671367
13681368Finally, the payload is used to generate a dictionary as expected by
1369- that Netbox API endpoint. Notice that the names of the fields of the
1370- Netbox payload have to match the names of the fields that are expected
1371- by the Netbox API .
1369+ that NetBox API endpoint. Notice that the names of the fields of the
1370+ NetBox payload have to match the names of the fields that are expected
1371+ by the NetBox API .
13721372
13731373```python
13741374def _create_object(payload: NetboxPayload, endpoint: Endpoint) -> int :
13751375 object = endpoint.create(payload.dict())
13761376 return object .id
13771377```
13781378
1379- The ID of the object that is created in Netbox is returned so that it
1379+ The ID of the object that is created in NetBox is returned so that it
13801380can be registered in the subscription for later reference, e.q. when the
13811381object needs to be modified or deleted.
13821382
13831383# ### Update
13841384
13851385The single dispatch `update()` is defined in a similar way, the only
13861386difference is that an additional argument is used to specify the ID of
1387- the object in Netbox that needs to be updated.
1387+ the object in NetBox that needs to be updated.
13881388
13891389```python
13901390@ update.register
13911391def _(payload: InterfacePayload, id : int , ** kwargs: Any) -> bool :
13921392 return _update_object(payload, id , endpoint = api.dcim.interfaces)
13931393```
13941394
1395- The ID is used to fetch the object from the Netbox API , update the
1395+ The ID is used to fetch the object from the NetBox API , update the
13961396object with the dictionary created from the supplied payload, and send
1397- the update to Netbox .
1397+ the update to NetBox .
13981398
13991399```python
14001400def _update_object(payload: NetboxPayload, id : int , endpoint: Endpoint) -> bool :
@@ -1405,8 +1405,8 @@ def _update_object(payload: NetboxPayload, id: int, endpoint: Endpoint) -> bool:
14051405
14061406# ### Get
14071407
1408- The Netbox service defines other helpers as well. For example, to get an
1409- single object , or a list of objects, of a specific type from Netbox .
1408+ The NetBox service defines other helpers as well. For example, to get an
1409+ single object , or a list of objects, of a specific type from NetBox .
14101410
14111411```python
14121412def get_interfaces(** kwargs) -> List:
@@ -1417,15 +1417,15 @@ def get_interface(**kwargs):
14171417```
14181418
14191419Both types of helpers accept keyword arguments that can be used to
1420- specify the object (s) that are wanted. For example `get_inteface (id = 3 )`
1421- will fetch the single interface object with ID equal to 3 from Netbox .
1420+ specify the object (s) that are wanted. For example `get_interface (id = 3 )`
1421+ will fetch the single interface object with ID equal to 3 from NetBox .
14221422And `get_interfaces(speed = 1000000 )` will get a list of all interface
1423- objects from Netbox that have a speed of 1Gbit / s.
1423+ objects from NetBox that have a speed of 1Gbit / s.
14241424
14251425# ### Delete
14261426
1427- Another set of helpers is defined to delete objects from Netbox . For
1428- example, to delete an Interface object from Netbox , see below.
1427+ Another set of helpers is defined to delete objects from NetBox . For
1428+ example, to delete an Interface object from NetBox , see below.
14291429
14301430```python
14311431def delete_interface(** kwargs) -> None :
@@ -1441,7 +1441,7 @@ def delete_from_netbox(endpoint, **kwargs) -> None:
14411441 object .delete()
14421442```
14431443
1444- # ### Product block to Netbox object mapping
1444+ # ### Product block to NetBox object mapping
14451445
14461446The modeling used in the orchestrator does not necessarily have to
14471447match exactly with the modeling in your OSS or BSS . In many cases,
@@ -1453,13 +1453,12 @@ external systems as much as possible.
14531453
14541454The diagram below shows the product blocks and relations as used in a
14551455core link between two nodes, and how they map to the objects as
1456- administered in Netbox. The product blocks are in orange and the Netbox
1457- objects are in green.
1456+ administered in NetBox. The product blocks are in orange and the NetBox objects are in green.
14581457
14591458< center>< img src=" .pictures/netbox_node_core_link.png" alt=" Node and core link type mapping" width=45 % height=45 % >< / center>
14601459
14611460And the following diagram shows the mapping and relation between product
1462- blocks and Netbox objects for a L2VPN on customer ports between two
1461+ blocks and NetBox objects for a L2VPN on customer ports between two
14631462nodes.
14641463
14651464< center>< img src=" .pictures/netbox_node_port_l2vpn.png" alt=" Node, port and L2VPN type mapping" width=40 % height=40 % >< / center>
@@ -1490,9 +1489,17 @@ For more information on federating new GraphQL types, or the existing WFO GraphQ
14901489
14911490# ### Example queries
14921491
1493- The following queries assume a running docker- compose environment with 2 configured Nodes. We' ll demonstrate how 2 separate GraphQL queries can now be performed in 1 federated query.
1492+ > ** Note:**
1493+ > The following queries assume a running `docker- compose` environment with :
1494+ > - Initial seed of NetBox via running a `Netbox bootstrap` Task
1495+ > - Two newly configured nodes
1496+ >
1497+ > See section [Using the example orchestrator](# using-the-example-orchestrator) on how to run Tasks and create nodes in the [Workflow Orchestrator UI](http://localhost:3000/)
1498+
1499+ We' ll demonstrate how two separate GraphQL queries can now be performed in one federated query.
14941500
1495- ** NetBox** : NetBox device details can be queried from the NetBox GraphQL endpoint at http:// localhost:8000 / graphql/ (be sure to authenticate first with admin/ admin)
1501+ ** NetBox** : NetBox device details can be queried from the NetBox GraphQL endpoint at
1502+ http:// localhost:8000 / graphql/ (be sure to authenticate first with admin/ admin in [NetBox](http:// localhost:8000 / ))
14961503
14971504```graphql
14981505query GetNetboxDevices {
@@ -1518,7 +1525,7 @@ query GetNetboxDevices {
15181525```graphql
15191526query GetSubscriptions {
15201527 subscriptions(filterBy:
1521- {field: " product " , value: " Node" }
1528+ {field: " Product type " , value: " Node" }
15221529 ) {
15231530 page {
15241531 ... on NodeSubscription {
@@ -1541,7 +1548,7 @@ query GetSubscriptions {
15411548```graphql
15421549query GetEnrichedSubscriptions {
15431550 subscriptions(filterBy:
1544- {field: " product " , value: " Node" }
1551+ {field: " Product type " , value: " Node" }
15451552 ) {
15461553 page {
15471554 ... on NodeSubscription {
@@ -1603,7 +1610,7 @@ https://resources.geant.org/wp-content/uploads/2023/06/M7.3_Common-NREN-Network-
16031610[^ 2 ]: Workflow Orchestrator website -
16041611https:// workfloworchestrator.org/ orchestrator- core/
16051612
1606- [^ 3 ]: Netbox is a tool for data center infrastructure management and IP
1613+ [^ 3 ]: NetBox is a tool for data center infrastructure management and IP
16071614address management - https:// netbox.dev
16081615
16091616[^ 4 ]: The Python SQL Toolkit and Object Relational Mapper -
0 commit comments