Skip to content

Commit

Permalink
add grpcmetadata chain element and unit test
Browse files Browse the repository at this point in the history
Signed-off-by: Nikita Skrynnik <nikita.skrynnik@xored.com>
  • Loading branch information
NikitaSkrynnik committed Oct 12, 2022
1 parent 654a02d commit 86de6da
Show file tree
Hide file tree
Showing 5 changed files with 210 additions and 10 deletions.
52 changes: 52 additions & 0 deletions pkg/registry/common/grpcmetadata/ns_client.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
// Copyright (c) 2022 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 authorize provides authz checks for incoming or returning connections.
package grpcmetadata

import (
"context"

"github.com/golang/protobuf/ptypes/empty"
"google.golang.org/grpc"

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

"github.com/networkservicemesh/sdk/pkg/registry/core/next"
"google.golang.org/grpc/metadata"
)

type grpcMetadataNSClient struct {
}

func NewNetworkServiceRegistryClient() registry.NetworkServiceRegistryClient {
return &grpcMetadataNSClient{}
}

func (s *grpcMetadataNSClient) Register(ctx context.Context, ns *registry.NetworkService, opts ...grpc.CallOption) (*registry.NetworkService, error) {
md := metadata.New(map[string]string{})
md["hello"] = []string{"world"}
ctx = metadata.NewOutgoingContext(ctx, md)
return next.NetworkServiceRegistryClient(ctx).Register(ctx, ns, opts...)
}

func (s *grpcMetadataNSClient) Find(ctx context.Context, query *registry.NetworkServiceQuery, opts ...grpc.CallOption) (registry.NetworkServiceRegistry_FindClient, error) {
return next.NetworkServiceRegistryClient(ctx).Find(ctx, query, opts...)
}

func (s *grpcMetadataNSClient) Unregister(ctx context.Context, ns *registry.NetworkService, opts ...grpc.CallOption) (*empty.Empty, error) {
return next.NetworkServiceRegistryClient(ctx).Unregister(ctx, ns, opts...)
}
70 changes: 70 additions & 0 deletions pkg/registry/common/grpcmetadata/ns_client_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
// Copyright (c) 2022 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 grpcmetadata_test

import (
"context"
"net"
"testing"

"github.com/networkservicemesh/api/pkg/api/registry"
"github.com/networkservicemesh/sdk/pkg/registry/common/grpcmetadata"
"github.com/networkservicemesh/sdk/pkg/registry/common/updatepath"
"github.com/networkservicemesh/sdk/pkg/registry/core/next"
"github.com/stretchr/testify/require"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"

"go.uber.org/goleak"
)

func TestAuthzNetworkServiceRegistry(t *testing.T) {
t.Cleanup(func() { goleak.VerifyNone(t) })

ctx := context.Background()

address := "localhost:45000"
lis, err := net.Listen("tcp", address)
require.NoError(t, err)

server := next.NewNetworkServiceRegistryServer(
grpcmetadata.NewNetworkServiceRegistryServer(),
updatepath.NewNetworkServiceRegistryServer("server"),
)

grpcServer := grpc.NewServer()
registry.RegisterNetworkServiceRegistryServer(grpcServer, server)
go func() {
err := grpcServer.Serve(lis)
require.NoError(t, err)
}()

conn, err := grpc.Dial(address, grpc.WithTransportCredentials(insecure.NewCredentials()))
require.NoError(t, err)
defer conn.Close()

client := next.NewNetworkServiceRegistryClient(
grpcmetadata.NewNetworkServiceRegistryClient(),
updatepath.NewNetworkServiceRegistryClient("client"),
registry.NewNetworkServiceRegistryClient(conn))

ns := &registry.NetworkService{Name: "ns"}
ns, err = client.Register(ctx, ns)
require.NoError(t, err)

grpcServer.Stop()
}
55 changes: 55 additions & 0 deletions pkg/registry/common/grpcmetadata/ns_server.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
// Copyright (c) 2022 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 authorize provides authz checks for incoming or returning connections.
package grpcmetadata

import (
"context"
"fmt"

"github.com/golang/protobuf/ptypes/empty"
"google.golang.org/grpc/metadata"

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

"github.com/networkservicemesh/sdk/pkg/registry/core/next"
)

