From 38cd8b5df9e0389f60e1793f4092e8881eaaf851 Mon Sep 17 00:00:00 2001 From: longllu Date: Fri, 2 Dec 2022 14:17:32 +0000 Subject: [PATCH 1/5] WebUI: - script for starting the WebUI in developing mode --- src/start_webui_dev_mode.sh | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/start_webui_dev_mode.sh b/src/start_webui_dev_mode.sh index 74540bcb3..8c45cd89e 100755 --- a/src/start_webui_dev_mode.sh +++ b/src/start_webui_dev_mode.sh @@ -14,19 +14,23 @@ # for development purposes only -K8S_NAMESPACE=${K8S_NAMESPACE:-'tf-dev'} +# K8S_NAMESPACE=${K8S_NAMESPACE:-'tf-dev'} -export CONTEXTSERVICE_SERVICE_HOST=`kubectl get service/contextservice -n ${K8S_NAMESPACE} -o jsonpath='{.spec.clusterIP}'` +# export CONTEXTSERVICE_SERVICE_HOST=`kubectl get service/contextservice -n ${K8S_NAMESPACE} -o jsonpath='{.spec.clusterIP}'` -echo Context IP: $CONTEXTSERVICE_SERVICE_HOST +# echo Context IP: $CONTEXTSERVICE_SERVICE_HOST -export DEVICESERVICE_SERVICE_HOST=`kubectl get service/deviceservice -n ${K8S_NAMESPACE} -o jsonpath='{.spec.clusterIP}'` +# export DEVICESERVICE_SERVICE_HOST=`kubectl get service/deviceservice -n ${K8S_NAMESPACE} -o jsonpath='{.spec.clusterIP}'` -echo Device IP: $DEVICESERVICE_SERVICE_HOST +# echo Device IP: $DEVICESERVICE_SERVICE_HOST + +source tfs_runtime_env_vars.sh export PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION='python' export HOST="127.0.0.1" +export HOSTNAME="test" export FLASK_ENV="development" +export LOG_LEVEL="DEBUG" # python3 -m webbrowser http://${HOST}:8004 -- GitLab From 95e19c7ee95a032476ed53abc9333d8231361b84 Mon Sep 17 00:00:00 2001 From: longllu Date: Fri, 2 Dec 2022 14:30:58 +0000 Subject: [PATCH 2/5] WebUI: - Improving the Add device form - Updating the drivers list of the Add device form --- src/webui/service/device/forms.py | 36 ++- src/webui/service/device/routes.py | 85 ++++--- src/webui/service/templates/device/add.html | 215 +++++++++++------- .../service/templates/device/detail.html | 194 ++++++++-------- 4 files changed, 292 insertions(+), 238 deletions(-) diff --git a/src/webui/service/device/forms.py b/src/webui/service/device/forms.py index d1880d321..3d728ade1 100644 --- a/src/webui/service/device/forms.py +++ b/src/webui/service/device/forms.py @@ -14,7 +14,7 @@ # external imports from flask_wtf import FlaskForm -from wtforms import StringField, SelectField, TextAreaField, SubmitField +from wtforms import StringField, SelectField, TextAreaField, SubmitField, BooleanField, Form from wtforms.validators import DataRequired, Length, NumberRange, Regexp, ValidationError from common.proto.context_pb2 import DeviceDriverEnum, DeviceOperationalStatusEnum from webui.utils.form_validators import key_value_validator @@ -22,33 +22,23 @@ from webui.utils.form_validators import key_value_validator class AddDeviceForm(FlaskForm): device_id = StringField('ID', validators=[DataRequired(), Length(min=5)]) - device_type = StringField('Type', - validators=[DataRequired(), Length(min=5)]) - device_config = TextAreaField('Configurations', validators=[key_value_validator()]) + 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_drivers = TextAreaField('Drivers', validators=[DataRequired(), Regexp(r'^\d+(,\d+)*$')]) + device_drivers_undefined = BooleanField('UNDEFINED') + device_drivers_openconfig = BooleanField('OPENCONFIG') + device_drivers_transport_api = BooleanField('TRANSPORT_API') + device_drivers_p4 = BooleanField('P4') + device_drivers_ietf_network_topology = BooleanField('IETF_NETWORK_TOPOLOGY') + device_drivers_onf_tr_352 = BooleanField('ONF_TR_352') + device_drivers_xr = BooleanField('XR') + device_config_address = StringField('connect/address',default='127.0.0.1',validators=[DataRequired(), Length(min=5)]) + device_config_port = StringField('connect/port',default='0',validators=[DataRequired(), Length(min=1)]) + device_config_settings = TextAreaField('connect/settings',default='{}',validators=[DataRequired(), Length(min=2)]) submit = SubmitField('Add') def validate_operational_status(form, field): if field.data not in DeviceOperationalStatusEnum.DESCRIPTOR.values_by_number: - raise ValidationError('The operational status value selected is incorrect!') - - def validate_device_drivers(form, field): - if ',' not in field.data: - data = str(field.data) + ',' - else: - data = field.data - for value in data.split(','): - value = value.strip() - if len(value) == 0: - continue - try: - value_int = int(value) - except: - raise ValidationError(f'The value "{value}" is not a valid driver identified.') - if value_int not in DeviceDriverEnum.DESCRIPTOR.values_by_number: - values = ', '.join([str(x) for x in DeviceDriverEnum.DESCRIPTOR.values_by_number]) - raise ValidationError(f'The device driver {value_int} is not correct. Allowed values are: {values}.') + raise ValidationError('The operational status value selected is incorrect!') \ No newline at end of file diff --git a/src/webui/service/device/routes.py b/src/webui/service/device/routes.py index b57c5735d..220a3a33c 100644 --- a/src/webui/service/device/routes.py +++ b/src/webui/service/device/routes.py @@ -16,12 +16,14 @@ from flask import current_app, render_template, Blueprint, flash, session, redir from common.proto.context_pb2 import ( ConfigActionEnum, ConfigRule, Device, DeviceDriverEnum, DeviceId, DeviceList, DeviceOperationalStatusEnum, - Empty, TopologyId) + Empty, TopologyId, ContextId) 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 common.DeviceTypes import DeviceTypeEnum device = Blueprint('device', __name__, url_prefix='/device') context_client = ContextClient() @@ -57,60 +59,75 @@ def add(): form = AddDeviceForm() # listing enum values - form.operational_status.choices = [(-1, 'Select...')] + form.operational_status.choices = [] for key, value in DeviceOperationalStatusEnum.DESCRIPTOR.values_by_name.items(): form.operational_status.choices.append( (DeviceOperationalStatusEnum.Value(key), key.replace('DEVICEOPERATIONALSTATUS_', ''))) - # device driver ids - device_driver_ids = [] - for key in DeviceDriverEnum.DESCRIPTOR.values_by_name: - device_driver_ids.append(f"{DeviceDriverEnum.Value(key)}={key.replace('DEVICEDRIVER_', '')}") - device_driver_ids = ', '.join(device_driver_ids) + # items for Device Type field + for device_type in DeviceTypeEnum: + form.device_type.choices.append((device_type.value,device_type.value)) if form.validate_on_submit(): device = Device() + # Device UUID: device.device_id.device_uuid.uuid = form.device_id.data - device.device_type = form.device_type.data - if '\n' not in form.device_config.data: - data = form.device_config.data.strip() + '\n' - else: - data = form.device_config.data.strip() - - for config in data.split('\n'): - if len(config.strip()) > 0: - parts = config.strip().split('=') - config_rule: ConfigRule = ConfigRule() - config_rule.action = ConfigActionEnum.CONFIGACTION_SET - config_rule.custom.resource_key = parts[0].strip() - config_rule.custom.resource_value = parts[1].strip() - device.device_config.config_rules.append(config_rule) + # 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 - if ',' not in form.device_drivers.data: - data = form.device_drivers.data.strip() + ',' - else: - data = form.device_drivers.data.strip() - - for driver in data.split(','): - driver = driver.strip() - if len(driver) == 0: - continue - device.device_drivers.append(int(driver)) + # 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, - submit_text='Add New Device', - device_driver_ids=device_driver_ids) + submit_text='Add New Device') @device.route('detail/', methods=['GET', 'POST']) def detail(device_uuid: str): diff --git a/src/webui/service/templates/device/add.html b/src/webui/service/templates/device/add.html index fe1ba31f2..1acbc7e48 100644 --- a/src/webui/service/templates/device/add.html +++ b/src/webui/service/templates/device/add.html @@ -17,100 +17,145 @@ {% extends 'base.html' %} {% block content %} -

