Skip to content

Commit

Permalink
Initial (very rough) nsmgr chain
Browse files Browse the repository at this point in the history
This lays down a pattern for providing the Nsmgr chain.

Signed-off-by: Ed Warnicke <hagbard@gmail.com>
  • Loading branch information
edwarnicke committed Mar 30, 2020
1 parent ca0b7c9 commit 2c0a3a2
Show file tree
Hide file tree
Showing 3 changed files with 191 additions and 0 deletions.
4 changes: 4 additions & 0 deletions .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -205,3 +205,7 @@ issues:
linters:
- interfacer
text: "can be `fmt.Stringer`"
- path: pkg/networkservice/chains/nsmgr/peertracker/server.go
linters:
- interfacer
text: "can be `fmt.Stringer`"
111 changes: 111 additions & 0 deletions pkg/networkservice/chains/nsmgr/peertracker/server.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
// Copyright (c) 2020 Cisco and/or its affiliates.
//
// SPDX-License-Identifier: Apache-2.0
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at:
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// Package peertracker provides a wrapper for a Nsmgr that tracks connections received from local Clients
// Its designed to be used in a DevicePlugin to allow us to properly Close connections on re-Allocate
package peertracker

import (
"context"
"net/url"

"github.com/golang/protobuf/ptypes/empty"
"github.com/networkservicemesh/api/pkg/api/networkservice"
"google.golang.org/grpc/peer"

"github.com/networkservicemesh/sdk/pkg/networkservice/chains/nsmgr"
"github.com/networkservicemesh/sdk/pkg/tools/serialize"
)

const (
unixScheme = "unix"
)

type peerTrackerServer struct {
nsmgr.Nsmgr
executor serialize.Executor
// Outer map is peer url.URL.String(), inner map key is Connection.Id
connections map[string]map[string]*networkservice.Connection
}

// NewServer - Creates a new peer tracker Server
// inner - Nsmgr being wrapped
// closeAll - pointer to memory location to which you should write a pointer to the function to be called
// to close all connections for the provided url (presuming a unix URL)
func NewServer(inner nsmgr.Nsmgr, closeAll *func(ctx context.Context, u *url.URL)) nsmgr.Nsmgr {
rv := &peerTrackerServer{
connections: make(map[string]map[string]*networkservice.Connection),
Nsmgr: inner,
}
*closeAll = rv.closeAllConnectionsForPeer
return rv
}

func (p *peerTrackerServer) Request(ctx context.Context, request *networkservice.NetworkServiceRequest) (*networkservice.Connection, error) {
conn, err := p.Nsmgr.Request(ctx, request)
if err != nil {
return nil, err
}
mypeer, ok := peer.FromContext(ctx)
if ok {
if mypeer.Addr.Network() == unixScheme {
u := &url.URL{
Scheme: mypeer.Addr.Network(),
Path: mypeer.Addr.String(),
}
p.executor.AsyncExec(func() {
_, ok := p.connections[u.String()]
if !ok {
p.connections[u.String()] = make(map[string]*networkservice.Connection)
}
p.connections[u.String()][conn.GetId()] = conn
})
}
}
return conn, nil
}

func (p *peerTrackerServer) Close(ctx context.Context, conn *networkservice.Connection) (*empty.Empty, error) {
_, err := p.Nsmgr.Close(ctx, conn)
if err != nil {
return nil, err
}
mypeer, ok := peer.FromContext(ctx)
if ok {
if mypeer.Addr.Network() == unixScheme {
u := &url.URL{
Scheme: mypeer.Addr.Network(),
Path: mypeer.Addr.String(),
}
p.executor.AsyncExec(func() {
delete(p.connections[u.String()], conn.GetId())
})
}
}
return &empty.Empty{}, nil
}

func (p *peerTrackerServer) closeAllConnectionsForPeer(ctx context.Context, u *url.URL) {
finishedChan := make(chan struct{})
<-p.executor.AsyncExec(func() {
if connMap, ok := p.connections[u.String()]; ok {
for _, conn := range connMap {
_, _ = p.Close(ctx, conn)
}
}
close(finishedChan)
})
}
76 changes: 76 additions & 0 deletions pkg/networkservice/chains/nsmgr/server.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
// Copyright (c) 2020 Cisco and/or its affiliates.
//
// SPDX-License-Identifier: Apache-2.0
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at:
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// Package nsmgr provides a Network Service Manager (nsmgr), but interface and implementation
package nsmgr

import (
"github.com/networkservicemesh/api/pkg/api/registry"
"github.com/open-policy-agent/opa/rego"
"google.golang.org/grpc"

"github.com/networkservicemesh/sdk/pkg/networkservice/chains/client"
"github.com/networkservicemesh/sdk/pkg/networkservice/chains/endpoint"
"github.com/networkservicemesh/sdk/pkg/networkservice/common/connect"
"github.com/networkservicemesh/sdk/pkg/networkservice/common/discover"
"github.com/networkservicemesh/sdk/pkg/networkservice/common/localbypass"
"github.com/networkservicemesh/sdk/pkg/networkservice/common/roundrobin"
"github.com/networkservicemesh/sdk/pkg/networkservice/core/adapters"
adapter_registry "github.com/networkservicemesh/sdk/pkg/registry/core/adapters"
chain_registry "github.com/networkservicemesh/sdk/pkg/registry/core/chain"
"github.com/networkservicemesh/sdk/pkg/tools/addressof"
)

// Nsmgr - A simple combintation of the Endpoint, registry.NetworkServiceRegistryServer, and registry.NetworkServiceDiscoveryServer interfaces
type Nsmgr interface {
endpoint.Endpoint
registry.NetworkServiceRegistryServer
registry.NetworkServiceDiscoveryServer
}

type nsmgr struct {
endpoint.Endpoint
registry.NetworkServiceRegistryServer
registry.NetworkServiceDiscoveryServer
}

// NewServer - Creates a new Nsmgr
// name - name of the Nsmgr
// authzPolicy - authorization policy
// registryCC - client connection to reach the upstream registry
func NewServer(name string, authzPolicy *rego.PreparedEvalQuery, registryCC grpc.ClientConnInterface) Nsmgr {
rv := &nsmgr{}
rv.Endpoint = endpoint.NewServer(
name,
authzPolicy,
discover.NewServer(registry.NewNetworkServiceDiscoveryClient(registryCC)),
roundrobin.NewServer(),
localbypass.NewServer(&rv.NetworkServiceRegistryServer),
connect.NewServer(client.NewClientFactory(name, addressof.NetworkServiceClient(adapters.NewServerToClient(rv)))),
)
rv.NetworkServiceRegistryServer = chain_registry.NewRegistryServer(
rv.NetworkServiceRegistryServer,
adapter_registry.NewRegistryClientToServer(registry.NewNetworkServiceRegistryClient(registryCC)),
)
rv.NetworkServiceDiscoveryServer = adapter_registry.NewDiscoveryClientToServer(registry.NewNetworkServiceDiscoveryClient(registryCC))
return rv
}

func (n *nsmgr) Register(s *grpc.Server) {
n.Endpoint.Register(s)
registry.RegisterNetworkServiceRegistryServer(s, n)
registry.RegisterNetworkServiceDiscoveryServer(s, n)
}

0 comments on commit 2c0a3a2

Please sign in to comment.