Commit 1bddb0ca authored by Lluis Gifre Renom's avatar Lluis Gifre Renom
Browse files

WebUI - Service Management form

- Leftover cosmetic changes from merge request
parent b6ba15c1
Loading
Loading
Loading
Loading
+167 −166
Original line number Diff line number Diff line
@@ -12,36 +12,38 @@
# See the License for the specific language governing permissions and
# limitations under the License.

 
import json, logging #, re
import json
import grpc
import grpc, json, logging #, re
from collections import defaultdict
from flask import current_app, redirect, render_template, Blueprint, flash, session, url_for, request
from typing import Optional, Set
from wtforms.validators import ValidationError

from common.proto.context_pb2 import (
    ContextId, IsolationLevelEnum, Service, ServiceId, ServiceTypeEnum, ServiceStatusEnum, Connection, Empty, DeviceDriverEnum,
    ConfigActionEnum, Device, DeviceList)
    ContextId, IsolationLevelEnum, Service, ServiceId, ServiceTypeEnum, ServiceStatusEnum, Connection,
    Empty, DeviceDriverEnum, ConfigActionEnum, Device, DeviceList
)
from common.tools.context_queries.Context import get_context
from common.tools.context_queries.Topology import get_topology
from common.tools.context_queries.EndPoint import get_endpoint_names
from wtforms.validators import ValidationError
from context.client.ContextClient import ContextClient
from service.client.ServiceClient import ServiceClient
from device.client.DeviceClient import DeviceClient
from common.tools.object_factory.Service import (
    json_service_l2nm_planned, json_service_l3nm_planned)
from common.tools.object_factory.Constraint import (
    json_constraint_sla_availability, json_constraint_sla_capacity, json_constraint_sla_isolation,
    json_constraint_sla_latency)
from common.tools.context_queries.Service import get_service_by_uuid
from common.tools.context_queries.Topology import get_topology
from common.tools.descriptor.Loader import DescriptorLoader, compose_notifications
from common.tools.object_factory.ConfigRule import json_config_rule_set
from common.tools.object_factory.Constraint import (
    json_constraint_sla_availability, json_constraint_sla_capacity, json_constraint_sla_isolation,
    json_constraint_sla_latency
)
from common.tools.object_factory.Context import json_context_id
from common.tools.object_factory.Device import json_device_id
from common.tools.object_factory.EndPoint import json_endpoint_id
from webui.service.service.forms import AddServiceForm_1, AddServiceForm_ACL_L2, AddServiceForm_ACL_IPV4, AddServiceForm_ACL_IPV6, AddServiceForm_L2VPN, AddServiceForm_L3VPN
from common.tools.context_queries.Service import get_service_by_uuid
from common.tools.object_factory.Context import json_context_id
from common.tools.object_factory.Service import json_service_l2nm_planned, json_service_l3nm_planned
from common.tools.object_factory.Topology import json_topology_id
from typing import Optional, Set
from context.client.ContextClient import ContextClient
from device.client.DeviceClient import DeviceClient
from service.client.ServiceClient import ServiceClient
from webui.service.service.forms import (
    AddServiceForm_1, AddServiceForm_ACL_L2, AddServiceForm_ACL_IPV4, AddServiceForm_ACL_IPV6,
    AddServiceForm_L2VPN, AddServiceForm_L3VPN
)

LOGGER = logging.getLogger(__name__)
service = Blueprint('service', __name__, url_prefix='/service')
@@ -50,21 +52,10 @@ context_client = ContextClient()
service_client = ServiceClient()
device_client = DeviceClient()

type     = ["ACL_UNDEFINED", "ACL_IPV4","ACL_IPV6","ACL_L2","ACL_MPLS","ACL_MIXED"]
ACL_TYPE = ["ACL_UNDEFINED", "ACL_IPV4","ACL_IPV6","ACL_L2","ACL_MPLS","ACL_MIXED"]
f_action = ["UNDEFINED", "DROP","ACCEPT","REJECT"]
l_action = ["UNDEFINED", "LOG_NONE","LOG_SYSLOG"]

'''
@service.get('/')                                                                   #Route for the homepage of the created "service" blueprint 
@contextmanager
def connected_client(c):
    try:
        c.connect()
        yield c
    finally:
        c.close()
'''

def get_device_drivers_in_use(topology_uuid: str, context_uuid: str) -> Set[str]:
    active_drivers = set()
    grpc_topology = get_topology(context_client, topology_uuid, context_uuid=context_uuid, rw_copy=False)
@@ -118,7 +109,9 @@ def add():

def get_hub_module_name(dev: Device) -> Optional[str]:
    for cr in dev.device_config.config_rules:
        if cr.action == ConfigActionEnum.CONFIGACTION_SET and cr.custom and cr.custom.resource_key == "_connect/settings":
        if cr.action != ConfigActionEnum.CONFIGACTION_SET: continue
        if not cr.custom: continue
        if cr.custom.resource_key != "_connect/settings": continue
        try:
            cr_dict = json.loads(cr.custom.resource_value)
            if "hub_module_name" in cr_dict:
