Skip to content
Snippets Groups Projects
Commit b6fdf507 authored by Lluis Gifre Renom's avatar Lluis Gifre Renom
Browse files

WebUI component:

- added section to control load generator
- updated basic Debug API endpoints
parent 73efb256
No related branches found
No related tags found
2 merge requests!142Release TeraFlowSDN 2.1,!64Slice Grouping
# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/)
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from flask_wtf import FlaskForm
from wtforms import BooleanField, FloatField, IntegerField, StringField, SubmitField
from wtforms.validators import DataRequired, NumberRange
class LoadGenStartForm(FlaskForm):
num_requests = IntegerField('Num Requests', default=100, validators=[DataRequired(), NumberRange(min=0)])
num_generated = IntegerField('Num Generated', render_kw={'readonly': True})
request_type_service_l2nm = BooleanField('Service L2NM', default=False)
request_type_service_l3nm = BooleanField('Service L3NM', default=False)
request_type_service_mw = BooleanField('Service MW', default=False)
request_type_service_tapi = BooleanField('Service TAPI', default=False)
request_type_slice_l2nm = BooleanField('Slice L2NM', default=True)
request_type_slice_l3nm = BooleanField('Slice L3NM', default=False)
offered_load = FloatField('Offered Load [Erlang]', default=50, validators=[NumberRange(min=1.e-12)])
holding_time = FloatField('Holding Time [seconds]', default=10, validators=[NumberRange(min=1.e-12)])
inter_arrival_time = FloatField('Inter Arrival Time[seconds]', default=0, validators=[NumberRange(min=1.e-12)])
do_teardown = BooleanField('Do Teardown', default=True)
record_to_dlt = BooleanField('Record to DLT', default=False)
dlt_domain_id = StringField('DLT Domain Id', default='')
infinite_loop = BooleanField('Infinite Loop', render_kw={'readonly': True})
running = BooleanField('Running', render_kw={'readonly': True})
submit = SubmitField('Start')
class LoadGenStopForm(FlaskForm):
submit = SubmitField('Stop')
......@@ -14,32 +14,93 @@
from flask import render_template, Blueprint, flash
from common.proto.context_pb2 import Empty
from common.proto.load_generator_pb2 import Parameters, RequestTypeEnum
from load_generator.client.LoadGeneratorClient import LoadGeneratorClient
from .forms import LoadGenStartForm, LoadGenStopForm
load_gen = Blueprint('load_gen', __name__, url_prefix='/load_gen')
@load_gen.route('start', methods=['GET'])
def start():
@load_gen.route('home', methods=['GET', 'POST'])
def home():
load_gen_client = LoadGeneratorClient()
try:
load_gen_client.connect()
load_gen_client.Start(Empty())
load_gen_client.close()
flash('Load Generator Started.', 'success')
except Exception as e: # pylint: disable=broad-except
flash('Problem starting Load Generator. {:s}'.format(str(e)), 'danger')
return render_template('main/debug.html')
@load_gen.route('stop', methods=['GET'])
def stop():
load_gen_client = LoadGeneratorClient()
try:
load_gen_client.connect()
load_gen_client.Stop(Empty())
load_gen_client.close()
flash('Load Generator Stoped.', 'success')
except Exception as e: # pylint: disable=broad-except
flash('Problem stopping Load Generator. {:s}'.format(str(e)), 'danger')
return render_template('main/debug.html')
form_start = LoadGenStartForm()
form_stop = LoadGenStopForm()
if form_start.validate_on_submit():
load_gen_params = Parameters()
load_gen_params.num_requests = form_start.num_requests.data
load_gen_params.offered_load = form_start.offered_load.data
load_gen_params.holding_time = form_start.holding_time.data
load_gen_params.inter_arrival_time = form_start.inter_arrival_time.data
load_gen_params.do_teardown = form_start.do_teardown.data
load_gen_params.dry_mode = False
load_gen_params.record_to_dlt = form_start.record_to_dlt.data
load_gen_params.dlt_domain_id = form_start.dlt_domain_id.data
del load_gen_params.request_types[:] # pylint: disable=no-member
request_types = list()
if form_start.request_type_service_l2nm.data: request_types.append(RequestTypeEnum.REQUESTTYPE_SERVICE_L2NM)
if form_start.request_type_service_l3nm.data: request_types.append(RequestTypeEnum.REQUESTTYPE_SERVICE_L3NM)
if form_start.request_type_service_mw .data: request_types.append(RequestTypeEnum.REQUESTTYPE_SERVICE_MW )
if form_start.request_type_service_tapi.data: request_types.append(RequestTypeEnum.REQUESTTYPE_SERVICE_TAPI)
if form_start.request_type_slice_l2nm .data: request_types.append(RequestTypeEnum.REQUESTTYPE_SLICE_L2NM )
if form_start.request_type_slice_l3nm .data: request_types.append(RequestTypeEnum.REQUESTTYPE_SLICE_L3NM )
load_gen_params.request_types.extend(request_types) # pylint: disable=no-member
try:
load_gen_client.connect()
load_gen_client.Start(load_gen_params)
load_gen_client.close()
flash('Load Generator Started.', 'success')
except Exception as e: # pylint: disable=broad-except
flash('Problem starting Load Generator. {:s}'.format(str(e)), 'danger')
if form_stop.validate_on_submit():
try:
load_gen_client.connect()
load_gen_client.Stop(Empty())
load_gen_client.close()
flash('Load Generator Stoped.', 'success')
except Exception as e: # pylint: disable=broad-except
flash('Problem stopping Load Generator. {:s}'.format(str(e)), 'danger')
load_gen_client.connect()
status = load_gen_client.GetStatus(Empty())
load_gen_client.close()
form_start.num_requests .default = status.parameters.num_requests
form_start.offered_load .default = status.parameters.offered_load
form_start.holding_time .default = status.parameters.holding_time
form_start.inter_arrival_time.default = status.parameters.inter_arrival_time
form_start.do_teardown .default = status.parameters.do_teardown
form_start.record_to_dlt .default = status.parameters.record_to_dlt
form_start.dlt_domain_id .default = status.parameters.dlt_domain_id
form_start.num_generated .default = status.num_generated
form_start.infinite_loop .default = status.infinite_loop
form_start.running .default = status.running
request_types = status.parameters.request_types
form_start.request_type_service_l2nm.default = RequestTypeEnum.REQUESTTYPE_SERVICE_L2NM in request_types
form_start.request_type_service_l3nm.default = RequestTypeEnum.REQUESTTYPE_SERVICE_L3NM in request_types
form_start.request_type_service_mw .default = RequestTypeEnum.REQUESTTYPE_SERVICE_MW in request_types
form_start.request_type_service_tapi.default = RequestTypeEnum.REQUESTTYPE_SERVICE_TAPI in request_types
form_start.request_type_slice_l2nm .default = RequestTypeEnum.REQUESTTYPE_SLICE_L2NM in request_types
form_start.request_type_slice_l3nm .default = RequestTypeEnum.REQUESTTYPE_SLICE_L3NM in request_types
form_start.num_requests .render_kw['readonly'] = status.running
form_start.offered_load .render_kw['readonly'] = status.running
form_start.holding_time .render_kw['readonly'] = status.running
form_start.inter_arrival_time.render_kw['readonly'] = status.running
form_start.do_teardown .render_kw['readonly'] = status.running
form_start.record_to_dlt .render_kw['readonly'] = status.running
form_start.dlt_domain_id .render_kw['readonly'] = status.running
form_start.request_type_service_l2nm.render_kw['readonly'] = status.running
form_start.request_type_service_l3nm.render_kw['readonly'] = status.running
form_start.request_type_service_mw .render_kw['readonly'] = status.running
form_start.request_type_service_tapi.render_kw['readonly'] = status.running
form_start.request_type_slice_l2nm .render_kw['readonly'] = status.running
form_start.request_type_slice_l3nm .render_kw['readonly'] = status.running
return render_template('load_gen/home.html', form_start=form_start, form_stop=form_stop)
......@@ -86,10 +86,16 @@
<li class="nav-item">
<a class="nav-link" href="/grafana" id="grafana_link" target="grafana">Grafana</a>
</li>
<li class="nav-item">
<a class="nav-link" href="{{ url_for('main.debug') }}">Debug</a>
</li>
<li class="nav-item">
{% if '/load-gen/' in request.path %}
<a class="nav-link active" aria-current="page" href="{{ url_for('load_gen.home') }}">Load Generator</a>
{% else %}
<a class="nav-link" href="{{ url_for('load_gen.home') }}">Load Generator</a>
{% endif %}
</li>
<!-- <li class="nav-item">
<a class="nav-link" href="#">Context</a>
......
<!--
Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/)
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
{% extends 'base.html' %}
{% block content %}
<h1>Load Generator</h1>
<br />
<form id="load_gen_start" method="POST">
{{ form_start.hidden_tag() }}
<fieldset>
<div class="row mb-3">
{{ form_start.num_requests.label(class="col-sm-2 col-form-label") }}
<div class="col-sm-10">
{% if form_start.num_requests.errors %}
{{ form_start.num_requests(class="form-control is-invalid") }}
<div class="invalid-feedback">
{% for error in form_start.num_requests.errors %}<span>{{ error }}</span>{% endfor %}
</div>
{% else %}
{{ form_start.num_requests(class="form-control") }}
{% endif %}
</div>
</div>
<br />
<div class="row mb-3">
{{ form_start.num_generated.label(class="col-sm-2 col-form-label") }}
<div class="col-sm-10">
{% if form_start.num_generated.errors %}
{{ form_start.num_generated(class="form-control is-invalid") }}
<div class="invalid-feedback">
{% for error in form_start.num_generated.errors %}<span>{{ error }}</span>{% endfor %}
</div>
{% else %}
{{ form_start.num_generated(class="form-control") }}
{% endif %}
</div>
</div>
<br />
<div class="row mb-3">
<div class="col-sm-2 col-form-label">Service Types:</div>
<div class="col-sm-10">
{{ form_start.request_type_service_l2nm }} {{ form_start.request_type_service_l2nm.label(class="col-sm-3 col-form-label") }}
{{ form_start.request_type_service_l3nm }} {{ form_start.request_type_service_l3nm.label(class="col-sm-3 col-form-label") }}
{{ form_start.request_type_service_mw }} {{ form_start.request_type_service_mw .label(class="col-sm-3 col-form-label") }}
{{ form_start.request_type_service_tapi }} {{ form_start.request_type_service_tapi.label(class="col-sm-3 col-form-label") }}
{{ form_start.request_type_slice_l2nm }} {{ form_start.request_type_slice_l2nm .label(class="col-sm-3 col-form-label") }}
{{ form_start.request_type_slice_l3nm }} {{ form_start.request_type_slice_l3nm .label(class="col-sm-3 col-form-label") }}
</div>
</div>
<br />
<div class="row mb-3">
{{ form_start.offered_load.label(class="col-sm-2 col-form-label") }}
<div class="col-sm-10">
{% if form_start.offered_load.errors %}
{{ form_start.offered_load(class="form-control is-invalid") }}
<div class="invalid-feedback">
{% for error in form_start.offered_load.errors %}<span>{{ error }}</span>{% endfor %}
</div>
{% else %}
{{ form_start.offered_load(class="form-control") }}
{% endif %}
</div>
</div>
<br />
<div class="row mb-3">
{{ form_start.holding_time.label(class="col-sm-2 col-form-label") }}
<div class="col-sm-10">
{% if form_start.holding_time.errors %}
{{ form_start.holding_time(class="form-control is-invalid") }}
<div class="invalid-feedback">
{% for error in form_start.holding_time.errors %}<span>{{ error }}</span>{% endfor %}
</div>
{% else %}
{{ form_start.holding_time(class="form-control") }}
{% endif %}
</div>
</div>
<br />
<div class="row mb-3">
{{ form_start.inter_arrival_time.label(class="col-sm-2 col-form-label") }}
<div class="col-sm-10">
{% if form_start.inter_arrival_time.errors %}
{{ form_start.inter_arrival_time(class="form-control is-invalid") }}
<div class="invalid-feedback">
{% for error in form_start.inter_arrival_time.errors %}<span>{{ error }}</span>{% endfor %}
</div>
{% else %}
{{ form_start.inter_arrival_time(class="form-control") }}
{% endif %}
</div>
</div>
<br />
<div class="row mb-3">
{{ form_start.do_teardown(class="form-control") }} {{ form_start.do_teardown.label(class="col-sm-2 col-form-label") }}
</div>
<br />
<div class="row mb-3">
{{ form_start.record_to_dlt(class="form-control") }} {{ form_start.record_to_dlt.label(class="col-sm-2 col-form-label") }}
</div>
<br />
<div class="row mb-3">
{{ form_start.dlt_domain_id.label(class="col-sm-2 col-form-label") }}
<div class="col-sm-10">
{% if form_start.dlt_domain_id.errors %}
{{ form_start.dlt_domain_id(class="form-control is-invalid") }}
<div class="invalid-feedback">
{% for error in form_start.dlt_domain_id.errors %}<span>{{ error }}</span>{% endfor %}
</div>
{% else %}
{{ form_start.dlt_domain_id(class="form-control") }}
{% endif %}
</div>
</div>
<br />
<div class="row mb-3">
{{ form_start.infinite_loop(class="form-control") }} {{ form_start.infinite_loop.label(class="col-sm-2 col-form-label") }}
</div>
<br />
<div class="row mb-3">
{{ form_start.running(class="form-control") }} {{ form_start.running.label(class="col-sm-2 col-form-label") }}
</div>
<br />
<div class="d-grid gap-2 d-md-flex justify-content-md-start">
{{ form_start.submit(class="btn btn-primary") }}
</div>
</fieldset>
</form>
<form id="load_gen_stop" method="POST">
{{ form_stop.hidden_tag() }}
<fieldset>
<div class="d-grid gap-2 d-md-flex justify-content-md-start">
{{ form_stop.submit(class="btn btn-primary") }}
</div>
</fieldset>
</form>
{% endblock %}
......@@ -17,26 +17,12 @@
{% extends 'base.html' %}
{% block content %}
<h1>Debug</h1>
<h1>Debug API</h1>
<!--
<h3>Dump ContextDB:</h3>
<ul>
<li>
<a class="nav-link" href="/context/api/dump/html" id="context_html_link" target="context_html">
as HTML
</a>
</li>
<li>
<a class="nav-link" href="/context/api/dump/text" id="context_text_link" target="context_text">
as Text
</a>
</li>
</ul>
-->
<h3>Load Generator:</h3>
<a href="{{ url_for('load_gen.start') }}" class="btn btn-primary" style="margin-bottom: 10px;">Start</a>
<a href="{{ url_for('load_gen.stop') }}" class="btn btn-primary" style="margin-bottom: 10px;">Stop</a>
<ul>
<li><a class="nav-link" href="/restconf/debug-api/contexts" id="contexts_link" target="contexts">Contexts</a></li>
<li><a class="nav-link" href="/restconf/debug-api/devices" id="devices_link" target="devices">Devices</a></li>
<li><a class="nav-link" href="/restconf/debug-api/links" id="links_link" target="links">Links</a></li>
</ul>
{% endblock %}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment