Newer
Older
# 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.
from flask import current_app, render_template, Blueprint, flash, session, redirect, url_for
from common.proto.context_pb2 import (
ConfigActionEnum, ConfigRule,
Device, DeviceDriverEnum, DeviceId, DeviceList, DeviceOperationalStatusEnum,
from common.tools.object_factory.Context import json_context_id
from common.tools.object_factory.Topology import json_topology_id
from common.tools.context_queries.Device import add_device_to_topology
from context.client.ContextClient import ContextClient
from device.client.DeviceClient import DeviceClient
from webui.service.device.forms import AddDeviceForm
from webui.service.device.forms import ConfigForm
from webui.service.device.forms import UpdateDeviceForm
device = Blueprint('device', __name__, url_prefix='/device')
context_client = ContextClient()
device_client = DeviceClient()
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']
json_topo_id = json_topology_id(topology_uuid, context_id=json_context_id(context_uuid))
grpc_topology = context_client.GetTopology(TopologyId(**json_topo_id))
topo_device_uuids = {device_id.device_uuid.uuid for device_id in grpc_topology.device_ids}
grpc_devices: DeviceList = context_client.ListDevices(Empty())
devices = [
device for device in grpc_devices.devices
if device.device_id.device_uuid.uuid in topo_device_uuids
]
return render_template(
'device/home.html', devices=devices, dde=DeviceDriverEnum,
dose=DeviceOperationalStatusEnum)
@device.route('add', methods=['GET', 'POST'])
def add():
form = AddDeviceForm()
# listing enum values
for key, value in DeviceOperationalStatusEnum.DESCRIPTOR.values_by_name.items():
form.operational_status.choices.append(
(DeviceOperationalStatusEnum.Value(key), key.replace('DEVICEOPERATIONALSTATUS_', '')))
# items for Device Type field
for device_type in DeviceTypeEnum:
form.device_type.choices.append((device_type.value,device_type.value))
device.device_id.device_uuid.uuid = form.device_id.data
# Device type:
device.device_type = str(form.device_type.data)
# Device configurations:
config_rule = device.device_config.config_rules.add()
config_rule.action = ConfigActionEnum.CONFIGACTION_SET
config_rule.custom.resource_key = '_connect/address'
config_rule.custom.resource_value = form.device_config_address.data
config_rule = device.device_config.config_rules.add()
config_rule.action = ConfigActionEnum.CONFIGACTION_SET
config_rule.custom.resource_key = '_connect/port'
config_rule.custom.resource_value = form.device_config_port.data
config_rule = device.device_config.config_rules.add()
config_rule.action = ConfigActionEnum.CONFIGACTION_SET
config_rule.custom.resource_key = '_connect/settings'
config_rule.custom.resource_value = form.device_config_settings.data
# Device status:
device.device_operational_status = form.operational_status.data
# Device drivers:
if form.device_drivers_undefined.data:
device.device_drivers.append(DeviceDriverEnum.DEVICEDRIVER_UNDEFINED)
if form.device_drivers_openconfig.data:
device.device_drivers.append(DeviceDriverEnum.DEVICEDRIVER_OPENCONFIG)
if form.device_drivers_transport_api.data:
device.device_drivers.append(DeviceDriverEnum.DEVICEDRIVER_TRANSPORT_API)
if form.device_drivers_p4.data:
device.device_drivers.append(DeviceDriverEnum.DEVICEDRIVER_P4)
if form.device_drivers_ietf_network_topology.data:
device.device_drivers.append(DeviceDriverEnum.DEVICEDRIVER_IETF_NETWORK_TOPOLOGY)
if form.device_drivers_onf_tr_352.data:
device.device_drivers.append(DeviceDriverEnum.DEVICEDRIVER_ONF_TR_352)
if form.device_drivers_xr.data:
device.device_drivers.append(DeviceDriverEnum.DEVICEDRIVER_XR)
try:
device_client.connect()
response: DeviceId = device_client.AddDevice(device)
device_client.close()
context_uuid = session['context_uuid']
topology_uuid = session['topology_uuid']
context_client.connect()
context_id = ContextId(**json_context_id(context_uuid))
add_device_to_topology(context_client, context_id, topology_uuid, device.device_id.device_uuid.uuid)
context_client.close()
flash(f'New device was created with ID "{response.device_uuid.uuid}".', 'success')
return redirect(url_for('device.home'))
except Exception as e:
flash(f'Problem adding the device. {e.details()}', 'danger')
return render_template('device/add.html', form=form,
@device.route('detail/<path:device_uuid>', methods=['GET', 'POST'])
request.device_uuid.uuid = device_uuid
context_client.connect()
response = context_client.GetDevice(request)
return render_template('device/detail.html', device=response,
dde=DeviceDriverEnum,
dose=DeviceOperationalStatusEnum)
@device.get('<path:device_uuid>/delete')
def delete(device_uuid):
try:
# first, check if device exists!
# request: DeviceId = DeviceId()
# request.device_uuid.uuid = device_uuid
# response: Device = client.GetDevice(request)
# TODO: finalize implementation
request.device_uuid.uuid = device_uuid
device_client.connect()
response = device_client.DeleteDevice(request)
device_client.close()
flash(f'Device "{device_uuid}" deleted successfully!', 'success')
flash(f'Problem deleting device "{device_uuid}": {e.details()}', 'danger')
return redirect(url_for('device.home'))
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
@device.route('<path:device_uuid>/addconfig', methods=['GET', 'POST'])
def addconfig(device_uuid):
form = ConfigForm()
request = DeviceId()
request.device_uuid.uuid = device_uuid
context_client.connect()
response = context_client.GetDevice(request)
context_client.close()
if form.validate_on_submit():
device = Device()
device.CopyFrom(response)
config_rule = device.device_config.config_rules.add()
config_rule.action = ConfigActionEnum.CONFIGACTION_SET
config_rule.custom.resource_key = form.device_key_config.data
config_rule.custom.resource_value = form.device_value_config.data
try:
device_client.connect()
response: DeviceId = device_client.ConfigureDevice(device)
device_client.close()
flash(f'New configuration was created with ID "{response.device_uuid.uuid}".', 'success')
return redirect(url_for('device.home'))
except Exception as e:
flash(f'Problem adding the device. {e.details()}', 'danger')
return render_template('device/addconfig.html', form=form, submit_text='Add New Configuration')
@device.route('updateconfig', methods=['GET', 'POST'])
def updateconfig():
return render_template('device/updateconfig.html')
@device.route('<path:device_uuid>/update', methods=['GET', 'POST'])
def update(device_uuid):
form = UpdateDeviceForm()
request = DeviceId()
request.device_uuid.uuid = device_uuid
context_client.connect()
response = context_client.GetDevice(request)
context_client.close()
# listing enum values
form.update_operational_status.choices = []
for key, value in DeviceOperationalStatusEnum.DESCRIPTOR.values_by_name.items():
form.update_operational_status.choices.append((DeviceOperationalStatusEnum.Value(key), key.replace('DEVICEOPERATIONALSTATUS_', '')))
form.update_operational_status.default = response.device_operational_status
if form.validate_on_submit():
device = Device()
device.CopyFrom(response)
device.device_operational_status = form.update_operational_status.data
try:
device_client.connect()
response: DeviceId = device_client.ConfigureDevice(device)
device_client.close()
flash(f'Status of device with ID "{response.device_uuid.uuid}" was updated.', 'success')
return redirect(url_for('device.home'))
except Exception as e:
flash(f'Problem updating the device. {e.details()}', 'danger')
return render_template('device/update.html', device=response, form=form, submit_text='Update Device')