type grpcMetadataNSServer struct {
}

// NewNetworkServiceRegistryServer - returns a new authorization registry.NetworkServiceRegistryServer
// Authorize registry server checks spiffeID of NS.
func NewNetworkServiceRegistryServer() registry.NetworkServiceRegistryServer {
return &grpcMetadataNSServer{}
}

func (s *grpcMetadataNSServer) Register(ctx context.Context, ns *registry.NetworkService) (*registry.NetworkService, error) {
md, loaded := metadata.FromIncomingContext(ctx)

fmt.Printf("md: %v\n", md)
fmt.Printf("loaded: %v\n", loaded)
return next.NetworkServiceRegistryServer(ctx).Register(ctx, ns)
}

func (s *grpcMetadataNSServer) Find(query *registry.NetworkServiceQuery, server registry.NetworkServiceRegistry_FindServer) error {
return next.NetworkServiceRegistryServer(server.Context()).Find(query, server)
}

func (s *grpcMetadataNSServer) Unregister(ctx context.Context, ns *registry.NetworkService) (*empty.Empty, error) {
return next.NetworkServiceRegistryServer(ctx).Unregister(ctx, ns)
}
21 changes: 15 additions & 6 deletions pkg/registry/common/updatepath/ns_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,16 @@ package updatepath

import (
"context"
"encoding/json"

"github.com/golang/protobuf/ptypes/empty"
"github.com/pkg/errors"
"google.golang.org/grpc"
"google.golang.org/grpc/metadata"

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

"github.com/networkservicemesh/sdk/pkg/registry/core/next"
"github.com/networkservicemesh/sdk/pkg/tools/log"
)

type updatePathNSClient struct {
Expand All @@ -40,17 +42,24 @@ func NewNetworkServiceRegistryClient(name string) registry.NetworkServiceRegistr
}

func (s *updatePathNSClient) Register(ctx context.Context, ns *registry.NetworkService, opts ...grpc.CallOption) (*registry.NetworkService, error) {
log.FromContext(ctx).Infof("updatepath opts: %v", opts)
if ns.Path == nil {
ns.Path = &registry.Path{}
md, loaded := metadata.FromOutgoingContext(ctx)
if !loaded {
return nil, errors.New("failed to load grpc metadata from context")
}

path, index, err := updatePath(ns.Path, s.name)
path := &registry.Path{}

path, index, err := updatePath(path, s.name)
if err != nil {
return nil, err
}

ns.Path = path
bytes, err := json.Marshal(path)
v := []string{string(bytes)}
md["path"] = v

ctx = metadata.AppendToOutgoingContext(ctx, "path", string(bytes))

ns, err = next.NetworkServiceRegistryClient(ctx).Register(ctx, ns, opts...)
if err != nil {
return nil, err
Expand Down
22 changes: 18 additions & 4 deletions pkg/registry/common/updatepath/ns_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,11 @@ package updatepath

import (
"context"
"encoding/json"

"github.com/golang/protobuf/ptypes/empty"
"github.com/pkg/errors"
"google.golang.org/grpc/metadata"

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

Expand All @@ -39,16 +42,27 @@ func NewNetworkServiceRegistryServer(name string) registry.NetworkServiceRegistr
}

func (s *updatePathNSServer) Register(ctx context.Context, ns *registry.NetworkService) (*registry.NetworkService, error) {
if ns.Path == nil {
ns.Path = &registry.Path{}
md, loaded := metadata.FromIncomingContext(ctx)
if !loaded {
return nil, errors.New("failed to load grpc metadata from context")
}

path, index, err := updatePath(ns.Path, s.name)
pathValue, loaded := md["path"]
if !loaded {
return nil, errors.New("failed to load path from grpc metadata")
}

path := &registry.Path{}
err := json.Unmarshal([]byte(pathValue[0]), path)
if err != nil {
return nil, err
}

path, index, err := updatePath(path, s.name)
if err != nil {
return nil, err
}

ns.Path = path
ns, err = next.NetworkServiceRegistryServer(ctx).Register(ctx, ns)
if err != nil {
return nil, err
Expand Down

0 comments on commit 86de6da

Please sign in to comment.