Add New Device

- -
- {{ form.hidden_tag() }} -
-
- {{ form.device_id.label(class="col-sm-2 col-form-label") }} -
- {% if form.device_id.errors %} - {{ form.device_id(class="form-control is-invalid") }} -
- {% for error in form.device_id.errors %} - {{ error }} - {% endfor %} -
- {% else %} - {{ form.device_id(class="form-control") }} - {% endif %} +

Add New Device

+
+ + {{ form.hidden_tag() }} +
+
+ {{ form.device_id.label(class="col-sm-2 col-form-label") }} +
+ {% if form.device_id.errors %} + {{ form.device_id(class="form-control is-invalid") }} +
+ {% for error in form.device_id.errors %} + {{ error }} + {% endfor %} +
+ {% else %} + {{ form.device_id(class="form-control") }} + {% endif %} +
+
+
+
+ {{ form.device_type.label(class="col-sm-2 col-form-label") }} +
+ {% if form.device_type.errors %} + {{ form.device_type(class="form-control is-invalid") }} +
+ {% for error in form.device_type.errors %} + {{ error }} + {% endfor %}
+ {% else %} + {{ form.device_type(class="form-select")}} + {% endif %}
-
- {{ form.device_type.label(class="col-sm-2 col-form-label") }} -
- {% if form.device_type.errors %} - {{ form.device_type(class="form-control is-invalid") }} -
- {% for error in form.device_type.errors %} - {{ error }} - {% endfor %} -
- {% else %} - {{ form.device_type(class="form-control") }} - {% endif %} +
+
+
+ {{ form.operational_status.label(class="col-sm-2 col-form-label") }} +
+ {% if form.operational_status.errors %} + {{ form.operational_status(class="form-control is-invalid") }} +
+ {% for error in form.operational_status.errors %} + {{ error }} + {% endfor %}
+ {% else %} + {{ form.operational_status(class="form-select") }} + {% endif %}
-
- {{ form.operational_status.label(class="col-sm-2 col-form-label") }} -
- {% if form.operational_status.errors %} - {{ form.operational_status(class="form-control is-invalid") }} -
- {% for error in form.operational_status.errors %} - {{ error }} - {% endfor %} -
- {% else %} - {{ form.operational_status(class="form-control") }} - {% endif %} +
+
+
+
Drivers
+
+ {% if form.device_drivers_undefined.errors %} + {{ form.device_drivers_undefined(class="form-control is-invalid") }} +
+ {% for error in form.device_drivers_undefined.errors %} + {{ error }} + {% endfor %}
+ {% else %} + {{ form.device_drivers_undefined }} {{ form.device_drivers_undefined.label(class="col-sm-3 + col-form-label") }} + {{ form.device_drivers_openconfig }} {{ form.device_drivers_openconfig.label(class="col-sm-3 + col-form-label") }} + {{ form.device_drivers_transport_api }} {{ form.device_drivers_transport_api.label(class="col-sm-3 + col-form-label") }} +
{{ form.device_drivers_p4 }} {{ form.device_drivers_p4.label(class="col-sm-3 col-form-label") }} + {{ form.device_drivers_ietf_network_topology }} {{ + form.device_drivers_ietf_network_topology.label(class="col-sm-3 + col-form-label") }} + {{ form.device_drivers_onf_tr_352 }} {{ form.device_drivers_onf_tr_352.label(class="col-sm-3 + col-form-label") }}
+ {{ form.device_drivers_xr }} {{ form.device_drivers_xr.label(class="col-sm-3 + col-form-label") }} + {% endif %}
-
- {{ form.device_config.label(class="col-sm-2 col-form-label") }} -
- {% if form.device_config.errors %} - {{ form.device_config(class="form-control is-invalid", rows=5) }} -
- {% for error in form.device_config.errors %} - {{ error }} - {% endfor %} -
- {% else %} - {{ form.device_config(class="form-control", rows=5) }} - {% endif %} +
+
+ Configuration Rules
+
+ {{ form.device_config_address.label(class="col-sm-2 col-form-label") }} +
+ {% if form.device_config_address.errors %} + {{ form.device_config_address(class="form-control is-invalid", rows=5) }} +
+ {% for error in form.device_config_address.errors %} + {{ error }} + {% endfor %}
-
The device configurations should follow a key=value format, one configuration per line.
+ {% else %} + {{ form.device_config_address(class="form-control", rows=5) }} + {% endif %}
-
- {{ form.device_drivers.label(class="col-sm-2 col-form-label") }} -
- {% if form.device_drivers.errors %} - {{ form.device_drivers(class="form-control is-invalid", rows=5) }} -
- {% for error in form.device_drivers.errors %} - {{ error }} - {% endfor %} -
- {% else %} - {{ form.device_drivers(class="form-control", rows=5) }} - {% endif %} +
+
+ {{ form.device_config_port.label(class="col-sm-2 col-form-label") }} +
+ {% if form.device_config_port.errors %} + {{ form.device_config_port(class="form-control is-invalid", rows=5) }} +
+ {% for error in form.device_config_port.errors %} + {{ error }} + {% endfor %}
-
- List the device drivers by their numerical ID, separated by commas, without spaces between them. Numerical IDs: {{ device_driver_ids }}. + {% else %} + {{ form.device_config_port(class="form-control", rows=5) }} + {% endif %} +
+
+
+ {{ form.device_config_settings.label(class="col-sm-2 col-form-label") }} +
+ {% if form.device_config_settings.errors %} + {{ form.device_config_settings(class="form-control is-invalid", rows=5) }} +
+ {% for error in form.device_config_settings.errors %} + {{ error }} + {% endfor %}
+ {% else %} + {{ form.device_config_settings(class="form-control", rows=5) }} + {% endif %}
-
- - -
-
- +
+
+
+ + +
+
+ {% endblock %} \ No newline at end of file diff --git a/src/webui/service/templates/device/detail.html b/src/webui/service/templates/device/detail.html index 69ca93727..f07b9c985 100644 --- a/src/webui/service/templates/device/detail.html +++ b/src/webui/service/templates/device/detail.html @@ -13,118 +13,120 @@ See the License for the specific language governing permissions and limitations under the License. --> - - {% extends 'base.html' %} - - {% block content %} -