@@ -142,7 +135,7 @@ def add_xr():
    if grpc_topology is None:
        flash('Context({:s})/Topology({:s}) not found'.format(str(context_uuid), str(topology_uuid)), 'danger')
        return redirect(url_for("main.home"))
    else:

    topo_device_uuids = {device_id.device_uuid.uuid for device_id in grpc_topology.device_ids}
    grpc_devices= context_client.ListDevices(Empty())
    devices = [
@@ -189,8 +182,11 @@ def add_xr():
    context_client.close()

    if request.method != 'POST':
        return render_template('service/add-xr.html', devices=devices, hub_if=hub_interfaces_by_device, leaf_if=leaf_interfaces_by_device, ep_used_by=ep_used_by)
    else:
        return render_template(
            'service/add-xr.html', devices=devices, hub_if=hub_interfaces_by_device,
            leaf_if=leaf_interfaces_by_device, ep_used_by=ep_used_by
        )

    service_name = request.form["service_name"]
    if service_name == "":
        flash(f"Service name must be specified", 'danger')
@@ -223,8 +219,16 @@ def add_xr():
        },
        'service_type'        : ServiceTypeEnum.SERVICETYPE_TAPI_CONNECTIVITY_SERVICE,
        "service_endpoint_ids": [
                {'device_id': {'device_uuid': {'uuid': constellation_uuid}}, 'endpoint_uuid': {'uuid': hub_if_uuid}, 'topology_id': json_topology_id("admin", context_id=json_context_uuid)},
                {'device_id': {'device_uuid': {'uuid': constellation_uuid}}, 'endpoint_uuid': {'uuid': leaf_if_uuid}, 'topology_id': json_topology_id("admin", context_id=json_context_uuid)}
            {
                'device_id': {'device_uuid': {'uuid': constellation_uuid}},
                'endpoint_uuid': {'uuid': hub_if_uuid},
                'topology_id': json_topology_id("admin", context_id=json_context_uuid)
            },
            {
                'device_id': {'device_uuid': {'uuid': constellation_uuid}},
                'endpoint_uuid': {'uuid': leaf_if_uuid},
                'topology_id': json_topology_id("admin", context_id=json_context_uuid)
            }
        ],
        'service_status'      : {'service_status': ServiceStatusEnum.SERVICESTATUS_PLANNED},
        'service_constraints' : [],
@@ -239,10 +243,12 @@ def add_xr():
    }
    config_rule = json_config_rule_set('/settings', json_tapi_settings)

        with connected_client(service_client) as sc:
    try:
        service_client.connect()

        endpoints, sr['service_endpoint_ids'] = sr['service_endpoint_ids'], []
        try:
                create_response = sc.CreateService(Service(**sr))
            create_response = service_client.CreateService(Service(**sr))
        except Exception as e:
            flash(f'Failure to update service name {service_name} with endpoints and configuration, exception {str(e)}', 'danger')
            return redirect(request.url)
@@ -251,13 +257,15 @@ def add_xr():
        sr['service_config'] = {'config_rules': [config_rule]}

        try:
                update_response = sc.UpdateService(Service(**sr))
            update_response = service_client.UpdateService(Service(**sr))
            flash(f'Created service {update_response.service_uuid.uuid}', 'success')
        except Exception as e: 
            flash(f'Failure to update service {create_response.service_uuid.uuid} with endpoints and configuration, exception {str(e)}', 'danger')
            return redirect(request.url)

        return redirect(url_for('service.home'))
    finally:
        service_client.close()

@service.get('<path:service_uuid>/detail')
def detail(service_uuid: str):
@@ -287,7 +295,9 @@ def detail(service_uuid: str):
        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, type = type, f_action = f_action, l_action = l_action)
            endpoints_data=endpoints_data, ste=ServiceTypeEnum, sse=ServiceStatusEnum, ile=IsolationLevelEnum,
            type=ACL_TYPE, f_action=f_action, l_action=l_action
        )
    except Exception as e:
        flash('The system encountered an error and cannot show the details of this service.', 'warning')
        current_app.logger.exception(e)
@@ -318,16 +328,9 @@ def delete(service_uuid: str):
def add_configure():
    form_1 = AddServiceForm_1()
    if form_1.validate_on_submit():
        if form_1.service_type.data == 'ACL_L2':
            return redirect(url_for('service.add_configure_ACL_L2'))
        elif form_1.service_type.data == 'ACL_IPV4':
            return redirect(url_for('service.add_configure_ACL_IPV4'))      
        elif form_1.service_type.data == 'ACL_IPV6':
            return redirect(url_for('service.add_configure_ACL_IPV6'))      
        elif form_1.service_type.data == 'L2VPN':
            return redirect(url_for('service.add_configure_L2VPN'))      
        elif form_1.service_type.data == 'L3VPN':
            return redirect(url_for('service.add_configure_L3VPN'))
        service_type = str(form_1.service_type.data)
        if service_type in {'ACL_L2', 'ACL_IPV4', 'ACL_IPV6', 'L2VPN', 'L3VPN'}:
            return redirect(url_for('service.add_configure_{:s}'.format(service_type)))
    return render_template('service/add.html', form_1=form_1, submit_text='Continue to configuraton')

@service.route('add/configure/ACL_L2', methods=['GET', 'POST'])
@@ -595,15 +598,13 @@ def get_device_vendor(form, devices):
    return vendor_value_1, vendor_value_2

def validate_params_vendor(form, vendor, device_num):
    if vendor == "ADVA":
    if vendor != "ADVA": return

    if form.NI_name.data != f"ELAN-AC:{getattr(form, f'Device_{device_num}_IF_vlan_id').data}":
        raise ValidationError('For an ADVA device, the name of the Network Instance should have this name: "ELAN-AC:vlanID"')

    elif getattr(form, f'Device_{device_num}_NI_VC_ID').data != getattr(form, f'Device_{device_num}_IF_vlan_id').data:
        raise ValidationError('For an ADVA device, the value of the VlanID and the value of the VC_ID must be the same')
    else:
        None
    return None

def set_service_parameters(service_obj, form, selected_device_1, selected_device_2, selected_endpoint_1, selected_endpoint_2):
    service_obj.service_id.service_uuid.uuid = str(form.service_name.data)