From e129caab480927deb5e00e26ad86bc9079735772 Mon Sep 17 00:00:00 2001 From: Denis Tingaikin Date: Thu, 14 Jul 2022 04:14:06 +0300 Subject: [PATCH] add cluster-info chain elements Signed-off-by: Denis Tingaikin --- .../chains/nsmgrproxy/server.go | 4 ++ .../common/clusterinfo/options.go | 27 +++++++ .../common/clusterinfo/server.go | 66 +++++++++++++++++ .../common/clusterinfo/server_test.go | 46 ++++++++++++ pkg/registry/common/clusterinfo/nse_server.go | 70 +++++++++++++++++++ .../common/clusterinfo/nse_server_test.go | 49 +++++++++++++ pkg/registry/common/clusterinfo/options.go | 27 +++++++ 7 files changed, 289 insertions(+) create mode 100644 pkg/networkservice/common/clusterinfo/options.go create mode 100644 pkg/networkservice/common/clusterinfo/server.go create mode 100644 pkg/networkservice/common/clusterinfo/server_test.go create mode 100644 pkg/registry/common/clusterinfo/nse_server.go create mode 100644 pkg/registry/common/clusterinfo/nse_server_test.go create mode 100644 pkg/registry/common/clusterinfo/options.go diff --git a/pkg/networkservice/chains/nsmgrproxy/server.go b/pkg/networkservice/chains/nsmgrproxy/server.go index e4e007d7f..6c19a0d68 100644 --- a/pkg/networkservice/chains/nsmgrproxy/server.go +++ b/pkg/networkservice/chains/nsmgrproxy/server.go @@ -33,6 +33,7 @@ import ( "github.com/networkservicemesh/sdk/pkg/networkservice/chains/endpoint" "github.com/networkservicemesh/sdk/pkg/networkservice/chains/nsmgr" "github.com/networkservicemesh/sdk/pkg/networkservice/common/authorize" + "github.com/networkservicemesh/sdk/pkg/networkservice/common/clusterinfo" "github.com/networkservicemesh/sdk/pkg/networkservice/common/connect" "github.com/networkservicemesh/sdk/pkg/networkservice/common/discover" "github.com/networkservicemesh/sdk/pkg/networkservice/common/interdomainbypass" @@ -41,6 +42,7 @@ import ( "github.com/networkservicemesh/sdk/pkg/registry/common/begin" "github.com/networkservicemesh/sdk/pkg/registry/common/clientconn" "github.com/networkservicemesh/sdk/pkg/registry/common/clienturl" + registryclusterinfo "github.com/networkservicemesh/sdk/pkg/registry/common/clusterinfo" registryconnect "github.com/networkservicemesh/sdk/pkg/registry/common/connect" "github.com/networkservicemesh/sdk/pkg/registry/common/dial" registryswapip "github.com/networkservicemesh/sdk/pkg/registry/common/swapip" @@ -187,6 +189,7 @@ func NewServer(ctx context.Context, regURL, proxyURL *url.URL, tokenGenerator to interdomainbypass.NewServer(&interdomainBypassNSEServer, opts.listenOn), discover.NewServer(nsClient, nseClient), swapip.NewServer(opts.openMapIPChannel(ctx)), + clusterinfo.NewServer(), connect.NewServer( client.NewClient( ctx, @@ -216,6 +219,7 @@ func NewServer(ctx context.Context, regURL, proxyURL *url.URL, tokenGenerator to clienturl.NewNetworkServiceEndpointRegistryServer(proxyURL), interdomainBypassNSEServer, registryswapip.NewNetworkServiceEndpointRegistryServer(opts.openMapIPChannel(ctx)), + registryclusterinfo.NewNetworkServiceEndpointRegistryServer(), registryconnect.NewNetworkServiceEndpointRegistryServer( chain.NewNetworkServiceEndpointRegistryClient( clientconn.NewNetworkServiceEndpointRegistryClient(), diff --git a/pkg/networkservice/common/clusterinfo/options.go b/pkg/networkservice/common/clusterinfo/options.go new file mode 100644 index 000000000..4582bda37 --- /dev/null +++ b/pkg/networkservice/common/clusterinfo/options.go @@ -0,0 +1,27 @@ +// 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 clusterinfo + +// Option overrides default configuration +type Option = func(*clusterinfoServer) + +// WithConfigPath replaces defeault clusterinfo config file path +func WithConfigPath(p string) func(o *clusterinfoServer) { + return func(o *clusterinfoServer) { + o.configPath = p + } +} diff --git a/pkg/networkservice/common/clusterinfo/server.go b/pkg/networkservice/common/clusterinfo/server.go new file mode 100644 index 000000000..7871506c5 --- /dev/null +++ b/pkg/networkservice/common/clusterinfo/server.go @@ -0,0 +1,66 @@ +// 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 clusterinfo provides a chain element that appends clusterinfo labels into the request. +package clusterinfo + +import ( + "context" + "io/ioutil" + + "github.com/golang/protobuf/ptypes/empty" + "github.com/networkservicemesh/api/pkg/api/networkservice" + "gopkg.in/yaml.v2" + + "github.com/networkservicemesh/sdk/pkg/networkservice/core/next" +) + +type clusterinfoServer struct { + configPath string +} + +// NewServer - returns a new clusterinfo NetworkServiceServer that adds clusterinfo labels into request from the cluterinfo configuration. +func NewServer(opts ...Option) networkservice.NetworkServiceServer { + var r = &clusterinfoServer{ + configPath: "/etc/clusterinfo/config.yaml", + } + for _, opt := range opts { + opt(r) + } + return r +} + +func (n *clusterinfoServer) Request(ctx context.Context, request *networkservice.NetworkServiceRequest) (*networkservice.Connection, error) { + if request.GetConnection().GetLabels() == nil { + request.GetConnection().Labels = make(map[string]string) + } + + var m = make(map[string]string) + + if b, err := ioutil.ReadFile(n.configPath); err == nil { + _ = yaml.Unmarshal(b, &m) + } + + for k, v := range m { + request.GetConnection().GetLabels()[k] = v + } + + return next.Server(ctx).Request(ctx, request) +} + +func (n *clusterinfoServer) Close(ctx context.Context, conn *networkservice.Connection) (*empty.Empty, error) { + return next.Server(ctx).Close(ctx, conn) +} diff --git a/pkg/networkservice/common/clusterinfo/server_test.go b/pkg/networkservice/common/clusterinfo/server_test.go new file mode 100644 index 000000000..0c9e3da2e --- /dev/null +++ b/pkg/networkservice/common/clusterinfo/server_test.go @@ -0,0 +1,46 @@ +// 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 clusterinfo_test + +import ( + "context" + "io/ioutil" + "os" + "path/filepath" + "testing" + + "github.com/networkservicemesh/api/pkg/api/networkservice" + "github.com/stretchr/testify/require" + "go.uber.org/goleak" + + "github.com/networkservicemesh/sdk/pkg/networkservice/common/clusterinfo" +) + +func TestReadClusterName(t *testing.T) { + t.Cleanup(func() { goleak.VerifyNone(t) }) + + var path = filepath.Join(t.TempDir(), "clusterinfo.yaml") + require.NoError(t, ioutil.WriteFile(path, []byte("CLUSTER_NAME: my-cluster1"), os.ModePerm)) + + var s = clusterinfo.NewServer(clusterinfo.WithConfigPath(path)) + + var resp, err = s.Request(context.Background(), &networkservice.NetworkServiceRequest{Connection: &networkservice.Connection{}}) + require.NoError(t, err) + + require.Len(t, resp.Labels, 1) + require.Equal(t, "my-cluster1", resp.GetLabels()["CLUSTER_NAME"]) +} diff --git a/pkg/registry/common/clusterinfo/nse_server.go b/pkg/registry/common/clusterinfo/nse_server.go new file mode 100644 index 000000000..ef85e7920 --- /dev/null +++ b/pkg/registry/common/clusterinfo/nse_server.go @@ -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 clusterinfo provides a chain element that appends clusterinfo labels into the request. +package clusterinfo + +import ( + "context" + "io/ioutil" + + "github.com/golang/protobuf/ptypes/empty" + "github.com/networkservicemesh/api/pkg/api/registry" + "gopkg.in/yaml.v2" + + "github.com/networkservicemesh/sdk/pkg/registry/core/next" +) + +type clusterinfoNSEServer struct { + configPath string +} + +func (n *clusterinfoNSEServer) Register(ctx context.Context, nse *registry.NetworkServiceEndpoint) (*registry.NetworkServiceEndpoint, error) { + var m = make(map[string]string) + + if b, err := ioutil.ReadFile(n.configPath); err == nil { + _ = yaml.Unmarshal(b, &m) + } + + for k, v := range m { + for _, labels := range nse.GetNetworkServiceLabels() { + if labels.GetLabels() == nil { + labels.Labels = make(map[string]string) + } + labels.GetLabels()[k] = v + } + } + return next.NetworkServiceEndpointRegistryServer(ctx).Register(ctx, nse) +} + +func (n *clusterinfoNSEServer) Find(query *registry.NetworkServiceEndpointQuery, server registry.NetworkServiceEndpointRegistry_FindServer) error { + return next.NetworkServiceEndpointRegistryServer(server.Context()).Find(query, server) +} + +func (n *clusterinfoNSEServer) Unregister(ctx context.Context, nse *registry.NetworkServiceEndpoint) (*empty.Empty, error) { + return next.NetworkServiceEndpointRegistryServer(ctx).Unregister(ctx, nse) +} + +// NewNetworkServiceEndpointRegistryServer - returns a new clusterinfo server that adds clusterinfo labels into nse registration +func NewNetworkServiceEndpointRegistryServer(opts ...Option) registry.NetworkServiceEndpointRegistryServer { + var r = &clusterinfoNSEServer{ + configPath: "/etc/clusterinfo/config.yaml", + } + for _, opt := range opts { + opt(r) + } + return r +} diff --git a/pkg/registry/common/clusterinfo/nse_server_test.go b/pkg/registry/common/clusterinfo/nse_server_test.go new file mode 100644 index 000000000..107094d44 --- /dev/null +++ b/pkg/registry/common/clusterinfo/nse_server_test.go @@ -0,0 +1,49 @@ +// 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 clusterinfo_test + +import ( + "context" + "io/ioutil" + "os" + "path/filepath" + "testing" + + "github.com/networkservicemesh/api/pkg/api/registry" + "github.com/stretchr/testify/require" + "go.uber.org/goleak" + + "github.com/networkservicemesh/sdk/pkg/registry/common/clusterinfo" +) + +func TestReadClusterName(t *testing.T) { + t.Cleanup(func() { goleak.VerifyNone(t) }) + + var path = filepath.Join(t.TempDir(), "clusterinfo.yaml") + require.NoError(t, ioutil.WriteFile(path, []byte("CLUSTER_NAME: my-cluster1"), os.ModePerm)) + + var s = clusterinfo.NewNetworkServiceEndpointRegistryServer(clusterinfo.WithConfigPath(path)) + + var resp, err = s.Register(context.Background(), ®istry.NetworkServiceEndpoint{NetworkServiceLabels: map[string]*registry.NetworkServiceLabels{ + "ns-1": {}, + }}) + require.NoError(t, err) + + require.Len(t, resp.GetNetworkServiceLabels(), 1) + require.Len(t, resp.GetNetworkServiceLabels()["ns-1"].GetLabels(), 1) + require.Equal(t, "my-cluster1", resp.GetNetworkServiceLabels()["ns-1"].GetLabels()["CLUSTER_NAME"]) +} diff --git a/pkg/registry/common/clusterinfo/options.go b/pkg/registry/common/clusterinfo/options.go new file mode 100644 index 000000000..7d8fcfd62 --- /dev/null +++ b/pkg/registry/common/clusterinfo/options.go @@ -0,0 +1,27 @@ +// 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 clusterinfo + +// Option overrides default configuration +type Option = func(*clusterinfoNSEServer) + +// WithConfigPath replaces defeault clusterinfo config file path +func WithConfigPath(p string) func(o *clusterinfoNSEServer) { + return func(o *clusterinfoNSEServer) { + o.configPath = p + } +}