Skip to content

Commit

Permalink
Merge pull request #320 from Nordix/refactor-chains-options-pattern
Browse files Browse the repository at this point in the history
Refactor chains/forwarder to use Options pattern
  • Loading branch information
denis-tingaikin authored Apr 18, 2024
2 parents 9074299 + 2183c3f commit d21bcac
Show file tree
Hide file tree
Showing 3 changed files with 128 additions and 39 deletions.
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ require (
github.com/Mellanox/sriovnet v1.0.3-0.20210630121212-0453bd4b7fbc
github.com/edwarnicke/genericsync v0.0.0-20220910010113-61a344f9bc29
github.com/golang/protobuf v1.5.3
github.com/google/uuid v1.3.1
github.com/networkservicemesh/api v1.13.1-0.20240411170402-f357d8c715a2
github.com/networkservicemesh/sdk v0.5.1-0.20240418094831-608b1b518564
github.com/networkservicemesh/sdk-kernel v0.0.0-20240418095606-2a4c66902432
Expand Down Expand Up @@ -48,7 +49,6 @@ require (
github.com/google/go-cmp v0.6.0 // indirect
github.com/google/gofuzz v1.2.0 // indirect
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
github.com/google/uuid v1.3.1 // indirect
github.com/googleapis/gnostic v0.5.5 // indirect
github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0 // indirect
github.com/imdario/mergo v0.3.12 // indirect
Expand Down
85 changes: 83 additions & 2 deletions pkg/networkservice/chains/forwarder/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,19 +20,100 @@
package forwarder

import (
"net/url"
"time"

"google.golang.org/grpc"

"github.com/networkservicemesh/api/pkg/api/networkservice"

"github.com/networkservicemesh/sdk-ovs/pkg/networkservice/mechanisms/vxlan"
)

type forwarderOptions struct {
vxlanOpts []vxlan.Option
dialOpts []grpc.DialOption
name string
bridgeName string
authorizeServer networkservice.NetworkServiceServer
authorizeMonitorConnectionServer networkservice.MonitorConnectionServer
resourcePoolServer networkservice.NetworkServiceServer
resourcePoolClient networkservice.NetworkServiceClient
clientURL *url.URL
dialTimeout time.Duration
vxlanOpts []vxlan.Option
dialOpts []grpc.DialOption
}

// Option is an option pattern for forwarder chain elements
type Option func(o *forwarderOptions)

// WithName sets forwarder name
func WithName(name string) Option {
return func(o *forwarderOptions) {
o.name = name
}
}

// WithBridgeName sets bridge name
func WithBridgeName(bridgeName string) Option {
return func(o *forwarderOptions) {
o.bridgeName = bridgeName
}
}

// WithAuthorizeServer sets authorization server chain element
func WithAuthorizeServer(authorizeServer networkservice.NetworkServiceServer) Option {
if authorizeServer == nil {
panic("Authorize server cannot be nil")
}
return func(o *forwarderOptions) {
o.authorizeServer = authorizeServer
}
}

// WithAuthorizeMonitorConnectionServer sets authorization server chain element
func WithAuthorizeMonitorConnectionServer(authorizeMonitorConnectionServer networkservice.MonitorConnectionServer) Option {
if authorizeMonitorConnectionServer == nil {
panic("Authorize monitor server cannot be nil")
}
return func(o *forwarderOptions) {
o.authorizeMonitorConnectionServer = authorizeMonitorConnectionServer
}
}

// WithResourcePoolServer sets resource pool server
func WithResourcePoolServer(resourcePoolServer networkservice.NetworkServiceServer) Option {
if resourcePoolServer == nil {
panic("Authorize server cannot be nil")
}
return func(o *forwarderOptions) {
o.resourcePoolServer = resourcePoolServer
}
}

// WithResourcePoolClient sets resource pool client
func WithResourcePoolClient(resourcePoolClient networkservice.NetworkServiceClient) Option {
if resourcePoolClient == nil {
panic("Authorize server cannot be nil")
}
return func(o *forwarderOptions) {
o.resourcePoolClient = resourcePoolClient
}
}

// WithClientURL sets clientURL.
func WithClientURL(clientURL *url.URL) Option {
return func(c *forwarderOptions) {
c.clientURL = clientURL
}
}

// WithDialTimeout sets dial timeout for the client
func WithDialTimeout(dialTimeout time.Duration) Option {
return func(o *forwarderOptions) {
o.dialTimeout = dialTimeout
}
}

// WithVxlanOptions sets vxlan option
func WithVxlanOptions(opts ...vxlan.Option) Option {
return func(o *forwarderOptions) {
Expand Down
80 changes: 44 additions & 36 deletions pkg/networkservice/chains/forwarder/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ import (
"sync"
"time"

"github.com/google/uuid"

"github.com/networkservicemesh/api/pkg/api/networkservice"
kernelmech "github.com/networkservicemesh/api/pkg/api/networkservice/mechanisms/kernel"
vxlanmech "github.com/networkservicemesh/api/pkg/api/networkservice/mechanisms/vxlan"
Expand All @@ -42,6 +44,7 @@ import (
"github.com/networkservicemesh/sdk-sriov/pkg/sriov/config"
"github.com/networkservicemesh/sdk/pkg/networkservice/chains/client"
"github.com/networkservicemesh/sdk/pkg/networkservice/chains/endpoint"
"github.com/networkservicemesh/sdk/pkg/networkservice/common/authorize"
"github.com/networkservicemesh/sdk/pkg/networkservice/common/connect"
"github.com/networkservicemesh/sdk/pkg/networkservice/common/discover"
"github.com/networkservicemesh/sdk/pkg/networkservice/common/filtermechanisms"
Expand All @@ -54,6 +57,7 @@ import (
"github.com/networkservicemesh/sdk/pkg/networkservice/common/switchcase"
"github.com/networkservicemesh/sdk/pkg/networkservice/core/chain"
"github.com/networkservicemesh/sdk/pkg/networkservice/utils/metadata"
authmonitor "github.com/networkservicemesh/sdk/pkg/tools/monitorconnection/authorize"
"github.com/networkservicemesh/sdk/pkg/tools/token"

"github.com/networkservicemesh/sdk-ovs/pkg/networkservice/l2ovsconnect"
Expand All @@ -68,33 +72,39 @@ type ovsConnectNSServer struct {
}

// NewSriovServer - returns sriov implementation of the ovsconnectns network service
func NewSriovServer(ctx context.Context, name string, authzServer networkservice.NetworkServiceServer,
authzMonitorServer networkservice.MonitorConnectionServer, tokenGenerator token.GeneratorFunc,
clientURL *url.URL, bridgeName string, tunnelIPCidr net.IP, pciPool resourcepool.PCIPool,
resourcePool resourcepool.ResourcePool, sriovConfig *config.Config, dialTimeout time.Duration,
l2Connections map[string]*ovsutil.L2ConnectionPoint, options ...Option) (endpoint.Endpoint, error) {
func NewSriovServer(ctx context.Context, tokenGenerator token.GeneratorFunc, tunnelIPCidr net.IP,
pciPool resourcepool.PCIPool, resourcePool resourcepool.ResourcePool, sriovConfig *config.Config,
l2Connections map[string]*ovsutil.L2ConnectionPoint, options ...Option,
) (endpoint.Endpoint, error) {
resourceLock := &sync.Mutex{}
resourcePoolClient := resourcepool.NewClient(sriov.KernelDriver, resourceLock, pciPool, resourcePool, sriovConfig)
resourcePoolServer := resourcepool.NewServer(sriov.KernelDriver, resourceLock, pciPool, resourcePool, sriovConfig)
options = append(options, WithResourcePoolServer(resourcePoolServer), WithResourcePoolClient(resourcePoolClient))

return newEndPoint(ctx, name, authzMonitorServer, authzServer, resourcePoolServer, resourcePoolClient, tokenGenerator,
clientURL, bridgeName, tunnelIPCidr, dialTimeout, l2Connections, options...)
return newEndPoint(ctx, tokenGenerator, tunnelIPCidr, l2Connections, options...)
}

func newEndPoint(ctx context.Context, name string, authzMonitorServer networkservice.MonitorConnectionServer,
authzServer, resourcePoolServer networkservice.NetworkServiceServer,
resourcePoolClient networkservice.NetworkServiceClient, tokenGenerator token.GeneratorFunc, clientURL *url.URL,
bridgeName string, tunnelIPCidr net.IP, dialTimeout time.Duration, l2Connections map[string]*ovsutil.L2ConnectionPoint,
options ...Option) (endpoint.Endpoint, error) {
opts := &forwarderOptions{}
func newEndPoint(ctx context.Context, tokenGenerator token.GeneratorFunc, tunnelIPCidr net.IP,
l2Connections map[string]*ovsutil.L2ConnectionPoint, options ...Option,
) (endpoint.Endpoint, error) {
opts := &forwarderOptions{
name: "forwarder-ovs-" + uuid.New().String(),
bridgeName: "br-nsm",
authorizeServer: authorize.NewServer(authorize.Any()),
authorizeMonitorConnectionServer: authmonitor.NewMonitorConnectionServer(authmonitor.Any()),
resourcePoolServer: null.NewServer(),
resourcePoolClient: null.NewClient(),
clientURL: &url.URL{Scheme: "unix", Host: "connect.to.socket"},
dialTimeout: time.Millisecond * 200,
}
for _, opt := range options {
opt(opts)
}
tunnelIP, err := ovsutil.ParseTunnelIP(tunnelIPCidr)
if err != nil {
return nil, err
}
err = ovsutil.ConfigureOvS(ctx, l2Connections, bridgeName)
err = ovsutil.ConfigureOvS(ctx, l2Connections, opts.bridgeName)
if err != nil {
return nil, err
}
Expand All @@ -107,12 +117,12 @@ func newEndPoint(ctx context.Context, name string, authzMonitorServer networkser
rv := &ovsConnectNSServer{}

nseClient := registryclient.NewNetworkServiceEndpointRegistryClient(ctx,
registryclient.WithClientURL(clientURL),
registryclient.WithClientURL(opts.clientURL),
registryclient.WithNSEAdditionalFunctionality(registryrecvfd.NewNetworkServiceEndpointRegistryClient()),
registryclient.WithDialOptions(opts.dialOpts...),
)
nsClient := registryclient.NewNetworkServiceRegistryClient(ctx,
registryclient.WithClientURL(clientURL),
registryclient.WithClientURL(opts.clientURL),
registryclient.WithDialOptions(opts.dialOpts...))

additionalFunctionality := []networkservice.NetworkServiceServer{
Expand All @@ -128,35 +138,35 @@ func newEndPoint(ctx context.Context, name string, authzMonitorServer networkser
return sriovtokens.IsTokenID(kernelmech.ToMechanism(conn.GetMechanism()).GetDeviceTokenID())
},
Server: chain.NewNetworkServiceServer(
resourcePoolServer,
kernel.NewSmartVFServer(bridgeName, parentIfMutex, parentIfRefCount),
opts.resourcePoolServer,
kernel.NewSmartVFServer(opts.bridgeName, parentIfMutex, parentIfRefCount),
),
},
&switchcase.ServerCase{
Condition: switchcase.Default,
Server: kernel.NewVethServer(bridgeName, parentIfMutex, parentIfRefCount),
Server: kernel.NewVethServer(opts.bridgeName, parentIfMutex, parentIfRefCount),
},
),
vxlanmech.MECHANISM: vxlan.NewServer(tunnelIP, bridgeName, vxlanInterfacesMutex, vxlanInterfaces, opts.vxlanOpts...),
vxlanmech.MECHANISM: vxlan.NewServer(tunnelIP, opts.bridgeName, vxlanInterfacesMutex, vxlanInterfaces, opts.vxlanOpts...),
}),
inject.NewServer(),
connectioncontextkernel.NewServer(),
connect.NewServer(
client.NewClient(ctx,
client.WithoutRefresh(),
client.WithName(name),
client.WithName(opts.name),
client.WithDialOptions(opts.dialOpts...),
client.WithDialTimeout(dialTimeout),
client.WithDialTimeout(opts.dialTimeout),
client.WithAdditionalFunctionality(
mechanismtranslation.NewClient(),
l2ovsconnect.NewClient(bridgeName),
l2ovsconnect.NewClient(opts.bridgeName),
connectioncontextkernel.NewClient(),
inject.NewClient(),
// mechanisms
kernel.NewClient(bridgeName, parentIfMutex, parentIfRefCount),
resourcePoolClient,
vxlan.NewClient(tunnelIP, bridgeName, vxlanInterfacesMutex, vxlanInterfaces, opts.vxlanOpts...),
vlan.NewClient(bridgeName, l2Connections),
kernel.NewClient(opts.bridgeName, parentIfMutex, parentIfRefCount),
opts.resourcePoolClient,
vxlan.NewClient(tunnelIP, opts.bridgeName, vxlanInterfacesMutex, vxlanInterfaces, opts.vxlanOpts...),
vlan.NewClient(opts.bridgeName, l2Connections),
filtermechanisms.NewClient(),
recvfd.NewClient(),
sendfd.NewClient(),
Expand All @@ -166,19 +176,17 @@ func newEndPoint(ctx context.Context, name string, authzMonitorServer networkser
}

rv.Endpoint = endpoint.NewServer(ctx, tokenGenerator,
endpoint.WithName(name),
endpoint.WithAuthorizeServer(authzServer),
endpoint.WithAuthorizeMonitorConnectionServer(authzMonitorServer),
endpoint.WithName(opts.name),
endpoint.WithAuthorizeServer(opts.authorizeServer),
endpoint.WithAuthorizeMonitorConnectionServer(opts.authorizeMonitorConnectionServer),
endpoint.WithAdditionalFunctionality(additionalFunctionality...))

return rv, nil
}

// NewKernelServer - returns kernel implementation of the ovsconnectns network service
func NewKernelServer(ctx context.Context, name string, authzServer networkservice.NetworkServiceServer,
authzMonitorServer networkservice.MonitorConnectionServer, tokenGenerator token.GeneratorFunc,
clientURL *url.URL, bridgeName string, tunnelIPCidr net.IP, dialTimeout time.Duration,
l2Connections map[string]*ovsutil.L2ConnectionPoint, options ...Option) (endpoint.Endpoint, error) {
return newEndPoint(ctx, name, authzMonitorServer, authzServer, null.NewServer(), null.NewClient(), tokenGenerator,
clientURL, bridgeName, tunnelIPCidr, dialTimeout, l2Connections, options...)
func NewKernelServer(ctx context.Context, tokenGenerator token.GeneratorFunc, tunnelIPCidr net.IP,
l2Connections map[string]*ovsutil.L2ConnectionPoint, options ...Option,
) (endpoint.Endpoint, error) {
return newEndPoint(ctx, tokenGenerator, tunnelIPCidr, l2Connections, options...)
}

0 comments on commit d21bcac

Please sign in to comment.