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 (20)
Showing
with 255 additions and 70 deletions
......@@ -669,6 +669,10 @@ if [[ "$TFS_COMPONENTS" == *"monitoring"* ]] && [[ "$TFS_COMPONENTS" == *"webui"
printf "\n\n"
fi
echo "Pruning Docker Images..."
docker image prune --force
printf "\n\n"
if [ "$DOCKER_BUILD" == "docker buildx build" ]; then
echo "Pruning Docker Buildx Cache..."
docker buildx prune --force
......
......@@ -62,10 +62,10 @@ spec:
name: nbiservice
port:
number: 8080
- path: /()(qkd_app/.*)
- pathType: Prefix
- path: /()(qkd_app/.*)
pathType: Prefix
backend:
service:
name: qkdappservice
name: qkd-appservice
port:
number: 8005
......@@ -15,16 +15,16 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: qkdappservice
name: qkd-appservice
spec:
selector:
matchLabels:
app: qkdappservice
app: qkd-appservice
#replicas: 1
template:
metadata:
labels:
app: qkdappservice
app: qkd-appservice
spec:
terminationGracePeriodSeconds: 5
containers:
......@@ -36,10 +36,8 @@ spec:
- containerPort: 9192
- containerPort: 8005
env:
- name: MB_BACKEND
value: "nats"
- name: LOG_LEVEL
value: "INFO"
value: "DEBUG"
- name: CRDB_DATABASE_APP
value: "qkd_app"
envFrom:
......@@ -64,13 +62,13 @@ spec:
apiVersion: v1
kind: Service
metadata:
name: qkdappservice
name: qkd-appservice
labels:
app: qkdappservice
app: qkd-appservice
spec:
type: ClusterIP
selector:
app: qkdappservice
app: qkd-appservice
ports:
- name: grpc
protocol: TCP
......
#!/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/qkd-appservice -c server
......@@ -38,6 +38,30 @@ build device:
- manifests/${IMAGE_NAME}service.yaml
- .gitlab-ci.yml
## Start Mock QKD Nodes before unit testing
#start_mock_nodes:
# stage: deploy
# script:
# - bash src/tests/tools/mock_qkd_nodes/start.sh &
# - sleep 10 # wait for nodes to spin up
# artifacts:
# paths:
# - mock_nodes.log
# rules:
# - if: '$CI_PIPELINE_SOURCE == "merge_request_event" && ($CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "develop" || $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == $CI_DEFAULT_BRANCH)'
# - if: '$CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH == "develop"'
## Prepare Scenario (Start NBI, mock services)
#prepare_scenario:
# stage: deploy
# script:
# - pytest src/tests/qkd/unit/PrepareScenario.py
# needs:
# - start_mock_nodes
# rules:
# - if: '$CI_PIPELINE_SOURCE == "merge_request_event" && ($CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "develop" || $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == $CI_DEFAULT_BRANCH)'
# - if: '$CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH == "develop"'
# Apply unit test to the component
unit_test device:
variables:
......@@ -46,6 +70,8 @@ unit_test device:
stage: unit_test
needs:
- build device
#- start_mock_nodes
#- prepare_scenario
before_script:
- docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" $CI_REGISTRY
- >
......@@ -68,6 +94,7 @@ unit_test device:
- docker logs $IMAGE_NAME
- docker exec -i $IMAGE_NAME bash -c "coverage run --append -m pytest --log-level=INFO --verbose $IMAGE_NAME/tests/test_unitary_emulated.py --junitxml=/opt/results/${IMAGE_NAME}_report_emulated.xml"
- docker exec -i $IMAGE_NAME bash -c "coverage run --append -m pytest --log-level=INFO --verbose $IMAGE_NAME/tests/test_unitary_ietf_actn.py --junitxml=/opt/results/${IMAGE_NAME}_report_ietf_actn.xml"
#- docker exec -i $IMAGE_NAME bash -c "coverage run --append -m pytest --log-level=INFO --verbose $IMAGE_NAME/tests/qkd/unit/test_*.py"
- docker exec -i $IMAGE_NAME bash -c "coverage report --include='${IMAGE_NAME}/*' --show-missing"
coverage: '/TOTAL\s+\d+\s+\d+\s+(\d+%)/'
after_script:
......
{
"contexts": [
{"context_id": {"context_uuid": {"uuid": "admin"}}}
],
"topologies": [
{"topology_id": {"topology_uuid": {"uuid": "admin"}, "context_id": {"context_uuid": {"uuid": "admin"}}}}
],
"devices": [
{
"device_id": {"device_uuid": {"uuid": "QKD1"}}, "device_type": "qkd-node",
"device_operational_status": 0, "device_drivers": [12], "device_endpoints": [],
"device_config": {"config_rules": [
{"action": 1, "custom": {"resource_key": "_connect/address", "resource_value": "10.0.2.10"}},
{"action": 1, "custom": {"resource_key": "_connect/port", "resource_value": "11111"}},
{"action": 1, "custom": {"resource_key": "_connect/settings", "resource_value": {
"scheme": "http"
}}}
]}
},
{
"device_id": {"device_uuid": {"uuid": "QKD2"}}, "device_type": "qkd-node",
"device_operational_status": 0, "device_drivers": [12], "device_endpoints": [],
"device_config": {"config_rules": [
{"action": 1, "custom": {"resource_key": "_connect/address", "resource_value": "10.0.2.10"}},
{"action": 1, "custom": {"resource_key": "_connect/port", "resource_value": "22222"}},
{"action": 1, "custom": {"resource_key": "_connect/settings", "resource_value": {
"scheme": "http"
}}}
]}
},
{
"device_id": {"device_uuid": {"uuid": "QKD3"}}, "device_type": "qkd-node",
"device_operational_status": 0, "device_drivers": [12], "device_endpoints": [],
"device_config": {"config_rules": [
{"action": 1, "custom": {"resource_key": "_connect/address", "resource_value": "10.0.2.10"}},
{"action": 1, "custom": {"resource_key": "_connect/port", "resource_value": "33333"}},
{"action": 1, "custom": {"resource_key": "_connect/settings", "resource_value": {
"scheme": "http"
}}}
]}
}
],
"links": [
{
"link_id": {"link_uuid": {"uuid": "QKD1/10.0.2.10:1001==QKD2/10.0.2.10:2001"}},
"link_endpoint_ids": [
{"device_id": {"device_uuid": {"uuid": "QKD1"}}, "endpoint_uuid": {"uuid": "10.0.2.10:1001"}},
{"device_id": {"device_uuid": {"uuid": "QKD2"}}, "endpoint_uuid": {"uuid": "10.0.2.10:2001"}}
]
},
{
"link_id": {"link_uuid": {"uuid": "QKD2/10.0.2.10:2001==QKD1/10.0.2.10:1001"}},
"link_endpoint_ids": [
{"device_id": {"device_uuid": {"uuid": "QKD2"}}, "endpoint_uuid": {"uuid": "10.0.2.10:2001"}},
{"device_id": {"device_uuid": {"uuid": "QKD1"}}, "endpoint_uuid": {"uuid": "10.0.2.10:1001"}}
]
},
{
"link_id": {"link_uuid": {"uuid": "QKD2/10.0.2.10:2002==QKD3/10.0.2.10:3001"}},
"link_endpoint_ids": [
{"device_id": {"device_uuid": {"uuid": "QKD2"}}, "endpoint_uuid": {"uuid": "10.0.2.10:2002"}},
{"device_id": {"device_uuid": {"uuid": "QKD3"}}, "endpoint_uuid": {"uuid": "10.0.2.10:3001"}}
]
},
{
"link_id": {"link_uuid": {"uuid": "QKD3/10.0.2.10:3001==QKD2/10.0.2.10:2002"}},
"link_endpoint_ids": [
{"device_id": {"device_uuid": {"uuid": "QKD3"}}, "endpoint_uuid": {"uuid": "10.0.2.10:3001"}},
{"device_id": {"device_uuid": {"uuid": "QKD2"}}, "endpoint_uuid": {"uuid": "10.0.2.10:2002"}}
]
}
]
}
......@@ -14,9 +14,11 @@
import pytest
import json
import os
os.environ['DEVICE_EMULATED_ONLY'] = 'YES'
from device.service.drivers.qkd.QKDDriver2 import QKDDriver
MOCK_QKD_ADDRRESS = '127.0.0.1'
MOCK_QKD_ADDRRESS = '10.0.2.10'
MOCK_PORT = 11111
@pytest.fixture
......
# 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.
import requests
QKD_ADDRESS = '10.0.2.10'
QKD_URL = 'http://{:s}/qkd_app/create_qkd_app'.format(QKD_ADDRESS)
QKD_REQUEST_1 = {
'app': {
'server_app_id': '1',
'client_app_id': [],
'app_status': 'ON',
'local_qkdn_id': '00000001-0000-0000-0000-0000000000',
'backing_qkdl_id': ['00000003-0002-0000-0000-0000000000']
}
}
print(requests.post(QKD_URL, json=QKD_REQUEST_1))
QKD_REQUEST_2 = {
'app': {
'server_app_id': '1',
'client_app_id': [],
'app_status': 'ON',
'local_qkdn_id': '00000003-0000-0000-0000-0000000000',
'backing_qkdl_id': ['00000003-0002-0000-0000-0000000000']
}
}
print(requests.post(QKD_URL, json=QKD_REQUEST_2))
......@@ -28,8 +28,8 @@ RETRY_DECORATOR = retry(max_retries=MAX_RETRIES, delay_function=DELAY_FUNCTION,
class QKDAppClient:
def __init__(self, host=None, port=None):
if not host: host = get_service_host(ServiceNameEnum.APP)
if not port: port = get_service_port_grpc(ServiceNameEnum.APP)
if not host: host = get_service_host(ServiceNameEnum.QKD_APP)
if not port: port = get_service_port_grpc(ServiceNameEnum.QKD_APP)
self.endpoint = '{:s}:{:s}'.format(str(host), str(port))
LOGGER.debug('Creating channel to {:s}...'.format(self.endpoint))
self.channel = None
......
......@@ -29,7 +29,7 @@ class AppService(GenericGrpcService):
def __init__(
self, db_engine : sqlalchemy.engine.Engine, messagebroker : MessageBroker, cls_name: str = __name__
) -> None:
port = get_service_port_grpc(ServiceNameEnum.APP)
port = get_service_port_grpc(ServiceNameEnum.QKD_APP)
super().__init__(port, max_workers=GRPC_MAX_WORKERS, cls_name=cls_name)
self.app_servicer = AppServiceServicerImpl(db_engine, messagebroker)
......
......@@ -18,6 +18,6 @@ from common.tools.service.GenericRestServer import GenericRestServer
class RestServer(GenericRestServer):
def __init__(self, cls_name: str = __name__) -> None:
bind_port = get_service_port_http(ServiceNameEnum.APP)
base_url = get_service_baseurl_http(ServiceNameEnum.APP)
bind_port = get_service_port_http(ServiceNameEnum.QKD_APP)
base_url = get_service_baseurl_http(ServiceNameEnum.QKD_APP)
super().__init__(bind_port, base_url, cls_name=cls_name)
......@@ -23,8 +23,8 @@ killbg() {
trap killbg EXIT
pids=()
flask --app mock run --host 0.0.0.0 --port 11111 &
flask run --host 0.0.0.0 --port 11111 &
pids+=($!)
flask --app mock run --host 0.0.0.0 --port 22222 &
flask run --host 0.0.0.0 --port 22222 &
pids+=($!)
flask --app mock run --host 0.0.0.0 --port 33333
flask run --host 0.0.0.0 --port 33333
......@@ -23,7 +23,7 @@ yang_validator = YangValidator('etsi-qkd-sdn-node', ['etsi-qkd-node-types'])
nodes = {
'127.0.0.1:11111': {'node': {
'10.0.2.10:11111': {'node': {
'qkdn_id': '00000001-0000-0000-0000-000000000000',
},
'qkdn_capabilities': {
......@@ -54,7 +54,7 @@ nodes = {
{
'qkdi_id': '101',
'qkdi_att_point': {
'device':'127.0.0.1',
'device':'10.0.2.10',
'port':'1001'
},
'qkdi_capabilities': {
......@@ -69,7 +69,7 @@ nodes = {
}
},
'127.0.0.1:22222': {'node': {
'10.0.2.10:22222': {'node': {
'qkdn_id': '00000002-0000-0000-0000-000000000000',
},
'qkdn_capabilities': {
......@@ -100,7 +100,7 @@ nodes = {
{
'qkdi_id': '201',
'qkdi_att_point': {
'device':'127.0.0.1',
'device':'10.0.2.10',
'port':'2001'
},
'qkdi_capabilities': {
......@@ -109,7 +109,7 @@ nodes = {
{
'qkdi_id': '202',
'qkdi_att_point': {
'device':'127.0.0.1',
'device':'10.0.2.10',
'port':'2002'
},
'qkdi_capabilities': {
......@@ -124,7 +124,7 @@ nodes = {
}
},
'127.0.0.1:33333': {'node': {
'10.0.2.10:33333': {'node': {
'qkdn_id': '00000003-0000-0000-0000-000000000000',
},
'qkdn_capabilities': {
......@@ -155,7 +155,7 @@ nodes = {
{
'qkdi_id': '301',
'qkdi_att_point': {
'device':'127.0.0.1',
'device':'10.0.2.10',
'port':'3001'
},
'qkdi_capabilities': {
......
......@@ -84,9 +84,11 @@ COPY --chown=webui:webui src/service/__init__.py service/__init__.py
COPY --chown=webui:webui src/service/client/. service/client/
COPY --chown=webui:webui src/slice/__init__.py slice/__init__.py
COPY --chown=webui:webui src/slice/client/. slice/client/
COPY --chown=webui:webui src/webui/. webui/
COPY --chown=webui:webui src/qkd_app/__init__.py qkd_app/__init__.py
COPY --chown=webui:webui src/qkd_app/client/. qkd_app/client/
COPY --chown=webui:webui src/bgpls_speaker/__init__.py bgpls_speaker/__init__.py
COPY --chown=webui:webui src/bgpls_speaker/client/. bgpls_speaker/client/
COPY --chown=webui:webui src/webui/. webui/
# Start the service
ENTRYPOINT ["python", "-m", "webui.service"]
......@@ -43,8 +43,8 @@ def main():
get_env_var_name(ServiceNameEnum.SERVICE, ENVVAR_SUFIX_SERVICE_PORT_GRPC),
get_env_var_name(ServiceNameEnum.SLICE, ENVVAR_SUFIX_SERVICE_HOST ),
get_env_var_name(ServiceNameEnum.SLICE, ENVVAR_SUFIX_SERVICE_PORT_GRPC),
# get_env_var_name(ServiceNameEnum.APP, ENVVAR_SUFIX_SERVICE_HOST ),
# get_env_var_name(ServiceNameEnum.APP, ENVVAR_SUFIX_SERVICE_PORT_GRPC),
get_env_var_name(ServiceNameEnum.QKD_APP, ENVVAR_SUFIX_SERVICE_HOST ),
get_env_var_name(ServiceNameEnum.QKD_APP, ENVVAR_SUFIX_SERVICE_PORT_GRPC),
])
logger.info('Starting...')
......
......@@ -24,19 +24,19 @@
# from qkd_app.client.QKDAppClient import QKDAppClient
# LOGGER = logging.getLogger(__name__)
# app = Blueprint('qkd_app', __name__, url_prefix='/qkd_app')
LOGGER = logging.getLogger(__name__)
qkd_app = Blueprint('qkd_app', __name__, url_prefix='/qkd_app')
# qkd_app_client = QKDAppClient()
# context_client = ContextClient()
# @app.get('/')
# def home():
# if 'context_uuid' not in session or 'topology_uuid' not in session:
# flash("Please select a context!", "warning")
# return redirect(url_for("main.home"))
# context_uuid = session['context_uuid']
# topology_uuid = session['topology_uuid']
@qkd_app.get('/')
def home():
if 'context_uuid' not in session or 'topology_uuid' not in session:
flash("Please select a context!", "warning")
return redirect(url_for("main.home"))
context_uuid = session['context_uuid']
topology_uuid = session['topology_uuid']
# context_client.connect()
# device_names = dict()
......@@ -66,31 +66,31 @@
# if device is not None:
# device_names[app.remote_device_id.device_uuid.uuid] = device.name
# context_client.close()
# return render_template(
# 'app/home.html', apps=apps, device_names=device_names, ate=QKDAppTypesEnum, ase=QKDAppStatusEnum)
context_client.close()
return render_template(
'qkd_app/home.html', apps=apps, device_names=device_names, ate=QKDAppTypesEnum, ase=QKDAppStatusEnum)
# @app.route('detail/<path:app_uuid>', methods=('GET', 'POST'))
# def detail(app_uuid: str):
# '''
# context_client.connect()
# link_obj = get_link(context_client, link_uuid, rw_copy=False)
# if link_obj is None:
# flash('Link({:s}) not found'.format(str(link_uuid)), 'danger')
# link_obj = Link()
# device_names, endpoints_data = dict(), dict()
# else:
# device_names, endpoints_data = get_endpoint_names(context_client, link_obj.link_endpoint_ids)
# context_client.close()
# return render_template('link/detail.html',link=link_obj, device_names=device_names, endpoints_data=endpoints_data)
# '''
# pass
@qkd_app.route('detail/<path:app_uuid>', methods=('GET', 'POST'))
def detail(app_uuid: str):
'''
context_client.connect()
link_obj = get_link(context_client, link_uuid, rw_copy=False)
if link_obj is None:
flash('Link({:s}) not found'.format(str(link_uuid)), 'danger')
link_obj = Link()
device_names, endpoints_data = dict(), dict()
else:
device_names, endpoints_data = get_endpoint_names(context_client, link_obj.link_endpoint_ids)
context_client.close()
return render_template('link/detail.html',link=link_obj, device_names=device_names, endpoints_data=endpoints_data)
'''
pass
# @app.get('<path:app_uuid>/delete')
# def delete(app_uuid):
# '''
# try:
@qkd_app.get('<path:app_uuid>/delete')
def delete(app_uuid):
'''
try:
# # first, check if link exists!
# # request: LinkId = LinkId()
......
......@@ -110,7 +110,13 @@
<a class="nav-link" href="{{ url_for('load_gen.home') }}">Load Generator</a>
{% endif %}
</li>
<li class="nav-item">
{% if '/qkd_app/' in request.path %}
<a class="nav-link active" aria-current="page" href="{{ url_for('qkd_app.home') }}">QKD Apps</a>
{% else %}
<a class="nav-link" href="{{ url_for('qkd_app.home') }}">QKD Apps</a>
{% endif %}
</li>
<li class="nav-item">
{% if '/bgpls/' in request.path %}
<a class="nav-link active" aria-current="page" href="{{ url_for('bgpls.home') }}">BGPLS</a>
......
......@@ -41,7 +41,7 @@
{% for app in apps %}
<tr>
<td>
{{ app.app_id.app_uuid.uuid }}
{{ app.app_id.app_uuid.uuid }}
</td>
<td>
{{ ase.Name(app.app_status).replace('QKDAPPSTATUS_', '') }}
......@@ -74,12 +74,14 @@
{% endif %}
</td>
<td>
<a href="{{ url_for('app.detail', app_uuid=app.app_id.app_uuid.uuid) }}">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-eye" viewBox="0 0 16 16">
<path d="M16 8s-3-5.5-8-5.5S0 8 0 8s3 5.5 8 5.5S16 8 16 8zM1.173 8a13.133 13.133 0 0 1 1.66-2.043C4.12 4.668 5.88 3.5 8 3.5c2.12 0 3.879 1.168 5.168 2.457A13.133 13.133 0 0 1 14.828 8c-.058.087-.122.183-.195.288-.335.48-.83 1.12-1.465 1.755C11.879 11.332 10.119 12.5 8 12.5c-2.12 0-3.879-1.168-5.168-2.457A13.134 13.134 0 0 1 1.172 8z"/>
<path d="M8 5.5a2.5 2.5 0 1 0 0 5 2.5 2.5 0 0 0 0-5zM4.5 8a3.5 3.5 0 1 1 7 0 3.5 3.5 0 0 1-7 0z"/>
</svg>
</a>
<!--
<a href="{{ url_for('qkd_app.detail', app_uuid=app.app_id.app_uuid.uuid) }}">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-eye" viewBox="0 0 16 16">
<path d="M16 8s-3-5.5-8-5.5S0 8 0 8s3 5.5 8 5.5S16 8 16 8zM1.173 8a13.133 13.133 0 0 1 1.66-2.043C4.12 4.668 5.88 3.5 8 3.5c2.12 0 3.879 1.168 5.168 2.457A13.133 13.133 0 0 1 14.828 8c-.058.087-.122.183-.195.288-.335.48-.83 1.12-1.465 1.755C11.879 11.332 10.119 12.5 8 12.5c-2.12 0-3.879-1.168-5.168-2.457A13.134 13.134 0 0 1 1.172 8z"/>
<path d="M8 5.5a2.5 2.5 0 1 0 0 5 2.5 2.5 0 0 0 0-5zM4.5 8a3.5 3.5 0 1 1 7 0 3.5 3.5 0 0 1-7 0z"/>
</svg>
</a>
-->
</td>
</tr>
{% endfor %}
......