Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • tfs/controller
1 result
Show changes
Commits on Source (161)
Showing
with 341 additions and 41 deletions
......@@ -52,6 +52,8 @@ include:
- local: '/src/telemetry/.gitlab-ci.yml'
- local: '/src/analytics/.gitlab-ci.yml'
- local: '/src/qos_profile/.gitlab-ci.yml'
- local: '/src/vnt_manager/.gitlab-ci.yml'
- local: '/src/e2e_orchestrator/.gitlab-ci.yml'
# This should be last one: end-to-end integration tests
- local: '/src/tests/.gitlab-ci.yml'
src/tests/ecoc24/
\ No newline at end of file
......@@ -20,8 +20,12 @@ spec:
selector:
matchLabels:
app: e2e-orchestratorservice
replicas: 1
template:
metadata:
annotations:
config.linkerd.io/skip-outbound-ports: "8761"
config.linkerd.io/skip-inbound-ports: "8761"
labels:
app: e2e-orchestratorservice
spec:
......@@ -33,9 +37,18 @@ spec:
ports:
- containerPort: 10050
- containerPort: 9192
- containerPort: 8761
env:
- name: LOG_LEVEL
value: "INFO"
- name: WS_IP_HOST
value: "nbiservice.tfs-ip.svc.cluster.local"
- name: WS_IP_PORT
value: "8761"
- name: WS_E2E_HOST
value: "e2e-orchestratorservice.tfs-e2e.svc.cluster.local"
- name: WS_E2E_PORT
value: "8762"
readinessProbe:
exec:
command: ["/bin/grpc_health_probe", "-addr=:10050"]
......@@ -67,25 +80,6 @@ spec:
- name: metrics
port: 9192
targetPort: 9192
---
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: e2e-orchestratorservice-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: e2e-orchestratorservice
minReplicas: 1
maxReplicas: 20
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 80
#behavior:
# scaleDown:
# stabilizationWindowSeconds: 30
- name: ws
port: 8761
targetPort: 8761
......@@ -23,6 +23,9 @@ spec:
replicas: 1
template:
metadata:
annotations:
config.linkerd.io/skip-inbound-ports: "8762"
config.linkerd.io/skip-outbound-ports: "8762"
labels:
app: nbiservice
spec:
......@@ -35,11 +38,14 @@ spec:
- containerPort: 8080
- containerPort: 9090
- containerPort: 9192
- containerPort: 8762
env:
- name: LOG_LEVEL
value: "INFO"
- name: IETF_NETWORK_RENDERER
value: "LIBYANG"
- name: WS_E2E_PORT
value: "8762"
readinessProbe:
exec:
command: ["/bin/grpc_health_probe", "-addr=:9090"]
......@@ -77,3 +83,7 @@ spec:
protocol: TCP
port: 9192
targetPort: 9192
- name: ws
protocol: TCP
port: 8762
targetPort: 8762
# Copyright 2022-2024 ETSI OSG/SDG TeraFlowSDN (TFS) (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: vnt-managerservice
spec:
selector:
matchLabels:
app: vnt-managerservice
replicas: 1
template:
metadata:
annotations:
config.linkerd.io/skip-outbound-ports: "8765"
config.linkerd.io/skip-inbound-ports: "8765"
labels:
app: vnt-managerservice
spec:
terminationGracePeriodSeconds: 5
containers:
- name: server
image: labs.etsi.org:5050/tfs/controller/vnt_manager:latest
imagePullPolicy: Always
ports:
- containerPort: 10080
- containerPort: 9192
env:
- name: LOG_LEVEL
value: "INFO"
- name: WS_IP_PORT
value: "8761"
- name: WS_E2E_PORT
value: "8762"
readinessProbe:
exec:
command: ["/bin/grpc_health_probe", "-addr=:10080"]
livenessProbe:
exec:
command: ["/bin/grpc_health_probe", "-addr=:10080"]
resources:
requests:
cpu: 250m
memory: 128Mi
limits:
cpu: 1000m
memory: 1024Mi
---
apiVersion: v1
kind: Service
metadata:
name: vnt-managerservice
labels:
app: vnt-managerservice
spec:
type: ClusterIP
selector:
app: vnt-managerservice
ports:
- name: grpc
port: 10080
targetPort: 10080
- name: metrics
port: 9192
targetPort: 9192
......@@ -65,6 +65,9 @@ export TFS_COMPONENTS="context device pathcomp service slice nbi webui"
# Uncomment to activate E2E Orchestrator
#export TFS_COMPONENTS="${TFS_COMPONENTS} e2e_orchestrator"
# Uncomment to activate VNT Manager
#export TFS_COMPONENTS="${TFS_COMPONENTS} vnt_manager"
# Uncomment to activate DLT and Interdomain
#export TFS_COMPONENTS="${TFS_COMPONENTS} interdomain dlt"
#if [[ "$TFS_COMPONENTS" == *"dlt"* ]]; then
......
......@@ -260,6 +260,7 @@ message Link {
string name = 2;
repeated EndPointId link_endpoint_ids = 3;
LinkAttributes attributes = 4;
LinkTypeEnum link_type = 5;
}
message LinkIdList {
......@@ -275,6 +276,13 @@ message LinkEvent {
LinkId link_id = 2;
}
enum LinkTypeEnum {
LINKTYPE_UNKNOWN = 0;
LINKTYPE_COPPER = 1;
LINKTYPE_VIRTUAL_COPPER = 2;
LINKTYPE_OPTICAL = 3;
LINKTYPE_VIRTUAL_OPTICAL = 4;
}
// ----- Service -------------------------------------------------------------------------------------------------------
message ServiceId {
......
......@@ -20,7 +20,8 @@ import "context.proto";
service E2EOrchestratorService {
rpc Compute(E2EOrchestratorRequest) returns (E2EOrchestratorReply) {}
rpc Compute(E2EOrchestratorRequest) returns (E2EOrchestratorReply) {}
rpc PushTopology(context.Topology) returns (context.Empty) {}
}
message E2EOrchestratorRequest {
......
// Copyright 2022-2024 ETSI OSG/SDG TeraFlowSDN (TFS) (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.
// protocol buffers documentation: https://developers.google.com/protocol-buffers/docs/proto3
syntax = "proto3";
package vnt_manager;
import "context.proto";
service VNTManagerService {
rpc VNTSubscript (VNTSubscriptionRequest) returns (VNTSubscriptionReply) {}
rpc ListVirtualLinkIds (context.Empty) returns (context.LinkIdList) {}
rpc ListVirtualLinks (context.Empty) returns (context.LinkList) {}
rpc GetVirtualLink (context.LinkId) returns (context.Link) {}
rpc SetVirtualLink (context.Link) returns (context.LinkId) {}
rpc RemoveVirtualLink (context.LinkId) returns (context.Empty) {}
}
message VNTSubscriptionRequest {
string host = 1;
string port = 2;
}
message VNTSubscriptionReply {
string subscription = 1;
}
#!/bin/bash
# Copyright 2022-2024 ETSI OSG/SDG TeraFlowSDN (TFS) (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.
PROJECTDIR=`pwd`
cd $PROJECTDIR/src
RCFILE=$PROJECTDIR/coverage/.coveragerc
# Run unitary tests and analyze coverage of code at same time
# helpful pytest flags: --log-level=INFO -o log_cli=true --verbose --maxfail=1 --durations=0
coverage run --rcfile=$RCFILE --append -m pytest --log-level=INFO --verbose \
device/tests/gnmi_openconfig/test_unitary_gnmi_openconfig.py
#!/bin/bash
# Copyright 2022-2024 ETSI OSG/SDG TeraFlowSDN (TFS) (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.
PROJECTDIR=`pwd`
cd $PROJECTDIR/src
RCFILE=$PROJECTDIR/coverage/.coveragerc
# Run unitary tests and analyze coverage of code at same time
# helpful pytest flags: --log-level=INFO -o log_cli=true --verbose --maxfail=1 --durations=0
coverage run --rcfile=$RCFILE --append -m pytest --log-level=INFO -o log_cli=true --verbose \
device/tests/test_unitary_openconfig_arista_l2vpn.py
......@@ -24,4 +24,4 @@ export TFS_K8S_NAMESPACE=${TFS_K8S_NAMESPACE:-"tfs"}
# Automated steps start here
########################################################################################################################
kubectl --namespace $TFS_K8S_NAMESPACE logs deployment/e2eorchestratorservice -c server
kubectl --namespace $TFS_K8S_NAMESPACE logs deployment/e2e-orchestratorservice -c server
#!/bin/bash
# Copyright 2022-2024 ETSI OSG/SDG TeraFlowSDN (TFS) (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.
########################################################################################################################
# Define your deployment settings here
########################################################################################################################
# If not already set, set the name of the Kubernetes namespace to deploy to.
export TFS_K8S_NAMESPACE=${TFS_K8S_NAMESPACE:-"tfs"}
########################################################################################################################
# Automated steps start here
########################################################################################################################
kubectl --namespace $TFS_K8S_NAMESPACE logs deployment/vnt_managerservice -c server
......@@ -32,6 +32,7 @@ STR_NEW_COPYRIGHT = 'Copyright 2022-2024 ETSI OSG/SDG TeraFlowSDN (TFS) (https:/
RE_OLD_COPYRIGHTS = [
r'Copyright\ 2021\-2023\ H2020\ TeraFlow\ \(https\:\/\/www\.teraflow\-h2020\.eu\/\)',
r'Copyright\ 2022\-2023\ ETSI\ TeraFlowSDN\ \-\ TFS\ OSG\ \(https\:\/\/tfs\.etsi\.org\/\)',
r'Copyright\ 2022\-2024\ ETSI\ TeraFlowSDN\ \-\ TFS\ OSG\ \(https\:\/\/tfs\.etsi\.org\/\)',
]
RE_OLD_COPYRIGHTS = [
(re.compile(r'.*{}.*'.format(re_old_copyright)), re.compile(re_old_copyright))
......
......@@ -61,6 +61,7 @@ class ServiceNameEnum(Enum):
FORECASTER = 'forecaster'
E2EORCHESTRATOR = 'e2e-orchestrator'
OPTICALCONTROLLER = 'opticalcontroller'
VNTMANAGER = 'vnt-manager'
BGPLS = 'bgpls-speaker'
QKD_APP = 'qkd_app'
KPIMANAGER = 'kpi-manager'
......@@ -100,6 +101,7 @@ DEFAULT_SERVICE_GRPC_PORTS = {
ServiceNameEnum.E2EORCHESTRATOR .value : 10050,
ServiceNameEnum.OPTICALCONTROLLER .value : 10060,
ServiceNameEnum.QKD_APP .value : 10070,
ServiceNameEnum.VNTMANAGER .value : 10080,
ServiceNameEnum.BGPLS .value : 20030,
ServiceNameEnum.QOSPROFILE .value : 20040,
ServiceNameEnum.KPIMANAGER .value : 30010,
......
......@@ -43,13 +43,14 @@ def json_endpoint_ids(
def json_endpoint(
device_id : Dict, endpoint_uuid : str, endpoint_type : str, topology_id : Optional[Dict] = None,
kpi_sample_types : List[int] = [], location : Optional[Dict] = None
name : Optional[str] = None, kpi_sample_types : List[int] = [], location : Optional[Dict] = None
):
result = {
'endpoint_id': json_endpoint_id(device_id, endpoint_uuid, topology_id=topology_id),
'endpoint_type': endpoint_type,
}
if name is not None: result['name'] = name
if kpi_sample_types is not None and len(kpi_sample_types) > 0:
result['kpi_sample_types'] = copy.deepcopy(kpi_sample_types)
if location is not None:
......
......@@ -48,6 +48,8 @@ def validate_device_driver_enum(message):
'DEVICEDRIVER_GNMI_OPENCONFIG',
'DEVICEDRIVER_OPTICAL_TFS',
'DEVICEDRIVER_IETF_ACTN',
'DEVICEDRIVER_OC',
'DEVICEDRIVER_QKD',
]
def validate_device_operational_status_enum(message):
......@@ -58,6 +60,20 @@ def validate_device_operational_status_enum(message):
'DEVICEOPERATIONALSTATUS_ENABLED'
]
def validate_isolation_level_enum(message):
assert isinstance(message, str)
assert message in [
'NO_ISOLATION',
'PHYSICAL_ISOLATION',
'LOGICAL_ISOLATION',
'PROCESS_ISOLATION',
'PHYSICAL_MEMORY_ISOLATION',
'PHYSICAL_NETWORK_ISOLATION',
'VIRTUAL_RESOURCE_ISOLATION',
'NETWORK_FUNCTIONS_ISOLATION',
'SERVICE_ISOLATION',
]
def validate_kpi_sample_types_enum(message):
assert isinstance(message, str)
assert message in [
......@@ -70,6 +86,16 @@ def validate_kpi_sample_types_enum(message):
'KPISAMPLETYPE_LINK_USED_CAPACITY_GBPS',
]
def validate_link_type_enum(message):
assert isinstance(message, str)
assert message in [
'LINKTYPE_UNKNOWN',
'LINKTYPE_COPPER',
'LINKTYPE_VIRTUAL_COPPER',
'LINKTYPE_OPTICAL',
'LINKTYPE_VIRTUAL_OPTICAL',
]
def validate_service_type_enum(message):
assert isinstance(message, str)
assert message in [
......@@ -79,6 +105,8 @@ def validate_service_type_enum(message):
'SERVICETYPE_TAPI_CONNECTIVITY_SERVICE',
'SERVICETYPE_TE',
'SERVICETYPE_E2E',
'SERVICETYPE_OPTICAL_CONNECTIVITY',
'SERVICETYPE_QKD',
]
def validate_service_state_enum(message):
......@@ -148,6 +176,22 @@ def validate_constraint_custom(message):
assert 'constraint_value' in message
assert isinstance(message['constraint_value'], str)
def validate_constraint_schedule(message):
assert isinstance(message, dict)
assert len(message.keys()) == 2
assert 'start_timestamp' in message
assert isinstance(message['start_timestamp'], (int, float))
assert 'duration_days' in message
assert isinstance(message['duration_days'], (int, float))
def validate_constraint_endpoint_priority(message):
assert isinstance(message, dict)
assert len(message.keys()) == 2
assert 'endpoint_id' in message
validate_endpoint_id(message['endpoint_id'])
assert 'priority' in message
assert isinstance(message['priority'], int)
def validate_constraint_sla_capacity(message):
assert isinstance(message, dict)
assert len(message.keys()) == 1
......@@ -172,16 +216,25 @@ def validate_constraint_sla_availability(message):
assert isinstance(message['availability'], (int, float))
assert message['availability'] >= 0 and message['availability'] <= 100
def validate_constraint_sla_isolation(message):
assert isinstance(message, dict)
assert len(message.keys()) == 1
assert 'isolation_level' in message
assert isinstance(message['isolation_level'], list)
for isolation_level in message['isolation_level']:
validate_isolation_level_enum(isolation_level)
CONSTRAINT_TYPE_TO_VALIDATOR = {
'custom' : validate_constraint_custom,
#'schedule' : validate_constraint_schedule,
'schedule' : validate_constraint_schedule,
#'endpoint_location' : validate_constraint_endpoint_location,
#'endpoint_priority' : validate_constraint_endpoint_priority,
'endpoint_priority' : validate_constraint_endpoint_priority,
'sla_capacity' : validate_constraint_sla_capacity,
'sla_latency' : validate_constraint_sla_latency,
'sla_availability' : validate_constraint_sla_availability,
#'sla_isolation' : validate_constraint_sla_isolation,
'sla_isolation' : validate_constraint_sla_isolation,
#'exclusions' : validate_constraint_exclusions,
#'qos_profile' : validate_constraint_qos_profile,
}
def validate_constraint(message):
......@@ -479,7 +532,7 @@ def validate_device(message):
def validate_link(message):
assert isinstance(message, dict)
assert len(message.keys()) == 4
assert len(message.keys()) == 5
assert 'link_id' in message
validate_link_id(message['link_id'])
assert 'name' in message
......@@ -489,6 +542,8 @@ def validate_link(message):
for endpoint_id in message['link_endpoint_ids']: validate_endpoint_id(endpoint_id)
assert 'attributes' in message
validate_link_attributes(message['attributes'])
assert 'link_type' in message
validate_link_type_enum(message['link_type'])
def validate_connection(message):
assert isinstance(message, dict)
......
......@@ -16,9 +16,24 @@ FROM python:3.9-slim
# Install dependencies
RUN apt-get --yes --quiet --quiet update && \
apt-get --yes --quiet --quiet install wget g++ git && \
apt-get --yes --quiet --quiet install wget g++ git build-essential cmake libpcre2-dev python3-dev python3-cffi && \
rm -rf /var/lib/apt/lists/*
# Download, build and install libyang. Note that APT package is outdated
# - Ref: https://github.com/CESNET/libyang
# - Ref: https://github.com/CESNET/libyang-python/
RUN mkdir -p /var/libyang
RUN git clone https://github.com/CESNET/libyang.git /var/libyang
WORKDIR /var/libyang
RUN git fetch
RUN git checkout v2.1.148
RUN mkdir -p /var/libyang/build
WORKDIR /var/libyang/build
RUN cmake -D CMAKE_BUILD_TYPE:String="Release" ..
RUN make
RUN make install
RUN ldconfig
# Set Python to show logs as they occur
ENV PYTHONUNBUFFERED=0
......@@ -62,17 +77,30 @@ RUN python3 -m pip install -r requirements.txt
# Add component files into working directory
WORKDIR /var/teraflow
COPY src/device/. device/
COPY src/context/__init__.py context/__init__.py
COPY src/context/client/. context/client/
COPY src/monitoring/__init__.py monitoring/__init__.py
COPY src/monitoring/client/. monitoring/client/
COPY src/device/. device/
# Clone test mock tools
RUN mkdir -p tests/tools/mock_ietf_actn_sdn_ctrl
RUN touch tests/__init__.py
RUN touch tests/tools/__init__.py
RUN touch tests/tools/mock_ietf_actn_sdn_ctrl/__init__.py
COPY src/tests/tools/mock_ietf_actn_sdn_ctrl/. tests/tools/mock_ietf_actn_sdn_ctrl/
# Clone OpenConfig YANG models
RUN mkdir -p /var/teraflow/device/service/drivers/gnmi_openconfig/git/openconfig/public
RUN mkdir -p /tmp/openconfig
RUN git clone https://github.com/openconfig/public.git /tmp/openconfig
WORKDIR /tmp/openconfig
RUN git fetch
RUN git checkout v4.4.0
RUN mv /tmp/openconfig/release /var/teraflow/device/service/drivers/gnmi_openconfig/git/openconfig/public
RUN mv /tmp/openconfig/third_party /var/teraflow/device/service/drivers/gnmi_openconfig/git/openconfig/public
RUN rm -rf /tmp/openconfig
WORKDIR /var/teraflow
# Start the service
ENTRYPOINT ["python", "-m", "device.service"]
......@@ -12,9 +12,9 @@
# See the License for the specific language governing permissions and
# limitations under the License.
anytree==2.8.0
APScheduler==3.10.1
bitarray==2.8.*
cryptography==36.0.2
deepdiff==6.7.*
deepmerge==1.1.*
......@@ -22,26 +22,27 @@ deepmerge==1.1.*
Flask==2.1.3
Flask-HTTPAuth==4.5.0
Flask-RESTful==0.3.9
ipaddress
Jinja2==3.0.3
numpy<2.0.0
libyang==2.8.0
macaddress
ncclient==0.6.15
numpy<2.0.0
p4runtime==1.3.0
pandas==1.5.*
paramiko==2.9.2
pyang==2.6.*
git+https://github.com/robshakir/pyangbind.git
python-json-logger==2.0.2
#pytz==2021.3
#redis==4.1.2
requests==2.27.1
requests-mock==1.9.3
xmltodict==0.12.0
tabulate
ipaddress
macaddress
yattag
pyang==2.6.0
git+https://github.com/robshakir/pyangbind.git
websockets==10.4
werkzeug==2.3.7
xmltodict==0.12.0
yattag
# pip's dependency resolver does not take into account installed packages.
# p4runtime does not specify the version of grpcio/protobuf it needs, so it tries to install latest one
......
......@@ -16,8 +16,10 @@ import logging, signal, sys, threading
from prometheus_client import start_http_server
from common.Constants import ServiceNameEnum
from common.Settings import (
ENVVAR_SUFIX_SERVICE_HOST, ENVVAR_SUFIX_SERVICE_PORT_GRPC, get_env_var_name, get_log_level, get_metrics_port,
wait_for_environment_variables)
ENVVAR_SUFIX_SERVICE_HOST, ENVVAR_SUFIX_SERVICE_PORT_GRPC,
get_env_var_name, get_log_level, get_metrics_port,
wait_for_environment_variables
)
from .DeviceService import DeviceService
from .driver_api.DriverFactory import DriverFactory
from .driver_api.DriverInstanceCache import DriverInstanceCache, preload_drivers
......