Skip to content

Commit 99214c9

Browse files
author
Thomas van der Ven
committed
Updated docs to update instructions using federation and remove typo's and inconsistencies
1 parent 9ce6f7b commit 99214c9

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:
@@ -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
12491249
functions, 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
12511251
of payload. The Pynetbox[^7] Python API client library is used to
1252-
interface with Netbox.
1252+
interface with NetBox.
12531253

12541254
#### Payload
12551255

12561256
The `build_payload()` single dispatch allows a first argument of type
12571257
product block model, and a subscription model parameter that is used
12581258
when 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
12601260
payload definitions.
12611261

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

12911291
The values from the product block are copied to the appropriate place in
12921292
the 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
12941294
the fixed input speed with the same name on the subscription, the
12951295
multiplication 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
13001300
single dispatch `create()` is used:
13011301

13021302
```python
@@ -1306,7 +1306,7 @@ def create(payload: NetboxPayload, **kwargs: Any) -> int:
13061306
```
13071307

13081308
When 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
13101310
desired object. In the example below can be seen that interface payload
13111311
is to be used against the `api.dcim.interfaces` endpoint.
13121312

@@ -1317,35 +1317,35 @@ def _(payload: InterfacePayload, **kwargs: Any) -> int:
13171317
```
13181318

13191319
Finally, 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
13251325
def _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
13311331
can be registered in the subscription for later reference, e.q. when the
13321332
object needs to be modified or deleted.
13331333

13341334
#### Update
13351335

13361336
The single dispatch `update()` is defined in a similar way, the only
13371337
difference 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
13421342
def _(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
13471347
object with the dictionary created from the supplied payload, and send
1348-
the update to Netbox.
1348+
the update to NetBox.
13491349

13501350
```python
13511351
def _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
13631363
def get_interfaces(**kwargs) -> List:
@@ -1368,15 +1368,15 @@ def get_interface(**kwargs):
13681368
```
13691369

13701370
Both 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.
13731373
And `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
13821382
def 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

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

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

14121411
And 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
14141413
nodes.
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
14491456
query GetNetboxDevices {
@@ -1469,7 +1476,7 @@ query GetNetboxDevices {
14691476
```graphql
14701477
query 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
14931500
query 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 -
15551562
https://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
15581565
address management - https://netbox.dev
15591566

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

0 commit comments

Comments
 (0)