Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add article about creating NSEs #266

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion content/docs/concepts/features.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,5 @@ date = "2023-06-24"
Since NSM can run in any environment, here is described only concepts of the available functionality.

- [Healing](../features/healing)
- [Datapath Healing](../features/datapath_healing)
- [Datapath Healing](../features/datapath_healing)
- [Development of Network Service Mesh Endpoint](../features/develop_nse)
128 changes: 128 additions & 0 deletions content/docs/concepts/features/develop_nse.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
+++
title = "Development of Network Service Endpoint"
description = "Concept of development NSE"
short = "devnse"
date = "2022-11-29"
+++


# Development of Network Service Mesh Endpoint

## Description

Working with Network Service Mesh involves developing endpoints that set up and configure the network service. Specifically, in this article, we will only touch on the aspect of creating network points; more details about end points can be found [here](https://networkservicemesh.io/docs/concepts/architecture/#endpoints). Basic endpoints can be developed following the NSM protocol, using SDK and also using nsmctl.

## Concept

The endpoint is responsible for the following connection fields:

Select the connection mechanism for its forwarder.

**ConnectionContext** where the endpoint has the right to control:
- **IPContext** - responsible for IP addresses for the client, endpoint, routes, prefixes, neighbors, and policy-based routing
- **DNSContext** - is responsible for setting up the DNS servers serving the connection.
- **EthernetContext** - allows you to control the poppy address for the client and endpoint interfaces, as well as set the vlan tag.
- **ExtraContext** - allows you to set your own parameters involved in the connection.

### Chain element

A chain element is a small piece of logic that processes part of an NSM request, which usually performs exactly one function.

For example, the chain element [timeout](https://github.com/networkservicemesh/sdk/blob/main/pkg/networkservice/common/timeout/server.go) closes the connection if the connection has expired.

To develop a chain element for an endpoint, you need to implement the Go interface.
```go
// NetworkServiceServer is the server API for NetworkService service.
type NetworkServiceServer interface {
Request(context.Context, *NetworkServiceRequest) (*Connection, error)
Close(context.Context, *Connection) (*emptypb.Empty, error)
}
```
Next, the package with the chained element can be included in the existing NSE chain or a new chain can be created.

For example, here is an example of creating a simple chain element that captures total requests and close for the NSE.
```go
package count

import (
"sync/atomic"
"github.com/sirupsen/logrus"
)

type myCountServer struct{
closes, requests int32
}
// Close performs close and increments request count
func (s *myCountServer) Request(ctx context.Context, request *networkservice.NetworkServiceRequest) (*networkservice.Connection, error) {
atomic.AddInt32(&s.requests, 1)
logrus.Infof("total request count: %v", s.requests)
return next.Server(ctx).Request(ctx, request)
}

func NewServer() NetworkServiceServer {
return new(myCountServer)
}

// Close performs close and increments closes count
func (s *myCountServer) Close(ctx context.Context, connection *networkservice.Connection) (*empty.Empty, error) {
atomic.AddInt32(&s.closes, 1)
logrus.Infof("total close count: %v", s.requests)
return next.Server(ctx).Close(ctx, connection)
}
```

A chain can be created using the chain elements [chain](https://github.com/networkservicemesh/sdk/tree/main/pkg/networkservice/core/chain) or [next](https://github.com/networkservicemesh/sdk/tree/main/pkg/networkservice/core/next). The difference between these chain elements is that when using `chain` logging will be added.


For example, for the example above we can create the following chain:

```go

var myChain = chain.NewServer(
count.NewServer(),
timeout.NewServer()
...
)
```

Look at the usage of chains in these repositories: https://github.com/networkservicemesh?q=nse-&type=all&language=&sort=



### Develop a new Network Service Endpoint with using `nsmctl`

To simplify the work of creating new endpoints, we have an experimental utility called `nsmctl`. Which allows you to generate folders for endpoints.

Requirements:
1. Install Go: https://go.dev/doc/install
2. Install nsmctl: go install github.com/networkservicemesh/nsmctl@latest


Once everything is installed, go to your go projects folder [GOPATH](https://go.dev/doc/code).

Next, create a folder with your NSE project:
```bash
nsmctl generate endpoint --name my-first-nse --path my-first-nse --go 1.20
```

After which, the folder my-first-nse will be created, where the starting files for developing your NSE project will be located.

```
my-first-nse
│ deployment.yaml
│ main.go
| Dockerfile
└───internal
└───pkg
└───imports
└───imports.go
```


Please note that generation is an experimental feature and errors may occur.

## References

1. https://github.com/networkservicemesh/api/blob/main/pkg/api/networkservice/connectioncontext.proto
2. https://networkservicemesh.io/docs/concepts/architecture/#endpoints
3. https://github.com/networkservicemesh/nsmctl