Skip to content

Commit 8d19d17

Browse files
authored
Merge pull request #37 from workfloworchestrator/docs/updated-documentation-federation
Updated docs with correct instructions using federation and fixed typo's / inconsistencies
2 parents 205b9f4 + 99214c9 commit 8d19d17

File tree

1 file changed

+59
-52
lines changed

1 file changed

+59
-52
lines changed

README.md

Lines changed: 59 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -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

114114
Use 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

138138
While 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
183183
generation of a description based on the product block domain model, or
184184
a complete interface to query, create, update or delete objects in an
185185
OSS 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
188188
the interface is fully implemented for the supported products.
189189

190190
The 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
442442
the 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
741741
and a check is performed to ensure that both pieces of information are
742742
present on the product block. During the provisioning phase the node is
743743
administered 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
745745
handle is also stored. If both of these two actions were successful, the
746746
subscription is transitioned to Active and it is checked that the type
747747
and 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")
827827
def 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

859859
As 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

986986
The node role is defined as type Choice and will be rendered as a
987987
dropdown that is filled with a mapping between the role IDs and names as
988-
defined in Netbox.
988+
defined in NetBox.
989989

990990
```python
991991
def 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
12981298
functions, 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
13001300
of payload. The Pynetbox[^7] Python API client library is used to
1301-
interface with Netbox.
1301+
interface with NetBox.
13021302

13031303
#### Payload
13041304

13051305
The `build_payload()` single dispatch allows a first argument of type
13061306
product block model, and a subscription model parameter that is used
13071307
when 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
13091309
payload definitions.
13101310

13111311
```python
@@ -1317,7 +1317,7 @@ def build_payload(model: ProductBlockModel, subscription: SubscriptionModel, **k
13171317
When the payload is generated from a product block, the correct mapping
13181318
is made between the types used in the orchestrator and the types used in
13191319
the 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

13401340
The values from the product block are copied to the appropriate place in
13411341
the 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
13431343
the fixed input speed with the same name on the subscription, the
13441344
multiplication 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
13491349
single dispatch `create()` is used:
13501350

13511351
```python
@@ -1355,7 +1355,7 @@ def create(payload: NetboxPayload, **kwargs: Any) -> int:
13551355
```
13561356

13571357
When 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
13591359
desired object. In the example below can be seen that interface payload
13601360
is to be used against the `api.dcim.interfaces` endpoint.
13611361

@@ -1366,35 +1366,35 @@ def _(payload: InterfacePayload, **kwargs: Any) -> int:
13661366
```
13671367

13681368
Finally, 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
13741374
def _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
13801380
can be registered in the subscription for later reference, e.q. when the
13811381
object needs to be modified or deleted.
13821382

13831383
#### Update
13841384

13851385
The single dispatch `update()` is defined in a similar way, the only
13861386
difference 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
13911391
def _(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
13961396
object with the dictionary created from the supplied payload, and send
1397-
the update to Netbox.
1397+
the update to NetBox.
13981398

13991399
```python
14001400
def _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
14121412
def get_interfaces(**kwargs) -> List:
@@ -1417,15 +1417,15 @@ def get_interface(**kwargs):
14171417
```
14181418

14191419
Both 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.
14221422
And `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
14311431
def 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

14461446
The modeling used in the orchestrator does not necessarily have to
14471447
match exactly with the modeling in your OSS or BSS. In many cases,
@@ -1453,13 +1453,12 @@ external systems as much as possible.
14531453

14541454
The diagram below shows the product blocks and relations as used in a
14551455
core 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

14611460
And 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
14631462
nodes.
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
14981505
query GetNetboxDevices {
@@ -1518,7 +1525,7 @@ query GetNetboxDevices {
15181525
```graphql
15191526
query 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
15421549
query 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 -
16041611
https://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
16071614
address management - https://netbox.dev
16081615

16091616
[^4]: The Python SQL Toolkit and Object Relational Mapper -

0 commit comments

Comments
 (0)