diff --git a/src/webui/service/__init__.py b/src/webui/service/__init__.py index fca1071419b3b2b61739c2a0d1d8bfa45aba5119..e7f50ed42d19921b3423617f6860b5630e93adba 100644 --- a/src/webui/service/__init__.py +++ b/src/webui/service/__init__.py @@ -95,6 +95,9 @@ def create_app(use_config=None, web_app_root=None): from webui.service.link.routes import link # pylint: disable=import-outside-toplevel app.register_blueprint(link) + from webui.service.policy.routes import policy # pylint: disable=import-outside-toplevel + app.register_blueprint(policy) + app.jinja_env.globals.update({ # pylint: disable=no-member 'enumerate' : enumerate, 'json_to_list' : json_to_list, diff --git a/src/webui/service/policy/__init__.py b/src/webui/service/policy/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..1549d9811aa5d1c193a44ad45d0d7773236c0612 --- /dev/null +++ b/src/webui/service/policy/__init__.py @@ -0,0 +1,14 @@ +# 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. + diff --git a/src/webui/service/policy/routes.py b/src/webui/service/policy/routes.py new file mode 100644 index 0000000000000000000000000000000000000000..6d14f86b4f1428695b474b3f2e2dd4dc72657452 --- /dev/null +++ b/src/webui/service/policy/routes.py @@ -0,0 +1,50 @@ +# 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. + +import grpc +from flask import render_template, Blueprint +from common.proto.context_pb2 import Empty +from common.proto.policy_pb2 import PolicyRuleStateEnum +from context.client.ContextClient import ContextClient + +policy = Blueprint('policy', __name__, url_prefix='/policy') + +context_client = ContextClient() + +@policy.get('/') +def home(): + context_client.connect() + policy_rules = context_client.ListPolicyRules(Empty()) + policy_rules = policy_rules.policyRules + context_client.close() + return render_template('policy/home.html', policy_rules=policy_rules, prse=PolicyRuleStateEnum) + +#@policy.get('<path:policy_uuid>/detail') +#def detail(policy_uuid: str): +# try: +# context_client.connect() +# +# slice_obj = get_slice_by_uuid(context_client, slice_uuid, rw_copy=False) +# if slice_obj is None: +# flash('Context({:s})/Slice({:s}) not found'.format(str(context_uuid), str(slice_uuid)), 'danger') +# slice_obj = Slice() +# +# context_client.close() +# +# return render_template( +# 'slice/detail.html', slice=slice_obj, prse=PolicyRuleStateEnum) +# except Exception as e: +# flash('The system encountered an error and cannot show the details of this slice.', 'warning') +# current_app.logger.exception(e) +# return redirect(url_for('slice.home')) diff --git a/src/webui/service/templates/base.html b/src/webui/service/templates/base.html index 1dfa3687198d8a33db346ba2bbcd2989f6f109bb..61c283b0d957b4d13b7cc57e47d3ea2675ab76f0 100644 --- a/src/webui/service/templates/base.html +++ b/src/webui/service/templates/base.html @@ -83,6 +83,13 @@ <a class="nav-link" href="{{ url_for('slice.home') }}">Slice</a> {% endif %} </li> + <li class="nav-item"> + {% if '/policy/' in request.path %} + <a class="nav-link active" aria-current="page" href="{{ url_for('policy.home') }}">Policy</a> + {% else %} + <a class="nav-link" href="{{ url_for('policy.home') }}">Policy</a> + {% endif %} + </li> <li class="nav-item"> <a class="nav-link" href="/grafana" id="grafana_link" target="grafana">Grafana</a> </li> diff --git a/src/webui/service/templates/policy/home.html b/src/webui/service/templates/policy/home.html new file mode 100644 index 0000000000000000000000000000000000000000..64a8f82881bbb172d42f60770b30dac7e31e64c9 --- /dev/null +++ b/src/webui/service/templates/policy/home.html @@ -0,0 +1,84 @@ +<!-- + 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>Policy</h1> + + <div class="row"> + <div class="col"> + {{ policies | length }} policies found in context <i>{{ session['context_uuid'] }}</i> + </div> + </div> + + <table class="table table-striped table-hover"> + <thead> + <tr> + <th scope="col">UUID</th> + <th scope="col">Kind</th> + <th scope="col">Priority</th> + <th scope="col">Condition</th> + <th scope="col">Operator</th> + <th scope="col">Action</th> + <th scope="col">Service</th> + <th scope="col">Devices</th> + <th scope="col">State</th> + <th scope="col">Message</th> + <th scope="col">Extra</th> + <th scope="col"></th> + </tr> + </thead> + <tbody> + {% if policies %} + {% for policy in policies %} + {% if policy.WhichOneof('policy_rule') == 'device' %} + <tr> + <td>{{ policy.device.policyRuleBasic.policyRuleId.uuid }}</td> + <td>{{ policy.WhichOneof('policy_rule') }}</td> + <td>{{ policy.device.policyRuleBasic.priority }}</td> + <td>{{ policy.device.policyRuleBasic.conditionList }}</td> + <td>{{ policy.device.policyRuleBasic.booleanOperator }}</td> + <td>{{ policy.device.policyRuleBasic.actionList }}</td> + <td>-</td> + <td>{{ policy.device.deviceList }}</td> + <td>{{ prse.Name(policy.device.policyRuleBasic.policyRuleState.policyRuleState).replace('POLICY_', '') }}</td> + <td>{{ policy.device.policyRuleBasic.policyRuleState.policyRuleStateMessage }}</td> + </tr> + {% elif policy.WhichOneof('policy_rule') == 'service' %} + <tr> + <td>{{ policy.service.policyRuleBasic.policyRuleId.uuid }}</td> + <td>{{ policy.WhichOneof('policy_rule') }}</td> + <td>{{ policy.service.policyRuleBasic.priority }}</td> + <td>{{ policy.service.policyRuleBasic.conditionList }}</td> + <td>{{ policy.service.policyRuleBasic.booleanOperator }}</td> + <td>{{ policy.service.policyRuleBasic.actionList }}</td> + <td>{{ policy.service.serviceId }}</td> + <td>{{ policy.service.deviceList }}</td> + <td>{{ prse.Name(policy.service.policyRuleBasic.policyRuleState.policyRuleState).replace('POLICY_', '') }}</td> + <td>{{ policy.service.policyRuleBasic.policyRuleState.policyRuleStateMessage }}</td> + </tr> + {% else %} + <tr><td colspan="7">Unsupported policy type {{ policy.WhichOneof('policy_rule') }}</td></tr> + {% endif %} + {% endfor %} + {% else %} + <tr><td colspan="7">No policies found</td></tr> + {% endif %} + </tbody> + </table> + +{% endblock %}