@@ -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:
@@ -1243,20 +1243,20 @@ def _(product: NodeProvisioning) -> str:
12431243 return f " node { product.node.node_name} ( { product.node.node_status} ) "
12441244```
12451245
1246- # ## Netbox
1246+ # ## NetBox
12471247
1248- The Netbox service is an interplay between several single dispatch
1248+ The NetBox service is an interplay between several single dispatch
12491249functions, one to generate the payload for a specific product block, and
1250- two others that create or modify an object in Netbox based on the type
1250+ two others that create or modify an object in NetBox based on the type
12511251of payload. The Pynetbox[^ 7 ] Python API client library is used to
1252- interface with Netbox .
1252+ interface with NetBox .
12531253
12541254# ### Payload
12551255
12561256The `build_payload()` single dispatch allows a first argument of type
12571257product block model, and a subscription model parameter that is used
12581258when related information is needed from other parts of the subscription.
1259- The specified return type is the base class that is used for all Netbox
1259+ The specified return type is the base class that is used for all NetBox
12601260payload definitions.
12611261
12621262```python
@@ -1268,7 +1268,7 @@ def build_payload(model: ProductBlockModel, subscription: SubscriptionModel, **k
12681268When the payload is generated from a product block, the correct mapping
12691269is made between the types used in the orchestrator and the types used in
12701270the OSS or BSS . For example, the Port product block maps on the
1271- Interface type in Netbox , as can be seen below.
1271+ Interface type in NetBox , as can be seen below.
12721272
12731273```python
12741274@ build_payload.register
@@ -1290,13 +1290,13 @@ def build_port_payload(model: PortBlockProvisioning, subscription: SubscriptionM
12901290
12911291The values from the product block are copied to the appropriate place in
12921292the Interface payload. The interface payload field names match the ones
1293- that are expected by Netbox . The speed of the interface is taken from
1293+ that are expected by NetBox . The speed of the interface is taken from
12941294the fixed input speed with the same name on the subscription, the
12951295multiplication by 1000 is to convert between Mbit/ s and Kbit/ s.
12961296
12971297# ### Create
12981298
1299- To create an object in Netbox based on the type of Netbox payload, the
1299+ To create an object in NetBox based on the type of NetBox payload, the
13001300single dispatch `create()` is used:
13011301
13021302```python
@@ -1306,7 +1306,7 @@ def create(payload: NetboxPayload, **kwargs: Any) -> int:
13061306```
13071307
13081308When registering the payload type , a keyword argument is used to inject
1309- the matching endpoint on the Netbox API that is used to create the
1309+ the matching endpoint on the NetBox API that is used to create the
13101310desired object . In the example below can be seen that interface payload
13111311is to be used against the `api.dcim.interfaces` endpoint.
13121312
@@ -1317,35 +1317,35 @@ def _(payload: InterfacePayload, **kwargs: Any) -> int:
13171317```
13181318
13191319Finally, the payload is used to generate a dictionary as expected by
1320- that Netbox API endpoint. Notice that the names of the fields of the
1321- Netbox payload have to match the names of the fields that are expected
1322- by the Netbox API .
1320+ that NetBox API endpoint. Notice that the names of the fields of the
1321+ NetBox payload have to match the names of the fields that are expected
1322+ by the NetBox API .
13231323
13241324```python
13251325def _create_object(payload: NetboxPayload, endpoint: Endpoint) -> int :
13261326 object = endpoint.create(payload.dict())
13271327 return object .id
13281328```
13291329
1330- The ID of the object that is created in Netbox is returned so that it
1330+ The ID of the object that is created in NetBox is returned so that it
13311331can be registered in the subscription for later reference, e.q. when the
13321332object needs to be modified or deleted.
13331333
13341334# ### Update
13351335
13361336The single dispatch `update()` is defined in a similar way, the only
13371337difference is that an additional argument is used to specify the ID of
1338- the object in Netbox that needs to be updated.
1338+ the object in NetBox that needs to be updated.
13391339
13401340```python
13411341@ update.register
13421342def _(payload: InterfacePayload, id : int , ** kwargs: Any) -> bool :
13431343 return _update_object(payload, id , endpoint = api.dcim.interfaces)
13441344```
13451345
1346- The ID is used to fetch the object from the Netbox API , update the
1346+ The ID is used to fetch the object from the NetBox API , update the
13471347object with the dictionary created from the supplied payload, and send
1348- the update to Netbox .
1348+ the update to NetBox .
13491349
13501350```python
13511351def _update_object(payload: NetboxPayload, id : int , endpoint: Endpoint) -> bool :
@@ -1356,8 +1356,8 @@ def _update_object(payload: NetboxPayload, id: int, endpoint: Endpoint) -> bool:
13561356
13571357# ### Get
13581358
1359- The Netbox service defines other helpers as well. For example, to get an
1360- single object , or a list of objects, of a specific type from Netbox .
1359+ The NetBox service defines other helpers as well. For example, to get an
1360+ single object , or a list of objects, of a specific type from NetBox .
13611361
13621362```python
13631363def get_interfaces(** kwargs) -> List:
@@ -1368,15 +1368,15 @@ def get_interface(**kwargs):
13681368```
13691369
13701370Both types of helpers accept keyword arguments that can be used to
1371- specify the object (s) that are wanted. For example `get_inteface (id = 3 )`
1372- will fetch the single interface object with ID equal to 3 from Netbox .
1371+ specify the object (s) that are wanted. For example `get_interface (id = 3 )`
1372+ will fetch the single interface object with ID equal to 3 from NetBox .
13731373And `get_interfaces(speed = 1000000 )` will get a list of all interface
1374- objects from Netbox that have a speed of 1Gbit / s.
1374+ objects from NetBox that have a speed of 1Gbit / s.
13751375
13761376# ### Delete
13771377
1378- Another set of helpers is defined to delete objects from Netbox . For
1379- example, to delete an Interface object from Netbox , see below.
1378+ Another set of helpers is defined to delete objects from NetBox . For
1379+ example, to delete an Interface object from NetBox , see below.
13801380
13811381```python
13821382def delete_interface(** kwargs) -> None :
@@ -1392,7 +1392,7 @@ def delete_from_netbox(endpoint, **kwargs) -> None:
13921392 object .delete()
13931393```
13941394
1395- # ### Product block to Netbox object mapping
1395+ # ### Product block to NetBox object mapping
13961396
13971397The modeling used in the orchestrator does not necessarily have to
13981398match exactly with the modeling in your OSS or BSS . In many cases,
@@ -1404,13 +1404,12 @@ external systems as much as possible.
14041404
14051405The diagram below shows the product blocks and relations as used in a
14061406core link between two nodes, and how they map to the objects as
1407- administered in Netbox. The product blocks are in orange and the Netbox
1408- objects are in green.
1407+ administered in NetBox. The product blocks are in orange and the NetBox objects are in green.
14091408
14101409< center>< img src=" .pictures/netbox_node_core_link.png" alt=" Node and core link type mapping" width=45 % height=45 % >< / center>
14111410
14121411And the following diagram shows the mapping and relation between product
1413- blocks and Netbox objects for a L2VPN on customer ports between two
1412+ blocks and NetBox objects for a L2VPN on customer ports between two
14141413nodes.
14151414
14161415< center>< img src=" .pictures/netbox_node_port_l2vpn.png" alt=" Node, port and L2VPN type mapping" width=40 % height=40 % >< / center>
@@ -1441,9 +1440,17 @@ For more information on federating new GraphQL types, or the existing WFO GraphQ
14411440
14421441# ### Example queries
14431442
1444- 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.
1443+ > ** Note:**
1444+ > The following queries assume a running `docker- compose` environment with :
1445+ > - Initial seed of NetBox via running a `Netbox bootstrap` Task
1446+ > - Two newly configured nodes
1447+ >
1448+ > 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/)
1449+
1450+ We' ll demonstrate how two separate GraphQL queries can now be performed in one federated query.
14451451
1446- ** 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)
1452+ ** NetBox** : NetBox device details can be queried from the NetBox GraphQL endpoint at
1453+ http:// localhost:8000 / graphql/ (be sure to authenticate first with admin/ admin in [NetBox](http:// localhost:8000 / ))
14471454
14481455```graphql
14491456query GetNetboxDevices {
@@ -1469,7 +1476,7 @@ query GetNetboxDevices {
14691476```graphql
14701477query GetSubscriptions {
14711478 subscriptions(filterBy:
1472- {field: " product " , value: " Node" }
1479+ {field: " Product type " , value: " Node" }
14731480 ) {
14741481 page {
14751482 ... on NodeSubscription {
@@ -1492,7 +1499,7 @@ query GetSubscriptions {
14921499```graphql
14931500query GetEnrichedSubscriptions {
14941501 subscriptions(filterBy:
1495- {field: " product " , value: " Node" }
1502+ {field: " Product type " , value: " Node" }
14961503 ) {
14971504 page {
14981505 ... on NodeSubscription {
@@ -1554,7 +1561,7 @@ https://resources.geant.org/wp-content/uploads/2023/06/M7.3_Common-NREN-Network-
15541561[^ 2 ]: Workflow Orchestrator website -
15551562https:// workfloworchestrator.org/ orchestrator- core/
15561563
1557- [^ 3 ]: Netbox is a tool for data center infrastructure management and IP
1564+ [^ 3 ]: NetBox is a tool for data center infrastructure management and IP
15581565address management - https:// netbox.dev
15591566
15601567[^ 4 ]: The Python SQL Toolkit and Object Relational Mapper -
0 commit comments