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

Initial functional versions of Interdomain and Slice components

parent 8cfa12d1
No related branches found
No related tags found
1 merge request!54Release 2.0.0
Showing
with 331 additions and 62 deletions
# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
#
# 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.
# stages of the cicd pipeline # stages of the cicd pipeline
stages: stages:
- dependencies - dependencies
...@@ -21,6 +35,8 @@ include: ...@@ -21,6 +35,8 @@ include:
- local: '/src/opticalcentralizedattackdetector/.gitlab-ci.yml' - local: '/src/opticalcentralizedattackdetector/.gitlab-ci.yml'
- local: '/src/automation/.gitlab-ci.yml' - local: '/src/automation/.gitlab-ci.yml'
- local: '/src/webui/.gitlab-ci.yml' - local: '/src/webui/.gitlab-ci.yml'
- local: '/src/l3_distributedattackdetector/.gitlab-ci.yml' #- local: '/src/l3_distributedattackdetector/.gitlab-ci.yml'
- local: '/src/l3_centralizedattackdetector/.gitlab-ci.yml' #- local: '/src/l3_centralizedattackdetector/.gitlab-ci.yml'
- local: '/src/l3_attackmitigator/.gitlab-ci.yml' #- local: '/src/l3_attackmitigator/.gitlab-ci.yml'
#- local: '/src/slice/.gitlab-ci.yml'
#- local: '/src/interdomain/.gitlab-ci.yml'
...@@ -131,9 +131,12 @@ for COMPONENT in $COMPONENTS; do ...@@ -131,9 +131,12 @@ for COMPONENT in $COMPONENTS; do
printf "\n" printf "\n"
done done
echo "Configuring DataStores and Dashboards..."
./configure_dashboards.sh if [[ "$COMPONENTS" == *"webui"* ]]; then
printf "\n\n" echo "Configuring WebUI DataStores and Dashboards..."
./configure_dashboards.sh
printf "\n\n"
fi
echo "Reporting Deployment..." echo "Reporting Deployment..."
kubectl --namespace $K8S_NAMESPACE get all kubectl --namespace $K8S_NAMESPACE get all
......
# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
#
# 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: interdomainservice
spec:
selector:
matchLabels:
app: interdomainservice
template:
metadata:
labels:
app: interdomainservice
spec:
terminationGracePeriodSeconds: 5
containers:
- name: server
image: registry.gitlab.com/teraflow-h2020/controller/interdomain:latest
imagePullPolicy: Always
ports:
- containerPort: 10010
env:
- name: LOG_LEVEL
value: "DEBUG"
readinessProbe:
exec:
command: ["/bin/grpc_health_probe", "-addr=:10010"]
livenessProbe:
exec:
command: ["/bin/grpc_health_probe", "-addr=:10010"]
resources:
requests:
cpu: 250m
memory: 512Mi
limits:
cpu: 700m
memory: 1024Mi
---
apiVersion: v1
kind: Service
metadata:
name: interdomainservice
spec:
type: ClusterIP
selector:
app: interdomainservice
ports:
- name: grpc
protocol: TCP
port: 10010
targetPort: 10010
# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
#
# 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: sliceservice
spec:
selector:
matchLabels:
app: sliceservice
template:
metadata:
labels:
app: sliceservice
spec:
terminationGracePeriodSeconds: 5
containers:
- name: server
image: registry.gitlab.com/teraflow-h2020/controller/slice:latest
imagePullPolicy: Always
ports:
- containerPort: 4040
env:
- name: LOG_LEVEL
value: "DEBUG"
readinessProbe:
exec:
command: ["/bin/grpc_health_probe", "-addr=:4040"]
livenessProbe:
exec:
command: ["/bin/grpc_health_probe", "-addr=:4040"]
resources:
requests:
cpu: 250m
memory: 512Mi
limits:
cpu: 700m
memory: 1024Mi
---
apiVersion: v1
kind: Service
metadata:
name: sliceservice
spec:
type: ClusterIP
selector:
app: sliceservice
ports:
- name: grpc
protocol: TCP
port: 4040
targetPort: 4040
...@@ -71,14 +71,14 @@ spec: ...@@ -71,14 +71,14 @@ spec:
path: /robots.txt path: /robots.txt
port: 3000 port: 3000
scheme: HTTP scheme: HTTP
initialDelaySeconds: 5 initialDelaySeconds: 10
periodSeconds: 5 periodSeconds: 30
successThreshold: 1 successThreshold: 1
timeoutSeconds: 2 timeoutSeconds: 2
livenessProbe: livenessProbe:
failureThreshold: 3 failureThreshold: 3
initialDelaySeconds: 5 initialDelaySeconds: 30
periodSeconds: 5 periodSeconds: 10
successThreshold: 1 successThreshold: 1
tcpSocket: tcpSocket:
port: 3000 port: 3000
......
src/tests/oeccpsc22/
\ No newline at end of file
...@@ -53,6 +53,13 @@ service ContextService { ...@@ -53,6 +53,13 @@ service ContextService {
rpc RemoveService (ServiceId ) returns ( Empty ) {} rpc RemoveService (ServiceId ) returns ( Empty ) {}
rpc GetServiceEvents (Empty ) returns (stream ServiceEvent ) {} rpc GetServiceEvents (Empty ) returns (stream ServiceEvent ) {}
rpc ListSliceIds (ContextId ) returns ( SliceIdList ) {}
rpc ListSlices (ContextId ) returns ( SliceList ) {}
rpc GetSlice (SliceId ) returns ( Slice ) {}
rpc SetSlice (Slice ) returns ( SliceId ) {}
rpc RemoveSlice (SliceId ) returns ( Empty ) {}
rpc GetSliceEvents (Empty ) returns (stream SliceEvent ) {}
rpc ListConnectionIds (ServiceId ) returns ( ConnectionIdList) {} rpc ListConnectionIds (ServiceId ) returns ( ConnectionIdList) {}
rpc ListConnections (ServiceId ) returns ( ConnectionList ) {} rpc ListConnections (ServiceId ) returns ( ConnectionList ) {}
rpc GetConnection (ConnectionId) returns ( Connection ) {} rpc GetConnection (ConnectionId) returns ( Connection ) {}
...@@ -253,6 +260,45 @@ message ServiceEvent { ...@@ -253,6 +260,45 @@ message ServiceEvent {
ServiceId service_id = 2; ServiceId service_id = 2;
} }
// ----- Slice ---------------------------------------------------------------------------------------------------------
message SliceId {
ContextId context_id = 1;
Uuid slice_uuid = 2;
}
message Slice {
SliceId slice_id = 1;
repeated EndPointId slice_endpoint_ids = 2;
repeated Constraint slice_constraints = 3;
repeated ServiceId slice_service_ids = 4;
repeated SliceId slice_subslice_ids = 5;
SliceStatus slice_status = 6;
}
enum SliceStatusEnum {
SLICESTATUS_UNDEFINED = 0;
SLICESTATUS_PLANNED = 1;
SLICESTATUS_INIT = 2;
SLICESTATUS_ACTIVE = 3;
SLICESTATUS_DEINIT = 4;
}
message SliceStatus {
SliceStatusEnum slice_status = 1;
}
message SliceIdList {
repeated SliceId slice_ids = 1;
}
message SliceList {
repeated Slice slices = 1;
}
message SliceEvent {
Event event = 1;
SliceId slice_id = 2;
}
// ----- Connection ---------------------------------------------------------------------------------------------------- // ----- Connection ----------------------------------------------------------------------------------------------------
message ConnectionId { message ConnectionId {
......
...@@ -12,23 +12,15 @@ ...@@ -12,23 +12,15 @@
// 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.
//Example of topology
syntax = "proto3"; syntax = "proto3";
package interdomain; package interdomain;
import "context.proto"; import "context.proto";
import "slice.proto";
service InterdomainService { service InterdomainService {
rpc Authenticate (context.TeraFlowController) returns (context.AuthenticationResult) {} rpc Authenticate (context.TeraFlowController) returns (context.AuthenticationResult) {}
rpc LookUpSlice(slice.TransportSlice) returns (slice.SliceId) {} //Slice component or from interdomain component rpc RequestSlice (context.Slice ) returns (context.SliceId ) {}
rpc OrderSliceFromCatalog(slice.TransportSlice) returns (slice.SliceStatus) {} rpc LookUpSlice (context.Slice ) returns (context.SliceId ) {}
rpc CreateSliceAndAddToCatalog(slice.TransportSlice) returns (slice.SliceStatus) {} rpc OrderSliceFromCatalog (context.Slice ) returns (context.Slice ) {}
rpc CreateSliceAndAddToCatalog(context.Slice ) returns (context.Slice ) {}
} }
...@@ -12,43 +12,13 @@ ...@@ -12,43 +12,13 @@
// 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.
//Example of topology
syntax = "proto3"; syntax = "proto3";
package slice; package slice;
import "context.proto"; import "context.proto";
service SliceService { service SliceService {
rpc CreateUpdateSlice (TransportSlice) returns (SliceStatus) {} rpc CreateSlice(context.Slice ) returns (context.SliceId) {}
rpc DeleteSlice (TransportSlice) returns (context.Empty) {} rpc UpdateSlice(context.Slice ) returns (context.SliceId) {}
} rpc DeleteSlice(context.SliceId) returns (context.Empty ) {}
message SliceEndpoint {
context.EndPoint port_id = 1;
}
message TransportSlice {
SliceId slice_id = 1;
repeated slice.SliceEndpoint endpoints = 2;
repeated context.Constraint constraints = 3;
repeated context.ServiceId services = 4;
repeated SliceId subSlicesId = 5;
SliceStatus status = 6;
}
message SliceId {
context.ContextId contextId = 1;
context.Uuid slice_id = 2;
}
message SliceStatus {
slice.SliceId slice_id = 1;
SliceStatusEnum status = 2;
}
enum SliceStatusEnum {
PLANNED = 0;
INIT = 1;
ACTIVE = 2;
DEINIT = 3;
} }
#!/bin/bash
./report_coverage_all.sh | grep --color -E -i "^slice/.*$|$"
#!/bin/bash
# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
#
# 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
# Useful flags for pytest:
#-o log_cli=true -o log_file=service.log -o log_file_level=DEBUG
coverage run --rcfile=$RCFILE --append -m pytest --log-level=INFO --verbose \
slice/tests/test_unitary.py
...@@ -94,3 +94,6 @@ coverage run --rcfile=$RCFILE --append -m pytest --log-level=INFO --verbose \ ...@@ -94,3 +94,6 @@ coverage run --rcfile=$RCFILE --append -m pytest --log-level=INFO --verbose \
coverage run --rcfile=$RCFILE --append -m pytest --log-level=INFO --verbose \ coverage run --rcfile=$RCFILE --append -m pytest --log-level=INFO --verbose \
monitoring/tests/test_unitary.py monitoring/tests/test_unitary.py
coverage run --rcfile=$RCFILE --append -m pytest --log-level=INFO --verbose \
slice/tests/test_unitary.py
from enum import Enum
class SliceStatus(Enum):
PLANNED = 0
INIT = 1
ACTIVE = 2
DEINIT = 3
ANY_TO_ENUM = {
0: SliceStatus.PLANNED,
1: SliceStatus.INIT,
2: SliceStatus.ACTIVE,
3: SliceStatus.DEINIT,
'0': SliceStatus.PLANNED,
'1': SliceStatus.INIT,
'2': SliceStatus.ACTIVE,
'3': SliceStatus.DEINIT,
'planned': SliceStatus.PLANNED,
'init': SliceStatus.INIT,
'active': SliceStatus.ACTIVE,
'deinit': SliceStatus.DEINIT,
}
def slicestatus_enum_values():
return {m.value for m in SliceStatus.__members__.values()}
def to_slicestatus_enum(int_or_str):
if isinstance(int_or_str, str): int_or_str = int_or_str.lower()
return ANY_TO_ENUM.get(int_or_str)
#!/usr/bin/python #!/usr/bin/python
# #
# Copyright 2018 Google LLC # Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
......
...@@ -17,6 +17,7 @@ from enum import Enum ...@@ -17,6 +17,7 @@ from enum import Enum
from typing import Dict, List from typing import Dict, List
from prometheus_client import Counter, Histogram from prometheus_client import Counter, Histogram
from prometheus_client.metrics import MetricWrapperBase from prometheus_client.metrics import MetricWrapperBase
from common.tools.grpc.Tools import grpc_message_to_json_string
from .ServiceExceptions import ServiceException from .ServiceExceptions import ServiceException
class RequestConditionEnum(Enum): class RequestConditionEnum(Enum):
...@@ -62,9 +63,9 @@ def safe_and_metered_rpc_method(metrics : Dict[str, MetricWrapperBase], logger : ...@@ -62,9 +63,9 @@ def safe_and_metered_rpc_method(metrics : Dict[str, MetricWrapperBase], logger :
def inner_wrapper(self, request, grpc_context : grpc.ServicerContext): def inner_wrapper(self, request, grpc_context : grpc.ServicerContext):
COUNTER_STARTED.inc() COUNTER_STARTED.inc()
try: try:
logger.debug('{:s} request: {:s}'.format(function_name, str(request))) logger.debug('{:s} request: {:s}'.format(function_name, grpc_message_to_json_string(request)))
reply = func(self, request, grpc_context) reply = func(self, request, grpc_context)
logger.debug('{:s} reply: {:s}'.format(function_name, str(reply))) logger.debug('{:s} reply: {:s}'.format(function_name, grpc_message_to_json_string(reply)))
COUNTER_COMPLETED.inc() COUNTER_COMPLETED.inc()
return reply return reply
except ServiceException as e: # pragma: no cover (ServiceException not thrown) except ServiceException as e: # pragma: no cover (ServiceException not thrown)
......
# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
#
# 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.Settings import get_setting
from common.tools.grpc.Tools import grpc_message_to_json_string
from context.client.ContextClient import ContextClient
from slice.proto.context_pb2 import Empty, Slice, SliceId, SliceStatusEnum
from slice.proto.slice_pb2_grpc import SliceServiceServicer
LOGGER = logging.getLogger(__name__)
class MockServicerImpl_Slice(SliceServiceServicer):
def __init__(self):
LOGGER.info('[__init__] Creating Servicer...')
self.context_client = ContextClient(
get_setting('CONTEXTSERVICE_SERVICE_HOST'),
get_setting('CONTEXTSERVICE_SERVICE_PORT_GRPC'))
LOGGER.info('[__init__] Servicer Created')
def CreateSlice(self, request : Slice, context : grpc.ServicerContext) -> SliceId:
LOGGER.info('[CreateSlice] request={:s}'.format(grpc_message_to_json_string(request)))
return self.context_client.SetSlice(request)
def UpdateSlice(self, request : Slice, context : grpc.ServicerContext) -> SliceId:
LOGGER.info('[UpdateSlice] request={:s}'.format(grpc_message_to_json_string(request)))
slice_ = Slice()
slice_.CopyFrom(request)
slice_.slice_status.slice_status = SliceStatusEnum.SLICESTATUS_ACTIVE # pylint: disable=no-member
return self.context_client.SetSlice(slice_)
def DeleteSlice(self, request : SliceId, context : grpc.ServicerContext) -> Empty:
LOGGER.info('[DeleteSlice] request={:s}'.format(grpc_message_to_json_string(request)))
return self.context_client.RemoveSlice(request)
...@@ -57,7 +57,7 @@ def delay_linear(initial=0, increment=0, maximum=None): ...@@ -57,7 +57,7 @@ def delay_linear(initial=0, increment=0, maximum=None):
def delay_exponential(initial=1, increment=1, maximum=None): def delay_exponential(initial=1, increment=1, maximum=None):
def compute(num_try): def compute(num_try):
delay = initial * pow((num_try - 1), increment) delay = initial * pow(increment, (num_try - 1))
if maximum is not None: delay = max(delay, maximum) if maximum is not None: delay = max(delay, maximum)
return delay return delay
return compute return compute
......
...@@ -16,8 +16,9 @@ import json ...@@ -16,8 +16,9 @@ import json
from google.protobuf.json_format import MessageToDict from google.protobuf.json_format import MessageToDict
def grpc_message_to_json( def grpc_message_to_json(
message, including_default_value_fields=True, preserving_proto_field_name=True, use_integers_for_enums=False): message, including_default_value_fields=True, preserving_proto_field_name=True, use_integers_for_enums=False
):
if not hasattr(message, 'DESCRIPTOR'): return json.dumps(str(message), sort_keys=True) # not a gRPC message
return MessageToDict( return MessageToDict(
message, including_default_value_fields=including_default_value_fields, message, including_default_value_fields=including_default_value_fields,
preserving_proto_field_name=preserving_proto_field_name, use_integers_for_enums=use_integers_for_enums) preserving_proto_field_name=preserving_proto_field_name, use_integers_for_enums=use_integers_for_enums)
......
...@@ -46,6 +46,7 @@ COPY common/. common ...@@ -46,6 +46,7 @@ COPY common/. common
COPY compute/. compute COPY compute/. compute
COPY context/. context COPY context/. context
COPY service/. service COPY service/. service
COPY slice/. slice
# Start compute service # Start compute service
ENTRYPOINT ["python", "-m", "compute.service"] ENTRYPOINT ["python", "-m", "compute.service"]
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