Device {{ device.device_id.device_uuid.uuid }}

- -
-
- -
- -
- - -
-
-
-
-
- UUID: {{ device.device_id.device_uuid.uuid }}

- Type: {{ device.device_type }}

- Status: {{ dose.Name(device.device_operational_status).replace('DEVICEOPERATIONALSTATUS_', '') }}
- Drivers: -
    - {% for driver in device.device_drivers %} -
  • {{ dde.Name(driver).replace('DEVICEDRIVER_', '').replace('UNDEFINED', 'EMULATED') }}
  • - {% endfor %} -
-
-
- - - - - - - - - {% for endpoint in device.device_endpoints %} - - - - - {% endfor %} - -
EndpointsType
- {{ endpoint.endpoint_id.endpoint_uuid.uuid }} - - {{ endpoint.endpoint_type }} -
-
-
- +{% extends 'base.html' %} + +{% block content %} +

Device {{ device.device_id.device_uuid.uuid }}

+ +
+
+ +
+ +
+ + +
+
- Configurations: +
+
+
+ UUID: {{ device.device_id.device_uuid.uuid }}

+ Type: {{ device.device_type }}

+ Status: {{ dose.Name(device.device_operational_status).replace('DEVICEOPERATIONALSTATUS_', '') }}
+ Drivers: +
    + {% for driver in device.device_drivers %} +
  • {{ dde.Name(driver).replace('DEVICEDRIVER_', '').replace('UNDEFINED', 'EMULATED') }}
  • + {% endfor %} +
