Loading deploy/tfs.sh +1 −1 Original line number Diff line number Diff line Loading @@ -85,7 +85,7 @@ TMP_LOGS_FOLDER="$TMP_FOLDER/logs" mkdir -p $TMP_LOGS_FOLDER echo "Deleting and Creating a new namespace..." kubectl delete namespace $TFS_K8S_NAMESPACE kubectl delete namespace $TFS_K8S_NAMESPACE --ignore-not-found kubectl create namespace $TFS_K8S_NAMESPACE printf "\n" Loading src/device/service/drivers/emulated/SyntheticSamplingParameters.py +1 −1 Original line number Diff line number Diff line Loading @@ -51,7 +51,7 @@ class SyntheticSamplingParameters: metric = match.group(2) metric_sense = metric.lower().replace('packets_', '').replace('bytes_', '') LOGGER.info(MSG_INFO.format(monitoring_resource_key, endpoint_uuid, metric, metric_sense)) LOGGER.debug(MSG_INFO.format(monitoring_resource_key, endpoint_uuid, metric, metric_sense)) parameters_key = '{:s}-{:s}'.format(endpoint_uuid, metric_sense) parameters = self.__data.get(parameters_key) 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') Loading
deploy/tfs.sh +1 −1 Original line number Diff line number Diff line Loading @@ -85,7 +85,7 @@ TMP_LOGS_FOLDER="$TMP_FOLDER/logs" mkdir -p $TMP_LOGS_FOLDER echo "Deleting and Creating a new namespace..." kubectl delete namespace $TFS_K8S_NAMESPACE kubectl delete namespace $TFS_K8S_NAMESPACE --ignore-not-found kubectl create namespace $TFS_K8S_NAMESPACE printf "\n" Loading
src/device/service/drivers/emulated/SyntheticSamplingParameters.py +1 −1 Original line number Diff line number Diff line Loading @@ -51,7 +51,7 @@ class SyntheticSamplingParameters: metric = match.group(2) metric_sense = metric.lower().replace('packets_', '').replace('bytes_', '') LOGGER.info(MSG_INFO.format(monitoring_resource_key, endpoint_uuid, metric, metric_sense)) LOGGER.debug(MSG_INFO.format(monitoring_resource_key, endpoint_uuid, metric, metric_sense)) parameters_key = '{:s}-{:s}'.format(endpoint_uuid, metric_sense) parameters = self.__data.get(parameters_key) 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')