Loading src/webui/service/__init__.py +1 −0 Original line number Diff line number Diff line Loading @@ -96,6 +96,7 @@ def create_app(use_config=None, web_app_root=None): app.register_blueprint(link) app.jinja_env.globals.update({ # pylint: disable=no-member 'enumerate' : enumerate, 'json_to_list' : json_to_list, 'get_working_context' : get_working_context, 'get_working_topology': get_working_topology, Loading src/webui/service/device/forms.py +4 −9 Original line number Diff line number Diff line Loading @@ -12,21 +12,16 @@ # See the License for the specific language governing permissions and # limitations under the License. # external imports from flask_wtf import FlaskForm from wtforms import StringField, SelectField, TextAreaField, SubmitField, BooleanField, Form from wtforms.validators import DataRequired, Length, NumberRange, Regexp, ValidationError from wtforms import StringField, SelectField, TextAreaField, SubmitField, BooleanField from wtforms.validators import DataRequired, Length, NumberRange, ValidationError from common.proto.context_pb2 import DeviceOperationalStatusEnum from webui.utils.form_validators import key_value_validator class AddDeviceForm(FlaskForm): device_id = StringField('ID', validators=[DataRequired(), Length(min=5)]) device_type = SelectField('Type', choices = []) operational_status = SelectField('Operational Status', # choices=[(-1, 'Select...'), (0, 'Undefined'), (1, 'Disabled'), (2, 'Enabled')], coerce=int, validators=[NumberRange(min=0)]) device_type = SelectField('Type') operational_status = SelectField('Operational Status', coerce=int, validators=[NumberRange(min=0)]) device_drivers_undefined = BooleanField('UNDEFINED / EMULATED') device_drivers_openconfig = BooleanField('OPENCONFIG') device_drivers_transport_api = BooleanField('TRANSPORT_API') Loading src/webui/service/device/routes.py +55 −51 Original line number Diff line number Diff line Loading @@ -14,16 +14,14 @@ import json from flask import current_app, render_template, Blueprint, flash, session, redirect, url_for from common.DeviceTypes import DeviceTypeEnum from common.proto.context_pb2 import ( ConfigActionEnum, Device, DeviceDriverEnum, DeviceId, DeviceList, DeviceOperationalStatusEnum, Empty, TopologyId) from common.tools.object_factory.Context import json_context_id from common.tools.object_factory.Topology import json_topology_id ConfigActionEnum, Device, DeviceDriverEnum, DeviceId, DeviceList, DeviceOperationalStatusEnum, Empty) from common.tools.context_queries.Device import get_device from common.tools.context_queries.Topology import get_topology from context.client.ContextClient import ContextClient from device.client.DeviceClient import DeviceClient from webui.service.device.forms import AddDeviceForm from common.DeviceTypes import DeviceTypeEnum from webui.service.device.forms import ConfigForm from webui.service.device.forms import UpdateDeviceForm from webui.service.device.forms import AddDeviceForm, ConfigForm, UpdateDeviceForm device = Blueprint('device', __name__, url_prefix='/device') context_client = ContextClient() Loading @@ -39,16 +37,18 @@ def home(): topology_uuid = session['topology_uuid'] context_client.connect() json_topo_id = json_topology_id(topology_uuid, context_id=json_context_id(context_uuid)) grpc_topology = context_client.GetTopology(TopologyId(**json_topo_id)) grpc_topology = get_topology(context_client, topology_uuid, context_uuid=context_uuid, rw_copy=False) if grpc_topology is None: flash('Context({:s})/Topology({:s}) not found'.format(str(context_uuid), str(topology_uuid)), 'danger') devices = [] else: topo_device_uuids = {device_id.device_uuid.uuid for device_id in grpc_topology.device_ids} grpc_devices: DeviceList = context_client.ListDevices(Empty()) context_client.close() devices = [ device for device in grpc_devices.devices if device.device_id.device_uuid.uuid in topo_device_uuids ] context_client.close() return render_template( 'device/home.html', devices=devices, dde=DeviceDriverEnum, Loading @@ -71,23 +71,23 @@ def add(): if form.validate_on_submit(): device_obj = Device() # Device UUID: device_obj.device_id.device_uuid.uuid = form.device_id.data device_obj.device_id.device_uuid.uuid = form.device_id.data # pylint: disable=no-member # Device type: device_obj.device_type = str(form.device_type.data) # Device configurations: config_rule = device_obj.device_config.config_rules.add() config_rule = device_obj.device_config.config_rules.add() # pylint: disable=no-member 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_obj.device_config.config_rules.add() config_rule = device_obj.device_config.config_rules.add() # pylint: disable=no-member 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_obj.device_config.config_rules.add() config_rule = device_obj.device_config.config_rules.add() # pylint: disable=no-member config_rule.action = ConfigActionEnum.CONFIGACTION_SET config_rule.custom.resource_key = '_connect/settings' Loading @@ -105,20 +105,22 @@ def add(): device_obj.device_operational_status = form.operational_status.data # Device drivers: device_drivers = list() if form.device_drivers_undefined.data: device_obj.device_drivers.append(DeviceDriverEnum.DEVICEDRIVER_UNDEFINED) device_drivers.append(DeviceDriverEnum.DEVICEDRIVER_UNDEFINED) if form.device_drivers_openconfig.data: device_obj.device_drivers.append(DeviceDriverEnum.DEVICEDRIVER_OPENCONFIG) device_drivers.append(DeviceDriverEnum.DEVICEDRIVER_OPENCONFIG) if form.device_drivers_transport_api.data: device_obj.device_drivers.append(DeviceDriverEnum.DEVICEDRIVER_TRANSPORT_API) device_drivers.append(DeviceDriverEnum.DEVICEDRIVER_TRANSPORT_API) if form.device_drivers_p4.data: device_obj.device_drivers.append(DeviceDriverEnum.DEVICEDRIVER_P4) device_drivers.append(DeviceDriverEnum.DEVICEDRIVER_P4) if form.device_drivers_ietf_network_topology.data: device_obj.device_drivers.append(DeviceDriverEnum.DEVICEDRIVER_IETF_NETWORK_TOPOLOGY) device_drivers.append(DeviceDriverEnum.DEVICEDRIVER_IETF_NETWORK_TOPOLOGY) if form.device_drivers_onf_tr_352.data: device_obj.device_drivers.append(DeviceDriverEnum.DEVICEDRIVER_ONF_TR_352) device_drivers.append(DeviceDriverEnum.DEVICEDRIVER_ONF_TR_352) if form.device_drivers_xr.data: device_obj.device_drivers.append(DeviceDriverEnum.DEVICEDRIVER_XR) device_drivers.append(DeviceDriverEnum.DEVICEDRIVER_XR) device_obj.device_drivers.extend(device_drivers) # pylint: disable=no-member try: device_client.connect() Loading @@ -126,7 +128,7 @@ def add(): device_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: except Exception as e: # pylint: disable=broad-except flash(f'Problem adding the device. {e.details()}', 'danger') return render_template('device/add.html', form=form, Loading @@ -134,14 +136,15 @@ def add(): @device.route('detail/<path:device_uuid>', methods=['GET', 'POST']) def detail(device_uuid: str): request = DeviceId() request.device_uuid.uuid = device_uuid context_client.connect() response = context_client.GetDevice(request) device_obj = get_device(context_client, device_uuid, rw_copy=False) if device_obj is None: flash('Device({:s}) not found'.format(str(device_uuid)), 'danger') device_obj = Device() context_client.close() return render_template('device/detail.html', device=response, dde=DeviceDriverEnum, dose=DeviceOperationalStatusEnum) return render_template( 'device/detail.html', device=device_obj, dde=DeviceDriverEnum, dose=DeviceOperationalStatusEnum) @device.get('<path:device_uuid>/delete') def delete(device_uuid): Loading @@ -154,13 +157,13 @@ def delete(device_uuid): # TODO: finalize implementation request = DeviceId() request.device_uuid.uuid = device_uuid request.device_uuid.uuid = device_uuid # pylint: disable=no-member device_client.connect() response = device_client.DeleteDevice(request) device_client.DeleteDevice(request) device_client.close() flash(f'Device "{device_uuid}" deleted successfully!', 'success') except Exception as e: except Exception as e: # pylint: disable=broad-except flash(f'Problem deleting device "{device_uuid}": {e.details()}', 'danger') current_app.logger.exception(e) return redirect(url_for('device.home')) Loading @@ -169,25 +172,25 @@ def delete(device_uuid): def addconfig(device_uuid): form = ConfigForm() request = DeviceId() request.device_uuid.uuid = device_uuid request.device_uuid.uuid = device_uuid # pylint: disable=no-member 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() device_obj = Device() device_obj.CopyFrom(response) config_rule = device_obj.device_config.config_rules.add() # pylint: disable=no-member 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) response: DeviceId = device_client.ConfigureDevice(device_obj) 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: except Exception as e: # pylint: disable=broad-except flash(f'Problem adding the device. {e.details()}', 'danger') return render_template('device/addconfig.html', form=form, submit_text='Add New Configuration') Loading @@ -203,28 +206,29 @@ def updateconfig(): def update(device_uuid): form = UpdateDeviceForm() request = DeviceId() request.device_uuid.uuid = device_uuid request.device_uuid.uuid = device_uuid # pylint: disable=no-member 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_', ''))) for key, _ in DeviceOperationalStatusEnum.DESCRIPTOR.values_by_name.items(): item = (DeviceOperationalStatusEnum.Value(key), key.replace('DEVICEOPERATIONALSTATUS_', '')) form.update_operational_status.choices.append(item) 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 device_obj = Device() device_obj.CopyFrom(response) device_obj.device_operational_status = form.update_operational_status.data try: device_client.connect() response: DeviceId = device_client.ConfigureDevice(device) response: DeviceId = device_client.ConfigureDevice(device_obj) 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: except Exception as e: # pylint: disable=broad-except flash(f'Problem updating the device. {e.details()}', 'danger') return render_template('device/update.html', device=response, form=form, submit_text='Update Device') src/webui/service/link/routes.py +25 −21 Original line number Diff line number Diff line Loading @@ -14,10 +14,10 @@ from flask import render_template, Blueprint, flash, session, redirect, url_for from common.proto.context_pb2 import Empty, LinkId, LinkList, TopologyId from common.proto.context_pb2 import Empty, Link, LinkList from common.tools.context_queries.EndPoint import get_endpoint_names 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.Link import get_link from common.tools.context_queries.Topology import get_topology from context.client.ContextClient import ContextClient Loading @@ -33,19 +33,20 @@ def home(): context_uuid = session['context_uuid'] topology_uuid = session['topology_uuid'] links, endpoint_ids = list(), list() device_names, endpoints_data = dict(), dict() context_client.connect() json_topo_id = json_topology_id(topology_uuid, context_id=json_context_id(context_uuid)) grpc_topology = context_client.GetTopology(TopologyId(**json_topo_id)) grpc_topology = get_topology(context_client, topology_uuid, context_uuid=context_uuid, rw_copy=False) if grpc_topology is None: flash('Context({:s})/Topology({:s}) not found'.format(str(context_uuid), str(topology_uuid)), 'danger') else: topo_link_uuids = {link_id.link_uuid.uuid for link_id in grpc_topology.link_ids} grpc_links: LinkList = context_client.ListLinks(Empty()) endpoint_ids = [] links = [] for link_ in grpc_links.links: if link_.link_id.link_uuid.uuid not in topo_link_uuids: continue links.append(link_) endpoint_ids.extend(link_.link_endpoint_ids) device_names, endpoints_data = get_endpoint_names(context_client, endpoint_ids) context_client.close() Loading @@ -54,10 +55,13 @@ def home(): @link.route('detail/<path:link_uuid>', methods=('GET', 'POST')) def detail(link_uuid: str): request = LinkId() request.link_uuid.uuid = link_uuid # pylint: disable=no-member context_client.connect() response = context_client.GetLink(request) device_names, endpoints_data = get_endpoint_names(context_client, response.link_endpoint_ids) 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=response, device_names=device_names, endpoints_data=endpoints_data) return render_template('link/detail.html',link=link_obj, device_names=device_names, endpoints_data=endpoints_data) src/webui/service/service/routes.py +51 −47 Original line number Diff line number Diff line Loading @@ -14,8 +14,11 @@ import grpc from flask import current_app, redirect, render_template, Blueprint, flash, session, url_for from common.proto.context_pb2 import ContextId, Service, ServiceId, ServiceTypeEnum, ServiceStatusEnum, Connection from common.proto.context_pb2 import ( IsolationLevelEnum, Service, ServiceId, ServiceTypeEnum, ServiceStatusEnum, Connection) from common.tools.context_queries.Context import get_context from common.tools.context_queries.EndPoint import get_endpoint_names from common.tools.context_queries.Service import get_service from context.client.ContextClient import ContextClient from service.client.ServiceClient import ServiceClient Loading @@ -26,93 +29,94 @@ service_client = ServiceClient() @service.get('/') def home(): # flash('This is an info message', 'info') # flash('This is a danger message', 'danger') context_uuid = session.get('context_uuid', '-') if context_uuid == "-": if 'context_uuid' not in session or 'topology_uuid' not in session: flash("Please select a context!", "warning") return redirect(url_for("main.home")) request = ContextId() request.context_uuid.uuid = context_uuid context_uuid = session['context_uuid'] context_client.connect() context_obj = get_context(context_client, context_uuid, rw_copy=False) if context_obj is None: flash('Context({:s}) not found'.format(str(context_uuid)), 'danger') services, device_names, endpoints_data = list(), list(), list() else: try: service_list = context_client.ListServices(request) # print(service_list) services = service_list.services context_found = True services = context_client.ListServices(context_obj.context_id) services = services.services except grpc.RpcError as e: if e.code() != grpc.StatusCode.NOT_FOUND: raise if e.details() != 'Context({:s}) not found'.format(context_uuid): raise services = [] context_found = False if context_found: endpoint_ids = [] services, device_names, endpoints_data = list(), dict(), dict() else: endpoint_ids = list() for service_ in services: endpoint_ids.extend(service_.service_endpoint_ids) device_names, endpoints_data = get_endpoint_names(context_client, endpoint_ids) else: device_names, endpoints_data = [],[] context_client.close() return render_template( 'service/home.html', services=services, device_names=device_names, endpoints_data=endpoints_data, context_not_found=not context_found, ste=ServiceTypeEnum, sse=ServiceStatusEnum) ste=ServiceTypeEnum, sse=ServiceStatusEnum) @service.route('add', methods=['GET', 'POST']) def add(): flash('Add service route called', 'danger') raise NotImplementedError() return render_template('service/home.html') #return render_template('service/home.html') @service.get('<path:service_uuid>/detail') def detail(service_uuid: str): context_uuid = session.get('context_uuid', '-') if context_uuid == "-": 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'] request: ServiceId = ServiceId() request.service_uuid.uuid = service_uuid request.context_id.context_uuid.uuid = context_uuid try: context_client.connect() response: Service = context_client.GetService(request) connections: Connection = context_client.ListConnections(request) endpoint_ids = list() service_obj = get_service(context_client, service_uuid, rw_copy=False) if service_obj is None: flash('Context({:s})/Service({:s}) not found'.format(str(context_uuid), str(service_uuid)), 'danger') service_obj = Service() else: endpoint_ids.extend(service_obj.service_endpoint_ids) connections: Connection = context_client.ListConnections(service_obj.service_id) connections = connections.connections for connection in connections: endpoint_ids.extend(connection.path_hops_endpoint_ids) endpoint_ids = [] endpoint_ids.extend(response.service_endpoint_ids) for connection in connections: endpoint_ids.extend(connection.path_hops_endpoint_ids) if len(endpoint_ids) > 0: device_names, endpoints_data = get_endpoint_names(context_client, endpoint_ids) else: device_names, endpoints_data = dict(), dict() context_client.close() return render_template( 'service/detail.html', service=service_obj, connections=connections, device_names=device_names, endpoints_data=endpoints_data, ste=ServiceTypeEnum, sse=ServiceStatusEnum, ile=IsolationLevelEnum) except Exception as e: flash('The system encountered an error and cannot show the details of this service.', 'warning') current_app.logger.exception(e) return redirect(url_for('service.home')) return render_template( 'service/detail.html', service=response, connections=connections, device_names=device_names, endpoints_data=endpoints_data, ste=ServiceTypeEnum, sse=ServiceStatusEnum) @service.get('<path:service_uuid>/delete') def delete(service_uuid: str): context_uuid = session.get('context_uuid', '-') if context_uuid == "-": 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'] try: request = ServiceId() request.service_uuid.uuid = service_uuid request.context_id.context_uuid.uuid = context_uuid service_client.connect() response = service_client.DeleteService(request) service_client.DeleteService(request) service_client.close() flash('Service "{:s}" deleted successfully!'.format(service_uuid), 'success') Loading Loading
src/webui/service/__init__.py +1 −0 Original line number Diff line number Diff line Loading @@ -96,6 +96,7 @@ def create_app(use_config=None, web_app_root=None): app.register_blueprint(link) app.jinja_env.globals.update({ # pylint: disable=no-member 'enumerate' : enumerate, 'json_to_list' : json_to_list, 'get_working_context' : get_working_context, 'get_working_topology': get_working_topology, Loading
src/webui/service/device/forms.py +4 −9 Original line number Diff line number Diff line Loading @@ -12,21 +12,16 @@ # See the License for the specific language governing permissions and # limitations under the License. # external imports from flask_wtf import FlaskForm from wtforms import StringField, SelectField, TextAreaField, SubmitField, BooleanField, Form from wtforms.validators import DataRequired, Length, NumberRange, Regexp, ValidationError from wtforms import StringField, SelectField, TextAreaField, SubmitField, BooleanField from wtforms.validators import DataRequired, Length, NumberRange, ValidationError from common.proto.context_pb2 import DeviceOperationalStatusEnum from webui.utils.form_validators import key_value_validator class AddDeviceForm(FlaskForm): device_id = StringField('ID', validators=[DataRequired(), Length(min=5)]) device_type = SelectField('Type', choices = []) operational_status = SelectField('Operational Status', # choices=[(-1, 'Select...'), (0, 'Undefined'), (1, 'Disabled'), (2, 'Enabled')], coerce=int, validators=[NumberRange(min=0)]) device_type = SelectField('Type') operational_status = SelectField('Operational Status', coerce=int, validators=[NumberRange(min=0)]) device_drivers_undefined = BooleanField('UNDEFINED / EMULATED') device_drivers_openconfig = BooleanField('OPENCONFIG') device_drivers_transport_api = BooleanField('TRANSPORT_API') Loading
src/webui/service/device/routes.py +55 −51 Original line number Diff line number Diff line Loading @@ -14,16 +14,14 @@ import json from flask import current_app, render_template, Blueprint, flash, session, redirect, url_for from common.DeviceTypes import DeviceTypeEnum from common.proto.context_pb2 import ( ConfigActionEnum, Device, DeviceDriverEnum, DeviceId, DeviceList, DeviceOperationalStatusEnum, Empty, TopologyId) from common.tools.object_factory.Context import json_context_id from common.tools.object_factory.Topology import json_topology_id ConfigActionEnum, Device, DeviceDriverEnum, DeviceId, DeviceList, DeviceOperationalStatusEnum, Empty) from common.tools.context_queries.Device import get_device from common.tools.context_queries.Topology import get_topology from context.client.ContextClient import ContextClient from device.client.DeviceClient import DeviceClient from webui.service.device.forms import AddDeviceForm from common.DeviceTypes import DeviceTypeEnum from webui.service.device.forms import ConfigForm from webui.service.device.forms import UpdateDeviceForm from webui.service.device.forms import AddDeviceForm, ConfigForm, UpdateDeviceForm device = Blueprint('device', __name__, url_prefix='/device') context_client = ContextClient() Loading @@ -39,16 +37,18 @@ def home(): topology_uuid = session['topology_uuid'] context_client.connect() json_topo_id = json_topology_id(topology_uuid, context_id=json_context_id(context_uuid)) grpc_topology = context_client.GetTopology(TopologyId(**json_topo_id)) grpc_topology = get_topology(context_client, topology_uuid, context_uuid=context_uuid, rw_copy=False) if grpc_topology is None: flash('Context({:s})/Topology({:s}) not found'.format(str(context_uuid), str(topology_uuid)), 'danger') devices = [] else: topo_device_uuids = {device_id.device_uuid.uuid for device_id in grpc_topology.device_ids} grpc_devices: DeviceList = context_client.ListDevices(Empty()) context_client.close() devices = [ device for device in grpc_devices.devices if device.device_id.device_uuid.uuid in topo_device_uuids ] context_client.close() return render_template( 'device/home.html', devices=devices, dde=DeviceDriverEnum, Loading @@ -71,23 +71,23 @@ def add(): if form.validate_on_submit(): device_obj = Device() # Device UUID: device_obj.device_id.device_uuid.uuid = form.device_id.data device_obj.device_id.device_uuid.uuid = form.device_id.data # pylint: disable=no-member # Device type: device_obj.device_type = str(form.device_type.data) # Device configurations: config_rule = device_obj.device_config.config_rules.add() config_rule = device_obj.device_config.config_rules.add() # pylint: disable=no-member 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_obj.device_config.config_rules.add() config_rule = device_obj.device_config.config_rules.add() # pylint: disable=no-member 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_obj.device_config.config_rules.add() config_rule = device_obj.device_config.config_rules.add() # pylint: disable=no-member config_rule.action = ConfigActionEnum.CONFIGACTION_SET config_rule.custom.resource_key = '_connect/settings' Loading @@ -105,20 +105,22 @@ def add(): device_obj.device_operational_status = form.operational_status.data # Device drivers: device_drivers = list() if form.device_drivers_undefined.data: device_obj.device_drivers.append(DeviceDriverEnum.DEVICEDRIVER_UNDEFINED) device_drivers.append(DeviceDriverEnum.DEVICEDRIVER_UNDEFINED) if form.device_drivers_openconfig.data: device_obj.device_drivers.append(DeviceDriverEnum.DEVICEDRIVER_OPENCONFIG) device_drivers.append(DeviceDriverEnum.DEVICEDRIVER_OPENCONFIG) if form.device_drivers_transport_api.data: device_obj.device_drivers.append(DeviceDriverEnum.DEVICEDRIVER_TRANSPORT_API) device_drivers.append(DeviceDriverEnum.DEVICEDRIVER_TRANSPORT_API) if form.device_drivers_p4.data: device_obj.device_drivers.append(DeviceDriverEnum.DEVICEDRIVER_P4) device_drivers.append(DeviceDriverEnum.DEVICEDRIVER_P4) if form.device_drivers_ietf_network_topology.data: device_obj.device_drivers.append(DeviceDriverEnum.DEVICEDRIVER_IETF_NETWORK_TOPOLOGY) device_drivers.append(DeviceDriverEnum.DEVICEDRIVER_IETF_NETWORK_TOPOLOGY) if form.device_drivers_onf_tr_352.data: device_obj.device_drivers.append(DeviceDriverEnum.DEVICEDRIVER_ONF_TR_352) device_drivers.append(DeviceDriverEnum.DEVICEDRIVER_ONF_TR_352) if form.device_drivers_xr.data: device_obj.device_drivers.append(DeviceDriverEnum.DEVICEDRIVER_XR) device_drivers.append(DeviceDriverEnum.DEVICEDRIVER_XR) device_obj.device_drivers.extend(device_drivers) # pylint: disable=no-member try: device_client.connect() Loading @@ -126,7 +128,7 @@ def add(): device_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: except Exception as e: # pylint: disable=broad-except flash(f'Problem adding the device. {e.details()}', 'danger') return render_template('device/add.html', form=form, Loading @@ -134,14 +136,15 @@ def add(): @device.route('detail/<path:device_uuid>', methods=['GET', 'POST']) def detail(device_uuid: str): request = DeviceId() request.device_uuid.uuid = device_uuid context_client.connect() response = context_client.GetDevice(request) device_obj = get_device(context_client, device_uuid, rw_copy=False) if device_obj is None: flash('Device({:s}) not found'.format(str(device_uuid)), 'danger') device_obj = Device() context_client.close() return render_template('device/detail.html', device=response, dde=DeviceDriverEnum, dose=DeviceOperationalStatusEnum) return render_template( 'device/detail.html', device=device_obj, dde=DeviceDriverEnum, dose=DeviceOperationalStatusEnum) @device.get('<path:device_uuid>/delete') def delete(device_uuid): Loading @@ -154,13 +157,13 @@ def delete(device_uuid): # TODO: finalize implementation request = DeviceId() request.device_uuid.uuid = device_uuid request.device_uuid.uuid = device_uuid # pylint: disable=no-member device_client.connect() response = device_client.DeleteDevice(request) device_client.DeleteDevice(request) device_client.close() flash(f'Device "{device_uuid}" deleted successfully!', 'success') except Exception as e: except Exception as e: # pylint: disable=broad-except flash(f'Problem deleting device "{device_uuid}": {e.details()}', 'danger') current_app.logger.exception(e) return redirect(url_for('device.home')) Loading @@ -169,25 +172,25 @@ def delete(device_uuid): def addconfig(device_uuid): form = ConfigForm() request = DeviceId() request.device_uuid.uuid = device_uuid request.device_uuid.uuid = device_uuid # pylint: disable=no-member 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() device_obj = Device() device_obj.CopyFrom(response) config_rule = device_obj.device_config.config_rules.add() # pylint: disable=no-member 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) response: DeviceId = device_client.ConfigureDevice(device_obj) 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: except Exception as e: # pylint: disable=broad-except flash(f'Problem adding the device. {e.details()}', 'danger') return render_template('device/addconfig.html', form=form, submit_text='Add New Configuration') Loading @@ -203,28 +206,29 @@ def updateconfig(): def update(device_uuid): form = UpdateDeviceForm() request = DeviceId() request.device_uuid.uuid = device_uuid request.device_uuid.uuid = device_uuid # pylint: disable=no-member 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_', ''))) for key, _ in DeviceOperationalStatusEnum.DESCRIPTOR.values_by_name.items(): item = (DeviceOperationalStatusEnum.Value(key), key.replace('DEVICEOPERATIONALSTATUS_', '')) form.update_operational_status.choices.append(item) 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 device_obj = Device() device_obj.CopyFrom(response) device_obj.device_operational_status = form.update_operational_status.data try: device_client.connect() response: DeviceId = device_client.ConfigureDevice(device) response: DeviceId = device_client.ConfigureDevice(device_obj) 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: except Exception as e: # pylint: disable=broad-except flash(f'Problem updating the device. {e.details()}', 'danger') return render_template('device/update.html', device=response, form=form, submit_text='Update Device')
src/webui/service/link/routes.py +25 −21 Original line number Diff line number Diff line Loading @@ -14,10 +14,10 @@ from flask import render_template, Blueprint, flash, session, redirect, url_for from common.proto.context_pb2 import Empty, LinkId, LinkList, TopologyId from common.proto.context_pb2 import Empty, Link, LinkList from common.tools.context_queries.EndPoint import get_endpoint_names 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.Link import get_link from common.tools.context_queries.Topology import get_topology from context.client.ContextClient import ContextClient Loading @@ -33,19 +33,20 @@ def home(): context_uuid = session['context_uuid'] topology_uuid = session['topology_uuid'] links, endpoint_ids = list(), list() device_names, endpoints_data = dict(), dict() context_client.connect() json_topo_id = json_topology_id(topology_uuid, context_id=json_context_id(context_uuid)) grpc_topology = context_client.GetTopology(TopologyId(**json_topo_id)) grpc_topology = get_topology(context_client, topology_uuid, context_uuid=context_uuid, rw_copy=False) if grpc_topology is None: flash('Context({:s})/Topology({:s}) not found'.format(str(context_uuid), str(topology_uuid)), 'danger') else: topo_link_uuids = {link_id.link_uuid.uuid for link_id in grpc_topology.link_ids} grpc_links: LinkList = context_client.ListLinks(Empty()) endpoint_ids = [] links = [] for link_ in grpc_links.links: if link_.link_id.link_uuid.uuid not in topo_link_uuids: continue links.append(link_) endpoint_ids.extend(link_.link_endpoint_ids) device_names, endpoints_data = get_endpoint_names(context_client, endpoint_ids) context_client.close() Loading @@ -54,10 +55,13 @@ def home(): @link.route('detail/<path:link_uuid>', methods=('GET', 'POST')) def detail(link_uuid: str): request = LinkId() request.link_uuid.uuid = link_uuid # pylint: disable=no-member context_client.connect() response = context_client.GetLink(request) device_names, endpoints_data = get_endpoint_names(context_client, response.link_endpoint_ids) 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=response, device_names=device_names, endpoints_data=endpoints_data) return render_template('link/detail.html',link=link_obj, device_names=device_names, endpoints_data=endpoints_data)
src/webui/service/service/routes.py +51 −47 Original line number Diff line number Diff line Loading @@ -14,8 +14,11 @@ import grpc from flask import current_app, redirect, render_template, Blueprint, flash, session, url_for from common.proto.context_pb2 import ContextId, Service, ServiceId, ServiceTypeEnum, ServiceStatusEnum, Connection from common.proto.context_pb2 import ( IsolationLevelEnum, Service, ServiceId, ServiceTypeEnum, ServiceStatusEnum, Connection) from common.tools.context_queries.Context import get_context from common.tools.context_queries.EndPoint import get_endpoint_names from common.tools.context_queries.Service import get_service from context.client.ContextClient import ContextClient from service.client.ServiceClient import ServiceClient Loading @@ -26,93 +29,94 @@ service_client = ServiceClient() @service.get('/') def home(): # flash('This is an info message', 'info') # flash('This is a danger message', 'danger') context_uuid = session.get('context_uuid', '-') if context_uuid == "-": if 'context_uuid' not in session or 'topology_uuid' not in session: flash("Please select a context!", "warning") return redirect(url_for("main.home")) request = ContextId() request.context_uuid.uuid = context_uuid context_uuid = session['context_uuid'] context_client.connect() context_obj = get_context(context_client, context_uuid, rw_copy=False) if context_obj is None: flash('Context({:s}) not found'.format(str(context_uuid)), 'danger') services, device_names, endpoints_data = list(), list(), list() else: try: service_list = context_client.ListServices(request) # print(service_list) services = service_list.services context_found = True services = context_client.ListServices(context_obj.context_id) services = services.services except grpc.RpcError as e: if e.code() != grpc.StatusCode.NOT_FOUND: raise if e.details() != 'Context({:s}) not found'.format(context_uuid): raise services = [] context_found = False if context_found: endpoint_ids = [] services, device_names, endpoints_data = list(), dict(), dict() else: endpoint_ids = list() for service_ in services: endpoint_ids.extend(service_.service_endpoint_ids) device_names, endpoints_data = get_endpoint_names(context_client, endpoint_ids) else: device_names, endpoints_data = [],[] context_client.close() return render_template( 'service/home.html', services=services, device_names=device_names, endpoints_data=endpoints_data, context_not_found=not context_found, ste=ServiceTypeEnum, sse=ServiceStatusEnum) ste=ServiceTypeEnum, sse=ServiceStatusEnum) @service.route('add', methods=['GET', 'POST']) def add(): flash('Add service route called', 'danger') raise NotImplementedError() return render_template('service/home.html') #return render_template('service/home.html') @service.get('<path:service_uuid>/detail') def detail(service_uuid: str): context_uuid = session.get('context_uuid', '-') if context_uuid == "-": 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'] request: ServiceId = ServiceId() request.service_uuid.uuid = service_uuid request.context_id.context_uuid.uuid = context_uuid try: context_client.connect() response: Service = context_client.GetService(request) connections: Connection = context_client.ListConnections(request) endpoint_ids = list() service_obj = get_service(context_client, service_uuid, rw_copy=False) if service_obj is None: flash('Context({:s})/Service({:s}) not found'.format(str(context_uuid), str(service_uuid)), 'danger') service_obj = Service() else: endpoint_ids.extend(service_obj.service_endpoint_ids) connections: Connection = context_client.ListConnections(service_obj.service_id) connections = connections.connections for connection in connections: endpoint_ids.extend(connection.path_hops_endpoint_ids) endpoint_ids = [] endpoint_ids.extend(response.service_endpoint_ids) for connection in connections: endpoint_ids.extend(connection.path_hops_endpoint_ids) if len(endpoint_ids) > 0: device_names, endpoints_data = get_endpoint_names(context_client, endpoint_ids) else: device_names, endpoints_data = dict(), dict() context_client.close() return render_template( 'service/detail.html', service=service_obj, connections=connections, device_names=device_names, endpoints_data=endpoints_data, ste=ServiceTypeEnum, sse=ServiceStatusEnum, ile=IsolationLevelEnum) except Exception as e: flash('The system encountered an error and cannot show the details of this service.', 'warning') current_app.logger.exception(e) return redirect(url_for('service.home')) return render_template( 'service/detail.html', service=response, connections=connections, device_names=device_names, endpoints_data=endpoints_data, ste=ServiceTypeEnum, sse=ServiceStatusEnum) @service.get('<path:service_uuid>/delete') def delete(service_uuid: str): context_uuid = session.get('context_uuid', '-') if context_uuid == "-": 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'] try: request = ServiceId() request.service_uuid.uuid = service_uuid request.context_id.context_uuid.uuid = context_uuid service_client.connect() response = service_client.DeleteService(request) service_client.DeleteService(request) service_client.close() flash('Service "{:s}" deleted successfully!'.format(service_uuid), 'success') Loading