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: ...@@ -52,6 +52,8 @@ include:
- local: '/src/telemetry/.gitlab-ci.yml' - local: '/src/telemetry/.gitlab-ci.yml'
- local: '/src/analytics/.gitlab-ci.yml' - local: '/src/analytics/.gitlab-ci.yml'
- local: '/src/qos_profile/.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 # This should be last one: end-to-end integration tests
- local: '/src/tests/.gitlab-ci.yml' - local: '/src/tests/.gitlab-ci.yml'
src/tests/ecoc24/
\ No newline at end of file
...@@ -20,8 +20,12 @@ spec: ...@@ -20,8 +20,12 @@ spec:
selector: selector:
matchLabels: matchLabels:
app: e2e-orchestratorservice app: e2e-orchestratorservice
replicas: 1
template: template:
metadata: metadata:
annotations:
config.linkerd.io/skip-outbound-ports: "8761"
config.linkerd.io/skip-inbound-ports: "8761"
labels: labels:
app: e2e-orchestratorservice app: e2e-orchestratorservice
spec: spec:
...@@ -33,9 +37,18 @@ spec: ...@@ -33,9 +37,18 @@ spec:
ports: ports:
- containerPort: 10050 - containerPort: 10050
- containerPort: 9192 - containerPort: 9192
- containerPort: 8761
env: env:
- name: LOG_LEVEL - name: LOG_LEVEL
value: "INFO" 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: readinessProbe:
exec: exec:
command: ["/bin/grpc_health_probe", "-addr=:10050"] command: ["/bin/grpc_health_probe", "-addr=:10050"]
...@@ -67,25 +80,6 @@ spec: ...@@ -67,25 +80,6 @@ spec:
- name: metrics - name: metrics
port: 9192 port: 9192
targetPort: 9192 targetPort: 9192
--- - name: ws
apiVersion: autoscaling/v2 port: 8761
kind: HorizontalPodAutoscaler targetPort: 8761
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
...@@ -23,6 +23,9 @@ spec: ...@@ -23,6 +23,9 @@ spec:
replicas: 1 replicas: 1
template: template:
metadata: metadata:
annotations:
config.linkerd.io/skip-inbound-ports: "8762"
config.linkerd.io/skip-outbound-ports: "8762"
labels: labels:
app: nbiservice app: nbiservice
spec: spec:
...@@ -35,11 +38,14 @@ spec: ...@@ -35,11 +38,14 @@ spec:
- containerPort: 8080 - containerPort: 8080
- containerPort: 9090 - containerPort: 9090
- containerPort: 9192 - containerPort: 9192
- containerPort: 8762
env: env:
- name: LOG_LEVEL - name: LOG_LEVEL
value: "INFO" value: "INFO"
- name: IETF_NETWORK_RENDERER - name: IETF_NETWORK_RENDERER
value: "LIBYANG" value: "LIBYANG"
- name: WS_E2E_PORT
value: "8762"
readinessProbe: readinessProbe:
exec: exec:
command: ["/bin/grpc_health_probe", "-addr=:9090"] command: ["/bin/grpc_health_probe", "-addr=:9090"]
...@@ -77,3 +83,7 @@ spec: ...@@ -77,3 +83,7 @@ spec:
protocol: TCP protocol: TCP
port: 9192 port: 9192
targetPort: 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" ...@@ -65,6 +65,9 @@ export TFS_COMPONENTS="context device pathcomp service slice nbi webui"
# Uncomment to activate E2E Orchestrator # Uncomment to activate E2E Orchestrator
#export TFS_COMPONENTS="${TFS_COMPONENTS} 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 # Uncomment to activate DLT and Interdomain
#export TFS_COMPONENTS="${TFS_COMPONENTS} interdomain dlt" #export TFS_COMPONENTS="${TFS_COMPONENTS} interdomain dlt"
#if [[ "$TFS_COMPONENTS" == *"dlt"* ]]; then #if [[ "$TFS_COMPONENTS" == *"dlt"* ]]; then
......
...@@ -260,6 +260,7 @@ message Link { ...@@ -260,6 +260,7 @@ message Link {
string name = 2; string name = 2;
repeated EndPointId link_endpoint_ids = 3; repeated EndPointId link_endpoint_ids = 3;
LinkAttributes attributes = 4; LinkAttributes attributes = 4;
LinkTypeEnum link_type = 5;
} }
message LinkIdList { message LinkIdList {
...@@ -275,6 +276,13 @@ message LinkEvent { ...@@ -275,6 +276,13 @@ message LinkEvent {
LinkId link_id = 2; LinkId link_id = 2;
} }
enum LinkTypeEnum {
LINKTYPE_UNKNOWN = 0;
LINKTYPE_COPPER = 1;
LINKTYPE_VIRTUAL_COPPER = 2;
LINKTYPE_OPTICAL = 3;
LINKTYPE_VIRTUAL_OPTICAL = 4;
}
// ----- Service ------------------------------------------------------------------------------------------------------- // ----- Service -------------------------------------------------------------------------------------------------------
message ServiceId { message ServiceId {
......
...@@ -20,7 +20,8 @@ import "context.proto"; ...@@ -20,7 +20,8 @@ import "context.proto";
service E2EOrchestratorService { service E2EOrchestratorService {
rpc Compute(E2EOrchestratorRequest) returns (E2EOrchestratorReply) {} rpc Compute(E2EOrchestratorRequest) returns (E2EOrchestratorReply) {}
rpc PushTopology(context.Topology) returns (context.Empty) {}
} }
message E2EOrchestratorRequest { 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"} ...@@ -24,4 +24,4 @@ export TFS_K8S_NAMESPACE=${TFS_K8S_NAMESPACE:-"tfs"}
# Automated steps start here # 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:/ ...@@ -32,6 +32,7 @@ STR_NEW_COPYRIGHT = 'Copyright 2022-2024 ETSI OSG/SDG TeraFlowSDN (TFS) (https:/
RE_OLD_COPYRIGHTS = [ RE_OLD_COPYRIGHTS = [
r'Copyright\ 2021\-2023\ H2020\ TeraFlow\ \(https\:\/\/www\.teraflow\-h2020\.eu\/\)', 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\-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_OLD_COPYRIGHTS = [
(re.compile(r'.*{}.*'.format(re_old_copyright)), re.compile(re_old_copyright)) (re.compile(r'.*{}.*'.format(re_old_copyright)), re.compile(re_old_copyright))
......
...@@ -61,6 +61,7 @@ class ServiceNameEnum(Enum): ...@@ -61,6 +61,7 @@ class ServiceNameEnum(Enum):
FORECASTER = 'forecaster' FORECASTER = 'forecaster'
E2EORCHESTRATOR = 'e2e-orchestrator' E2EORCHESTRATOR = 'e2e-orchestrator'
OPTICALCONTROLLER = 'opticalcontroller' OPTICALCONTROLLER = 'opticalcontroller'
VNTMANAGER = 'vnt-manager'
BGPLS = 'bgpls-speaker' BGPLS = 'bgpls-speaker'
QKD_APP = 'qkd_app' QKD_APP = 'qkd_app'
KPIMANAGER = 'kpi-manager' KPIMANAGER = 'kpi-manager'
...@@ -100,6 +101,7 @@ DEFAULT_SERVICE_GRPC_PORTS = { ...@@ -100,6 +101,7 @@ DEFAULT_SERVICE_GRPC_PORTS = {
ServiceNameEnum.E2EORCHESTRATOR .value : 10050, ServiceNameEnum.E2EORCHESTRATOR .value : 10050,
ServiceNameEnum.OPTICALCONTROLLER .value : 10060, ServiceNameEnum.OPTICALCONTROLLER .value : 10060,
ServiceNameEnum.QKD_APP .value : 10070, ServiceNameEnum.QKD_APP .value : 10070,
ServiceNameEnum.VNTMANAGER .value : 10080,
ServiceNameEnum.BGPLS .value : 20030, ServiceNameEnum.BGPLS .value : 20030,
ServiceNameEnum.QOSPROFILE .value : 20040, ServiceNameEnum.QOSPROFILE .value : 20040,
ServiceNameEnum.KPIMANAGER .value : 30010, ServiceNameEnum.KPIMANAGER .value : 30010,
......
...@@ -43,13 +43,14 @@ def json_endpoint_ids( ...@@ -43,13 +43,14 @@ def json_endpoint_ids(
def json_endpoint( def json_endpoint(
device_id : Dict, endpoint_uuid : str, endpoint_type : str, topology_id : Optional[Dict] = None, 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 = { result = {
'endpoint_id': json_endpoint_id(device_id, endpoint_uuid, topology_id=topology_id), 'endpoint_id': json_endpoint_id(device_id, endpoint_uuid, topology_id=topology_id),
'endpoint_type': endpoint_type, '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: if kpi_sample_types is not None and len(kpi_sample_types) > 0:
result['kpi_sample_types'] = copy.deepcopy(kpi_sample_types) result['kpi_sample_types'] = copy.deepcopy(kpi_sample_types)
if location is not None: if location is not None:
......
...@@ -48,6 +48,8 @@ def validate_device_driver_enum(message): ...@@ -48,6 +48,8 @@ def validate_device_driver_enum(message):
'DEVICEDRIVER_GNMI_OPENCONFIG', 'DEVICEDRIVER_GNMI_OPENCONFIG',
'DEVICEDRIVER_OPTICAL_TFS', 'DEVICEDRIVER_OPTICAL_TFS',
'DEVICEDRIVER_IETF_ACTN', 'DEVICEDRIVER_IETF_ACTN',
'DEVICEDRIVER_OC',
'DEVICEDRIVER_QKD',
] ]
def validate_device_operational_status_enum(message): def validate_device_operational_status_enum(message):
...@@ -58,6 +60,20 @@ def validate_device_operational_status_enum(message): ...@@ -58,6 +60,20 @@ def validate_device_operational_status_enum(message):
'DEVICEOPERATIONALSTATUS_ENABLED' '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): def validate_kpi_sample_types_enum(message):
assert isinstance(message, str) assert isinstance(message, str)
assert message in [ assert message in [
...@@ -70,6 +86,16 @@ def validate_kpi_sample_types_enum(message): ...@@ -70,6 +86,16 @@ def validate_kpi_sample_types_enum(message):
'KPISAMPLETYPE_LINK_USED_CAPACITY_GBPS', '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): def validate_service_type_enum(message):
assert isinstance(message, str) assert isinstance(message, str)
assert message in [ assert message in [
...@@ -79,6 +105,8 @@ def validate_service_type_enum(message): ...@@ -79,6 +105,8 @@ def validate_service_type_enum(message):
'SERVICETYPE_TAPI_CONNECTIVITY_SERVICE', 'SERVICETYPE_TAPI_CONNECTIVITY_SERVICE',
'SERVICETYPE_TE', 'SERVICETYPE_TE',
'SERVICETYPE_E2E', 'SERVICETYPE_E2E',
'SERVICETYPE_OPTICAL_CONNECTIVITY',
'SERVICETYPE_QKD',
] ]
def validate_service_state_enum(message): def validate_service_state_enum(message):
...@@ -148,6 +176,22 @@ def validate_constraint_custom(message): ...@@ -148,6 +176,22 @@ def validate_constraint_custom(message):
assert 'constraint_value' in message assert 'constraint_value' in message
assert isinstance(message['constraint_value'], str) 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): def validate_constraint_sla_capacity(message):
assert isinstance(message, dict) assert isinstance(message, dict)
assert len(message.keys()) == 1 assert len(message.keys()) == 1
...@@ -172,16 +216,25 @@ def validate_constraint_sla_availability(message): ...@@ -172,16 +216,25 @@ def validate_constraint_sla_availability(message):
assert isinstance(message['availability'], (int, float)) assert isinstance(message['availability'], (int, float))
assert message['availability'] >= 0 and message['availability'] <= 100 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 = { CONSTRAINT_TYPE_TO_VALIDATOR = {
'custom' : validate_constraint_custom, 'custom' : validate_constraint_custom,
#'schedule' : validate_constraint_schedule, 'schedule' : validate_constraint_schedule,
#'endpoint_location' : validate_constraint_endpoint_location, #'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_capacity' : validate_constraint_sla_capacity,
'sla_latency' : validate_constraint_sla_latency, 'sla_latency' : validate_constraint_sla_latency,
'sla_availability' : validate_constraint_sla_availability, 'sla_availability' : validate_constraint_sla_availability,
#'sla_isolation' : validate_constraint_sla_isolation, 'sla_isolation' : validate_constraint_sla_isolation,
#'exclusions' : validate_constraint_exclusions, #'exclusions' : validate_constraint_exclusions,
#'qos_profile' : validate_constraint_qos_profile,
} }
def validate_constraint(message): def validate_constraint(message):
...@@ -479,7 +532,7 @@ def validate_device(message): ...@@ -479,7 +532,7 @@ def validate_device(message):
def validate_link(message): def validate_link(message):
assert isinstance(message, dict) assert isinstance(message, dict)
assert len(message.keys()) == 4 assert len(message.keys()) == 5
assert 'link_id' in message assert 'link_id' in message
validate_link_id(message['link_id']) validate_link_id(message['link_id'])
assert 'name' in message assert 'name' in message
...@@ -489,6 +542,8 @@ def validate_link(message): ...@@ -489,6 +542,8 @@ def validate_link(message):
for endpoint_id in message['link_endpoint_ids']: validate_endpoint_id(endpoint_id) for endpoint_id in message['link_endpoint_ids']: validate_endpoint_id(endpoint_id)
assert 'attributes' in message assert 'attributes' in message
validate_link_attributes(message['attributes']) validate_link_attributes(message['attributes'])
assert 'link_type' in message
validate_link_type_enum(message['link_type'])
def validate_connection(message): def validate_connection(message):
assert isinstance(message, dict) assert isinstance(message, dict)
......
...@@ -16,9 +16,24 @@ FROM python:3.9-slim ...@@ -16,9 +16,24 @@ FROM python:3.9-slim
# Install dependencies # Install dependencies
RUN apt-get --yes --quiet --quiet update && \ 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/* 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 # Set Python to show logs as they occur
ENV PYTHONUNBUFFERED=0 ENV PYTHONUNBUFFERED=0
...@@ -62,17 +77,30 @@ RUN python3 -m pip install -r requirements.txt ...@@ -62,17 +77,30 @@ RUN python3 -m pip install -r requirements.txt
# Add component files into working directory # Add component files into working directory
WORKDIR /var/teraflow WORKDIR /var/teraflow
COPY src/device/. device/
COPY src/context/__init__.py context/__init__.py COPY src/context/__init__.py context/__init__.py
COPY src/context/client/. context/client/ COPY src/context/client/. context/client/
COPY src/monitoring/__init__.py monitoring/__init__.py COPY src/monitoring/__init__.py monitoring/__init__.py
COPY src/monitoring/client/. monitoring/client/ 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 mkdir -p tests/tools/mock_ietf_actn_sdn_ctrl
RUN touch tests/__init__.py RUN touch tests/__init__.py
RUN touch tests/tools/__init__.py RUN touch tests/tools/__init__.py
RUN touch tests/tools/mock_ietf_actn_sdn_ctrl/__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/ 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 # Start the service
ENTRYPOINT ["python", "-m", "device.service"] ENTRYPOINT ["python", "-m", "device.service"]
...@@ -12,9 +12,9 @@ ...@@ -12,9 +12,9 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
anytree==2.8.0 anytree==2.8.0
APScheduler==3.10.1 APScheduler==3.10.1
bitarray==2.8.*
cryptography==36.0.2 cryptography==36.0.2
deepdiff==6.7.* deepdiff==6.7.*
deepmerge==1.1.* deepmerge==1.1.*
...@@ -22,26 +22,27 @@ deepmerge==1.1.* ...@@ -22,26 +22,27 @@ deepmerge==1.1.*
Flask==2.1.3 Flask==2.1.3
Flask-HTTPAuth==4.5.0 Flask-HTTPAuth==4.5.0
Flask-RESTful==0.3.9 Flask-RESTful==0.3.9
ipaddress
Jinja2==3.0.3 Jinja2==3.0.3
numpy<2.0.0 libyang==2.8.0
macaddress
ncclient==0.6.15 ncclient==0.6.15
numpy<2.0.0
p4runtime==1.3.0 p4runtime==1.3.0
pandas==1.5.* pandas==1.5.*
paramiko==2.9.2 paramiko==2.9.2
pyang==2.6.*
git+https://github.com/robshakir/pyangbind.git
python-json-logger==2.0.2 python-json-logger==2.0.2
#pytz==2021.3 #pytz==2021.3
#redis==4.1.2 #redis==4.1.2
requests==2.27.1 requests==2.27.1
requests-mock==1.9.3 requests-mock==1.9.3
xmltodict==0.12.0
tabulate tabulate
ipaddress
macaddress
yattag
pyang==2.6.0
git+https://github.com/robshakir/pyangbind.git
websockets==10.4 websockets==10.4
werkzeug==2.3.7 werkzeug==2.3.7
xmltodict==0.12.0
yattag
# pip's dependency resolver does not take into account installed packages. # 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 # 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 ...@@ -16,8 +16,10 @@ import logging, signal, sys, threading
from prometheus_client import start_http_server from prometheus_client import start_http_server
from common.Constants import ServiceNameEnum from common.Constants import ServiceNameEnum
from common.Settings import ( from common.Settings import (
ENVVAR_SUFIX_SERVICE_HOST, ENVVAR_SUFIX_SERVICE_PORT_GRPC, get_env_var_name, get_log_level, get_metrics_port, ENVVAR_SUFIX_SERVICE_HOST, ENVVAR_SUFIX_SERVICE_PORT_GRPC,
wait_for_environment_variables) get_env_var_name, get_log_level, get_metrics_port,
wait_for_environment_variables
)
from .DeviceService import DeviceService from .DeviceService import DeviceService
from .driver_api.DriverFactory import DriverFactory from .driver_api.DriverFactory import DriverFactory
from .driver_api.DriverInstanceCache import DriverInstanceCache, preload_drivers from .driver_api.DriverInstanceCache import DriverInstanceCache, preload_drivers
......