+
+
- - + + - {% for config in device.device_config.config_rules %} - {% if config.WhichOneof('config_rule') == 'custom' %} + {% for endpoint in device.device_endpoints %} - {% endif %} {% endfor %}
KeyValueEndpointsType
- {{ config.custom.resource_key }} + {{ endpoint.endpoint_id.endpoint_uuid.uuid }} -
    - {% for key, value in (config.custom.resource_value | from_json).items() %} -
  • {{ key }}: {{ value }}
  • - {% endfor %} -
+ {{ endpoint.endpoint_type }}
+
+
+ +Configurations: + + + + + + + + + {% for config in device.device_config.config_rules %} + {% if config.WhichOneof('config_rule') == 'custom' %} + + + + + {% endif %} + {% endfor %} + +
KeyValue
+ {{ config.custom.resource_key }} + +
    + {% for key, value in (config.custom.resource_value | from_json).items() %} +
  • {{ key }}: {{ value }}
  • + {% endfor %} +
+
- - - - {% endblock %} - \ No newline at end of file + + + + +{% endblock %} -- GitLab From 87818c0775bcee6b2f2a14bba770c871fbd011b8 Mon Sep 17 00:00:00 2001 From: longllu Date: Fri, 2 Dec 2022 14:52:45 +0000 Subject: [PATCH 3/5] WebUI: - Adding link tooltip to the topology --- src/webui/service/templates/js/topology.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/webui/service/templates/js/topology.js b/src/webui/service/templates/js/topology.js index 69de0445d..29156224d 100644 --- a/src/webui/service/templates/js/topology.js +++ b/src/webui/service/templates/js/topology.js @@ -89,6 +89,8 @@ d3.json("{{ url_for('main.topology') }}", function(data) { // node tooltip node.append("title").text(function(d) { return d.id; }); + // link tooltip + link.append("title").text(function(d) { return d.id; }); // link style link -- GitLab From 05a7465e3161f819d08d78cce34b937d94305294 Mon Sep 17 00:00:00 2001 From: longllu Date: Tue, 13 Dec 2022 16:36:37 +0000 Subject: [PATCH 4/5] WebUI : - Adding the "Add configuration" form. - Adding the "Update device" form (not working). --- src/webui/service/device/forms.py | 18 ++++- src/webui/service/device/routes.py | 71 +++++++++++++++++++ .../service/templates/device/addconfig.html | 69 ++++++++++++++++++ .../service/templates/device/detail.html | 22 +++++- .../service/templates/device/update.html | 34 +++++++++ .../templates/device/updateconfig.html | 18 +++++ 6 files changed, 229 insertions(+), 3 deletions(-) create mode 100644 src/webui/service/templates/device/addconfig.html create mode 100644 src/webui/service/templates/device/update.html create mode 100644 src/webui/service/templates/device/updateconfig.html diff --git a/src/webui/service/device/forms.py b/src/webui/service/device/forms.py index 3d728ade1..3aae96cc0 100644 --- a/src/webui/service/device/forms.py +++ b/src/webui/service/device/forms.py @@ -16,7 +16,7 @@ from flask_wtf import FlaskForm from wtforms import StringField, SelectField, TextAreaField, SubmitField, BooleanField, Form from wtforms.validators import DataRequired, Length, NumberRange, Regexp, ValidationError -from common.proto.context_pb2 import DeviceDriverEnum, DeviceOperationalStatusEnum +from common.proto.context_pb2 import DeviceOperationalStatusEnum from webui.utils.form_validators import key_value_validator class AddDeviceForm(FlaskForm): @@ -41,4 +41,18 @@ class AddDeviceForm(FlaskForm): def validate_operational_status(form, field): if field.data not in DeviceOperationalStatusEnum.DESCRIPTOR.values_by_number: - raise ValidationError('The operational status value selected is incorrect!') \ No newline at end of file + raise ValidationError('The operational status value selected is incorrect!') + +class ConfigForm(FlaskForm): + device_key_config = StringField('Key configuration') + device_value_config = StringField('Value configuration') + submit = SubmitField('Add') + + +class UpdateDeviceForm(FlaskForm): + config_operational_status = SelectField('Operational Status', + choices=[(-1, 'Select...'), (0, 'Undefined'), (1, 'Disabled'), (2, 'Enabled')], + coerce=int, + validators=[NumberRange(min=0)]) + + submit = SubmitField('Update') diff --git a/src/webui/service/device/routes.py b/src/webui/service/device/routes.py index 220a3a33c..105fe3b98 100644 --- a/src/webui/service/device/routes.py +++ b/src/webui/service/device/routes.py @@ -24,6 +24,8 @@ 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 device = Blueprint('device', __name__, url_prefix='/device') context_client = ContextClient() @@ -161,3 +163,72 @@ def delete(device_uuid): flash(f'Problem deleting device "{device_uuid}": {e.details()}', 'danger') current_app.logger.exception(e) return redirect(url_for('device.home')) + +@device.route('/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('/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.operational_status.choices = [] + #for key, value in DeviceOperationalStatusEnum.DESCRIPTOR.values_by_name.items(): + # form.operational_status.choices.append((DeviceOperationalStatusEnum.Value(key), key.replace('DEVICEOPERATIONALSTATUS_', ''))) +# + #form.operational_status.default = response.device_operational_status + print(form.errors) + if form.is_submitted(): + print("submitted") + if form.validate(): + print("valid") + print(form.errors) + #if form.validate_on_submit(): + # device = Device() + # device.CopyFrom(response) + # device.device_operational_status = form.operational_status.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/update.html', device=response, form=form, submit_text='Update Device') diff --git a/src/webui/service/templates/device/addconfig.html b/src/webui/service/templates/device/addconfig.html new file mode 100644 index 000000000..c6a17e0a5 --- /dev/null +++ b/src/webui/service/templates/device/addconfig.html @@ -0,0 +1,69 @@ + + +{% extends 'base.html' %} + +{% block content %} +

Add New Configuration

+
+
+ {{ form.hidden_tag() }} +
+
+ {{ form.device_key_config.label(class="col-sm-2 col-form-label") }} +
+ {% if form.device_key_config.errors %} + {{ form.device_key_config(class="form-control is-invalid") }} +
+ {% for error in form.device_key_config.errors %} + {{ error }} + {% endfor %} +
+ {% else %} + {{ form.device_key_config(class="form-control") }} + {% endif %} +
+
+
+
+ {{ form.device_value_config.label(class="col-sm-2 col-form-label") }} +
+ {% if form.device_value_config.errors %} + {{ form.device_value_config(class="form-control is-invalid") }} +
+ {% for error in form.device_value_config.errors %} + {{ error }} + {% endfor %} +
+ {% else %} + {{ form.device_value_config(class="form-control") }} + {% endif %} +
+
+
+
+ + +
+
+
+{% endblock %} \ No newline at end of file diff --git a/src/webui/service/templates/device/detail.html b/src/webui/service/templates/device/detail.html index f07b9c985..e49396c4f 100644 --- a/src/webui/service/templates/device/detail.html +++ b/src/webui/service/templates/device/detail.html @@ -27,7 +27,7 @@
- + Update @@ -79,11 +79,14 @@
Configurations: + + + @@ -100,11 +103,28 @@ {% endfor %} + + {% endif %} {% endfor %}
Key Value
+ + + + + + +
+ diff --git a/src/webui/service/templates/device/update.html b/src/webui/service/templates/device/update.html new file mode 100644 index 000000000..3b25da9c1 --- /dev/null +++ b/src/webui/service/templates/device/update.html @@ -0,0 +1,34 @@ +{% extends 'base.html' %} + +{% block content %} +

Update Device {{ device.device_id.device_uuid.uuid }}

+
+
+
+
+ {{ form.config_operational_status.label(class="col-sm-2 col-form-label") }} +
+ {% if form.config_operational_status.errors %} + {{ form.config_operational_status(class="form-control is-invalid") }} +
+ {% for error in form.config_operational_status.errors %} + {{ error }} + {% endfor %} +
+ {% else %} + {{ form.config_operational_status(class="form-select") }} + {% endif %} +
+
+ + + +
+
+{% endblock %} \ No newline at end of file diff --git a/src/webui/service/templates/device/updateconfig.html b/src/webui/service/templates/device/updateconfig.html new file mode 100644 index 000000000..de217733d --- /dev/null +++ b/src/webui/service/templates/device/updateconfig.html @@ -0,0 +1,18 @@ + + + +{% extends 'base.html' %} \ No newline at end of file -- GitLab From d3aa64a2bed396e0b71f678bce30bed148384fbb Mon Sep 17 00:00:00 2001 From: longllu Date: Thu, 15 Dec 2022 10:10:35 +0000 Subject: [PATCH 5/5] WebUI: - Update device form. --- src/webui/service/device/forms.py | 2 +- src/webui/service/device/routes.py | 43 ++++++++----------- .../service/templates/device/update.html | 11 ++--- 3 files changed, 26 insertions(+), 30 deletions(-) diff --git a/src/webui/service/device/forms.py b/src/webui/service/device/forms.py index 3aae96cc0..cfa741ab3 100644 --- a/src/webui/service/device/forms.py +++ b/src/webui/service/device/forms.py @@ -50,7 +50,7 @@ class ConfigForm(FlaskForm): class UpdateDeviceForm(FlaskForm): - config_operational_status = SelectField('Operational Status', + update_operational_status = SelectField('Operational Status', choices=[(-1, 'Select...'), (0, 'Undefined'), (1, 'Disabled'), (2, 'Enabled')], coerce=int, validators=[NumberRange(min=0)]) diff --git a/src/webui/service/device/routes.py b/src/webui/service/device/routes.py index 105fe3b98..fe475594b 100644 --- a/src/webui/service/device/routes.py +++ b/src/webui/service/device/routes.py @@ -207,28 +207,23 @@ def update(device_uuid): response = context_client.GetDevice(request) context_client.close() - ## listing enum values - #form.operational_status.choices = [] - #for key, value in DeviceOperationalStatusEnum.DESCRIPTOR.values_by_name.items(): - # form.operational_status.choices.append((DeviceOperationalStatusEnum.Value(key), key.replace('DEVICEOPERATIONALSTATUS_', ''))) -# - #form.operational_status.default = response.device_operational_status - print(form.errors) - if form.is_submitted(): - print("submitted") - if form.validate(): - print("valid") - print(form.errors) - #if form.validate_on_submit(): - # device = Device() - # device.CopyFrom(response) - # device.device_operational_status = form.operational_status.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') + # 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') diff --git a/src/webui/service/templates/device/update.html b/src/webui/service/templates/device/update.html index 3b25da9c1..8c474f525 100644 --- a/src/webui/service/templates/device/update.html +++ b/src/webui/service/templates/device/update.html @@ -4,19 +4,20 @@

Update Device {{ device.device_id.device_uuid.uuid }}


+ {{ form.hidden_tag() }}
- {{ form.config_operational_status.label(class="col-sm-2 col-form-label") }} + {{ form.update_operational_status.label(class="col-sm-2 col-form-label") }}
- {% if form.config_operational_status.errors %} - {{ form.config_operational_status(class="form-control is-invalid") }} + {% if form.update_operational_status.errors %} + {{ form.update_operational_status(class="form-control is-invalid") }}
- {% for error in form.config_operational_status.errors %} + {% for error in form.update_operational_status.errors %} {{ error }} {% endfor %}
{% else %} - {{ form.config_operational_status(class="form-select") }} + {{ form.update_operational_status(class="form-select") }} {% endif %}
-- GitLab