diff --git a/examples/4g-network/README.md b/examples/4g-network/README.md index 20fdbd1..572d3a9 100644 --- a/examples/4g-network/README.md +++ b/examples/4g-network/README.md @@ -3,38 +3,38 @@ The goal of this example is to recreate the network topology of a typical 4G network setup using Network Service Mesh. ``` - +----------------+ +----------------+ +----------------+ - | | | | | | - | MME | | HSS | | PCRF | - s1-mme | | s6a | | | | - +---------> 10.60.1.0/24 <----------+ | | | - | | | | | | - | endpoint | | client | | client | - +--------^-------+ +----------------+ +--------+-------+ - | | - | s11 Gx | - | +--------------------------+ - | | - +--------+-------+ +--------v-------+ +----------------+ - | | | | | | - | S-GW-C | | P-GW-C | | TDF-C | - | | s5s8-c | | | | - | +--------->+ 10.60.2.0/24 | | | - | | | | | | - | client | | endpoint | | client | - Control plane +--------+-------+ +--------^-------+ +--------+-------+ - | | | - | Sxa | Sxb | Sxc + +----------------+ +----------------+ +----------------+ + | | | | | | + | MME | | HSS | | PCRF | + s1-mme | | s6a | | | | + +---------------> <--------------+ | | | + 10.60.1.0/24 | | 10.60.2.0/24 | | | | + | endpoint | | client | | client | + +--------^-------+ +----------------+ +--------+-------+ + | | + 10.60.3.0/24 | s11 Gx | + | +--------------------------+ + | | 10.60.5.0/24 + +--------+-------+ +--------v-------+ +----------------+ + | | | | | | + | S-GW-C | | P-GW-C | | TDF-C | + | | s5s8-c | | | | + | +--------------> | | | + | | 10.60.4.0/24 | | | | + | client | | endpoint | | client | + Control plane +--------+-------+ +--------^-------+ +--------+-------+ + | | | + 10.60.8.0/24 | Sxa 10.60.6.0/24 | Sxb 10.60.11.0/24 | Sxc +--------------------------------------------------------------------------------------------------------+ - | | | - | | | - Data plane +--------v-------+ +--------+-------+ +--------v-------+ - | | | | | | - | S-GW-U | | P-GW-U | | TDF-U | - s1-u | | s5s8-u | | SGi in | | SGi out - +---------> 10.60.3.0/24 <----------+ +---------> 10.60.4.0/24 +---------> - | | | | | | - | endpoint | | client | | endpoint | - +----------------+ +----------------+ +----------------+ + | | | + | | | + Data plane +--------v-------+ +--------+-------+ +--------v-------+ + | | | | | | + | S-GW-U | | P-GW-U | | TDF-U | + s1-u | | s5s8-u | | SGi in | | SGi out + +---------> <--------------+ +---------------> +---------> + 10.60.7.0/24 | | 10.60.9.0/24 | | 10.60.10.0/24 | | + | endpoint | | client | | endpoint | + +----------------+ +----------------+ +----------------+ ``` diff --git a/examples/4g-network/k8s/4g-network.yaml b/examples/4g-network/k8s/4g-network.yaml index 4047818..063c5a0 100644 --- a/examples/4g-network/k8s/4g-network.yaml +++ b/examples/4g-network/k8s/4g-network.yaml @@ -8,77 +8,77 @@ spec: matches: - match: sourceSelector: - app: s1-mme + link: s1-mme route: - destination: destinationSelector: app: mme - match: sourceSelector: - app: s6a + link: s6a route: - destination: destinationSelector: app: mme - match: sourceSelector: - app: s11 + link: s11 route: - destination: destinationSelector: app: mme - match: sourceSelector: - app: s5s8-c + link: s5s8-c route: - destination: destinationSelector: app: p-gw-c - match: sourceSelector: - app: gx + link: gx route: - destination: destinationSelector: app: p-gw-c - match: sourceSelector: - app: sxb + link: sxb route: - destination: destinationSelector: app: p-gw-c - match: sourceSelector: - app: s1-u + link: s1-u route: - destination: destinationSelector: app: s-gw-u - match: sourceSelector: - app: sxa + link: sxa route: - destination: destinationSelector: app: s-gw-u - match: sourceSelector: - app: s5s8-u + link: s5s8-u route: - destination: destinationSelector: app: s-gw-u - match: sourceSelector: - app: sgi + link: sgi route: - destination: destinationSelector: app: tdf-u - match: sourceSelector: - app: sxc + link: sxc route: - destination: destinationSelector: diff --git a/examples/4g-network/k8s/client-hss.yaml b/examples/4g-network/k8s/client-hss.yaml index 45d0897..8fe483a 100644 --- a/examples/4g-network/k8s/client-hss.yaml +++ b/examples/4g-network/k8s/client-hss.yaml @@ -19,4 +19,4 @@ metadata: name: "hss" namespace: default annotations: - ns.networkservicemesh.io: 4g-network?app=s6a + ns.networkservicemesh.io: 4g-network?link=s6a diff --git a/examples/4g-network/k8s/client-p-gw-u.yaml b/examples/4g-network/k8s/client-p-gw-u.yaml index fabb975..e067a85 100644 --- a/examples/4g-network/k8s/client-p-gw-u.yaml +++ b/examples/4g-network/k8s/client-p-gw-u.yaml @@ -19,4 +19,4 @@ metadata: name: "p-gw-u" namespace: default annotations: - ns.networkservicemesh.io: 4g-network?app=sgi,4g-network?app=s5s8-u,4g-network?app=sxb + ns.networkservicemesh.io: 4g-network?link=sgi,4g-network?link=s5s8-u,4g-network?link=sxb diff --git a/examples/4g-network/k8s/client-pcrf.yaml b/examples/4g-network/k8s/client-pcrf.yaml index c4e9be6..0c1302d 100644 --- a/examples/4g-network/k8s/client-pcrf.yaml +++ b/examples/4g-network/k8s/client-pcrf.yaml @@ -19,4 +19,4 @@ metadata: name: "pcrf" namespace: default annotations: - ns.networkservicemesh.io: 4g-network?app=gx + ns.networkservicemesh.io: 4g-network?link=gx diff --git a/examples/4g-network/k8s/client-s-gw-c.yaml b/examples/4g-network/k8s/client-s-gw-c.yaml index b5b1c73..75e1741 100644 --- a/examples/4g-network/k8s/client-s-gw-c.yaml +++ b/examples/4g-network/k8s/client-s-gw-c.yaml @@ -19,4 +19,4 @@ metadata: name: "s-gw-c" namespace: default annotations: - ns.networkservicemesh.io: 4g-network?app=s11,4g-network?app=s5s8-c,4g-network?app=sxa + ns.networkservicemesh.io: 4g-network?link=s11,4g-network?link=s5s8-c,4g-network?link=sxa diff --git a/examples/4g-network/k8s/client-tdf-c.yaml b/examples/4g-network/k8s/client-tdf-c.yaml index 047ef03..fae32e0 100644 --- a/examples/4g-network/k8s/client-tdf-c.yaml +++ b/examples/4g-network/k8s/client-tdf-c.yaml @@ -19,4 +19,4 @@ metadata: name: "tdf-c" namespace: default annotations: - ns.networkservicemesh.io: 4g-network?app=sxc + ns.networkservicemesh.io: 4g-network?link=sxc diff --git a/examples/4g-network/k8s/endpoint-mme.yaml b/examples/4g-network/k8s/endpoint-mme.yaml index 44c9c23..e993ca7 100644 --- a/examples/4g-network/k8s/endpoint-mme.yaml +++ b/examples/4g-network/k8s/endpoint-mme.yaml @@ -8,6 +8,17 @@ spec: networkservicemesh.io/app: "mme" template: metadata: + annotations: + ns.networkservicemesh.io/endpoints: | + { + "name": "4g-network", + "tracerEnabled": true, + "networkServices": [ + {"link": "s1-mme", "labels": "app=mme", "ipaddress": "10.60.1.0/24"}, + {"link": "s6a", "labels": "app=mme", "ipaddress": "10.60.2.0/24"}, + {"link": "s11", "labels": "app=mme", "ipaddress": "10.60.3.0/24"} + ] + } labels: networkservicemesh.io/app: "mme" networkservicemesh.io/impl: "4g-network" @@ -16,22 +27,23 @@ spec: - name: sidecar-nse image: networkservicemesh/4g-network-sidecar-nse:latest imagePullPolicy: IfNotPresent - env: - - name: ENDPOINT_NETWORK_SERVICE - value: "4g-network" - - name: ENDPOINT_LABELS - value: "app=mme" - - name: TRACER_ENABLED - value: "true" - - name: IP_ADDRESS - value: "10.60.1.0/24" resources: limits: networkservicemesh.io/socket: 1 + volumeMounts: + - name: nsm-endpoints + mountPath: /etc/nsminfo - name: mme image: alpine:latest command: ["tail", "-f", "/dev/null"] imagePullPolicy: IfNotPresent + volumes: + - name: nsm-endpoints + downwardAPI: + items: + - path: endpoints + fieldRef: + fieldPath: metadata.annotations['ns.networkservicemesh.io/endpoints'] metadata: name: mme namespace: default diff --git a/examples/4g-network/k8s/endpoint-p-gw-c.yaml b/examples/4g-network/k8s/endpoint-p-gw-c.yaml index 29112cc..540de42 100644 --- a/examples/4g-network/k8s/endpoint-p-gw-c.yaml +++ b/examples/4g-network/k8s/endpoint-p-gw-c.yaml @@ -8,6 +8,17 @@ spec: networkservicemesh.io/app: "p-gw-c" template: metadata: + annotations: + ns.networkservicemesh.io/endpoints: | + { + "name": "4g-network", + "tracerEnabled": true, + "networkServices": [ + {"link": "s5s8-c", "labels": "app=p-gw-c", "ipAddress": "10.60.4.0/24"}, + {"link": "gx", "labels": "app=p-gw-c", "ipAddress": "10.60.5.0/24"}, + {"link": "sxb", "labels": "app=p-gw-c", "ipAddress": "10.60.6.0/24"} + ] + } labels: networkservicemesh.io/app: "p-gw-c" networkservicemesh.io/impl: "4g-network" @@ -16,22 +27,23 @@ spec: - name: sidecar-nse image: networkservicemesh/4g-network-sidecar-nse:latest imagePullPolicy: IfNotPresent - env: - - name: ENDPOINT_NETWORK_SERVICE - value: "4g-network" - - name: ENDPOINT_LABELS - value: "app=p-gw-c" - - name: TRACER_ENABLED - value: "true" - - name: IP_ADDRESS - value: "10.60.2.0/24" resources: limits: networkservicemesh.io/socket: 1 + volumeMounts: + - name: nsm-endpoints + mountPath: /etc/nsminfo - name: p-gw-c image: alpine:latest command: ["tail", "-f", "/dev/null"] imagePullPolicy: IfNotPresent + volumes: + - name: nsm-endpoints + downwardAPI: + items: + - path: endpoints + fieldRef: + fieldPath: metadata.annotations['ns.networkservicemesh.io/endpoints'] metadata: name: p-gw-c namespace: default diff --git a/examples/4g-network/k8s/endpoint-s-gw-u.yaml b/examples/4g-network/k8s/endpoint-s-gw-u.yaml index 15f5dd0..57882c6 100644 --- a/examples/4g-network/k8s/endpoint-s-gw-u.yaml +++ b/examples/4g-network/k8s/endpoint-s-gw-u.yaml @@ -8,6 +8,17 @@ spec: networkservicemesh.io/app: "s-gw-u" template: metadata: + annotations: + ns.networkservicemesh.io/endpoints: | + { + "name": "4g-network", + "tracerEnabled": true, + "networkServices": [ + {"link": "s1-u", "labels": "app=s-gw-u", "ipAddress": "10.60.7.0/24"}, + {"link": "sxa", "labels": "app=s-gw-u", "ipAddress": "10.60.8.0/24"}, + {"link": "s5s8-u", "labels": "app=s-gw-u", "ipAddress": "10.60.9.0/24"} + ] + } labels: networkservicemesh.io/app: "s-gw-u" networkservicemesh.io/impl: "4g-network" @@ -16,22 +27,23 @@ spec: - name: sidecar-nse image: networkservicemesh/4g-network-sidecar-nse:latest imagePullPolicy: IfNotPresent - env: - - name: ENDPOINT_NETWORK_SERVICE - value: "4g-network" - - name: ENDPOINT_LABELS - value: "app=s-gw-u" - - name: TRACER_ENABLED - value: "true" - - name: IP_ADDRESS - value: "10.60.3.0/24" resources: limits: networkservicemesh.io/socket: 1 + volumeMounts: + - name: nsm-endpoints + mountPath: /etc/nsminfo - name: s-gw-u image: alpine:latest command: ["tail", "-f", "/dev/null"] imagePullPolicy: IfNotPresent + volumes: + - name: nsm-endpoints + downwardAPI: + items: + - path: endpoints + fieldRef: + fieldPath: metadata.annotations['ns.networkservicemesh.io/endpoints'] metadata: name: s-gw-u namespace: default diff --git a/examples/4g-network/k8s/endpoint-tdf-u.yaml b/examples/4g-network/k8s/endpoint-tdf-u.yaml index 4e64f7f..72e8898 100644 --- a/examples/4g-network/k8s/endpoint-tdf-u.yaml +++ b/examples/4g-network/k8s/endpoint-tdf-u.yaml @@ -8,6 +8,16 @@ spec: networkservicemesh.io/app: "tdf-u" template: metadata: + annotations: + ns.networkservicemesh.io/endpoints: | + { + "name": "4g-network", + "tracerEnabled": true, + "networkServices": [ + {"link": "sgi", "labels": "app=tdf-u", "ipAddress": "10.60.10.0/24"}, + {"link": "sxc", "labels": "app=tdf-u", "ipAddress": "10.60.11.0/24"} + ] + } labels: networkservicemesh.io/app: "tdf-u" networkservicemesh.io/impl: "4g-network" @@ -16,22 +26,23 @@ spec: - name: sidecar-nse image: networkservicemesh/4g-network-sidecar-nse:latest imagePullPolicy: IfNotPresent - env: - - name: ENDPOINT_NETWORK_SERVICE - value: "4g-network" - - name: ENDPOINT_LABELS - value: "app=tdf-u" - - name: TRACER_ENABLED - value: "true" - - name: IP_ADDRESS - value: "10.60.4.0/24" resources: limits: networkservicemesh.io/socket: 1 + volumeMounts: + - name: nsm-endpoints + mountPath: /etc/nsminfo - name: tdf-u image: alpine:latest command: ["tail", "-f", "/dev/null"] imagePullPolicy: IfNotPresent + volumes: + - name: nsm-endpoints + downwardAPI: + items: + - path: endpoints + fieldRef: + fieldPath: metadata.annotations['ns.networkservicemesh.io/endpoints'] metadata: name: tdf-u namespace: default diff --git a/examples/4g-network/scripts/check-connectivity.sh b/examples/4g-network/scripts/check-connectivity.sh index de49d20..404076b 100755 --- a/examples/4g-network/scripts/check-connectivity.sh +++ b/examples/4g-network/scripts/check-connectivity.sh @@ -8,52 +8,41 @@ ENDPOINTS="mme p-gw-c s-gw-u tdf-u" # Ping all the things! EXIT_VAL=0 for client in ${CLIENTS}; do - for nsc in $(kubectl get pods -n default -o=name | grep -E "${client}" | sed 's@.*/@@'); do - echo "===== >>>>> PROCESSING ${nsc} <<<<< ===========" - for ip in $(kubectl exec -n default -it -c "${client}" "${nsc}" -- ip addr| grep inet | awk '{print $2}'); do - if [[ "${ip}" == 10.60.*.* ]];then - firstSegment=$(echo "${ip}" | cut -d . -f 1-3) - lastSegment=$(echo "${ip}" | cut -d . -f 4 | cut -d / -f 1) - nextOp=$((lastSegment + 1)) - targetIp="${firstSegment}.${nextOp}" - # Get the name of its corresponding endpoint pair - for endpoint in ${ENDPOINTS}; do - for nse in $(kubectl get pods -n default -o=name | grep -E "${endpoint}" | sed 's@.*/@@'); do - for ip_e in $(kubectl exec -n default -it -c "${endpoint}" "${nse}" -- ip addr| grep inet | awk '{print $2}'); do - if [[ "${ip_e}" == "${targetIp}/30" ]];then - echo "===== >>>>> ENDPOINT PAIR - ${nse} <<<<< ===========" - endpointName="${nse}" - fi - done - done - done - fi - # Do the actual pinging once we have the target IP address - if [ -n "${targetIp}" ]; then - if kubectl exec -n default -it -c "${client}" "${nsc}" -- ping -c 1 "${targetIp}" ; then - echo "NSC ${nsc} with IP ${ip} pinging ${endpointName} TargetIP: ${targetIp} successful" - PingSuccess="true" - EXIT_VAL=0 - else - echo "NSC ${nsc} with IP ${ip} pinging ${endpointName} TargetIP: ${targetIp} unsuccessful" - EXIT_VAL=1 + # This is only applicable to single replica deployments + nsc=$(kubectl get pods -l=networkservicemesh.io/app=${client} -o jsonpath='{.items[*].metadata.name}') + echo "===== >>>>> PROCESSING ${nsc} <<<<< ===========" + for ip in $(kubectl exec -n default -it -c "${client}" "${nsc}" -- ip addr| grep "inet 10.60" | awk '{print $2}' | uniq); do + lastSegment=$(echo "${ip##*\.}" | cut -d / -f 1) + nextOp=$((lastSegment + 1)) + targetIp="${ip%\.*}.${nextOp}" + # Get the name of its corresponding endpoint pair + for endpoint in ${ENDPOINTS}; do + nse=$(kubectl get pods -l=networkservicemesh.io/app=${endpoint} -o jsonpath='{.items[*].metadata.name}') + for ip_e in $(kubectl exec -n default -it -c "${endpoint}" "${nse}" -- ip addr| grep "inet 10.60" | awk '{print $2}' | uniq ); do + if [[ "${ip_e}" == "${targetIp}/30" ]];then + echo "===== >>>>> ENDPOINT PAIR - ${nse} <<<<< ===========" + endpointName="${nse}" + + # Do the actual pinging once we have the target IP address + if kubectl exec -n default -it -c "${client}" "${nsc}" -- ping -c 1 "${targetIp}" > /dev/null; then + echo "NSC ${nsc} with IP ${ip} pinging ${endpointName} TargetIP: ${targetIp} successful" + else + EXIT_VAL=1 + echo "NSC ${nsc} with IP ${ip} pinging ${endpointName} TargetIP: ${targetIp} unsuccessful" + echo "+++++++==ERROR==ERROR=============================================================================+++++" + echo "NSC ${nsc} failed to connect to the desired ${endpointName} NetworkService" + kubectl get pod -n default "${nsc}" -o wide + echo "Client POD ${nsc} Network dump -------------------------------" + kubectl exec -n default -ti "${nsc}" -- ip addr + kubectl exec -n default -ti "${nsc}" -- ip route + echo "Endpoint POD ${nse} Network dump -------------------------------" + kubectl exec -n default -ti "${nse}" -- ip addr + kubectl exec -n default -ti "${nse}" -- ip route + echo "+++++++==ERROR==ERROR=============================================================================+++++" + fi fi - unset targetIp - unset endpointName - fi + done done - - if [ -z ${PingSuccess} ]; then - EXIT_VAL=1 - echo "+++++++==ERROR==ERROR=============================================================================+++++" - echo "NSC ${nsc} failed to connect to the desired ${endpointName} NetworkService" - kubectl get pod -n default "${nsc}" -o wide - echo "POD ${nsc} Network dump -------------------------------" - kubectl exec -n default -ti "${nsc}" -- ip addr - kubectl exec -n default -ti "${nsc}" ip route - echo "+++++++==ERROR==ERROR=============================================================================+++++" - fi - unset PingSuccess done done -exit ${EXIT_VAL} +exit ${EXIT_VAL} \ No newline at end of file diff --git a/examples/4g-network/sidecar-nse/Dockerfile b/examples/4g-network/sidecar-nse/Dockerfile index c98c81b..e3b7ee6 100644 --- a/examples/4g-network/sidecar-nse/Dockerfile +++ b/examples/4g-network/sidecar-nse/Dockerfile @@ -1,15 +1,17 @@ -FROM golang:alpine as build -RUN apk --no-cache add git +FROM golang:1.15.1-alpine3.12 as build + ENV PACKAGEPATH=github.com/networkservicemesh/networkservicemesh/ ENV GO111MODULE=on -RUN mkdir /root/networkservicemesh -ADD ["go.mod","/root/networkservicemesh"] WORKDIR /root/networkservicemesh/ + +RUN apk --no-cache add git=2.26.2-r0 +COPY go.mod . RUN go mod download -ADD [".","/root/networkservicemesh"] -RUN CGO_ENABLED=0 GOOS=linux go build -ldflags '-extldflags "-static"' -o /go/bin/sidecar-nse ./examples/4g-network/sidecar-nse/cmd/main.go -FROM alpine as runtime +COPY . . +RUN CGO_ENABLED=0 GOOS=linux go build -ldflags '-extldflags "-static"' -o /go/bin/sidecar-nse ./examples/4g-network/sidecar-nse/cmd/... + +FROM alpine:3.12 as runtime COPY --from=build /go/bin/sidecar-nse /bin/sidecar-nse ENTRYPOINT ["/bin/sidecar-nse"] diff --git a/examples/4g-network/sidecar-nse/cmd/endpoints.go b/examples/4g-network/sidecar-nse/cmd/endpoints.go new file mode 100644 index 0000000..4512285 --- /dev/null +++ b/examples/4g-network/sidecar-nse/cmd/endpoints.go @@ -0,0 +1,47 @@ +// Copyright 2020 Samsung Electronics +// 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 main + +import ( + "encoding/json" + "fmt" +) + +// Endpoint contains the information to create NSM objects. +type Endpoint struct { + Name string `json:"name"` + TracerEnabled bool `json:"tracerEnabled"` + NetworkServices []NetworkService `json:"networkServices"` +} + +// NetworkService contains the information to create NSM objects. +type NetworkService struct { + Link string `json:"link"` + Labels string `json:"labels"` + IPAddress string `json:"ipAddress"` + Route string `json:"route"` +} + +// GetEndpoint parses a stream of bytes to a Endpoint struct. +func GetEndpoint(endpointsFile []byte) (Endpoint, error) { + var endpointsConfig Endpoint + + if err := json.Unmarshal(endpointsFile, &endpointsConfig); err != nil { + return endpointsConfig, fmt.Errorf("failed to parse annotations file: %w", err) + } + + return endpointsConfig, nil +} diff --git a/examples/4g-network/sidecar-nse/cmd/main.go b/examples/4g-network/sidecar-nse/cmd/main.go index b5ade2d..08600ac 100644 --- a/examples/4g-network/sidecar-nse/cmd/main.go +++ b/examples/4g-network/sidecar-nse/cmd/main.go @@ -17,37 +17,94 @@ package main import ( "context" + "fmt" + "io/ioutil" + "os" + "strconv" + "github.com/networkservicemesh/networkservicemesh/controlplane/api/networkservice" "github.com/networkservicemesh/networkservicemesh/pkg/tools" "github.com/networkservicemesh/networkservicemesh/sdk/common" "github.com/networkservicemesh/networkservicemesh/sdk/endpoint" "github.com/sirupsen/logrus" ) +func readEndpointsConf() (*Endpoint, error) { + endpointsFile, err := os.Open("/etc/nsminfo/endpoints") + if err != nil { + return nil, fmt.Errorf("failed to read annotations file: %w", err) + } + defer endpointsFile.Close() + + byteValue, _ := ioutil.ReadAll(endpointsFile) + + result, err := GetEndpoint(byteValue) + if err != nil { + return nil, fmt.Errorf("failed to get enpoint configuration: %w", err) + } + + return &result, nil +} + func main() { + logrus.Info("Starting nse...") // Capture signals to cleanup before exiting c := tools.NewOSSignalChannel() + registrations := []endpoint.Registration{} + switchEndpoint := NewSwitchEndpoint("link") configuration := common.FromEnv() - podName := endpoint.CreatePodNameMutator() - composite := endpoint.NewCompositeEndpoint( - endpoint.NewMonitorEndpoint(configuration), - endpoint.NewConnectionEndpoint(configuration), - endpoint.NewIpamEndpoint(configuration), - endpoint.NewCustomFuncEndpoint("podName", podName), - ) - nsmEndpoint, err := endpoint.NewNSMEndpoint(context.Background(), configuration, composite) + endpointsConfig, err := readEndpointsConf() + if err != nil { + logrus.Fatalf("Unable to parse the endpoints file: %v", err) + } + + configuration.EndpointNetworkService = endpointsConfig.Name + os.Setenv("TRACER_ENABLED", strconv.FormatBool(endpointsConfig.TracerEnabled)) + + for _, config := range endpointsConfig.NetworkServices { + service := common.FromEnv() + service.EndpointNetworkService = endpointsConfig.Name + service.EndpointLabels = config.Labels + service.IPAddress = config.IPAddress + + endpoints := []networkservice.NetworkServiceServer{ + endpoint.NewConnectionEndpoint(service), + endpoint.NewIpamEndpoint(service), + endpoint.NewCustomFuncEndpoint("podName", endpoint.CreatePodNameMutator()), + } + + if config.Route != "" { + routeAddr := endpoint.CreateRouteMutator([]string{config.Route}) + endpoints = append(endpoints, endpoint.NewCustomFuncEndpoint("route", routeAddr)) + } + + switchEndpoint.Childs[config.Link] = endpoint.NewCompositeEndpoint(endpoints...) + registrations = append(registrations, endpoint.MakeRegistration(service)) + } + + nsEndpoint, err := endpoint.NewNSMEndpoint( + context.Background(), + configuration, + endpoint.NewCompositeEndpoint( + endpoint.NewMonitorEndpoint(configuration), + switchEndpoint, + ), + endpoint.WithRegistrations(registrations...), + ) if err != nil { logrus.Fatalf("%v", err) } - if err := nsmEndpoint.Start(); err != nil { + defer func() { + _ = nsEndpoint.Delete() + }() + + if err := nsEndpoint.Start(); err != nil { logrus.Fatalf("Unable to start the endpoint: %v", err) } - defer func() { _ = nsmEndpoint.Delete() }() - // Capture signals to cleanup before exiting <-c } diff --git a/examples/4g-network/sidecar-nse/cmd/switch.go b/examples/4g-network/sidecar-nse/cmd/switch.go new file mode 100644 index 0000000..766ca68 --- /dev/null +++ b/examples/4g-network/sidecar-nse/cmd/switch.go @@ -0,0 +1,71 @@ +// Copyright 2020 Samsung Electronics +// 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 main + +import ( + "context" + + "github.com/golang/protobuf/ptypes/empty" + "github.com/networkservicemesh/networkservicemesh/controlplane/api/connection" + "github.com/networkservicemesh/networkservicemesh/controlplane/api/networkservice" + "github.com/pkg/errors" +) + +// SwitchEndpoint is a simple NetworkServiceServer composition primitive which +// forwards incoming requests into one of its child NetworkServiceServer's based +// on the specified label. +type SwitchEndpoint struct { + Label string + Childs map[string]networkservice.NetworkServiceServer +} + +// Request implements NetworkServiceServer interface method. +func (s *SwitchEndpoint) Request(ctx context.Context, + request *networkservice.NetworkServiceRequest) (*connection.Connection, error) { + e, err := s.selectEndpoint(request.Connection) + if err == nil { + return e.Request(ctx, request) + } + + return nil, err +} + +// Close implements NetworkServiceServer interface method. +func (s *SwitchEndpoint) Close(ctx context.Context, connection *connection.Connection) (*empty.Empty, error) { + e, err := s.selectEndpoint(connection) + if err == nil { + return e.Close(ctx, connection) + } + + return nil, err +} + +func (s *SwitchEndpoint) selectEndpoint(c *connection.Connection) (networkservice.NetworkServiceServer, error) { + result := s.Childs[c.Labels[s.Label]] + if result == nil { + return nil, errors.New("Couldn't match the connection") + } + + return result, nil +} + +// NewSwitchEndpoint creates a new SwitchEndpoint object. +func NewSwitchEndpoint(label string) *SwitchEndpoint { + return &SwitchEndpoint{ + Label: label, + Childs: map[string]networkservice.NetworkServiceServer{}, + } +} diff --git a/go.mod b/go.mod index 6a78255..c513af3 100644 --- a/go.mod +++ b/go.mod @@ -7,6 +7,7 @@ require ( github.com/davecgh/go-spew v1.1.1 github.com/fsnotify/fsnotify v1.4.9 github.com/golang/protobuf v1.3.5 + github.com/google/go-cmp v0.5.3 // indirect github.com/grpc-ecosystem/grpc-opentracing v0.0.0-20180507213350-8e809c8a8645 github.com/networkservicemesh/networkservicemesh/controlplane/api v0.3.0 github.com/networkservicemesh/networkservicemesh/pkg v0.3.0 @@ -17,15 +18,18 @@ require ( github.com/sirupsen/logrus v1.5.0 github.com/spf13/viper v1.6.2 go.ligato.io/vpp-agent/v3 v3.1.0 + golang.org/x/net v0.0.0-20201021035429-f5854403a974 // indirect + golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect google.golang.org/grpc v1.28.0 + gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect gopkg.in/yaml.v2 v2.2.8 ) replace ( github.com/census-instrumentation/opencensus-proto v0.1.0-0.20181214143942-ba49f56771b8 => github.com/census-instrumentation/opencensus-proto v0.0.3-0.20181214143942-ba49f56771b8 - github.com/networkservicemesh/networkservicemesh => github.com/networkservicemesh/networkservicemesh v0.0.0-20200328192804-8d64ff42c90d - github.com/networkservicemesh/networkservicemesh/controlplane/api => github.com/networkservicemesh/networkservicemesh/controlplane/api v0.0.0-20200328192804-8d64ff42c90d - github.com/networkservicemesh/networkservicemesh/pkg => github.com/networkservicemesh/networkservicemesh/pkg v0.0.0-20200328192804-8d64ff42c90d - github.com/networkservicemesh/networkservicemesh/sdk => github.com/networkservicemesh/networkservicemesh/sdk v0.0.0-20200328192804-8d64ff42c90d - github.com/networkservicemesh/networkservicemesh/utils => github.com/networkservicemesh/networkservicemesh/utils v0.0.0-20200328192804-8d64ff42c90d + github.com/networkservicemesh/networkservicemesh => github.com/networkservicemesh/networkservicemesh v0.0.0-20201012191209-cb2e62e24eb3 + github.com/networkservicemesh/networkservicemesh/controlplane/api => github.com/networkservicemesh/networkservicemesh/controlplane/api v0.0.0-20201012191209-cb2e62e24eb3 + github.com/networkservicemesh/networkservicemesh/pkg => github.com/networkservicemesh/networkservicemesh/pkg v0.0.0-20201012191209-cb2e62e24eb3 + github.com/networkservicemesh/networkservicemesh/sdk => github.com/networkservicemesh/networkservicemesh/sdk v0.0.0-20201012191209-cb2e62e24eb3 + github.com/networkservicemesh/networkservicemesh/utils => github.com/networkservicemesh/networkservicemesh/utils v0.0.0-20201012191209-cb2e62e24eb3 ) diff --git a/go.sum b/go.sum index a0eca6b..918eb57 100644 --- a/go.sum +++ b/go.sum @@ -171,6 +171,8 @@ github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5a github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1 h1:Xye71clBPdm5HgqGwUkwhbynsUJZhDbS20FvLhQ2izg= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.5.3 h1:x95R7cp+rSeeqAMI2knLtQ0DKlaBhv2NrtrOvafPHRo= +github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= @@ -289,14 +291,14 @@ github.com/namsral/flag v1.7.4-pre/go.mod h1:OXldTctbM6SWH1K899kPZcf65KxJiD7Msce github.com/naoina/go-stringutil v0.1.0/go.mod h1:XJ2SJL9jCtBh+P9q5btrd/Ylo8XwT/h1USek5+NqSA0= github.com/naoina/toml v0.1.1/go.mod h1:NBIhNtsFMo3G2szEBne+bO4gS192HuIYRqfvOWb4i1E= github.com/nbio/st v0.0.0-20140626010706-e9e8d9816f32/go.mod h1:9wM+0iRr9ahx58uYLpLIr5fm8diHn0JbqRycJi6w0Ms= -github.com/networkservicemesh/networkservicemesh/controlplane/api v0.0.0-20200328192804-8d64ff42c90d h1:7enEgSWLXnpSlRMCS9/OJVXsoM6/TCbIfhvTxDmNqT4= -github.com/networkservicemesh/networkservicemesh/controlplane/api v0.0.0-20200328192804-8d64ff42c90d/go.mod h1:0jdEdOt2NntftpnBwlTR5aJ69w7aDnu6CEwwNNmZGVA= -github.com/networkservicemesh/networkservicemesh/pkg v0.0.0-20200328192804-8d64ff42c90d h1:XdDVbMHv0XOdjESS/mBy9LNMJL0nz9Nwo+d2frI5Cdg= -github.com/networkservicemesh/networkservicemesh/pkg v0.0.0-20200328192804-8d64ff42c90d/go.mod h1:6qYBSBbEDWVL2XlKmeh9YUOKVw+n1qWnWZXzpGo9yEo= -github.com/networkservicemesh/networkservicemesh/sdk v0.0.0-20200328192804-8d64ff42c90d h1:nCj/iEa1RF6LE9flainBzCuhykk9+LlrMtkm4IPDbm8= -github.com/networkservicemesh/networkservicemesh/sdk v0.0.0-20200328192804-8d64ff42c90d/go.mod h1:2Z2ha3eeCPYtGmvwyfta8REREo1OPYuXJwqC8RN1qcI= -github.com/networkservicemesh/networkservicemesh/utils v0.0.0-20200328192804-8d64ff42c90d h1:/pzIzF5B1zlZhUvfmnBXo7zi7gXd1D3zZ98xosfN2v4= -github.com/networkservicemesh/networkservicemesh/utils v0.0.0-20200328192804-8d64ff42c90d/go.mod h1:VvA+zSIv3iE7FixaPc2NTMcwL/u13pWG/3DLsLpYKXc= +github.com/networkservicemesh/networkservicemesh/controlplane/api v0.0.0-20201012191209-cb2e62e24eb3 h1:7zxPX/3/Tptai2bdg7zPCG13fxSQuiYuDTseS9LVM5o= +github.com/networkservicemesh/networkservicemesh/controlplane/api v0.0.0-20201012191209-cb2e62e24eb3/go.mod h1:0jdEdOt2NntftpnBwlTR5aJ69w7aDnu6CEwwNNmZGVA= +github.com/networkservicemesh/networkservicemesh/pkg v0.0.0-20201012191209-cb2e62e24eb3 h1:Cn/Ooaj1xMyqj3bV4tyi75O6/Cm2804aEz/p5eHQJL8= +github.com/networkservicemesh/networkservicemesh/pkg v0.0.0-20201012191209-cb2e62e24eb3/go.mod h1:6qYBSBbEDWVL2XlKmeh9YUOKVw+n1qWnWZXzpGo9yEo= +github.com/networkservicemesh/networkservicemesh/sdk v0.0.0-20201012191209-cb2e62e24eb3 h1:Mw1uaPK06iOFNcL5G7rYSnvTYL518dy9B3I2qRQ+ERg= +github.com/networkservicemesh/networkservicemesh/sdk v0.0.0-20201012191209-cb2e62e24eb3/go.mod h1:2Z2ha3eeCPYtGmvwyfta8REREo1OPYuXJwqC8RN1qcI= +github.com/networkservicemesh/networkservicemesh/utils v0.0.0-20201012191209-cb2e62e24eb3 h1:jN3MeD2h2G9gaKnyebYeHjMWLJon6fDQvlgrs53M/rM= +github.com/networkservicemesh/networkservicemesh/utils v0.0.0-20201012191209-cb2e62e24eb3/go.mod h1:VvA+zSIv3iE7FixaPc2NTMcwL/u13pWG/3DLsLpYKXc= github.com/nrdcg/auroradns v1.0.0/go.mod h1:6JPXKzIRzZzMqtTDgueIhTi6rFf1QvYE/HzqidhOhjw= github.com/nrdcg/goinwx v0.6.1/go.mod h1:XPiut7enlbEdntAqalBIqcYcTEVhpv/dKWgDCX2SwKQ= github.com/nrdcg/namesilo v0.2.1/go.mod h1:lwMvfQTyYq+BbjJd30ylEG4GPSS6PII0Tia4rRpRiyw= @@ -468,6 +470,7 @@ golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20190829043050-9756ffdc2472/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -501,6 +504,8 @@ golang.org/x/net v0.0.0-20190930134127-c5a3c61f89f3/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20191027093000-83d349e8ac1a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa h1:F+8P+gmewFQYRk6JoLQLwjBCTu3mcIURZfNkVweuRKA= golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20201021035429-f5854403a974 h1:IX6qOQeG5uLjB/hjjwjedwfjND0hgjPMMyO1RoIXQNI= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -536,11 +541,15 @@ golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200117145432-59e60aa80a0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9 h1:1/DFK4b7JH8DmkqhUk48onnSfrPzImPoVxuomtbT2nk= golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f h1:+Nyd8tzPX9R7BWHguqsrbFdRx3WQ/1ib8I44HXV5yTA= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 h1:SvFZT6jyqRaOeXpc5h/JSfZenJ2O330aBsf7JfSUXmQ= @@ -557,6 +566,9 @@ golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3 golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= @@ -596,6 +608,8 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/h2non/gock.v1 v1.0.15/go.mod h1:sX4zAkdYX1TRGJ2JY156cFspQn4yRWn6p9EMdODlynE=