Skip to content

Commit

Permalink
NDK docs refresh (#126)
Browse files Browse the repository at this point in the history
* refresh ndk intro

* bump mkdocs

* carve out operations

* foo

* revisit ndk operations doc

* added author profiles config

* refactored agent structure doc

* added roman's profile

* align versions

* restructure language guide section

* dev go index page

* reshuffle go/py layout

* added ndk artifacts list

* init ndk releases

* added diff

* added more stuff

* fix py doc links

* added notif stream doc

* finished tutorial

* fix links

* fix links

* fix links

* experiment with ignore htmltest

* exclude hrefs intercepted by mkdocs

* added py warning

* added version comment

* added logging
  • Loading branch information
hellt authored Dec 5, 2023
1 parent bf4a55f commit fb11f2e
Show file tree
Hide file tree
Showing 29 changed files with 1,345 additions and 482 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/cicd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ on:
pull_request:

env:
MKDOCS_MATERIAL_VER: 9.2.6-insiders-4.40.2-hellt
MKDOCS_MATERIAL_VER: 9.4.14-insiders-4.46.0-hellt

jobs:
docs-test:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ on:
workflow_dispatch:

env:
MKDOCS_MATERIAL_VER: 9.1.16-insiders-4.36.0-hellt-4 # insiders version
MKDOCS_MATERIAL_VER: 9.4.14-insiders-4.46.0-hellt # insiders version

jobs:
publish-docs:
Expand Down
6 changes: 3 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
MKDOCS_VER = 9.0.13
MKDOCS_VER = 9.4.14
# insiders version/tag https://github.com/srl-labs/mkdocs-material-insiders/pkgs/container/mkdocs-material-insiders
MKDOCS_INS_VER = 9.2.6-insiders-4.40.2-hellt
MKDOCS_INS_VER = 9.4.14-insiders-4.46.0-hellt

.PHONY: docs
docs:
docker run --rm -v $$(pwd):/docs --entrypoint mkdocs squidfunk/mkdocs-material:$(MKDOCS_VER) build --clean --strict
docker run --rm -v $$(pwd):/docs --entrypoint mkdocs ghcr.io/srl-labs/mkdocs-material-insiders:$(MKDOCS_INS_VER) build --clean --strict

# serve the site locally using mkdocs-material public container
.PHONY: serve
Expand Down
20 changes: 20 additions & 0 deletions docs/blog/author/rdodin.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Roman Dodin

<div class="grid" markdown>
<div markdown style="justify-content: center; align-items: center; width: 30vw;">
![Roman Dodin](https://gitlab.com/rdodin/pics/-/wikis/uploads/3d2bc0f6014eddb95f24016720ac63af/roman_dodin_avatar_pic.jpeg){.img-shadow width=50% style='border-radius: 20%;'}

[:material-twitter:{ .twemoji-md }][rd-twitter] [:material-linkedin:{ .twemoji-md }][rd-linkedin]

[rd-linkedin]: https://linkedin.com/in/rdodin
[rd-twitter]: https://twitter.com/ntdvps
</div>
<div markdown>
Hey there! I'm Roman Dodin, a member of the SR Linux Product Management team at Nokia. Although I am much more often called a "[containerlab](https://containerlab.dev) guy" as I am one of the maintainers of the project.

Network automation, virtual networking labs and beautifully looking docs with reproducible examples are my passion. I am also a big fan of open source initiatives and community building.
</div>

</div>

<hr/>
3 changes: 1 addition & 2 deletions docs/blog/posts/2023/intent-based-ansible.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,10 @@ While sounding simple, this approach can become a maintenance nightmare as the n

This is when the second approach comes into play. It requires a deeper understanding of Ansible concepts, but it is more scalable and maintainable in the long run. The idea is to abstract the configuration tasks into reusable Ansible roles and use variables to pass the configuration parameters to the roles. This way, the playbook becomes a list of roles that are applied to the devices in the inventory.

When roles are designed in a way that make services provisioned on all the devices in the inventory, the playbook becomes an intent-based service provisioning tool[^1]. To provide a practical example of using Ansible to manage the configuration of an SR Linux fabric with the **intent-based approach** leveraging the official [Ansible collection for SR Linux][collection-doc-link] we created a comprehensive tutorial that covers A to Z the steps required to start managing a fabric in that way - **[:material-book: Intent-based management with Ansible][tutorial]** tutorial.
When roles are designed in a way that make services provisioned on all the devices in the inventory, the playbook becomes an intent-based service provisioning tool. To provide a practical example of using Ansible to manage the configuration of an SR Linux fabric with the **intent-based approach** leveraging the official [Ansible collection for SR Linux][collection-doc-link] we created a comprehensive tutorial that covers A to Z the steps required to start managing a fabric in that way - **[:material-book: Intent-based management with Ansible][tutorial]** tutorial.

We are eager to hear your thoughts on that approach and the tutorial itself. Please drop a comment below or open an issue in the [GitHub repository][intent-based-ansible-lab] if you have any questions or remarks.

[^1]: Granted the roles maintain inter-dependencies between infrastructure configuration resources, e.g. a network instance and its associated interfaces, routes, etc. and the services themselves.
[collection-doc-link]: ../../../ansible/collection/index.md
[intent-based-ansible-lab]: https://github.com/srl-labs/intent-based-ansible-lab
[tutorial]: ../../../tutorials/programmability/ansible/intent-based-management/index.md
1 change: 1 addition & 0 deletions docs/ndk/.meta.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
comments: true
25 changes: 16 additions & 9 deletions docs/ndk/guide/agent-install-and-ops.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
## Installing the agent
# Installing the agent

The onboarding of an NDK agent onto the SR Linux system is simply a task of copying [the agent and its files](agent.md) over to the SR Linux filesystem and placing them in the relevant directories.

Expand All @@ -20,15 +20,18 @@ The agent installation procedure can be carried out in different ways:
The first two options are easy to execute, but they are a bit more involved as the installers need to maintain the remote paths for the copy commands. When using the `rpm` option, though, it becomes less cumbersome to install the package. All the installers deal with is a single `.rpm` file and a copy command.
Of course, the build process of the `rpm` package is still required, and we would like to explain this process in detail.

### RPM package
## RPM package

One of the easiest ways to create an rpm, deb, or apk package is to use the [nFPM][nFPM] tool - a simple, 0-dependencies packager.

The only thing that nFPM requires of a user is to create a configuration file with the general instructions on how to build a package, and the rest will be taken care of.

#### nFPM installation
### nFPM installation

nFPM offers many [installation options](https://nfpm.goreleaser.com/install/) for all kinds of operating systems and environments. In the course of this guide, we will use the universal [nFPM docker image](https://nfpm.goreleaser.com/install/#running-with-docker).

#### nFPM configuration file
### nFPM configuration file

nFPM configuration file is the way of letting nFPM know how to build a package for the software artifacts that users created.

The complete list of options the `nfpm.yml` file can have is documented on the [project's site](https://nfpm.goreleaser.com/configuration/). Here we will have a look at the configuration file that is suitable for a typical NDK application written in Go.
Expand All @@ -54,7 +57,8 @@ contents: # contents to add to the package
dst: /etc/opt/srlinux/appmgr/ # destination path of agent yml
```
#### Running nFPM
### Running nFPM
When nFPM configuration and NDK agent files are present, proceed with building an `rpm` package.

Consider the following file layout:
Expand All @@ -81,7 +85,8 @@ docker run --rm -v $PWD:/tmp -w /tmp goreleaser/nfpm package \

This command will create `ndkDemo-1.0.0.x86_64.rpm` file in the current directory that can be copied over to the SR Linux system for installation.

#### Installing RPM
### Installing RPM

Delivering the available rpm package to a fleet of SR Linux boxes can be done with any configuration management tools. For demo purposes, we will utilize the `scp` utility:

```bash
Expand Down Expand Up @@ -149,10 +154,11 @@ All the agent components are available by the paths specified in the nFPM config

Congratulations, the agent has been installed successfully.

### Loading the agent
## Loading the agent

SR Linux's Application Manager is in charge of managing the applications lifecycle. App Manager controls both the native apps and customer-written agents.

After a user installs the agent on the SR Linux system by copying the relevant files, they need to reload the `app_mgr` process to detect new applications. App Manager gets to know about the available apps by reading the [app configuration files](agent.md#configuration-file) located at the following paths:
After a user installs the agent on the SR Linux system by copying the relevant files, they need to reload the `app_mgr` process to detect new applications. App Manager gets to know about the available apps by reading the [app configuration files](agent.md#application-manager-and-application-configuration-file) located at the following paths:

| Directory | Description |
| -------------------------- | ------------------------------ |
Expand All @@ -172,6 +178,7 @@ Once reloaded, App Manager will detect the new applications and load them accord
```

## Managing the agent's lifecycle

An application's lifecycle can be managed via any management interface by using the following knobs from the `tools` schema.

```
Expand All @@ -188,4 +195,4 @@ The commands that can be given to an application are translated to system signal
| `quit` | Send `SIGQUIT` signal to the app. Default behavior is to terminate the process and dump core info |
| `kill` | Send `SIGKILL` signal to the app. Kills the process without any cleanup |
[nFPM]: https://nfpm.goreleaser.com/
[nFPM]: https://nfpm.goreleaser.com/
134 changes: 101 additions & 33 deletions docs/ndk/guide/agent.md
Original file line number Diff line number Diff line change
@@ -1,56 +1,80 @@
As was explained in the [NDK Architecture](architecture.md) section, an agent[^1] is a custom software that can extend SR Linux capabilities by running alongside SR Linux native applications and performing some user-defined tasks.
---
comments: true
---

# Agent Structure

As was explained in the [NDK Architecture](architecture.md) section, an NDK agent[^10] is a custom software that can extend SR Linux capabilities by running alongside SR Linux's native applications and perform some user-defined work.

To deeply integrate with the rest of the SR Linux architecture, the agents have to be defined like an application that SR Linux's application manager can take control of. The structure of the agents is the main topic of this chapter.

<div class="grid" markdown>
<div markdown>
The main three components of an agent:

1. Agent's executable file
2. YANG module
3. Agent configuration file

## Executable file
1. An executable file
2. A YANG module
3. Application configuration file

An executable file is called when the agent starts running on SR Linux system. It contains the application logic and is typically an executable binary or a script.
SR Linux application manager (which is like `systemd`) onboards the NDK application by reading its configuration file and YANG models and then starts the agent's executable file. We will cover the role of each of these components in the subsequent sections of this chapter.

The application logic handles the agents' configuration that may be provided via any management interface (CLI, gNMI, etc.) and contains the core logic of interfacing with gRPC based NDK services.
</div>

In the subsequent sections of the Developers Guide, we will cover how to write the logic of an agent and interact with various NDK services.
```mermaid
flowchart TD
APPMGR[Application Manager] --> |Load App YAML| APP[NDK Application]
APPMGR[Application Manager] --> |Load App YANG| APP[NDK Application]
APP[NDK Application] --> EXEC(Started Executable)
```

An executable file can be placed at `/usr/local/bin` directory.
</div>

## YANG module
## Application manager and Application configuration file

SR Linux is a [fully modeled](../../yang/index.md) Network OS - any native or custom application that can be configured or can have state is required to have a proper YANG model.
Recall the decoupled nature of SR Linux's architecture where each application is a separate process. Application manager is the service that is responsible for starting, stopping, and restarting applications, as well as for monitoring their health.

The "cost" associated with requiring users to write YANG models for their apps pays off immensely as this
Both native SR Linux applications (AAA, LLDP, BGP, etc.) and NDK agents are managed by the application manager. Applications that are managed by the application manager should have a configuration file[^30] that describes the application and its lifecycle. For native SR Linux applications the app config files are located by the `/opt/srlinux/appmgr` path, and for NDK agents, the files are located by the `/etc/opt/srlinux/appmgr` path.

* enables seamless integration of an agent with **all** management interfaces: CLI, gNMI, JSON-RPC.
Any agent's configuration knobs that users expressed in YANG will be immediately available in the SR Linux CLI as if it was part of it from the beginning. Yes, with auto-suggestion of the fields as well.
* provides out-of-the-box Streaming Telemetry (gNMI) support for any config or state data that the agent maintains
With an agent's config file, users define properties of an application, for example:

And secondly, the YANG modules for custom apps are not that hard to write as their data model is typically relatively small.
* application version
* location of the executable file
* YANG modules related to this app
* lifecycle management policy

///note
The YANG module is only needed if a developer wants their agent to be configurable via any management interfaces or keep state.
///
NDK agents must have their config file present by the `/etc/opt/srlinux/appmgr` directory. It is a good idea to name the agent's config file after the agent's name; if we have the agent called `greeter`, then its config file can be named `greeter.yml` and stored by the `/etc/opt/srlinux/appmgr/greeter.yml` path.

YANG files related to an agent are typically located by the `/opt/$agentName/yang` path.
Let's have a look at configuration file for a simple `greeter` NDK written in Go:

## Configuration file
```yaml
greeter:
path: /usr/local/bin #(1)!
launch-command: greeter #(2)!
version-command: greeter --version #(3)!
failure-action: wait=10 #(4)!
config-delivery-format: json #(5)!
yang-modules:
names:
- "greeter" #(6)!
source-directories:
- "/opt/greeter/yang" #(7)!
```
Due to SR Linux modular architecture, each application, be it an internal app like `bgp` or a custom NDK agent, needs to have a configuration file. This file contains application parameters read by the Application Manager service to onboard the application onto the system.
1. The path to use when searching for the executable file.
2. The binary app manager will launch. Relative to the `path`.
3. The command to run to get the version of the application. The version can be seen in the output of `show / system application <app name>`.
4. An action to carry out when the application fails (non zero exit code). The action can be one of the following:
* `reboot` - reboot the system
* `wait=<seconds>` - wait for `<seconds>` and then restart the application
5. The encoding format of the application's configuration when it is delivered to the application by the Notification Service.

With an agent's config file, users define properties of an application, for example:
For NDK agents the recommended format is `json`.

* application version
* location of the executable file
* YANG modules related to this app
* lifecycle management policy
* and others
6. The names of the YANG modules to load. This is usually the file-name without `.yang` extension.

Custom agents must have their config file present by the `/etc/opt/srlinux/appmgr` directory. It is a good idea to name the agent's config file after the agent's name; if we have the agent called `myCoolAgent`, then its config file can be named `myCoolAgent.yml` and stored by the `/etc/opt/srlinux/appmgr` path.
The YANG modules are searched for in the directories specified by the `source-directories` property.

Through the subsequent chapters of the Developers Guide, we will cover the most important options, but here is a complete list of config file parameters:
7. The source directories where to search for the YANG modules.

///details | Complete list of config files parameters

Expand Down Expand Up @@ -140,10 +164,54 @@ other-application-name:

///

## Dependency and other files
When Application Manager is started/reloaded, it watches for application configuration files in the `/opt/srlinux/appmgr` and `/etc/opt/srlinux/appmgr` directories and starts managing the applications.

Let us now have a closer look at the main components of an agent and understand their role.

## YANG module

SR Linux is a [fully modeled](../../yang/index.md) Network OS - any native or custom application that can be configured or can have state is required to have a proper YANG model describing the data.

The "cost" associated with requiring application developers to write YANG models for their apps pays off immensely as this

* enables seamless application integration with **all** management interfaces: CLI, gNMI, JSON-RPC, etc.
Any agent's configuration knobs that users expressed in YANG will be immediately available in the SR Linux CLI as if it was part of it from the beginning. Yes, with auto-suggestion of the fields as well.
* provides out-of-the-box Streaming Telemetry (gNMI) support for any config or state data that the application maintains

And secondly, the YANG modules for custom apps are not that hard to write as their data model is typically relatively small.

///note
The YANG module is only needed if a developer wants their agent to be configurable via any management interfaces or keep state.
///

YANG files related to an agent are typically located by the `/opt/$agentName/yang` directory.

Consider the following YANG module for a simple `greeter` agent:

```{.yang title="yang/greeter.yang"}
--8<-- "https://raw.githubusercontent.com/srl-labs/ndk-greeter-go/main/yang/greeter.yang"
```

The YANG module defines a container called `greeter` with two leaf nodes: `name` and `greeting`. The `name` leaf is a configuration node, and the `greeting` leaf is a state node.

With this YANG module our application will populate the configuration datastore of SR Linux with `name` leaf and state datastore with `name` and `greeting` leaves.

## Executable file

Executable file is the main component of an agent as it contains the application logic. Depending on the language you choose to write your agent in, the executable file can be a binary or a script[^20].

The application logic handles the configuration that may be provided by users via any management interface (CLI, gNMI, etc.) and contains the core business logic of the application that may be triggered by some events from SR Linux service.

In the subsequent sections of the Developers Guide, we will dive into the details of how to write an sample NDK application in [Go](dev/go/index.md) and [Python](dev/py/index.md).

An executable file can be placed at `/usr/local/bin` directory.

## Auxiliary files

Quite often, an agent may require additional files for its operation. It can be a virtual environment for your Python agent or some JSON file that your agent consumes.

All those auxiliary files can be saved by the `/opt/$agentName/` directory.

[^1]: terms NDK agent and NDK app are used interchangeably
[^10]: terms agent and application are used interchangeably.
[^20]: Binaries are typically relevant for compiled languages like C, Go, Rust, etc. Scripts are typically relevant for interpreted languages like Python.
[^30]: Expressed in YAML format.
Loading

0 comments on commit fb11f2e

Please sign in to comment.