Skip to content
Snippets Groups Projects
Commit 968f6d92 authored by Lluis Gifre Renom's avatar Lluis Gifre Renom
Browse files

Merge branch 'develop' of https://labs.etsi.org/rep/tfs/controller into feat/l3-components

parents ab3a5ef0 fb07f499
No related branches found
No related tags found
2 merge requests!142Release TeraFlowSDN 2.1,!135Fixed L3 Cybersecurity framework
Showing
with 510 additions and 5 deletions
...@@ -168,5 +168,8 @@ delete_local_deployment.sh ...@@ -168,5 +168,8 @@ delete_local_deployment.sh
local_docker_deployment.sh local_docker_deployment.sh
local_k8s_deployment.sh local_k8s_deployment.sh
# asdf configuration
.tool-versions
# Other logs # Other logs
**/logs/*.log.* **/logs/*.log.*
# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/)
#
# 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.
apiVersion: apps/v1
kind: Deployment
metadata:
name: teservice
spec:
selector:
matchLabels:
app: teservice
template:
metadata:
annotations:
config.linkerd.io/skip-inbound-ports: "4189"
labels:
app: teservice
spec:
terminationGracePeriodSeconds: 5
shareProcessNamespace: true
containers:
- name: server
image: labs.etsi.org:5050/tfs/controller/te:latest
imagePullPolicy: Always
ports:
- containerPort: 10030
env:
- name: ERLANG_LOGGER_LEVEL
value: "debug"
- name: ERLANG_COOKIE
value: "tfte-unsafe-cookie"
- name: ERLANG_NODE_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: ERLANG_NODE_IP
valueFrom:
fieldRef:
fieldPath: status.podIP
readinessProbe:
exec:
command: ["/tfte/bin/tfte", "status"]
livenessProbe:
exec:
command: ["/tfte/bin/tfte", "status"]
resources:
requests:
cpu: 250m
memory: 512Mi
limits:
cpu: 700m
memory: 1024Mi
---
apiVersion: v1
kind: Service
metadata:
name: teservice
spec:
type: ClusterIP
selector:
app: teservice
ports:
- name: grpc
protocol: TCP
port: 10030
targetPort: 10030
- name: pcep
protocol: TCP
port: 4189
targetPort: 4189
...@@ -34,6 +34,9 @@ export TFS_COMPONENTS="context device pathcomp service slice compute webui load_ ...@@ -34,6 +34,9 @@ export TFS_COMPONENTS="context device pathcomp service slice compute webui load_
# Uncomment to activate L3 CyberSecurity # Uncomment to activate L3 CyberSecurity
#export TFS_COMPONENTS="${TFS_COMPONENTS} l3_attackmitigator l3_centralizedattackdetector" #export TFS_COMPONENTS="${TFS_COMPONENTS} l3_attackmitigator l3_centralizedattackdetector"
# Uncomment to activate TE
#export TFS_COMPONENTS="${TFS_COMPONENTS} te"
# Set the tag you want to use for your images. # Set the tag you want to use for your images.
export TFS_IMAGE_TAG="dev" export TFS_IMAGE_TAG="dev"
......
...@@ -3,5 +3,8 @@ src/*/* ...@@ -3,5 +3,8 @@ src/*/*
# used to prevent breaking symbolic links from source code folders # used to prevent breaking symbolic links from source code folders
!src/*/.gitignore !src/*/.gitignore
!src/python/__init__.py !src/python/__init__.py
!src/erlang/rebar.config
!src/erlang/rebar.lock
!src/erlang/src/tfpb.app.src
uml/generated uml/generated
...@@ -273,6 +273,7 @@ enum ServiceTypeEnum { ...@@ -273,6 +273,7 @@ enum ServiceTypeEnum {
SERVICETYPE_L3NM = 1; SERVICETYPE_L3NM = 1;
SERVICETYPE_L2NM = 2; SERVICETYPE_L2NM = 2;
SERVICETYPE_TAPI_CONNECTIVITY_SERVICE = 3; SERVICETYPE_TAPI_CONNECTIVITY_SERVICE = 3;
SERVICETYPE_TE = 4;
} }
enum ServiceStatusEnum { enum ServiceStatusEnum {
......
#!/bin/bash -eu
# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/)
#
# 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.
set -e
FORCE=0
DEFAULT_ACTION="generate"
usage() {
echo "Usage: $0 [-f] [clean|generate]" 1>&2
echo "Options:"
echo " -f: Force regeneration of all protocol buffers"
exit 1;
}
while getopts "fc" o; do
case "${o}" in
f)
FORCE=1
;;
*)
usage
;;
esac
done
shift $((OPTIND-1))
ACTION=${1:-$DEFAULT_ACTION}
cd $(dirname $0)
ROOT=$(pwd)
ERLANG_PROTO_DIR="$ROOT/src/erlang"
BUILD_CHECK="$ERLANG_PROTO_DIR/.generated"
tfpb_clean() {
rm -f "$BUILD_CHECK"
rm -rf "$ERLANG_PROTO_DIR/src/"*.erl
rm -rf "$ERLANG_PROTO_DIR/src/erlang/_build"
}
tfpb_generate() {
if [[ -f "$BUILD_CHECK" && $FORCE != 1 ]]; then
echo "Protocol buffer code for Erlang already generated, use -f to force"
exit 0
fi
tfpb_clean
mkdir -p "$ERLANG_PROTO_DIR"
cd "$ERLANG_PROTO_DIR"
rebar3 compile
rebar3 grpc gen
rebar3 compile
touch "$BUILD_CHECK"
echo "Protocol buffer code for Erlang generated"
}
case "$ACTION" in
clean) tfpb_clean;;
generate) tfpb_generate;;
*) usage;;
esac
...@@ -18,13 +18,13 @@ import "context.proto"; ...@@ -18,13 +18,13 @@ import "context.proto";
service L3Centralizedattackdetector { service L3Centralizedattackdetector {
// Analyze single input to the ML model in the CAD component // Analyze single input to the ML model in the CAD component
rpc AnalyzeConnectionStatistics (L3CentralizedattackdetectorMetrics) returns (Empty) {} rpc AnalyzeConnectionStatistics (L3CentralizedattackdetectorMetrics) returns (StatusMessage) {}
// Analyze a batch of inputs to the ML model in the CAD component // Analyze a batch of inputs to the ML model in the CAD component
rpc AnalyzeBatchConnectionStatistics (L3CentralizedattackdetectorBatchInput) returns (Empty) {} rpc AnalyzeBatchConnectionStatistics (L3CentralizedattackdetectorBatchInput) returns (StatusMessage) {}
// Get the list of features used by the ML model in the CAD component // Get the list of features used by the ML model in the CAD component
rpc GetFeaturesIds (Empty) returns (AutoFeatures) {} rpc GetFeaturesIds (context.Empty) returns (AutoFeatures) {}
// Sets the list of attack IPs in order to be used to compute the prediction accuracy of the ML model in the CAD component in case of testing the ML model // Sets the list of attack IPs in order to be used to compute the prediction accuracy of the ML model in the CAD component in case of testing the ML model
rpc SetAttackIPs (AttackIPs) returns (Empty) {} rpc SetAttackIPs (AttackIPs) returns (Empty) {}
...@@ -66,7 +66,7 @@ message L3CentralizedattackdetectorBatchInput { ...@@ -66,7 +66,7 @@ message L3CentralizedattackdetectorBatchInput {
repeated L3CentralizedattackdetectorMetrics metrics = 1; repeated L3CentralizedattackdetectorMetrics metrics = 1;
} }
message Empty { message StatusMessage {
string message = 1; string message = 1;
} }
......
*
!rebar.config
!rebar.lock
!src/
!src/tfpb.app.src
% Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/)
%
% 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.
{erl_opts, [debug_info]}.
{deps, [grpcbox]}.
{grpc, [{protos, "../.."},
{gpb_opts, [{i, "../.."}, {strbin, true}, {descriptor, true}, {module_name_suffix, "_pb"}]}]}.
{plugins, [grpcbox_plugin]}.
{"1.2.0",
[{<<"acceptor_pool">>,{pkg,<<"acceptor_pool">>,<<"1.0.0">>},1},
{<<"chatterbox">>,{pkg,<<"ts_chatterbox">>,<<"0.12.0">>},1},
{<<"ctx">>,{pkg,<<"ctx">>,<<"0.6.0">>},1},
{<<"gproc">>,{pkg,<<"gproc">>,<<"0.8.0">>},1},
{<<"grpcbox">>,{pkg,<<"grpcbox">>,<<"0.15.0">>},0},
{<<"hpack">>,{pkg,<<"hpack_erl">>,<<"0.2.3">>},2}]}.
[
{pkg_hash,[
{<<"acceptor_pool">>, <<"43C20D2ACAE35F0C2BCD64F9D2BDE267E459F0F3FD23DAB26485BF518C281B21">>},
{<<"chatterbox">>, <<"4E54F199E15C0320B85372A24E35554A2CCFC4342E0B7CD8DAED9A04F9B8EF4A">>},
{<<"ctx">>, <<"8FF88B70E6400C4DF90142E7F130625B82086077A45364A78D208ED3ED53C7FE">>},
{<<"gproc">>, <<"CEA02C578589C61E5341FCE149EA36CCEF236CC2ECAC8691FBA408E7EA77EC2F">>},
{<<"grpcbox">>, <<"97C7126296A091602D372EBF5860A04F7BC795B45B33A984CAD2B8E362774FD8">>},
{<<"hpack">>, <<"17670F83FF984AE6CD74B1C456EDDE906D27FF013740EE4D9EFAA4F1BF999633">>}]},
{pkg_hash_ext,[
{<<"acceptor_pool">>, <<"0CBCD83FDC8B9AD2EEE2067EF8B91A14858A5883CB7CD800E6FCD5803E158788">>},
{<<"chatterbox">>, <<"6478C161BC60244F41CD5847CC3ACCD26D997883E9F7FACD36FF24533B2FA579">>},
{<<"ctx">>, <<"A14ED2D1B67723DBEBBE423B28D7615EB0BDCBA6FF28F2D1F1B0A7E1D4AA5FC2">>},
{<<"gproc">>, <<"580ADAFA56463B75263EF5A5DF4C86AF321F68694E7786CB057FD805D1E2A7DE">>},
{<<"grpcbox">>, <<"161ABE9E17E7D1982EFA6488ADEAA13C3E847A07984A6E6B224E553368918647">>},
{<<"hpack">>, <<"06F580167C4B8B8A6429040DF36CC93BBA6D571FAEAEC1B28816523379CBB23A">>}]}
].
%% Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/)
%%
%% 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.
{application, tfpb,
[{description, "Teraflow Erlang Protocol Buffers"},
{vsn, "0.1.0"},
{registered, []},
{applications, [kernel, stdlib, grpcbox]},
{env, []},
{modules, []},
{licenses, ["Apache 2.0"]},
{links, []}
]}.
...@@ -56,6 +56,7 @@ class ServiceNameEnum(Enum): ...@@ -56,6 +56,7 @@ class ServiceNameEnum(Enum):
OPTICALATTACKDETECTOR = 'opticalattackdetector' OPTICALATTACKDETECTOR = 'opticalattackdetector'
OPTICALATTACKMITIGATOR = 'opticalattackmitigator' OPTICALATTACKMITIGATOR = 'opticalattackmitigator'
CACHING = 'caching' CACHING = 'caching'
TE = 'te'
# Used for test and debugging only # Used for test and debugging only
DLT_GATEWAY = 'dltgateway' DLT_GATEWAY = 'dltgateway'
...@@ -80,6 +81,7 @@ DEFAULT_SERVICE_GRPC_PORTS = { ...@@ -80,6 +81,7 @@ DEFAULT_SERVICE_GRPC_PORTS = {
ServiceNameEnum.OPTICALATTACKMANAGER .value : 10005, ServiceNameEnum.OPTICALATTACKMANAGER .value : 10005,
ServiceNameEnum.INTERDOMAIN .value : 10010, ServiceNameEnum.INTERDOMAIN .value : 10010,
ServiceNameEnum.PATHCOMP .value : 10020, ServiceNameEnum.PATHCOMP .value : 10020,
ServiceNameEnum.TE .value : 10030,
# Used for test and debugging only # Used for test and debugging only
ServiceNameEnum.DLT_GATEWAY .value : 50051, ServiceNameEnum.DLT_GATEWAY .value : 50051,
......
...@@ -21,6 +21,7 @@ class ORM_ServiceTypeEnum(enum.Enum): ...@@ -21,6 +21,7 @@ class ORM_ServiceTypeEnum(enum.Enum):
L3NM = ServiceTypeEnum.SERVICETYPE_L3NM L3NM = ServiceTypeEnum.SERVICETYPE_L3NM
L2NM = ServiceTypeEnum.SERVICETYPE_L2NM L2NM = ServiceTypeEnum.SERVICETYPE_L2NM
TAPI_CONNECTIVITY_SERVICE = ServiceTypeEnum.SERVICETYPE_TAPI_CONNECTIVITY_SERVICE TAPI_CONNECTIVITY_SERVICE = ServiceTypeEnum.SERVICETYPE_TAPI_CONNECTIVITY_SERVICE
TE = ServiceTypeEnum.SERVICETYPE_TE
grpc_to_enum__service_type = functools.partial( grpc_to_enum__service_type = functools.partial(
grpc_to_enum, ServiceTypeEnum, ORM_ServiceTypeEnum) grpc_to_enum, ServiceTypeEnum, ORM_ServiceTypeEnum)
# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/)
#
# 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.
import grpc, logging
from common.Constants import ServiceNameEnum
from common.Settings import get_service_host, get_service_port_grpc
from common.proto.context_pb2 import Empty, Service, ServiceId, ServiceStatus
from common.proto.te_pb2_grpc import TEServiceStub
from common.tools.client.RetryDecorator import retry, delay_exponential
from common.tools.grpc.Tools import grpc_message_to_json_string
LOGGER = logging.getLogger(__name__)
MAX_RETRIES = 15
DELAY_FUNCTION = delay_exponential(initial=0.01, increment=2.0, maximum=5.0)
RETRY_DECORATOR = retry(max_retries=MAX_RETRIES, delay_function=DELAY_FUNCTION, prepare_method_name='connect')
class TEServiceClient:
def __init__(self, host=None, port=None):
if not host: host = get_service_host(ServiceNameEnum.TE)
if not port: port = get_service_port_grpc(ServiceNameEnum.TE)
self.endpoint = '{:s}:{:s}'.format(str(host), str(port))
LOGGER.debug('Creating channel to {:s}...'.format(str(self.endpoint)))
self.channel = None
self.stub = None
self.connect()
LOGGER.debug('Channel created')
def connect(self):
self.channel = grpc.insecure_channel(self.endpoint)
self.stub = TEServiceStub(self.channel)
def close(self):
if self.channel is not None: self.channel.close()
self.channel = None
self.stub = None
@RETRY_DECORATOR
def RequestLSP(self, request : Service) -> ServiceStatus:
LOGGER.debug('RequestLSP request: {:s}'.format(grpc_message_to_json_string(request)))
response = self.stub.RequestLSP(request)
LOGGER.debug('RequestLSP result: {:s}'.format(grpc_message_to_json_string(response)))
return response
@RETRY_DECORATOR
def UpdateLSP(self, request : ServiceId) -> ServiceStatus:
LOGGER.debug('UpdateLSP request: {:s}'.format(grpc_message_to_json_string(request)))
response = self.stub.UpdateLSP(request)
LOGGER.debug('UpdateLSP result: {:s}'.format(grpc_message_to_json_string(response)))
return response
@RETRY_DECORATOR
def DeleteLSP(self, request : ServiceId) -> Empty:
LOGGER.debug('DeleteLSP request: {:s}'.format(grpc_message_to_json_string(request)))
response = self.stub.DeleteLSP(request)
LOGGER.debug('DeleteLSP result: {:s}'.format(grpc_message_to_json_string(response)))
return response
...@@ -27,6 +27,7 @@ from common.tools.grpc.Tools import grpc_message_to_json, grpc_message_to_json_s ...@@ -27,6 +27,7 @@ from common.tools.grpc.Tools import grpc_message_to_json, grpc_message_to_json_s
from context.client.ContextClient import ContextClient from context.client.ContextClient import ContextClient
from pathcomp.frontend.client.PathCompClient import PathCompClient from pathcomp.frontend.client.PathCompClient import PathCompClient
from service.service.tools.ConnectionToString import connection_to_string from service.service.tools.ConnectionToString import connection_to_string
from service.client.TEServiceClient import TEServiceClient
from .service_handler_api.ServiceHandlerFactory import ServiceHandlerFactory from .service_handler_api.ServiceHandlerFactory import ServiceHandlerFactory
from .task_scheduler.TaskScheduler import TasksScheduler from .task_scheduler.TaskScheduler import TasksScheduler
from .tools.GeodesicDistance import gps_distance from .tools.GeodesicDistance import gps_distance
...@@ -117,6 +118,28 @@ class ServiceServiceServicerImpl(ServiceServiceServicer): ...@@ -117,6 +118,28 @@ class ServiceServiceServicerImpl(ServiceServiceServicer):
service.service_type = request.service_type # pylint: disable=no-member service.service_type = request.service_type # pylint: disable=no-member
service.service_status.service_status = ServiceStatusEnum.SERVICESTATUS_PLANNED # pylint: disable=no-member service.service_status.service_status = ServiceStatusEnum.SERVICESTATUS_PLANNED # pylint: disable=no-member
if service.service_type == ServiceTypeEnum.SERVICETYPE_TE:
# TE service:
context_client.SetService(request)
te_service_client = TEServiceClient()
service_status = te_service_client.RequestLSP(service)
if service_status.service_status == ServiceStatusEnum.SERVICESTATUS_ACTIVE:
_service : Optional[Service] = get_service_by_id(
context_client, request.service_id, rw_copy=True,
include_config_rules=False, include_constraints=False, include_endpoint_ids=False)
_service.service_status.service_status = ServiceStatusEnum.SERVICESTATUS_ACTIVE
service_id = context_client.SetService(_service)
return service_id
else:
MSG = 'RequestLSP for Service({:s}) returned ServiceStatus({:s})'
context_uuid = request.service_id.context_id.context_uuid.uuid
service_uuid = request.service_id.service_uuid.uuid
service_key = '{:s}/{:s}'.format(context_uuid, service_uuid)
str_service_status = ServiceStatusEnum.Name(service_status.service_status)
raise Exception(MSG.format(service_key, str_service_status))
del service.service_endpoint_ids[:] # pylint: disable=no-member del service.service_endpoint_ids[:] # pylint: disable=no-member
for endpoint_id in request.service_endpoint_ids: for endpoint_id in request.service_endpoint_ids:
service.service_endpoint_ids.add().CopyFrom(endpoint_id) # pylint: disable=no-member service.service_endpoint_ids.add().CopyFrom(endpoint_id) # pylint: disable=no-member
...@@ -214,6 +237,14 @@ class ServiceServiceServicerImpl(ServiceServiceServicer): ...@@ -214,6 +237,14 @@ class ServiceServiceServicerImpl(ServiceServiceServicer):
service.service_status.service_status = ServiceStatusEnum.SERVICESTATUS_PENDING_REMOVAL service.service_status.service_status = ServiceStatusEnum.SERVICESTATUS_PENDING_REMOVAL
context_client.SetService(service) context_client.SetService(service)
if service.service_type == ServiceTypeEnum.SERVICETYPE_TE:
# TE service
te_service_client = TEServiceClient()
te_service_client.DeleteLSP(request)
context_client.RemoveService(request)
return Empty()
# Normal service
# Feed TaskScheduler with this service and the sub-services and sub-connections related to this service. # Feed TaskScheduler with this service and the sub-services and sub-connections related to this service.
# TaskScheduler identifies inter-dependencies among them and produces a schedule of tasks (an ordered list of # TaskScheduler identifies inter-dependencies among them and produces a schedule of tasks (an ordered list of
# tasks to be executed) to implement the requested delete operation. # tasks to be executed) to implement the requested delete operation.
......
...@@ -23,7 +23,8 @@ SERVICE_TYPE_VALUES = { ...@@ -23,7 +23,8 @@ SERVICE_TYPE_VALUES = {
ServiceTypeEnum.SERVICETYPE_UNKNOWN, ServiceTypeEnum.SERVICETYPE_UNKNOWN,
ServiceTypeEnum.SERVICETYPE_L3NM, ServiceTypeEnum.SERVICETYPE_L3NM,
ServiceTypeEnum.SERVICETYPE_L2NM, ServiceTypeEnum.SERVICETYPE_L2NM,
ServiceTypeEnum.SERVICETYPE_TAPI_CONNECTIVITY_SERVICE ServiceTypeEnum.SERVICETYPE_TAPI_CONNECTIVITY_SERVICE,
ServiceTypeEnum.SERVICETYPE_TE,
} }
DEVICE_DRIVER_VALUES = { DEVICE_DRIVER_VALUES = {
......
Dockerfile
_build
README.md
.tool-versions
.tool-versions
.rebar3
_*
.eunit
*.o
*.beam
*.plt
*.swp
*.swo
.erlang.cookie
ebin
log
erl_crash.dump
.rebar
logs
_build
.idea
*.iml
rebar3.crashdump
*~
config/dev.config
# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/)
#
# 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.
# Multi-stage Docker image build
# Build stage 0
FROM erlang:24.3-alpine
RUN apk add --no-cache bash git
RUN mkdir /var/teraflow
WORKDIR /var/teraflow
COPY proto proto
RUN bash -c proto/generate_code_erlang.sh
RUN mkdir src
COPY src/te src/te
WORKDIR src/te
RUN rebar3 as prod release
# Build stage 1
FROM alpine
# Install some libs
RUN apk add --no-cache libgcc libstdc++ && \
apk add --no-cache openssl && \
apk add --no-cache libcrypto1.1 && \
apk add --no-cache ncurses-libs
# Install the released application
COPY --from=0 /var/teraflow/src/te/_build/prod/rel/tfte /tfte
# Expose relevant ports
EXPOSE 10030
EXPOSE 4189
ARG ERLANG_LOGGER_LEVEL_DEFAULT=debug
ARG ERLANG_COOKIE_DEFAULT=tfte-unsafe-cookie
ARG ERLANG_NODE_IP_DEFAULT=127.0.0.1
ARG ERLANG_NODE_NAME_DEFAULT=tfte
ENV ERLANG_LOGGER_LEVEL=$ERLANG_LOGGER_LEVEL_DEFAULT
ENV ERLANG_COOKIE=$ERLANG_COOKIE_DEFAULT
ENV ERLANG_NODE_IP=$ERLANG_NODE_IP_DEFAULT
ENV ERLANG_NODE_NAME=$ERLANG_NODE_NAME_DEFAULT
ENTRYPOINT ["/tfte/bin/tfte"]
CMD ["foreground"]
TeraFlow Traffic Engineering Service
====================================
This service is mean as an example of a Teraflow Service made in Erlang.
The Traffic Engineering service is tested on Ubuntu 20.04. Follow the instructions below to build, test, and run this service on your local environment.
## Build
First the TeraFlow protocol buffer code must have been generated:
$ ../../proto/generate_code_erlang.sh
Then the TE service can be built:
$ rebar3 compile
## Execute Unit Tests
$ rebar3 eunit
## Run Service Console
First you need to crete a configuration file if not already done, and customize it if required:
$ cp config/dev.config.template config/dev.config
Then you can start the service in console mode:
$ rebar3 shell
## Docker
### Build Image
The docker image must be built from the root of the Teraflow project:
$ docker build -t te:dev -f src/te/Dockerfile .
### Run a shell from inside the container
$ docker run -ti --rm --entrypoint sh te:dev
### Run Docker Container
$ docker run -d --name te --init te:dev
### Open a Console to a Docker Container's Service
$ docker exec -it te /tfte/bin/tfte remote_console
### Show Logs
$ docker logs te
## Kubernetes
### Open a Console
$ kubectl --namespace tfs exec -ti $(kubectl --namespace tfs get pods --selector=app=teservice -o name) -c server -- /tfte/bin/tfte remote_console
### Show Logs
$ kubectl --namespace tfs logs $(kubectl --namespace tfs get pods --selector=app=teservice -o name) -c server
## Teraflow
To build and deploy the TE service as part of Teraflow, the following line must be added or uncomented in your `my_deploy.sh`:
export TFS_COMPONENTS="${TFS_COMPONENTS} te"
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment