From 3f87ff51209e6c11f0c71b3d4a0a35e15d313639 Mon Sep 17 00:00:00 2001 From: jvelazquezm <j.velazquezm@alumnos.upm.es> Date: Fri, 25 Apr 2025 13:19:13 +0200 Subject: [PATCH] Initial code upload --- .gitignore | 4 + README.md | 122 +-- app.py | 37 + images/NSC_Architecture.png | Bin 0 -> 257615 bytes requirements.txt | 5 + src/Constants.py | 35 + src/helpers.py | 124 +++ src/network_slice_controller.py | 1055 +++++++++++++++++++ src/nrp_ddbb.json | 38 + src/old/intent_generator.py | 136 +++ src/old/send_request.py | 28 + src/slice_ddbb.json | 1 + src/templates/3gpp_template_empty.json | 176 ++++ src/templates/3gpp_template_example.json | 187 ++++ src/templates/3gpp_template_filled.json | 182 ++++ src/templates/L2-VPN_template_empty.json | 38 + src/templates/L2-VPN_template_example.json | 271 +++++ src/templates/L2-VPN_template_filled.json | 36 + src/templates/L3-VPN_template_empty.json | 46 + src/templates/L3-VPN_template_example.json | 102 ++ src/templates/L3-VPN_template_filled.json | 44 + src/templates/descriptor-topology copy.json | 570 ++++++++++ src/templates/descriptor-topology-tid.json | 752 +++++++++++++ src/templates/descriptor-topology.json | 290 +++++ src/templates/descriptor.json | 27 + src/templates/ietfL2VPN_template.json | 38 + src/templates/ietfL3VPN_template.json | 184 ++++ src/templates/ietf_template_empty.json | 178 ++++ src/templates/ietf_template_example.json | 158 +++ src/templates/ietf_template_filled.json | 152 +++ src/templates/ips.json | 18 + src/templates/test_service.json | 93 ++ swagger/models/create_models.py | 324 ++++++ swagger/slice_namespace.py | 126 +++ 34 files changed, 5518 insertions(+), 59 deletions(-) create mode 100644 .gitignore create mode 100644 app.py create mode 100644 images/NSC_Architecture.png create mode 100644 requirements.txt create mode 100644 src/Constants.py create mode 100644 src/helpers.py create mode 100644 src/network_slice_controller.py create mode 100644 src/nrp_ddbb.json create mode 100644 src/old/intent_generator.py create mode 100644 src/old/send_request.py create mode 100644 src/slice_ddbb.json create mode 100644 src/templates/3gpp_template_empty.json create mode 100644 src/templates/3gpp_template_example.json create mode 100644 src/templates/3gpp_template_filled.json create mode 100644 src/templates/L2-VPN_template_empty.json create mode 100644 src/templates/L2-VPN_template_example.json create mode 100644 src/templates/L2-VPN_template_filled.json create mode 100644 src/templates/L3-VPN_template_empty.json create mode 100644 src/templates/L3-VPN_template_example.json create mode 100644 src/templates/L3-VPN_template_filled.json create mode 100644 src/templates/descriptor-topology copy.json create mode 100644 src/templates/descriptor-topology-tid.json create mode 100644 src/templates/descriptor-topology.json create mode 100644 src/templates/descriptor.json create mode 100644 src/templates/ietfL2VPN_template.json create mode 100644 src/templates/ietfL3VPN_template.json create mode 100644 src/templates/ietf_template_empty.json create mode 100644 src/templates/ietf_template_example.json create mode 100644 src/templates/ietf_template_filled.json create mode 100644 src/templates/ips.json create mode 100644 src/templates/test_service.json create mode 100644 swagger/models/create_models.py create mode 100644 swagger/slice_namespace.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..177b023 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +__pycache__/ +swagger/__pycache__/ +src/__pycache__/ + diff --git a/README.md b/README.md index ad27d65..e42cae6 100644 --- a/README.md +++ b/README.md @@ -1,93 +1,97 @@ -# NSC +# Network Slice Controller (NSC) Architecture +The Network Slice Controller (NSC) is a component defined by the IETF to orchestrate the request, realization, and lifecycle control of network slices. It consists of two main modules: the mapper and the realizer. +## Overview -## Getting started +The NSC handles end-to-end network slice requests originating from 5G customers. These requests are managed by the 5G end-to-end orchestrator, which configures RAN and Core Network elements accordingly and passes the request to the NSC for processing. The NSC then interacts with relevant network controllers to implement the network slice into the transport network. -To make it easy for you to get started with GitLab, here's a list of recommended next steps. +## Main Modules -Already a pro? Just edit this README.md and make it your own. Want to make it easy? [Use the template at the bottom](#editing-this-readme)! +### Mapper -## Add your files +The mapper processes client network slice requests and correlates them with existing slices. When a slice request arrives, the mapper translates it by converting the request expressed in 3GPP NRM terms into the IETF NBI data model. This involves identifying the service demarcation points (SDPs) that define the connectivity in the transport network. Once these parameters are identified and mapped into the data model, the next step is to check the feasibility of implementing the slice request. -- [ ] [Create](https://docs.gitlab.com/ee/user/project/repository/web_editor.html#create-a-file) or [upload](https://docs.gitlab.com/ee/user/project/repository/web_editor.html#upload-a-file) files -- [ ] [Add files using the command line](https://docs.gitlab.com/ee/gitlab-basics/add-file.html#add-a-file-using-the-command-line) or push an existing Git repository with the following command: +Realizing a slice requires an existing network resource partition (NRP) with the specified slice requirements, which may not be available at the time of the request. This information will be retrieved from an external module, which is beyond the scope of this definition. This module will provide a response regarding the feasibility of realizing the slice. -``` -cd existing_repo -git remote add origin https://labs.etsi.org/rep/tfs/nsc.git -git branch -M main -git push -uf origin main -``` +If there are no available NRPs for instantiating the slice, the mapper will request the realizer to create a new NRP. This involves interacting with the network controllers responsible for the transport network handled by the NSC. This process is iterative until the mapper determines that the slice realization is feasible. In the current version, it is assumed that there is only one available NRP corresponding to the entire network, and that it is always accessible to the user. -## Integrate with your tools +### Realizer -- [ ] [Set up project integrations](https://labs.etsi.org/rep/tfs/nsc/-/settings/integrations) +The realizer module determines the realization of each slice by interacting with specific network controllers. This version is currently working with Teraflow SDN controller. It receives requests from the mapper and decides on the technologies to be used to instantiate the slice based on the selected NRP associated with the slice. For example, Layer 2 VPN is the technology employed to realize network slices in this version. To achieve this, the realizer generates a request for the network controller to establish a Layer 2 VPN between two SDPs with the requirements specified in the slice request. -## Collaborate with your team +## Workflow -- [ ] [Invite team members and collaborators](https://docs.gitlab.com/ee/user/project/members/) -- [ ] [Create a new merge request](https://docs.gitlab.com/ee/user/project/merge_requests/creating_merge_requests.html) -- [ ] [Automatically close issues from merge requests](https://docs.gitlab.com/ee/user/project/issues/managing_issues.html#closing-issues-automatically) -- [ ] [Enable merge request approvals](https://docs.gitlab.com/ee/user/project/merge_requests/approvals/) -- [ ] [Set auto-merge](https://docs.gitlab.com/ee/user/project/merge_requests/merge_when_pipeline_succeeds.html) +1. **Request Initiation**: Network slice request originates from a 5G customer and is managed by the 5G end-to-end orchestrator. -## Test and Deploy +2. **Mapper Processing**: Converts the request into the IETF NBI data model, identifies SDPs, and checks feasibility. -Use the built-in continuous integration in GitLab. +3. **Realizer Action**: Determines technology (e.g., Layer 2 VPN) and interacts with network controllers to instantiate the slice. -- [ ] [Get started with GitLab CI/CD](https://docs.gitlab.com/ee/ci/quick_start/) -- [ ] [Analyze your code for known vulnerabilities with Static Application Security Testing (SAST)](https://docs.gitlab.com/ee/user/application_security/sast/) -- [ ] [Deploy to Kubernetes, Amazon EC2, or Amazon ECS using Auto Deploy](https://docs.gitlab.com/ee/topics/autodevops/requirements.html) -- [ ] [Use pull-based deployments for improved Kubernetes management](https://docs.gitlab.com/ee/user/clusters/agent/) -- [ ] [Set up protected environments](https://docs.gitlab.com/ee/ci/environments/protected_environments.html) +4. **Implementation**: Network controllers configure the transport network as per the slice requirements. -*** +## Arquitecture -# Editing this README +<img src="images/NSC_Architecture.png" alt="NSC Architecture"> -When you're ready to make this README your own, just edit this file and use the handy template below (or feel free to structure it however you want - this is just a starting point!). Thanks to [makeareadme.com](https://www.makeareadme.com/) for this template. +## Requirements +- Python3 +- python3-pip +- python3-venv -## Suggestions for a good README +## Configuration Constants -Every project is different, so consider which of these sections apply to yours. The sections used in the template are suggestions for most open source projects. Also keep in mind that while a README can be too long and detailed, too long is better than too short. If you think your README is too long, consider utilizing another form of documentation rather than cutting out information. +In the main configuration file, several constants can be adjusted to customize the Network Slice Controller (NSC) behavior: -## Name -Choose a self-explaining name for your project. +### Logging +- `DEFAULT_LOGGING_LEVEL`: Sets logging verbosity + - Default: `logging.INFO` + - Options: `logging.DEBUG`, `logging.INFO`, `logging.WARNING`, `logging.ERROR` -## Description -Let people know what your project can do specifically. Provide context and add a link to any reference visitors might be unfamiliar with. A list of Features or a Background subsection can also be added here. If there are alternatives to your project, this is a good place to list differentiating factors. +### Server +- `NSC_PORT`: Server port + - Default: `8081` -## Badges -On some READMEs, you may see small images that convey metadata, such as whether or not all the tests are passing for the project. You can use Shields to add some to your README. Many services also have instructions for adding a badge. +### Paths +- `SRC_PATH`: Absolute path to source directory +- `TEMPLATES_PATH`: Path to templates directory -## Visuals -Depending on what you are making, it can be a good idea to include screenshots or even a video (you'll frequently see GIFs rather than actual videos). Tools like ttygif can help, but check out Asciinema for a more sophisticated method. - -## Installation -Within a particular ecosystem, there may be a common way of installing things, such as using Yarn, NuGet, or Homebrew. However, consider the possibility that whoever is reading your README is a novice and would like more guidance. Listing specific steps helps remove ambiguity and gets people to using your project as quickly as possible. If it only runs in a specific context like a particular programming language version or operating system or has dependencies that have to be installed manually, also add a Requirements subsection. +### Teraflow Configuration +- `TFS_UPLOAD`: Enable/disable uploading slice service to Teraflow + - Default: `False` +- `TFS_IP`: Teraflow SDN controller IP + - Default: `"192.168.165.10"` +- `TFS_L2VPN_SUPPORT`: Enable additional L2VPN configuration support + - Default: `False` ## Usage -Use examples liberally, and show the expected output if you can. It's helpful to have inline the smallest example of usage that you can demonstrate, while providing links to more sophisticated examples if they are too long to reasonably include in the README. -## Support -Tell people where they can go to for help. It can be any combination of an issue tracker, a chat room, an email address, etc. +To deploy and execute the NSC, follow these steps: + +0. **Preparation** + ``` + git clone https://github.com/Telefonica/network_slice_controller.git + cd network_slice_controller + python3 -m venv venv + source venv/bin/activate + pip install -r requirements.txt + ``` + +1. **Start NSC Server**: + ``` + python3 app.py + ``` -## Roadmap -If you have ideas for releases in the future, it is a good idea to list them in the README. +2. **Generate Slice Requests**: -## Contributing -State if you are open to contributions and what your requirements are for accepting them. + To send slice request, the NSC accepts POST request at the endpoint /slice. It is available in the swagger documentation panel at {ip}:{NSC_PORT}/nsc -For people who want to make changes to your project, it's helpful to have some documentation on how to get started. Perhaps there is a script that they should run or some environment variables that they need to set. Make these steps explicit. These instructions could also be useful to your future self. +<!-- ## Versioning and Assumptions -You can also document commands to lint the code or run tests. These steps help to ensure high code quality and reduce the likelihood that the changes inadvertently break something. Having instructions for running tests is especially helpful if it requires external setup, such as starting a Selenium server for testing in a browser. +- The current version assumes a single available Network Resource Partition (NRP) for the entire network. +- It interacts with specific network controllers tailored to the technology required for slice instantiation (e.g., Teraflow SDN controller). -## Authors and acknowledgment -Show your appreciation to those who have contributed to the project. +## External Modules -## License -For open source projects, say how it is licensed. +The planner module, which is out of the scope of this development, provides information on NRP availability and feasibility of slice realization. --> -## Project status -If you have run out of energy or time for your project, put a note at the top of the README saying that development has slowed down or stopped completely. Someone may choose to fork your project or volunteer to step in as a maintainer or owner, allowing your project to keep going. You can also make an explicit request for maintainers. diff --git a/app.py b/app.py new file mode 100644 index 0000000..383d31c --- /dev/null +++ b/app.py @@ -0,0 +1,37 @@ +# Copyright 2025 Telefonica Innovación Digital S.L. + +# 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 import Flask +from flask_restx import Api +from flask_cors import CORS +from swagger.slice_namespace import slice_ns +from src.Constants import NSC_PORT + +app = Flask(__name__) +CORS(app) + +# Create API instance +api = Api( + app, + version="1.0", + title="Network Slice Controller (NSC) API", + description="API for orchestrating and realizing transport network slice requests", + doc="/nsc" # Swagger UI URL +) + +# Register namespaces +api.add_namespace(slice_ns, path="/slice") + +if __name__ == "__main__": + app.run(host="0.0.0.0", port=NSC_PORT, debug=True) diff --git a/images/NSC_Architecture.png b/images/NSC_Architecture.png new file mode 100644 index 0000000000000000000000000000000000000000..adee5374846eccdbf1974e616890b55fc4c131e2 GIT binary patch literal 257615 zcmeFa$&%t&7eDqn9N};{!Y|<Pwj=&tbcg0)i9kXEfrJJS+Bk#;kk9~{5PAbYh8N!Y z4g3mz0581r!r_<jxg^S@GPAns`?|*Ns>-SaAvD~3hTr*}bC3QPeL4N_|GWR;zx&s} z{`KE0^2GSpzy7QL5B~jc|LuPRTmG;A_5c1q;Madu8B^h3|NH;>KmNb}`mZnlPc1ri z)<tm|{_8h#{PgNK0y`8{{Tn&?jUc?!>5m}x_NA9qf8=2eo8a@T2;wLXgQtB6jG%tU znBQ^I!m;1T5sm(%s6Pmbbf5P3_F;ZM;G*c`H1&QXB>E2w4)tF)aUK+x3SKTP_z%Zm zGbz9;_<*6FUUm%iKf#vK>6C_>a5s<PIwYE8{~#II{9op>wNQT}#_&3gk0Jb;hW@cY zUl||DB7-dwPQdxlU)X4RkypkKhd}of*53Z<evY|TdP%%0D8o{N?&>W!^wWK`VOhmR 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ê}+@A`XY%ju3c$)fPk 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 ONALPA?UHNvpZyEVp(3OJ literal 0 HcmV?d00001 diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..e01b558 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,5 @@ +Flask +flask-cors +flask-restx +netmiko +requests diff --git a/src/Constants.py b/src/Constants.py new file mode 100644 index 0000000..f699aed --- /dev/null +++ b/src/Constants.py @@ -0,0 +1,35 @@ +# Copyright 2025 Telefonica Innovación Digital S.L. + +# 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 logging, os +# Default logging level +DEFAULT_LOGGING_LEVEL = logging.INFO + +# Default port for NSC deployment +NSC_PORT = 8081 + +# Paths +# Obtain the absolute path of the current file +SRC_PATH = os.path.dirname(os.path.abspath(__file__)) + +# Create the path to the desired file relative to the current file +TEMPLATES_PATH = os.path.join(SRC_PATH, "templates") + +# TFS Flags +# Flag to determine if configurations should be uploaded to Teraflow +TFS_UPLOAD = False +# Teraflow IP +TFS_IP = "192.168.165.10" +# Flag to determine if additional L2VPN configuration support is required for deploying L2VPNs with path selection +TFS_L2VPN_SUPPORT = False \ No newline at end of file diff --git a/src/helpers.py b/src/helpers.py new file mode 100644 index 0000000..24c0dac --- /dev/null +++ b/src/helpers.py @@ -0,0 +1,124 @@ +# Copyright 2025 Telefonica Innovación Digital S.L. + +# 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 logging, requests, json +from netmiko import ConnectHandler +from src.Constants import DEFAULT_LOGGING_LEVEL + +# Configure logging to provide clear and informative log messages +logging.basicConfig( + level=DEFAULT_LOGGING_LEVEL, + format='%(levelname)s - %(message)s') + +#Teraflow +class tfs_connector(): + + def simple_post(self, tfs_ip, service): + user="admin" + password="admin" + token="" + session = requests.Session() + session.auth = (user, password) + url=f'http://{tfs_ip}/webui' + response=session.get(url=url) + for item in response.iter_lines(): + if("csrf_token" in str(item)): + string=str(item).split('<input id="csrf_token" name="csrf_token" type="hidden" value=')[1] + token=string.split(">")[0].strip('"') + logging.debug("csrf token %s",token) + + files = {'descriptors': ("data.json", json.dumps(service).encode("utf-8"), "application/json")} + token={'csrf_token':token} + response = session.post(url,files=files,data=token,timeout=60) + logging.debug("Http response: %s",response.text) + return response + +#CISCO +class cisco_connector(): + def __init__(self, address, configs=None): + self.address=address + self.configs=configs + + def execute_commands(self, commands): + try: + # Configuración del dispositivo + device = { + 'device_type': 'cisco_xr', # Esto depende del tipo de dispositivo (ej: 'cisco_ios', 'cisco_xr', 'linux', etc.) + 'host': self.address, + 'username': 'cisco', + 'password': 'cisco12345', + } + + # Conexión por SSH + connection = ConnectHandler(**device) + + # Enviar comandos + output = connection.send_config_set(commands) + logging.debug(output) + + # Cerrar la conexión + connection.disconnect() + + except Exception as e: + logging.error(f"Failed to execute commands on {self.address}: {str(e)}") + + def create_command_template(self, config): + + commands = [ + "l2vpn", + f"pw-class l2vpn_vpws_profile_example_{config["number"]}", + "encapsulation mpls" + ] + + commands.extend([ + "transport-mode vlan passthrough", + "control-word" + ]) + + commands.extend([ + f"preferred-path interface tunnel-te {config["number"]}", + "exit", + "exit" + ]) + + commands.extend([ + "xconnect group l2vpn_vpws_group_example", + f"p2p {config["ni_name"]}", + f"interface {config["interface"]}.{config["vlan"]}", + f"neighbor ipv4 {config["remote_router"]} pw-id {config["vlan"]}", + "no pw-class l2vpn_vpws_profile_example", + f"pw-class l2vpn_vpws_profile_example_{config["number"]}" + ]) + + + return commands + + def full_create_command_template(self): + commands =[] + for config in self.configs: + commands_temp = self.create_command_template(config) + commands.extend(commands_temp) + commands.append("commit") + commands.append("end") + return commands + + def create_command_template_delete(self): + commands = [ + "no l2vpn", + ] + + commands.append("commit") + commands.append("end") + + return commands \ No newline at end of file diff --git a/src/network_slice_controller.py b/src/network_slice_controller.py new file mode 100644 index 0000000..4f053da --- /dev/null +++ b/src/network_slice_controller.py @@ -0,0 +1,1055 @@ +# Copyright 2025 Telefonica Innovación Digital S.L. + +# 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 json, time, os, logging, uuid +from datetime import datetime +from src.helpers import tfs_connector, cisco_connector +from src.Constants import DEFAULT_LOGGING_LEVEL, TFS_UPLOAD, TFS_IP, TFS_L2VPN_SUPPORT, SRC_PATH, TEMPLATES_PATH + +# Configure logging to provide clear and informative log messages +logging.basicConfig( + level=DEFAULT_LOGGING_LEVEL, + format='%(levelname)s - %(message)s') + +class NSController: + """ + Network Slice Controller (NSC) - A class to manage network slice creation, + modification, and deletion across different network domains. + + This controller handles the translation, mapping, and realization of network + slice intents from different formats (3GPP and IETF) to network-specific + configurations. + + Key Functionalities: + - Intent Processing: Translate and process network slice intents + - Slice Management: Create, modify, and delete network slices + - NRP (Network Resource Partition) Mapping: Match slice requirements with available resources + - Slice Realization: Convert intents to specific network configurations (L2VPN, L3VPN) + """ + + def __init__(self, upload_to_tfs = TFS_UPLOAD, tfs_ip=TFS_IP, need_l2vpn_support=TFS_L2VPN_SUPPORT): + """ + Initialize the Network Slice Controller. + + Args: + upload_to_tfs (bool, optional): Flag to determine if configurations + should be uploaded to Teraflow system. Defaults to False. + need_l2vpn_support (bool, optional): Flag to determine if additional + L2VPN configuration support is required. Defaults to False. + + Attributes: + upload_to_tfs (bool): Flag for Teraflow upload + answer (dict): Stores slice creation responses + tfs_requests (dict): Stores requests to be sent to Teraflow + start_time (float): Tracks slice setup start time + end_time (float): Tracks slice setup end time + need_l2vpn_support (bool): Flag for additional L2VPN configuration support + """ + self.upload_to_tfs = upload_to_tfs + self.tfs_ip = tfs_ip + self.answer = {} + self.cool_answer = {} + self.start_time = 0 + self.end_time = 0 + self.setup_time = 0 + self.need_l2vpn_support = need_l2vpn_support + # Internal templates and views + self.__gpp_template = "" + self.__ietf_template = "" + self.__teraflow_template = "" + self.__nrp_view = "" + self.subnet="" + + # API Methods + def add_flow(self, intent): + """ + Create a new transport network slice. + + Args: + intent (dict): Network slice intent in 3GPP or IETF format + + Returns: + Result of the Network Slice Controller (NSC) operation + + API Endpoint: + POST /slice + + Raises: + ValueError: If no transport network slices are found + Exception: For unexpected errors during slice creation process + """ + return self.nsc(intent) + + def get_flows(self,slice_id=None): + """ + Retrieve transport network slice information. + + This method allows retrieving: + - All transport network slices + - A specific slice by its ID + + Args: + slice_id (str, optional): Unique identifier of a specific slice. + Defaults to None. + + Returns: + dict or list: + - If slice_id is provided: Returns the specific slice details + - If slice_id is None: Returns a list of all slices + - Returns an error response if no slices are found + + API Endpoint: + GET /slice/{id} + + Raises: + ValueError: If no transport network slices are found + Exception: For unexpected errors during file processing + """ + try: + # Read slice database from JSON file + with open(os.path.join(SRC_PATH, "slice_ddbb.json"), 'r') as file: + content = json.load(file) + # If specific slice ID is provided, find and return matching slice + if slice_id: + for slice in content: + if slice["slice_id"] == slice_id: + return slice + # If no slices exist, raise an error + if len(content) == 0: + raise ValueError("Transport network slices not found") + + # Return all slices if no specific ID is given + return content + + except ValueError as e: + # Handle case where no slices are found + return self.__send_response(False, code=404, message=str(e)) + except Exception as e: + # Handle unexpected errors + return self.__send_response(False, code=500, message=str(e)) + + def modify_flow(self,slice_id, intent): + """ + Modify an existing transport network slice. + + Args: + slice_id (str): Unique identifier of the slice to modify + intent (dict): New intent configuration for the slice + + Returns: + Result of the Network Slice Controller (NSC) operation + + API Endpoint: + PUT /slice/{id} + """ + return self.nsc(intent, slice_id) + + def delete_flows(self, slice_id=None): + """ + Delete transport network slice(s). + + This method supports: + - Deleting a specific slice by ID + - Deleting all slices + - Optional cleanup of L2VPN configurations + + Args: + slice_id (str, optional): Unique identifier of slice to delete. + Defaults to None. + + Returns: + dict: Response indicating successful deletion or error details + + API Endpoint: + DELETE /slice/{id} + + Raises: + ValueError: If no slices are found to delete + Exception: For unexpected errors during deletion process + + Notes: + - If upload_to_tfs is True, attempts to delete from Teraflow + - If need_l2vpn_support is True, performs additional L2VPN cleanup + """ + try: + # Read current slice database + with open(os.path.join(SRC_PATH, "slice_ddbb.json"), 'r') as file: + content = json.load(file) + id = None + + # Delete specific slice if slice_id is provided + if slice_id: + for i, slice in enumerate(content): + if slice["slice_id"] == slice_id: + del content[i] + id = i + break + # Raise error if slice not found + if not id: + raise ValueError("Transport network slice not found") + # Update slice database + with open(os.path.join(SRC_PATH, "slice_ddbb.json"), 'w') as file: + json.dump(content, file, indent=4) + logging.info(f"Slice {slice_id} removed successfully") + return self.__send_response(False, code=200, status="success", message=f"Transpor network slice {slice_id} deleted successfully") + + # Delete all slices + else: + # Optional: Delete in Teraflow if configured + if self.upload_to_tfs == True: + # TODO: should send a delete request to Teraflow + if self.need_l2vpn_support: + self.__tfs_l2vpn_delete() + + # Verify slices exist before deletion + with open(os.path.join(SRC_PATH, "slice_ddbb.json"), 'r') as file: + if len(json.load(file)) == 0: + raise ValueError("Transport network slices not found") + + # Clear slice database + with open(os.path.join(SRC_PATH, "slice_ddbb.json"), 'w') as file: + json.dump([], file, indent=4) + + logging.info("All slices removed successfully") + return self.__send_response(False, code=200, status="success", message="All transport network slices deleted successfully.") + + except ValueError as e: + return self.__send_response(False, code=404, message=str(e)) + except Exception as e: + return self.__send_response(False, code=500, message=str(e)) + + # Main NSC Functionalities + def nsc(self, intent_json, slice_id=None): + """ + Main Network Slice Controller method to process and realize network slice intents. + + Workflow: + 1. Load IETF template + 2. Process intent (detect format, translate if needed) + 3. Extract slice data + 4. Store slice information + 5. Map slice to Network Resource Pool (NRP) + 6. Realize slice configuration + 7. Upload to Teraflow (optional) + + Args: + intent_json (dict): Network slice intent in 3GPP or IETF format + slice_id (str, optional): Existing slice identifier for modification + + Returns: + tuple: Response status and HTTP status code + + """ + try: + # Start performance tracking + self.start_time = time.perf_counter() + + # Reset requests and load IETF template + self.__load_template(1, os.path.join(TEMPLATES_PATH, "ietf_template_empty.json")) + tfs_requests = {"services":[]} + + # Process intent (translate if 3GPP) + ietf_intents = self.__nbi_processor(intent_json) + + if ietf_intents: + for intent in ietf_intents: + # Extract and store slice request details + self.__extract_data(intent) + self.__store_data(intent, slice_id) + # Mapper + self.__mapper(intent) + # Realizer + tfs_request = self.__realizer(intent) + tfs_requests["services"].append(tfs_request) + else: + return self.__send_response(False, code=404, message="No intents found") + + # Generated service + logging.debug(json.dumps(tfs_requests, indent=2)) + + # Optional: Upload template to Teraflow + if self.upload_to_tfs == True: + response = tfs_connector().simple_post(self.tfs_ip, tfs_requests) + + if not response.ok: + return self.__send_response(False, code=response.status_code, message=f"Teraflow upload failed. Response: {response.text}") + + # For deploying an L2VPN with path selection (not supported by Teraflow) + if self.need_l2vpn_support: + self.__tfs_l2vpn_support(tfs_requests["services"]) + + logging.info("Request sent to Teraflow") + + # End performance tracking + self.end_time = time.perf_counter() + return self.__send_response(True, code=200) + + except ValueError as e: + return self.__send_response(False, code=400, message=str(e)) + except Exception as e: + return self.__send_response(False, code=500, message=str(e)) + + def __nbi_processor(self, intent_json): + """ + Process and translate network slice intents from different formats (3GPP or IETF). + + This method detects the input JSON format and converts 3GPP intents to IETF format. + Supports multiple slice subnets in 3GPP format. + + Args: + intent_json (dict): Input network slice intent in either 3GPP or IETF format. + + Returns: + list: A list of IETF-formatted network slice intents. + + Raises: + ValueError: If the JSON request format is not recognized. + """ + # Detect the input JSON format (3GPP or IETF) + format = self.__detect_format(intent_json) + ietf_intents = [] + logging.info("--------NEW REQUEST--------") + + # TODO Needs to be generalized to support different names of slicesubnets + # Process different input formats + if format == "3GPP": + # Translate each subnet in 3GPP format to IETF format + for subnet in intent_json["RANSliceSubnet1"]["networkSliceSubnetRef"]: + ietf_intents.append(self.__translator(intent_json, subnet)) + logging.info(f"3GPP requests translated to IETF template") + elif format == "IETF": + # If already in IETF format, add directly + logging.info(f"IETF intent received") + ietf_intents.append(intent_json) + else: + # Handle unrecognized format + logging.error(f"JSON request format not recognized") + raise ValueError("JSON request format not recognized") + + return ietf_intents + + def __mapper(self, ietf_intent): + """ + Map an IETF network slice intent to the most suitable Network Resource Partition (NRP). + + This method: + 1. Retrieves the current NRP view + 2. Extracts Service Level Objectives (SLOs) from the intent + 3. Finds NRPs that can meet the SLO requirements + 4. Selects the best NRP based on viability and availability + 5. Attaches the slice to the selected NRP or creates a new one + + Args: + ietf_intent (dict): IETF-formatted network slice intent. + + Raises: + Exception: If no suitable NRP is found and slice creation fails. + """ + # Retrieve NRP view + self.__realizer(None, True, "READ") + + # Extract Service Level Objectives (SLOs) from the intent + slos = ietf_intent["ietf-network-slice-service:network-slice-services"]["slo-sle-templates"]["slo-sle-template"][0]["slo-policy"]["metric-bound"] + + # Find candidate NRPs that can meet the SLO requirements + candidates = [ + (nrp, self.__slo_viability(slos, nrp)[1]) + for nrp in self.__nrp_view + if self.__slo_viability(slos, nrp)[0] and nrp["available"] + ] + logging.debug(f"Candidates: {candidates}") + + # Select the best NRP based on candidates + best_nrp = max(candidates, key=lambda x: x[1])[0] if candidates else None + logging.debug(f"Best NRP: {best_nrp}") + + if best_nrp: + best_nrp["slices"].append(ietf_intent["ietf-network-slice-service:network-slice-services"]["slice-service"][0]["id"]) + # Update NRP view + self.__realizer(ietf_intent, True, "UPDATE") + # TODO Here we should put how the slice is attached to an already created nrp + else: + # Request the controller to create a new NRP that meets the SLOs + answer = self.__realizer(ietf_intent, True, "CREATE", best_nrp) + if not answer: + raise Exception("Slice rejected due to lack of NRPs") + # TODO Here we should put how the slice is attached to the new nrp + + def __realizer(self, ietf_intent, need_nrp=False, order=None, nrp=None): + """ + Manage the slice creation workflow. + + This method handles two primary scenarios: + 1. Interact with network controllers for NRP (Network Resource Partition) operations when need_nrp is True + 2. Slice service selection when need_nrp is False + + Args: + ietf_intent (dict): IETF-formatted network slice intent. + need_nrp (bool, optional): Flag to indicate if NRP operations are needed. Defaults to False. + order (str, optional): Type of NRP operation (READ, UPDATE, CREATE). Defaults to None. + nrp (dict, optional): Specific Network Resource Partition to operate on. Defaults to None. + """ + if need_nrp: + # Perform NRP-related operations + self.__nrp(order, nrp) + else: + # Select slice service method + return self.__select_way("L2VPN", ietf_intent) + + ### Generic functionalities + def __load_template(self, which, dir_t): + """ + Load and process JSON templates for different network slice formats. + + Args: + which (int): Template selector (0: 3GPP, 1: IETF, other: Teraflow) + dir_t (str): Directory path to the template file + """ + try: + # Open and read the template file + with open(dir_t, 'r') as source: + # Clean up the JSON template + template = source.read().replace('\t', '').replace('\n', '').replace("'", '"').strip() + + # Store template based on selector + if which == 0: + self.__gpp_template = template + elif which == 1: + self.__ietf_template = template + else: + self.__teraflow_template = template + + except Exception as e: + logging.error(f"Template loading error: {e}") + return self.__send_response(False, code=500, message=f"Template loading error: {e}") + + def __send_response(self, result, status="error", message=None, code=None): + """ + Generate and send a response to the 3GPP client about the slice request. + + Args: + result (bool): Indicates whether the slice request was successful + status (str, optional): Response status. Defaults to "error" + message (str, optional): Additional error message. Defaults to None + code (str, optional): Response code. Defaults to None + + Returns: + tuple: A tuple containing the response dictionary and status code + """ + if result: + # Successful slice creation + logging.info("Your slice request was fulfilled sucessfully") + self.setup_time = (self.end_time - self.start_time)*1000 + logging.info(f"Setup time: {self.setup_time:.2f}") + + # Construct detailed successful response + answer = { + "status": "success", + "code": code, + "slices": [], + "setup_time": self.setup_time + } + # Add slice details to the response + for subnet in self.answer: + slice_info = { + "id": subnet, + "source": self.answer[subnet]["Source"], + "destination": self.answer[subnet]["Destination"], + "vlan": self.answer[subnet]["VLAN"], + "bandwidth(Mbps)": self.answer[subnet]["QoS Requirements"][0], + "latency(ms)": self.answer[subnet]["QoS Requirements"][1] + } + answer["slices"].append(slice_info) + self.cool_answer = answer + else: + # Failed slice creation + logging.info("Your request cannot be fulfilled. Reason: "+message) + self.cool_answer = { + "status" :status, + "code": code, + "message": message + } + return self.cool_answer, code + + def __extract_data(self, intent_json): + """ + Extract source and destination IP addresses from the IETF intent. + + Args: + intent_json (dict): IETF-formatted network slice intent + """ + # Extract source and destination IP addresses + source = intent_json["ietf-network-slice-service:network-slice-services"]["slice-service"][0]["sdps"]["sdp"][0]["sdp-ip-address"] + destination = intent_json["ietf-network-slice-service:network-slice-services"]["slice-service"][0]["sdps"]["sdp"][1]["sdp-ip-address"] + + logging.info(f"Intent generated between {source} and {destination}") + + # Store slice and connection details + self.subnet = intent_json["ietf-network-slice-service:network-slice-services"]["slice-service"][0]["id"] + self.subnet = intent_json["ietf-network-slice-service:network-slice-services"]["slice-service"][0]["id"] + self.answer[self.subnet] = { + "Source": source, + "Destination": destination + } + + def __store_data(self, intent, slice_id): + """ + Store network slice intent information in a JSON database file. + + This method: + 1. Creates a JSON file if it doesn't exist + 2. Reads existing content + 3. Updates or adds new slice intent information + + Args: + intent (dict): Network slice intent to be stored + slice_id (str, optional): Existing slice ID to update. Defaults to None. + """ + file_path = os.path.join(SRC_PATH, "slice_ddbb.json") + # Create initial JSON file if it doesn't exist + if not os.path.exists(file_path): + with open(file_path, 'w') as file: + json.dump([], file, indent=4) + + # Read existing content + with open(file_path, 'r') as file: + content = json.load(file) + + # Update or add new slice intent + if slice_id: + # Update existing slice intent + for slice in content: + if slice["slice_id"] == slice_id: + slice["intent"] = intent + else: + # Add new slice intent + content.append( + { + "slice_id": intent["ietf-network-slice-service:network-slice-services"]["slice-service"][0]["id"], + "intent": intent + }) + + # # Write updated content back to file + with open(file_path, 'w') as file: + json.dump(content, file, indent=4) + + ### NBI processor functionalities + def __detect_format(self,json_data): + """ + Detect the format of the input network slice intent. + + This method identifies whether the input JSON is in 3GPP or IETF format + by checking for specific keys in the JSON structure. + + Args: + json_data (dict): Input network slice intent JSON + + Returns: + str or None: + - "IETF" if IETF-specific keys are found + - "3GPP" if 3GPP-specific keys are found + - None if no recognizable format is detected + """ + # Check for IETF-specific key + if "ietf-network-slice-service:network-slice-services" in json_data: + return "IETF" + # Check for 3GPP-specific keys + if any(key in json_data for key in ["NetworkSlice1", "TopSliceSubnet1", "CNSliceSubnet1", "RANSliceSubnet1"]): + return "3GPP" + + return None + + def __translator(self, gpp_intent, subnet): + """ + Translate a 3GPP network slice intent to IETF format. + + This method converts a 3GPP intent into a standardized IETF intent template, + mapping key parameters such as QoS profiles, service endpoints, and connection details. + + Args: + gpp_intent (dict): Original 3GPP network slice intent + subnet (str): Specific subnet reference within the 3GPP intent + + Returns: + dict: Translated IETF-formatted network slice intent + + Notes: + - Generates a unique slice service ID using UUID + - Maps QoS requirements, source/destination endpoints + - Logs the translated intent to a JSON file for reference + """ + # Load IETF template and create a copy to modify + ietf_i = json.loads(str(self.__ietf_template)) + + # Extract endpoint transport objects + ep_transport_objects = gpp_intent[subnet]["EpTransport"] + + # Populate template with SLOs (currently supporting QoS profile, latency and bandwidth) + ietf_i["ietf-network-slice-service:network-slice-services"]["slo-sle-templates"]["slo-sle-template"][0]["id"] = gpp_intent[ep_transport_objects[0]]["qosProfile"] + ietf_i["ietf-network-slice-service:network-slice-services"]["slo-sle-templates"]["slo-sle-template"][0]["slo-policy"]["metric-bound"][0]["bound"] = gpp_intent[subnet]["SliceProfileList"][0]["RANSliceSubnetProfile"]["uLThptPerSliceSubnet"]["MaxThpt"] + ietf_i["ietf-network-slice-service:network-slice-services"]["slo-sle-templates"]["slo-sle-template"][0]["slo-policy"]["metric-bound"][1]["bound"] = gpp_intent[subnet]["SliceProfileList"][0]["RANSliceSubnetProfile"]["uLLatency"] + + # Generate unique slice service ID and description + ietf_i["ietf-network-slice-service:network-slice-services"]["slice-service"][0]["id"] = f"slice-service-{uuid.uuid4()}" + ietf_i["ietf-network-slice-service:network-slice-services"]["slice-service"][0]["description"] = f"Transport network slice mapped with 3GPP slice {next(iter(gpp_intent))}" + ietf_i["ietf-network-slice-service:network-slice-services"]["slice-service"][0]["slo-sle-policy"]["slo-sle-template"] = ietf_i["ietf-network-slice-service:network-slice-services"]["slo-sle-templates"]["slo-sle-template"][0]["id"] + + # Configure Source SDP + ietf_i["ietf-network-slice-service:network-slice-services"]["slice-service"][0]["sdps"]["sdp"][0]["node-id"] = ep_transport_objects[0].split(" ", 1)[1] + ietf_i["ietf-network-slice-service:network-slice-services"]["slice-service"][0]["sdps"]["sdp"][0]["sdp-ip-address"] = gpp_intent[gpp_intent[ep_transport_objects[0]]["EpApplicationRef"][0]]["remoteAddress"] + ietf_i["ietf-network-slice-service:network-slice-services"]["slice-service"][0]["sdps"]["sdp"][0]["service-match-criteria"]["match-criterion"][0]["match-type"] = gpp_intent[ep_transport_objects[0]]["logicalInterfaceInfo"]["logicalInterfaceType"] + ietf_i["ietf-network-slice-service:network-slice-services"]["slice-service"][0]["sdps"]["sdp"][0]["service-match-criteria"]["match-criterion"][0]["value"] = gpp_intent[ep_transport_objects[0]]["logicalInterfaceInfo"]["logicalInterfaceId"] + ietf_i["ietf-network-slice-service:network-slice-services"]["slice-service"][0]["sdps"]["sdp"][0]["attachment-circuits"]["attachment-circuit"][0]["ac-ipv4-address"] = gpp_intent[ep_transport_objects[1]]["IpAddress"] + ietf_i["ietf-network-slice-service:network-slice-services"]["slice-service"][0]["sdps"]["sdp"][0]["attachment-circuits"]["attachment-circuit"][0]["sdp-peering"]["peer-sap-id"] = gpp_intent[ep_transport_objects[1]]["NextHopInfo"] + + # Configure Destination SDP + ietf_i["ietf-network-slice-service:network-slice-services"]["slice-service"][0]["sdps"]["sdp"][1]["node-id"] = ep_transport_objects[1].split(" ", 1)[1] + ietf_i["ietf-network-slice-service:network-slice-services"]["slice-service"][0]["sdps"]["sdp"][1]["sdp-ip-address"] = gpp_intent[gpp_intent[ep_transport_objects[1]]["EpApplicationRef"][0]]["remoteAddress"] + ietf_i["ietf-network-slice-service:network-slice-services"]["slice-service"][0]["sdps"]["sdp"][1]["service-match-criteria"]["match-criterion"][0]["match-type"] = gpp_intent[ep_transport_objects[1]]["logicalInterfaceInfo"]["logicalInterfaceType"] + ietf_i["ietf-network-slice-service:network-slice-services"]["slice-service"][0]["sdps"]["sdp"][1]["service-match-criteria"]["match-criterion"][0]["value"] = gpp_intent[ep_transport_objects[1]]["logicalInterfaceInfo"]["logicalInterfaceId"] + ietf_i["ietf-network-slice-service:network-slice-services"]["slice-service"][0]["sdps"]["sdp"][1]["attachment-circuits"]["attachment-circuit"][0]["ac-ipv4-address"] = gpp_intent[ep_transport_objects[0]]["IpAddress"] + ietf_i["ietf-network-slice-service:network-slice-services"]["slice-service"][0]["sdps"]["sdp"][1]["attachment-circuits"]["attachment-circuit"][0]["sdp-peering"]["peer-sap-id"] = gpp_intent[ep_transport_objects[0]]["NextHopInfo"] + + # Configure Connection Group and match-criteria + ietf_i["ietf-network-slice-service:network-slice-services"]["slice-service"][0]["connection-groups"]["connection-group"][0]["id"] = f"{ep_transport_objects[0].split(' ', 1)[1]}_{ep_transport_objects[1].split(' ', 1)[1]}" + ietf_i["ietf-network-slice-service:network-slice-services"]["slice-service"][0]["sdps"]["sdp"][0]["service-match-criteria"]["match-criterion"][0]["target-connection-group-id"] = f"{ep_transport_objects[0].split(' ', 1)[1]}_{ep_transport_objects[1].split(' ', 1)[1]}" + ietf_i["ietf-network-slice-service:network-slice-services"]["slice-service"][0]["sdps"]["sdp"][1]["service-match-criteria"]["match-criterion"][0]["target-connection-group-id"] = f"{ep_transport_objects[0].split(' ', 1)[1]}_{ep_transport_objects[1].split(' ', 1)[1]}" + + # Log translated intent for debugging + logging.debug(json.dumps(ietf_i,indent=2)) + with open(os.path.join(TEMPLATES_PATH, "ietf_template_example.json"), "w") as archivo: + archivo.write(json.dumps(ietf_i,indent=2)) + return ietf_i + + ### Mapper functionalities + def __slo_viability(self, slice_slos, nrp_slos): + """ + Compare Service Level Objectives (SLOs) between a slice and a Network Resource Partition (NRP). + + This method assesses whether an NRP can satisfy the SLOs of a network slice. + + Args: + slice_slos (list): Service Level Objectives of the slice + nrp_slos (dict): Service Level Objectives of the Network Resource Pool + + Returns: + tuple: A boolean indicating viability and a flexibility score + - First value: True if NRP meets SLOs, False otherwise + - Second value: A score representing how well the NRP meets the SLOs + """ + # Define SLO types for maximum and minimum constraints + slo_type = { + "max": ["one-way-delay-maximum", "two-way-delay-maximum", "one-way-delay-percentile", "two-way-delay-percentile", + "one-way-delay-variation-maximum", "two-way-delay-variation-maximum", + "one-way-delay-variation-percentile", "two-way-delay-variation-percentile", + "one-way-packet-loss", "two-way-packet-loss"], + "min": ["one-way-bandwidth", "two-way-bandwidth", "shared-bandwidth"] + } + flexibility_scores = [] + for slo in slice_slos: + for nrp_slo in nrp_slos['slos']: + if slo["metric-type"] == nrp_slo["metric-type"]: + # Handle maximum type SLOs + if slo["metric-type"] in slo_type["max"]: + flexibility = (nrp_slo["bound"] - slo["bound"]) / slo["bound"] + if slo["bound"] > nrp_slo["bound"]: + return False, 0 # Does not meet maximum constraint + # Handle minimum type SLOs + if slo["metric-type"] in slo_type["min"]: + flexibility = (slo["bound"] - nrp_slo["bound"]) / slo["bound"] + if slo["bound"] < nrp_slo["bound"]: + return False, 0 # Does not meet minimum constraint + flexibility_scores.append(flexibility) + break # Exit inner loop after finding matching metric + + # Calculate final viability score + score = sum(flexibility_scores) / len(flexibility_scores) if flexibility_scores else 0 + return True, score # Si pasó todas las verificaciones, la NRP es viable + + def __planner(self, intent, nrp_view): + """ + TODO + Request slice viability from the Planner module. + + This method prepares and sends a viability request for network slice creation, + detaching the implementation from the main core thread. + + Args: + intent (dict): Network slice intent + nrp_view (list): Current Network Resource Pool view + + Returns: + tuple: A tuple containing: + - Viability status (str): "Good" or other status + - Reason (str): Explanation of viability + + Notes: + - Calculates source and destination service delivery points (SDP) + - Extracts QoS requirements + - Performs viability check through internal methods + """ + + #Version 1 + matriz = {} + matriz["payloads"] = [] + #for i in intent: + # SI ya existe, suma, si no existe, lo crea + origen = self.__calculate_sdp(intent["ietf-network-slice-service:network-slice-services"]["slice-service"][0]["sdps"]["sdp"][0]["sdp-ip-address"]) + destino = self.__calculate_sdp(intent["ietf-network-slice-service:network-slice-services"]["slice-service"][0]["sdps"]["sdp"][1]["sdp-ip-address"]) + #qos_req = i["ietf-network-slice-service:network-slice-services"]["slice-service"][0]["slo-sle-policy"]["slo-sle-template"] + qos_req = intent["ietf-network-slice-service:network-slice-services"]["slo-sle-templates"]["slo-sle-template"][0]["slo-policy"]["metric-bound"][0]["bound"] + payload = { + "Source": origen, + "Destination": destino, + "QoS requirements": qos_req + } + matriz["payloads"].append(payload) + m_res = [] + m_qos = [] + for p in matriz["payloads"]: + res = p + m_res.append(res) + m_qos.append(p["QoS requirements"]) + m_res, m_qos = self.__viability(m_res,intent, m_qos) + reason="Viable" + viability = "Good" + return viability, reason + + def __viability(self, matrix, intent, qos): + """ + TODO + """ + aux = {} + aux["good"] = [] + aux["bad"] = [] + l_qos = [] + for i in range(len(intent)): + # if matrix[i]['success'] == True: + aux["good"].append(matrix[i]) + l_qos.append(qos[i]) + # else: + # aux["bad"].append(intent[i]) + return aux, l_qos + + def __calculate_sdp(self, pip): + ''' + TODO + Imput: + Output: + Work: Identifies the network entpoint from the IP-sdp received. + Version 0 will be done directly with next hop. + Version 1 will translate directly from the public IP of each node to their Loopback address. + ''' + nid = 0 + with open(os.path.join(TEMPLATES_PATH, "ips.json"), 'r') as source: + jason = source.read() + jason = jason.replace('\t', '').replace('\n', '').replace("'", '"').strip() + nodos = json.loads(str(jason)) + #template = json.loads(str(jason)) + # Once we have the template, we search for the one charged. + for nodo in nodos["public-prefixes"]: + if pip == nodo["prefix"]: + #nid = nodo["node-id"] + nid = nodo["node-name"] + for nodo in nodos["CU"]: + if pip == nodo["prefix"]: + #nid = nodo["node-id"] + nid = nodo["node-name"] + for nodo in nodos["DU"]: + if pip == nodo["prefix"]: + #nid = nodo["node-id"] + nid = nodo["node-name"] + return nid + + + ### Realizer functionalities. + def __nrp(self, request, nrp): + """ + Manage Network Resource Partition (NRP) operations. + + This method handles CRUD operations for Network Resource Partitions, + interacting with Network Controllers (currently done statically via a JSON-based database file). + + Args: + request (str): The type of operation to perform. + Supported values: + - "CREATE": Add a new NRP to the database + - "READ": Retrieve the current NRP view + - "UPDATE": Update an existing NRP (currently a placeholder) + + nrp (dict): The Network Resource Partition details to create or update. + + Returns: + None or answer: + - For "CREATE": Returns the response from the controller (currently using a static JSON) + - For "READ": Gets the NRP view from the controller (currently using a static JSON) + - For "UPDATE": Placeholder for update functionality + + Notes: + - Uses a local JSON file "nrp_ddbb.json" to store NRP information as controller operation is not yet defined + """ + if request == "CREATE": + # TODO: Implement actual request to Controller to create an NRP + logging.debug("Creating NRP") + + # Load existing NRP database + with open(os.path.join(SRC_PATH, "nrp_ddbb.json"), "r") as archivo: + self.__nrp_view = json.load(archivo) + + # Append new NRP to the view + self.__nrp_view.append(nrp) + + # Placeholder for controller POST request + answer = None + return answer + elif request == "READ": + # TODO: Request to Controller to get topology and current NRP view + logging.debug("Reading Topology") + + # Load NRP database + with open(os.path.join(SRC_PATH, "nrp_ddbb.json"), "r") as archivo: + self.__nrp_view = json.load(archivo) + + elif request == "UPDATE": + # TODO: Implement request to Controller to update NRP + logging.debug("Updating NRP") + answer = "" + + def __select_way(self,way, ietf_intent): + """ + Determine the method of slice realization. + + Args: + way (str): The type of technology to use. + Supported values: + - "L2VPN": Layer 2 Virtual Private Network + - "L3VPN": Layer 3 Virtual Private Network + + ietf_intent (dict): IETF-formatted network slice intent. + + Returns: + dict: A realization request for the specified network slice type. + + """ + if way == "L2VPN": + realizing_request = self.__tfs_l2vpn(ietf_intent) + elif way == "L3VPN": + realizing_request = self.__tfs_l3vpn(ietf_intent) + return realizing_request + + def __tfs_l2vpn(self, ietf_intent): + """ + Translate slice intent into a TeraFlow service request. + + This method prepares a L2VPN service request by: + 1. Defining endpoint routers + 2. Loading a service template + 3. Generating a unique service UUID + 4. Configuring service endpoints + 5. Adding QoS constraints + 6. Preparing configuration rules for network interfaces + + Args: + ietf_intent (dict): IETF-formatted network slice intent. + + Returns: + dict: A TeraFlow service request for L2VPN configuration. + + """ + # Hardcoded router endpoints + # TODO (should be dynamically determined) + origin_router_id = '4.4.4.4' + origin_router_if = '0/0/0-GigabitEthernet0/0/0/0' + destination_router_id = '5.5.5.5' + destination_router_if = '0/0/3-GigabitEthernet0/0/0/3' + + # Extract QoS Profile from intent + QoSProfile = ietf_intent["ietf-network-slice-service:network-slice-services"]["slo-sle-templates"]["slo-sle-template"][0]["id"] + + vlan_value = 0 + + # Load L2VPN service template + self.__load_template(2, os.path.join(TEMPLATES_PATH, "L2-VPN_template_empty.json")) + tfs_request = json.loads(str(self.__teraflow_template))["services"][0] + + # Generate unique service UUID + tfs_request["service_id"]["service_uuid"]["uuid"] += "-" + str(int(datetime.now().timestamp() * 1e7)) + + # Configure service endpoints + for endpoint in tfs_request["service_endpoint_ids"]: + endpoint["device_id"]["device_uuid"]["uuid"] = origin_router_id if endpoint is tfs_request["service_endpoint_ids"][0] else destination_router_id + endpoint["endpoint_uuid"]["uuid"] = origin_router_if if endpoint is tfs_request["service_endpoint_ids"][0] else destination_router_if + + self.answer[self.subnet]["QoS Requirements"] = [] + # Add service constraints + for i, constraint in enumerate(tfs_request["service_constraints"]): + bound = ietf_intent["ietf-network-slice-service:network-slice-services"]["slo-sle-templates"]["slo-sle-template"][0]["slo-policy"]["metric-bound"][i]["bound"] + self.answer[self.subnet]["QoS Requirements"].append(bound) + constraint["custom"]["constraint_value"] = str(bound) + + # Add configuration rules + for i, config_rule in enumerate(tfs_request["service_config"]["config_rules"][1:], start=1): + router_id = origin_router_id if i == 1 else destination_router_id + router_if = origin_router_if if i == 1 else destination_router_if + resource_value = config_rule["custom"]["resource_value"] + + sdp_index = i - 1 + vlan_value = ietf_intent["ietf-network-slice-service:network-slice-services"]["slice-service"][0]["sdps"]["sdp"][sdp_index]["service-match-criteria"]["match-criterion"][0]["value"] + resource_value["vlan_id"] = int(vlan_value) + resource_value["circuit_id"] = vlan_value + resource_value["remote_router"] = destination_router_id if i == 1 else origin_router_id + resource_value["ni_name"] = 'ELAN{:s}'.format(str(vlan_value)) + config_rule["custom"]["resource_key"] = f"/device[{router_id}]/endpoint[{router_if}]/settings" + + # Log and store VLAN information + logging.info(f"Intent with VLAN {vlan_value} realized\n") + self.answer[self.subnet]["VLAN"] = vlan_value + return tfs_request + + def __tfs_l2vpn_support(self, requests): + """ + Configuration support for L2VPN with path selection based on MPLS traffic-engineering tunnels + + Args: + requests (list): A list of configuration parameters. + + """ + sources={ + "source": "10.60.125.44", + "config":[] + } + destinations={ + "destination": "10.60.125.45", + "config":[] + } + for request in requests: + # Configure Source Endpoint + temp_source = request["service_config"]["config_rules"][1]["custom"]["resource_value"] + endpoints = request["service_endpoint_ids"] + config = { + "ni_name": temp_source["ni_name"], + "remote_router": temp_source["remote_router"], + "interface": endpoints[0]["endpoint_uuid"]["uuid"].replace("0/0/0-", ""), + "vlan" : temp_source["vlan_id"], + "number" : temp_source["vlan_id"] % 10 + 1 + } + sources["config"].append(config) + + # Configure Destination Endpoint + temp_destiny = request["service_config"]["config_rules"][2]["custom"]["resource_value"] + config = { + "ni_name": temp_destiny["ni_name"], + "remote_router": temp_destiny["remote_router"], + "interface": endpoints[1]["endpoint_uuid"]["uuid"].replace("0/0/3-", ""), + "vlan" : temp_destiny["vlan_id"], + "number" : temp_destiny["vlan_id"] % 10 + 1 + } + destinations["config"].append(config) + + #cisco_source = cisco_connector(source_address, ni_name, remote_router, vlan, vlan % 10 + 1) + cisco_source = cisco_connector(sources["source"], sources["config"]) + commands = cisco_source.full_create_command_template() + cisco_source.execute_commands(commands) + + #cisco_destiny = cisco_connector(destination_address, ni_name, remote_router, vlan, vlan % 10 + 1) + cisco_destiny = cisco_connector(destinations["destination"], destinations["config"]) + commands = cisco_destiny.full_create_command_template() + cisco_destiny.execute_commands(commands) + + def __tfs_l2vpn_delete(self): + """ + Delete L2VPN configurations from Cisco devices. + + This method removes L2VPN configurations from Cisco routers + + Notes: + - Uses cisco_connector to generate and execute deletion commands + - Clears Network Interface (NI) settings + """ + # Delete Source Endpoint Configuration + source_address = "10.60.125.44" + cisco_source = cisco_connector(source_address) + cisco_source.execute_commands(cisco_source.create_command_template_delete()) + + # Delete Destination Endpoint Configuration + destination_address = "10.60.125.45" + cisco_destiny = cisco_connector(destination_address) + cisco_destiny.execute_commands(cisco_destiny.create_command_template_delete()) + + def __tfs_l3vpn(self, ietf_intent): + """ + Translate L3VPN (Layer 3 Virtual Private Network) intent into a TeraFlow service request. + + Similar to __tfs_l2vpn, but configured for Layer 3 VPN: + 1. Defines endpoint routers + 2. Loads service template + 3. Generates unique service UUID + 4. Configures service endpoints + 5. Adds QoS constraints + 6. Prepares configuration rules for network interfaces + + Args: + ietf_intent (dict): IETF-formatted network slice intent. + + Returns: + dict: A TeraFlow service request for L3VPN configuration. + """ + # Hardcoded router endpoints + # TODO should be dynamically determined + origin_router_id = '4.4.4.4' + origin_router_if = '0/0/0-GigabitEthernet0/0/0/0' + destination_router_id = '5.5.5.5' + destination_router_if = '0/0/3-GigabitEthernet0/0/0/3' + + # Load L3VPN service template + self.__load_template(2, os.path.join(TEMPLATES_PATH, "L3-VPN_template_empty.json")) + tfs_request = json.loads(str(self.__teraflow_template))["services"][0] + + # Generate unique service UUID + tfs_request["service_id"]["service_uuid"]["uuid"] += "-" + str(int(datetime.now().timestamp() * 1e7)) + + # Configure service endpoints + for endpoint in tfs_request["service_endpoint_ids"]: + endpoint["device_id"]["device_uuid"]["uuid"] = origin_router_id if endpoint is tfs_request["service_endpoint_ids"][0] else destination_router_id + endpoint["endpoint_uuid"]["uuid"] = origin_router_if if endpoint is tfs_request["service_endpoint_ids"][0] else destination_router_if + + # Add service constraints + for i, constraint in enumerate(tfs_request["service_constraints"]): + bound = ietf_intent["ietf-network-slice-service:network-slice-services"]["slo-sle-templates"]["slo-sle-template"][0]["slo-policy"]["metric-bound"][i]["bound"] + constraint["custom"]["constraint_value"] = str(bound) + + # Add configuration rules + for i, config_rule in enumerate(tfs_request["service_config"]["config_rules"][1:], start=1): + router_id = origin_router_id if i == 1 else destination_router_id + router_if = origin_router_if if i == 1 else destination_router_if + resource_value = config_rule["custom"]["resource_value"] + + sdp_index = i - 1 + vlan_value = ietf_intent["ietf-network-slice-service:network-slice-services"]["slice-service"][0]["sdps"]["sdp"][sdp_index]["service-match-criteria"]["match-criterion"][0]["value"] + resource_value["router_id"] = destination_router_id if i == 1 else origin_router_id + resource_value["vlan_id"] = int(vlan_value) + resource_value["address_ip"] = destination_router_id if i == 1 else origin_router_id + resource_value["policy_AZ"] = "policyA" + resource_value["policy_ZA"] = "policyB" + resource_value["ni_name"] = 'ELAN{:s}'.format(str(vlan_value)) + config_rule["custom"]["resource_key"] = f"/device[{router_id}]/endpoint[{router_if}]/settings" + + return tfs_request + + + + + + + diff --git a/src/nrp_ddbb.json b/src/nrp_ddbb.json new file mode 100644 index 0000000..948967e --- /dev/null +++ b/src/nrp_ddbb.json @@ -0,0 +1,38 @@ +[ + { + "nrp-id": "nrp_X", + "resources": ["link1", "link2", "node1"], + "slos": [ + { + "metric-type": "one-way-bandwidth", + "metric-unit": "kbps", + "bound": 1 + }, + { + "metric-type": "one-way-delay-maximum", + "metric-unit": "milliseconds", + "bound": 800 + } + ], + "slices": ["slice-service-02873501-bf0a-4b02-8540-2f9d970ea20f", "slice-service-e3b22fa8-f3da-4da8-881b-c66e5161b4a5"], + "available": true + }, + { + "nrp-id": "nrp_X2", + "resources": ["link1", "link2", "node1"], + "slos": [ + { + "metric-type": "one-way-bandwidth", + "metric-unit": "kbps", + "bound": 1 + }, + { + "metric-type": "one-way-delay-maximum", + "metric-unit": "milliseconds", + "bound": 800 + } + ], + "slices": ["slice-service-02873501-bf0a-4b02-8540-2f9d970ea20f", "slice-service-e3b22fa8-f3da-4da8-881b-c66e5161b4a5"], + "available": true + } +] \ No newline at end of file diff --git a/src/old/intent_generator.py b/src/old/intent_generator.py new file mode 100644 index 0000000..05eae79 --- /dev/null +++ b/src/old/intent_generator.py @@ -0,0 +1,136 @@ +#!/usr/bin/env python3 +import json +import os +#import requests +import socket +import random + +# Obtain the current directory +current_dir = os.path.dirname(os.path.abspath(__file__)) + +# Create the path to the templates directory +parent_dir = os.path.dirname(current_dir) +file_path = os.path.join(parent_dir, "templates") + +class IntentCreator: + + def __init__(self, plt, lnodes): + self.plantilla = '' + with open(plt, 'r') as source: + self.plantilla = source.read() + self.nodes = '' + with open(lnodes, 'r') as source: + self.nodes = source.read() + self.nodes = json.loads(str(self.nodes)) + + + def __create_ep(self,node_name, node_ip, vlan_id): + ep_tansport_key = f"EpTransport {node_name}" + ep_transport = { + ep_tansport_key:{ + "IpAddress":str(node_ip.rsplit('.', 1)[0] + '.1'), + "logicalInterfaceInfo":{ + "logicalInterfaceType":"VLAN", + "logicalInterfaceId":vlan_id + }, + "NextHopInfo": str(node_ip.rsplit('.', 1)[0] + '.254'), + "qosProfile":"A", + "EpApplicationRef":[f"EP_F1U {node_name}"] + } + } + + ep_rp_key = f"EP_F1U {node_name}" + ep_rp = { + ep_rp_key:{ + "localAddress":node_ip, + "remoteAddress":"", + "epTransportRef":[ep_tansport_key] + } + } + return ep_transport,ep_rp + + def create_intent(self): + ''' + In this function we are going to create intents randomly and return them as a json. + Parameters to modify: + - Origin IP, Destination IP, Interfaces, Match type + - SDP id and Node id + - Required value + ''' + + request = json.loads(str(self.plantilla)) + + # Subnet list in the slicing environment + subnets = [["TopSliceSubnet1","TopSliceSubnetProfile"],["CNSliceSubnet1","CNSliceSubnetProfile"], ["RANSliceSubnet1","RANSliceSubnetProfile"], ["MidhaulSliceSubnet1","RANSliceSubnetProfile"], ["BackhaulSliceSubnet1","RANSliceSubnetProfile"]] + + # Possible values for throughput and latency + throughput = [100, 200, 500, 1000] + latency = [5, 10, 15, 20] + + # Assign random values to the QoS parameters + top_slice_qos = [random.choice(throughput), 0, random.choice(latency)] + top_slice_qos[1] = int(2*top_slice_qos[0]) + cn_slice_qos = [int(val) for val in [top_slice_qos[0]/2,top_slice_qos[1]/2, top_slice_qos[2]*0.4]] + ran_slice_qos = [int(val) for val in [top_slice_qos[0]/2,top_slice_qos[1]/2, top_slice_qos[2]*0.6]] + midhaul_slice_qos = [int(val) for val in [ran_slice_qos[0]*0.6,ran_slice_qos[1]*0.6, ran_slice_qos[2]/3]] + backhaul_slice_qos = [int(val) for val in [ran_slice_qos[0]*0.4,ran_slice_qos[1]*0.4, ran_slice_qos[2]*2/3]] + + qos = [top_slice_qos, cn_slice_qos, ran_slice_qos, midhaul_slice_qos, backhaul_slice_qos] + + for index, subnet in enumerate(subnets): + request[subnet[0]]["SliceProfileList"][0][subnet[1]]["dLThptPerSliceSubnet"]["GuaThpt"] = qos[index][0] + request[subnet[0]]["SliceProfileList"][0][subnet[1]]["dLThptPerSliceSubnet"]["MaxThpt"] = qos[index][1] + request[subnet[0]]["SliceProfileList"][0][subnet[1]]["uLThptPerSliceSubnet"]["GuaThpt"] = qos[index][0] + request[subnet[0]]["SliceProfileList"][0][subnet[1]]["uLThptPerSliceSubnet"]["MaxThpt"] = qos[index][1] + request[subnet[0]]["SliceProfileList"][0][subnet[1]]["dLLatency"] = qos[index][2] + request[subnet[0]]["SliceProfileList"][0][subnet[1]]["uLLatency"] = qos[index][2] + + #dus = self.nodes["public-prefixes"] + #cus = self.nodes["public-prefixes"] + dus = self.nodes["DU"] + cus = self.nodes["CU"] + + if random.randint(0, 1) == 0: + src = random.choice(dus) + dst = random.choice(cus) + else: + src = random.choice(cus) + dst = random.choice(dus) + + # Delete all the EpTransport objects from the request + pop_keys = [] + + for key in request: + # Verify if the key is an EpTransport object + if key.startswith("EpTransport") or key.startswith("EP_F1U"): + # Aggregate the key to the list of keys to be removed + pop_keys.append(key) + + for key in pop_keys: + request.pop(key) + + # Randomly select a VLAN ID + l_iid = ["100","200","300", "400"] + vlan_id = random.choice(l_iid) + + # Create the EPs for the source and destination nodes + ep_transport_src, ep_rp_src = self.__create_ep(src["node-name"], src["prefix"], vlan_id) + request.update(ep_transport_src) + request.update(ep_rp_src) + ep_transport_dst, ep_rp_dst = self.__create_ep(dst["node-name"], dst["prefix"], vlan_id) + request.update(ep_transport_dst) + request.update(ep_rp_dst) + + ep_transport_src_name = list(ep_transport_src.keys())[0] + ep_transport_dst_name = list(ep_transport_dst.keys())[0] + + request["MidhaulSliceSubnet1"]["EpTransport"] = [ep_transport_src_name, ep_transport_dst_name] + + request[ep_transport_src[ep_transport_src_name]["EpApplicationRef"][0]]["remoteAddress"] = request[ep_transport_dst[ep_transport_dst_name]["EpApplicationRef"][0]]["localAddress"] + request[ep_transport_dst[ep_transport_dst_name]["EpApplicationRef"][0]]["remoteAddress"] = request[ep_transport_src[ep_transport_src_name]["EpApplicationRef"][0]]["localAddress"] + + return (str(request).replace('\t', '').replace('\n', '').replace("'", '"').replace("None", '"None"')) + +if __name__ == '__main__': + creador = IntentCreator(os.path.join(file_path, "3gpp_template_empty.json"), os.path.join(file_path, "ips.json")) + print(creador.create_intent()) diff --git a/src/old/send_request.py b/src/old/send_request.py new file mode 100644 index 0000000..dc55d57 --- /dev/null +++ b/src/old/send_request.py @@ -0,0 +1,28 @@ +import sys, os +import requests +import time +import json +from intent_generator import IntentCreator + +# Obtain the current directory +current_dir = os.path.dirname(os.path.abspath(__file__)) + +# Create the path to the templates directory +parent_dir = os.path.dirname(current_dir) +file_path = os.path.join(parent_dir, "templates") + +def send_request(port): + if len(sys.argv) == 2: + resp = IntentCreator(os.path.join(file_path, "3gpp_template_empty.json"), os.path.join(file_path, "ips.json")).create_intent() + requests.post(f'http://localhost:{port}/intent', headers={'Content-Type': 'application/json'}, data=resp) + else: + intent = sys.argv[2] + with open(intent, 'r') as source: + resp = source.read() + resp = str(resp).replace('\t', '').replace('\n', '').replace("'", '"').replace("None", '"None"') + requests.post(f'http://localhost:{port}/intent', headers={'Content-Type': 'application/json'}, data=resp) + +while True: + # Use: python3 send_request.py <port> <intent_file> + send_request(sys.argv[1]) + time.sleep(3) diff --git a/src/slice_ddbb.json b/src/slice_ddbb.json new file mode 100644 index 0000000..0637a08 --- /dev/null +++ b/src/slice_ddbb.json @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/src/templates/3gpp_template_empty.json b/src/templates/3gpp_template_empty.json new file mode 100644 index 0000000..a0c6225 --- /dev/null +++ b/src/templates/3gpp_template_empty.json @@ -0,0 +1,176 @@ +{ + "NetworkSlice1":{ + "operationalState":"", + "administrativeState":"", + "serviceProfileList":[], + "networkSliceSubnetRef":"TopSliceSubnet1" + }, + "TopSliceSubnet1":{ + "operationalState":"", + "administrativeState":"", + "nsInfo":{}, + "managedFunctionRef":[], + "networkSliceSubnetType":"TOP_SLICESUBNET", + "SliceProfileList":[ + { + "sliceProfileId":"TopId", + "pLMNInfoList":null, + "TopSliceSubnetProfile":{ + "dLThptPerSliceSubnet":{ + "GuaThpt":0, + "MaxThpt":0 + }, + "uLThptPerSliceSubnet":{ + "GuaThpt":0, + "MaxThpt":0 + }, + "dLLatency":0, + "uLLatency":0 + } + } + ], + "networkSliceSubnetRef":["CNSliceSubnet1","RANSliceSubnet1"] + }, + "CNSliceSubnet1":{ + "operationalState":"", + "administrativeState":"", + "nsInfo":{}, + "managedFunctionRef":[], + "networkSliceSubnetType":"CN_SLICESUBNET", + "SliceProfileList":[ + { + "sliceProfileId":"CNId", + "pLMNInfoList":null, + "CNSliceSubnetProfile":{ + "dLThptPerSliceSubnet":{ + "GuaThpt":0, + "MaxThpt":0 + }, + "uLThptPerSliceSubnet":{ + "GuaThpt":0, + "MaxThpt":0 + }, + "dLLatency":0, + "uLLatency":0 + } + } + ] + }, + "RANSliceSubnet1":{ + "operationalState":"", + "administrativeState":"", + "nsInfo":{}, + "managedFunctionRef":[], + "networkSliceSubnetType":"RAN_SLICESUBNET", + "SliceProfileList":[ + { + "sliceProfileId":"RANId", + "pLMNInfoList":null, + "RANSliceSubnetProfile":{ + "dLThptPerSliceSubnet":{ + "GuaThpt":0, + "MaxThpt":0 + }, + "uLThptPerSliceSubnet":{ + "GuaThpt":0, + "MaxThpt":0 + }, + "dLLatency":0, + "uLLatency":0 + } + } + ], + "networkSliceSubnetRef":["MidhaulSliceSubnet1", "BackhaulSliceSubnet1"] + }, + "MidhaulSliceSubnet1":{ + "operationalState":"", + "administrativeState":"", + "nsInfo":{}, + "managedFunctionRef":[], + "networkSliceSubnetType":"RAN_SLICESUBNET", + "SliceProfileList":[ + { + "sliceProfileId":"MidhaulId", + "pLMNInfoList":null, + "RANSliceSubnetProfile":{ + "dLThptPerSliceSubnet":{ + "GuaThpt":0, + "MaxThpt":0 + }, + "uLThptPerSliceSubnet":{ + "GuaThpt":0, + "MaxThpt":0 + }, + "dLLatency":0, + "uLLatency":0 + } + } + ], + "EpTransport":["EpTransport DU1","EpTransport CU-UP1"] + }, + "BackhaulSliceSubnet1":{ + "operationalState":"", + "administrativeState":"", + "nsInfo":{}, + "managedFunctionRef":[], + "networkSliceSubnetType":"RAN_SLICESUBNET", + "SliceProfileList":[ + { + "sliceProfileId":"BackhaulId", + "pLMNInfoList":null, + "RANSliceSubnetProfile":{ + "dLThptPerSliceSubnet":{ + "GuaThpt":0, + "MaxThpt":0 + }, + "uLThptPerSliceSubnet":{ + "GuaThpt":0, + "MaxThpt":0 + }, + "dLLatency":0, + "uLLatency":0 + } + } + ], + "EpTransport":["EpTransport CU-UP2","EpTransport UPF"] + }, + "EpTransport DU1": + { + "IpAddress":"", + "logicalInterfaceInfo":{ + "logicalInterfaceType":"", + "logicalInterfaceId":"" + }, + "NextHopInfo": "", + "qosProfile":"", + "EpApplicationRef":["EP_F1U DU1"] + }, + "EpTransport CU-UP1": + { + "IpAddress":"", + "logicalInterfaceInfo":{ + "logicalInterfaceType":"", + "logicalInterfaceId":"" + }, + "NextHopInfo": "", + "QosProfile":"", + "EpApplicationRef":["EP_F1U CU-UP1"] + }, + "EP_F1U DU1":[ + { + "localAddress":"", + "remoteAddress":"", + "epTransportRef":["EpTransport DU1"] + } + ], + "EP_F1U CU-UP1":[ + { + "localAddress":"", + "remoteAddress":"", + "epTransportRef":["EpTransport CU-UP1"] + } + ] +} + + + diff --git a/src/templates/3gpp_template_example.json b/src/templates/3gpp_template_example.json new file mode 100644 index 0000000..28471a8 --- /dev/null +++ b/src/templates/3gpp_template_example.json @@ -0,0 +1,187 @@ +{ + "NetworkSlice1": { + "operationalState": "", + "administrativeState": "", + "serviceProfileList": [], + "networkSliceSubnetRef": "TopSliceSubnet1" + }, + "TopSliceSubnet1": { + "operationalState": "", + "administrativeState": "", + "nsInfo": {}, + "managedFunctionRef": [], + "networkSliceSubnetType": "TOP_SLICESUBNET", + "SliceProfileList": [ + { + "sliceProfileId": "TopId", + "pLMNInfoList": null, + "TopSliceSubnetProfile": { + "dLThptPerSliceSubnet": { + "GuaThpt": 200, + "MaxThpt": 400 + }, + "uLThptPerSliceSubnet": { + "GuaThpt": 200, + "MaxThpt": 400 + }, + "dLLatency": 20, + "uLLatency": 20 + } + } + ], + "networkSliceSubnetRef": [ + "CNSliceSubnet1", + "RANSliceSubnet1" + ] + }, + "CNSliceSubnet1": { + "operationalState": "", + "administrativeState": "", + "nsInfo": {}, + "managedFunctionRef": [], + "networkSliceSubnetType": "CN_SLICESUBNET", + "SliceProfileList": [ + { + "sliceProfileId": "CNId", + "pLMNInfoList": null, + "CNSliceSubnetProfile": { + "dLThptPerSliceSubnet": { + "GuaThpt": 100, + "MaxThpt": 200 + }, + "uLThptPerSliceSubnet": { + "GuaThpt": 100, + "MaxThpt": 200 + }, + "dLLatency": 8, + "uLLatency": 8 + } + } + ] + }, + "RANSliceSubnet1": { + "operationalState": "", + "administrativeState": "", + "nsInfo": {}, + "managedFunctionRef": [], + "networkSliceSubnetType": "RAN_SLICESUBNET", + "SliceProfileList": [ + { + "sliceProfileId": "RANId", + "pLMNInfoList": null, + "RANSliceSubnetProfile": { + "dLThptPerSliceSubnet": { + "GuaThpt": 100, + "MaxThpt": 200 + }, + "uLThptPerSliceSubnet": { + "GuaThpt": 100, + "MaxThpt": 200 + }, + "dLLatency": 12, + "uLLatency": 12 + } + } + ], + "networkSliceSubnetRef": [ + "MidhaulSliceSubnet1", + "BackhaulSliceSubnet1" + ] + }, + "MidhaulSliceSubnet1": { + "operationalState": "", + "administrativeState": "", + "nsInfo": {}, + "managedFunctionRef": [], + "networkSliceSubnetType": "RAN_SLICESUBNET", + "SliceProfileList": [ + { + "sliceProfileId": "MidhaulId", + "pLMNInfoList": null, + "RANSliceSubnetProfile": { + "dLThptPerSliceSubnet": { + "GuaThpt": 60, + "MaxThpt": 120 + }, + "uLThptPerSliceSubnet": { + "GuaThpt": 60, + "MaxThpt": 120 + }, + "dLLatency": 4, + "uLLatency": 4 + } + } + ], + "EpTransport": [ + "EpTransport CU-UP1", + "EpTransport DU3" + ] + }, + "BackhaulSliceSubnet1": { + "operationalState": "", + "administrativeState": "", + "nsInfo": {}, + "managedFunctionRef": [], + "networkSliceSubnetType": "RAN_SLICESUBNET", + "SliceProfileList": [ + { + "sliceProfileId": "BackhaulId", + "pLMNInfoList": null, + "RANSliceSubnetProfile": { + "dLThptPerSliceSubnet": { + "GuaThpt": 40, + "MaxThpt": 80 + }, + "uLThptPerSliceSubnet": { + "GuaThpt": 40, + "MaxThpt": 80 + }, + "dLLatency": 8, + "uLLatency": 8 + } + } + ], + "EpTransport": [ + "EpTransport CU-UP2", + "EpTransport UPF" + ] + }, + "EpTransport CU-UP1": { + "IpAddress": "100.1.1.1", + "logicalInterfaceInfo": { + "logicalInterfaceType": "VLAN", + "logicalInterfaceId": "300" + }, + "NextHopInfo": "100.1.1.254", + "qosProfile": "5QI100", + "EpApplicationRef": [ + "EP_F1U CU-UP1" + ] + }, + "EP_F1U CU-UP1": { + "localAddress": "100.1.1.2", + "remoteAddress": "1.1.3.2", + "epTransportRef": [ + "EpTransport CU-UP1" + ] + }, + "EpTransport DU3": { + "IpAddress": "1.1.3.1", + "logicalInterfaceInfo": { + "logicalInterfaceType": "VLAN", + "logicalInterfaceId": "300" + }, + "NextHopInfo": "1.1.3.254", + "qosProfile": "5QI100", + "EpApplicationRef": [ + "EP_F1U DU3" + ] + }, + "EP_F1U DU3": { + "localAddress": "1.1.3.2", + "remoteAddress": "100.1.1.2", + "epTransportRef": [ + "EpTransport DU3" + ] + } +} \ No newline at end of file diff --git a/src/templates/3gpp_template_filled.json b/src/templates/3gpp_template_filled.json new file mode 100644 index 0000000..dcab03a --- /dev/null +++ b/src/templates/3gpp_template_filled.json @@ -0,0 +1,182 @@ +{ + "NetworkSlice1":{ + "operationalState":"", + "administrativeState":"", + "serviceProfileList":[ // Requisitos generales de una NetworkSlice. Lo suponemos vacÃo. The attributes in ServiceProfile represent mapped requirements from an Network Slice Customer (e.g. an enterprise) to an Network Slice Provider + //{ + // "serviceProfileId":"", + // "pLMNInfoList": null, //It defines which PLMN and S-NSSAI combinations that are assigned for the service to satisfy service requirements represented by the ServiceProfile + // "sST":"2" // 1 (eMBB), 2(URLLC), 3(MIoT), 4(V2X) o 5(HMTC) + //} + ], + "networkSliceSubnetRef":"TopSliceSubnet1" //Es un DN (string) + }, + "TopSliceSubnet1":{ + "operationalState":"", + "administrativeState":"", + "nsInfo":{}, // Se usa si la slice está en un entorno virtualizado + "managedFunctionRef":[], // ??? Es un DNList (array de strings) + "networkSliceSubnetType":"TOP_SLICESUBNET", + "SliceProfileList":[ // Requisitos de una NetworkSliceSubnet, la cual representa un conjunto de funciones de red agrupadas. + { + "sliceProfileId":"TopId", + "pLMNInfoList":null, + "TopSliceSubnetProfile":{ //Condition: It shall be present when the slice profile is for top/root network slice subnet + "dLThptPerSliceSubnet":{ //kbps + "GuaThpt":1000, + "MaxThpt":2000 + }, + "uLThptPerSliceSubnet":{ + "GuaThpt":1000, + "MaxThpt":2000 + }, + "dLLatency":5, //ms + "uLLatency":5 + } + } + ], + "networkSliceSubnetRef":["CNSliceSubnet1","RANSliceSubnet1"] + }, + "CNSliceSubnet1":{ + "operationalState":"", + "administrativeState":"", + "nsInfo":{}, // Se usa si la slice está en un entorno virtualizado + "managedFunctionRef":[], // ??? Es un DNList (array de strings) + "networkSliceSubnetType":"CN_SLICESUBNET", + "SliceProfileList":[ // Requisitos de una NetworkSliceSubnet, la cual representa un conjunto de funciones de red agrupadas. Los requisitos de transporte se representan aquà + { + "sliceProfileId":"CNId", + "pLMNInfoList":null, + "CNSliceSubnetProfile":{ + "dLThptPerSliceSubnet":{ + "GuaThpt":500, + "MaxThpt":1000 + }, + "uLThptPerSliceSubnet":{ + "GuaThpt":500, + "MaxThpt":1000 + }, + "dLLatency":2, + "uLLatency":2 + } + } + ] + }, + "RANSliceSubnet1":{ + "operationalState":"", + "administrativeState":"", + "nsInfo":{}, // Se usa si la slice está en un entorno virtualizado + "managedFunctionRef":[], // ??? Es un DNList (array de strings) + "networkSliceSubnetType":"RAN_SLICESUBNET", + "SliceProfileList":[ // Requisitos de una NetworkSliceSubnet, la cual representa un conjunto de funciones de red agrupadas. Los requisitos de transporte se representan aquà + { + "sliceProfileId":"RANId", + "pLMNInfoList":null, + "RANSliceSubnetProfile":{ + "dLThptPerSliceSubnet":{ + "GuaThpt":500, + "MaxThpt":1000 + }, + "uLThptPerSliceSubnet":{ + "GuaThpt":500, + "MaxThpt":1000 + }, + "dLLatency":3, + "uLLatency":3 + } + } + ], + "networkSliceSubnetRef":["MidhaulSliceSubnet1", "BackhaulSliceSubnet1"] + }, + "MidhaulSliceSubnet1":{ + "operationalState":"", + "administrativeState":"", + "nsInfo":{}, // Se usa si la slice está en un entorno virtualizado + "managedFunctionRef":[], // ??? Es un DNList (array de strings), + "networkSliceSubnetType":"RAN_SLICESUBNET", + "SliceProfileList":[ // Requisitos de una NetworkSliceSubnet, la cual representa un conjunto de funciones de red agrupadas. Los requisitos de transporte se representan aquà + { + "sliceProfileId":"MidhaulId", + "pLMNInfoList":null, + "RANSliceSubnetProfile":{ + "dLThptPerSliceSubnet":{ + "GuaThpt":300, + "MaxThpt":600 + }, + "uLThptPerSliceSubnet":{ + "GuaThpt":300, + "MaxThpt":600 + }, + "dLLatency":1, + "uLLatency":1 + } + } + ], + "EpTransport":["EpTransport DU1","EpTransport CU-UP1"] // Es un DNList (array de strings) + }, + "BackhaulSliceSubnet1":{ + "operationalState":"", + "administrativeState":"", + "nsInfo":{}, // Se usa si la slice está en un entorno virtualizado + "managedFunctionRef":[], // ??? Es un DNList (array de strings), + "networkSliceSubnetType":"RAN_SLICESUBNET", + "SliceProfileList":[ // Requisitos de una NetworkSliceSubnet, la cual representa un conjunto de funciones de red agrupadas. Los requisitos de transporte se representan aquà + { + "sliceProfileId":"BackhaulId", + "pLMNInfoList":null, + "RANSliceSubnetProfile":{ + "dLThptPerSliceSubnet":{ + "GuaThpt":200, + "MaxThpt":400 + }, + "uLThptPerSliceSubnet":{ + "GuaThpt":200, + "MaxThpt":400 + }, + "dLLatency":2, + "uLLatency":2 + } + } + ], + "EpTransport":["EpTransport CU-UP2","EpTransport UPF"] // Es un DNList (array de strings) + }, + "EpTransport DU1": + { + "IpAddress":"100.1.1.1", + "logicalInterfaceInfo":{ + "logicalInterfaceType":"VLAN", //VLAN, MPLS o Segment + "logicalInterfaceId":"100" + }, + "NextHopInfo": "100.1.1.254", + "qosProfile":"5QI100", //Revisar el mapeo de los requisitos de la slice con esto + "EpApplicationRef":["EP_F1U DU1"] //Es un DNList (array de string) + }, + "EpTransport CU-UP1": + { + "IpAddress":"1.1.1.1", + "logicalInterfaceInfo":{ + "logicalInterfaceType":"VLAN", //VLAN, MPLS o Segment + "logicalInterfaceId":"100" + }, + "NextHopInfo": "1.1.1.254", + "QosProfile":"5QI100", + "EpApplicationRef":["EP_F1U CU-UP1"] //Es un DNList (array de string) + }, + "EP_F1U DU1":[ // El 3GPP parece que aun no ha definido las interfaces entre los distinos functional splits, por lo que estos objetos no están claros. Suponemos EP_F1U para todo, que es el que se usa para la interfaz F1-U entre gNB-DU y gNB-CU + { + "localAddress":"100.1.1.2", + "remoteAddress":"1.1.1.2", + "epTransportRef":["EpTransport DU1"] //Es un DNList (array de string) + } + ], + "EP_F1U CU-UP1":[ //Otras opciones son EP_N3 (interfaz N3 entre RAN y UPF) y EP_NgU (interfaz NG-U entre gNB y UPF) + { + "localAddress":"1.1.1.2", + "remoteAddress":"100.1.1.2", + "epTransportRef":["EpTransport CU-UP1"] //Es un DNList (array de string) + } + ] +} + + + diff --git a/src/templates/L2-VPN_template_empty.json b/src/templates/L2-VPN_template_empty.json new file mode 100644 index 0000000..85caed0 --- /dev/null +++ b/src/templates/L2-VPN_template_empty.json @@ -0,0 +1,38 @@ +{ + "services": [ + { + "service_id": { + "context_id": {"context_uuid": {"uuid": "admin"}}, + "service_uuid": {"uuid": "l2-acl-svc"} + }, + "service_type": 2, + "service_status": {"service_status": 1}, + "service_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": ""}}, "endpoint_uuid": {"uuid": "eth-1/0/21"}}, + {"device_id": {"device_uuid": {"uuid": ""}}, "endpoint_uuid": {"uuid": "eth-1/0/21"}} + ], + "service_constraints": [ + {"custom": {"constraint_type": "bandwidth[kbps]", "constraint_value": "0"}}, + {"custom": {"constraint_type": "latency[ms]", "constraint_value": "0"}} + ], + "service_config": {"config_rules": [ + {"action": 1, "custom": {"resource_key": "/settings", "resource_value": { + }}}, + {"action": 1, "custom": {"resource_key": "", "resource_value": { + "sub_interface_index": 0, + "vlan_id": 0, + "circuit_id": "", + "remote_router":"", + "ni_name": "prueba" + }}}, + {"action": 1, "custom": {"resource_key": "", "resource_value": { + "sub_interface_index": 0, + "vlan_id": 0, + "circuit_id": "", + "remote_router":"", + "ni_name": "prueba" + }}} + ]} + } + ] +} \ No newline at end of file diff --git a/src/templates/L2-VPN_template_example.json b/src/templates/L2-VPN_template_example.json new file mode 100644 index 0000000..b29e3c6 --- /dev/null +++ b/src/templates/L2-VPN_template_example.json @@ -0,0 +1,271 @@ +{ + "services": [ + { + "service_id": { + "context_id": { + "context_uuid": { + "uuid": "admin" + } + }, + "service_uuid": { + "uuid": "l2-acl-svc-17429923732568250" + } + }, + "service_type": 2, + "service_status": { + "service_status": 1 + }, + "service_endpoint_ids": [ + { + "device_id": { + "device_uuid": { + "uuid": "4.4.4.4" + } + }, + "endpoint_uuid": { + "uuid": "0/0/0-GigabitEthernet0/0/0/0" + } + }, + { + "device_id": { + "device_uuid": { + "uuid": "5.5.5.5" + } + }, + "endpoint_uuid": { + "uuid": "0/0/3-GigabitEthernet0/0/0/3" + } + } + ], + "service_constraints": [ + { + "custom": { + "constraint_type": "bandwidth[kbps]", + "constraint_value": "20" + } + }, + { + "custom": { + "constraint_type": "latency[ms]", + "constraint_value": "20" + } + } + ], + "service_config": { + "config_rules": [ + { + "action": 1, + "custom": { + "resource_key": "/settings", + "resource_value": {} + } + }, + { + "action": 1, + "custom": { + "resource_key": "/device[4.4.4.4]/endpoint[0/0/0-GigabitEthernet0/0/0/0]/settings", + "resource_value": { + "sub_interface_index": 0, + "vlan_id": 100, + "circuit_id": "100", + "remote_router": "5.5.5.5", + "ni_name": "ELAN100" + } + } + }, + { + "action": 1, + "custom": { + "resource_key": "/device[5.5.5.5]/endpoint[0/0/3-GigabitEthernet0/0/0/3]/settings", + "resource_value": { + "sub_interface_index": 0, + "vlan_id": 100, + "circuit_id": "100", + "remote_router": "4.4.4.4", + "ni_name": "ELAN100" + } + } + } + ] + } + }, + { + "service_id": { + "context_id": { + "context_uuid": { + "uuid": "admin" + } + }, + "service_uuid": { + "uuid": "l2-acl-svc-17429923733224160" + } + }, + "service_type": 2, + "service_status": { + "service_status": 1 + }, + "service_endpoint_ids": [ + { + "device_id": { + "device_uuid": { + "uuid": "4.4.4.4" + } + }, + "endpoint_uuid": { + "uuid": "0/0/0-GigabitEthernet0/0/0/0" + } + }, + { + "device_id": { + "device_uuid": { + "uuid": "5.5.5.5" + } + }, + "endpoint_uuid": { + "uuid": "0/0/3-GigabitEthernet0/0/0/3" + } + } + ], + "service_constraints": [ + { + "custom": { + "constraint_type": "bandwidth[kbps]", + "constraint_value": "200" + } + }, + { + "custom": { + "constraint_type": "latency[ms]", + "constraint_value": "5" + } + } + ], + "service_config": { + "config_rules": [ + { + "action": 1, + "custom": { + "resource_key": "/settings", + "resource_value": {} + } + }, + { + "action": 1, + "custom": { + "resource_key": "/device[4.4.4.4]/endpoint[0/0/0-GigabitEthernet0/0/0/0]/settings", + "resource_value": { + "sub_interface_index": 0, + "vlan_id": 101, + "circuit_id": "101", + "remote_router": "5.5.5.5", + "ni_name": "ELAN101" + } + } + }, + { + "action": 1, + "custom": { + "resource_key": "/device[5.5.5.5]/endpoint[0/0/3-GigabitEthernet0/0/0/3]/settings", + "resource_value": { + "sub_interface_index": 0, + "vlan_id": 101, + "circuit_id": "101", + "remote_router": "4.4.4.4", + "ni_name": "ELAN101" + } + } + } + ] + } + }, + { + "service_id": { + "context_id": { + "context_uuid": { + "uuid": "admin" + } + }, + "service_uuid": { + "uuid": "l2-acl-svc-17429923733753200" + } + }, + "service_type": 2, + "service_status": { + "service_status": 1 + }, + "service_endpoint_ids": [ + { + "device_id": { + "device_uuid": { + "uuid": "4.4.4.4" + } + }, + "endpoint_uuid": { + "uuid": "0/0/0-GigabitEthernet0/0/0/0" + } + }, + { + "device_id": { + "device_uuid": { + "uuid": "5.5.5.5" + } + }, + "endpoint_uuid": { + "uuid": "0/0/3-GigabitEthernet0/0/0/3" + } + } + ], + "service_constraints": [ + { + "custom": { + "constraint_type": "bandwidth[kbps]", + "constraint_value": "200" + } + }, + { + "custom": { + "constraint_type": "latency[ms]", + "constraint_value": "10" + } + } + ], + "service_config": { + "config_rules": [ + { + "action": 1, + "custom": { + "resource_key": "/settings", + "resource_value": {} + } + }, + { + "action": 1, + "custom": { + "resource_key": "/device[4.4.4.4]/endpoint[0/0/0-GigabitEthernet0/0/0/0]/settings", + "resource_value": { + "sub_interface_index": 0, + "vlan_id": 102, + "circuit_id": "102", + "remote_router": "5.5.5.5", + "ni_name": "ELAN102" + } + } + }, + { + "action": 1, + "custom": { + "resource_key": "/device[5.5.5.5]/endpoint[0/0/3-GigabitEthernet0/0/0/3]/settings", + "resource_value": { + "sub_interface_index": 0, + "vlan_id": 102, + "circuit_id": "102", + "remote_router": "4.4.4.4", + "ni_name": "ELAN102" + } + } + } + ] + } + } + ] +} \ No newline at end of file diff --git a/src/templates/L2-VPN_template_filled.json b/src/templates/L2-VPN_template_filled.json new file mode 100644 index 0000000..594fc27 --- /dev/null +++ b/src/templates/L2-VPN_template_filled.json @@ -0,0 +1,36 @@ +{ + "services": [ + { + "service_id": { + "context_id": {"context_uuid": {"uuid": "admin"}}, //Siempre usaremos admin + "service_uuid": {"uuid": "l2-acl-svc"} //identificador unico + }, + "service_type": 2, // Numero que identifica que es una vpn de nivel 2, se mantiene + "service_status": {"service_status": 1}, + "service_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "R149"}}, "endpoint_uuid": {"uuid": "eth-1/0/21"}}, // Se tiene que cambiar por el endpoint de origen + {"device_id": {"device_uuid": {"uuid": "R155"}}, "endpoint_uuid": {"uuid": "eth-1/0/21"}} // Se tiene que cambiar por el endpoint de destino + ], + "service_constraints": [ //Requerimientos que han de darse, de momento no funciona por lo que mantener igual + {"custom": {"constraint_type": "bandwidth[kbps]", "constraint_value": "10.0"}}, + {"custom": {"constraint_type": "latency[ms]", "constraint_value": "15.2"}} + ], + "service_config": {"config_rules": [ + {"action": 1, "custom": {"resource_key": "/settings", "resource_value": { //Regla default, se mantiene + }}}, + {"action": 1, "custom": {"resource_key": "/device[R149]/endpoint[eth-1/0/21]/settings", "resource_value": { //Camino de ida, hay que cambiar la vlan, circuit_id y sub_interface_index por el valor de vlan que queramos usar + "sub_interface_index": 0, + "vlan_id": 999, + "circuit_id": "999", + "remote_router":"5.5.5.1" // Este valor es la ip del router en el otro extremo + }}}, + {"action": 1, "custom": {"resource_key": "/device[R155]/endpoint[eth-1/0/21]/settings", "resource_value": { //Camino de vuelta, hay que cambiar la vlan, circuit_id y sub_interface_index por el valor de vlan que queramos usar + "sub_interface_index": 0, + "vlan_id": 999, + "circuit_id": "999", + "remote_router":"5.5.5.5" // Este valor es la ip del router en el otro extremo + }}} + ]} + } + ] +} \ No newline at end of file diff --git a/src/templates/L3-VPN_template_empty.json b/src/templates/L3-VPN_template_empty.json new file mode 100644 index 0000000..e894cfa --- /dev/null +++ b/src/templates/L3-VPN_template_empty.json @@ -0,0 +1,46 @@ +{ + "services": [ + { + "service_id": { + "context_id": {"context_uuid": {"uuid": "admin"}}, + "service_uuid": {"uuid": "l3-acl-svc"} + }, + "service_type": 1, + "service_status": {"service_status": 1}, + "service_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": ""}}, "endpoint_uuid": {"uuid": ""}}, + {"device_id": {"device_uuid": {"uuid": ""}}, "endpoint_uuid": {"uuid": ""}} + ], + "service_constraints": [ + {"custom": {"constraint_type": "bandwidth[kbps]", "constraint_value": "0"}}, + {"custom": {"constraint_type": "latency[ms]", "constraint_value": "0"}} + ], + "service_config": {"config_rules": [ + {"action": 1, "custom": {"resource_key": "/settings", "resource_value": { + "bgp_as" : 65000, + "route_distinguisher": "65000:533" + }}}, + {"action": 1, "custom": {"resource_key": "/device[R149]/endpoint[eth-1/0/20]/settings", "resource_value": { + "router_id" : "", + "sub_interface_index": 0, + "vlan_id" : 0, + "address_ip" : "", + "address_prefix" : 16, + "policy_AZ" : "srv_ACL", + "policy_ZA" : "srv_ACLr", + "ni_name" : "prueba" + }}}, + {"action": 1, "custom": {"resource_key": "/device[R155]/endpoint[eth-1/0/20]/settings", "resource_value": { + "router_id" : "", + "sub_interface_index": 0, + "vlan_id" : 0, + "address_ip" : "", + "address_prefix" : 16, + "policy_AZ" : "srv_ACLr", + "policy_ZA" : "srv_ACL", + "ni_name" : "prueba" + }}} + ]} + } + ] +} \ No newline at end of file diff --git a/src/templates/L3-VPN_template_example.json b/src/templates/L3-VPN_template_example.json new file mode 100644 index 0000000..d0a70b7 --- /dev/null +++ b/src/templates/L3-VPN_template_example.json @@ -0,0 +1,102 @@ +{ + "services": [ + { + "service_id": { + "context_id": { + "context_uuid": { + "uuid": "admin" + } + }, + "service_uuid": { + "uuid": "l3-acl-svc-17258860855224490" + } + }, + "service_type": 1, + "service_status": { + "service_status": 1 + }, + "service_endpoint_ids": [ + { + "device_id": { + "device_uuid": { + "uuid": "4.4.4.4" + } + }, + "endpoint_uuid": { + "uuid": "0/0/1-GigabitEthernet0/0/0/1" + } + }, + { + "device_id": { + "device_uuid": { + "uuid": "5.5.5.5" + } + }, + "endpoint_uuid": { + "uuid": "0/0/1-GigabitEthernet0/0/0/1" + } + } + ], + "service_constraints": [ + { + "custom": { + "constraint_type": "bandwidth[kbps]", + "constraint_value": "120" + } + }, + { + "custom": { + "constraint_type": "latency[ms]", + "constraint_value": "2" + } + } + ], + "service_config": { + "config_rules": [ + { + "action": 1, + "custom": { + "resource_key": "/settings", + "resource_value": { + "bgp_as": 65000, + "route_distinguisher": "65000:533" + } + } + }, + { + "action": 1, + "custom": { + "resource_key": "/device[4.4.4.4]/endpoint[0/0/1-GigabitEthernet0/0/0/1]/settings", + "resource_value": { + "router_id": "5.5.5.5", + "sub_interface_index": 0, + "vlan_id": 300, + "address_ip": "5.5.5.5", + "address_prefix": 16, + "policy_AZ": "policyA", + "policy_ZA": "policyB", + "ni_name": "ELAN300" + } + } + }, + { + "action": 1, + "custom": { + "resource_key": "/device[5.5.5.5]/endpoint[0/0/1-GigabitEthernet0/0/0/1]/settings", + "resource_value": { + "router_id": "4.4.4.4", + "sub_interface_index": 0, + "vlan_id": 300, + "address_ip": "4.4.4.4", + "address_prefix": 16, + "policy_AZ": "policyA", + "policy_ZA": "policyB", + "ni_name": "ELAN300" + } + } + } + ] + } + } + ] +} \ No newline at end of file diff --git a/src/templates/L3-VPN_template_filled.json b/src/templates/L3-VPN_template_filled.json new file mode 100644 index 0000000..12bea2a --- /dev/null +++ b/src/templates/L3-VPN_template_filled.json @@ -0,0 +1,44 @@ +{ + "servs": [ + { + "service_id": { + "context_id": {"context_uuid": {"uuid": "admin"}}, //Siempre usaremos admin + "service_uuid": {"uuid": "l3-svc"} //identificador unico + }, + "service_type": 1, // Numero que identifica que es una vpn de nivel 3, se mantiene + "service_status": {"service_status": 1}, + "service_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "R149"}}, "endpoint_uuid": {"uuid": "eth-1/0/20"}}, // Se tiene que cambiar por el endpoint de origen + {"device_id": {"device_uuid": {"uuid": "R155"}}, "endpoint_uuid": {"uuid": "eth-1/0/20"}} // Se tiene que cambiar por el endpoint de destino + ], + "service_constraints": [ // Requerimientos que han de darse, de momento no funciona por lo que mantener igual + {"custom": {"constraint_type": "bandwidth[gbps]", "constraint_value": "10.0"}}, + {"custom": {"constraint_type": "latency[ms]", "constraint_value": "15.2"}} + ], + "service_config": {"config_rules": [ + {"action": 1, "custom": {"resource_key": "/settings", "resource_value": { //Regla default, se mantiene + "bgp_as" : 65000, + "route_distinguisher": "65000:533" + }}}, + {"action": 1, "custom": {"resource_key": "/device[R149]/endpoint[eth-1/0/20]/settings", "resource_value": { + "router_id" : "5.5.5.5", + "sub_interface_index": 0, + "vlan_id" : 533, + "address_ip" : "172.16.12.12", + "address_prefix" : 16, + "policy_AZ" : "srv_ACL", + "policy_ZA" : "srv_ACLr" + }}}, + {"action": 1, "custom": {"resource_key": "/device[R155]/endpoint[eth-1/0/20]/settings", "resource_value": { + "router_id" : "5.5.5.1", + "sub_interface_index": 0, + "vlan_id" : 533, + "address_ip" : "172.16.13.13", + "address_prefix" : 16, + "policy_AZ" : "srv_ACLr", + "policy_ZA" : "srv_ACL" + }}} + ]} + } + ] +} \ No newline at end of file diff --git a/src/templates/descriptor-topology copy.json b/src/templates/descriptor-topology copy.json new file mode 100644 index 0000000..304373a --- /dev/null +++ b/src/templates/descriptor-topology copy.json @@ -0,0 +1,570 @@ +{ + "dummy_mode": true, + "contexts":[ + { + "context_id":{ + "context_uuid":{ + "uuid":"admin" + } + }, + "topology_ids":[ + + ], + "service_ids":[ + + ] + } + ], + "topologies":[ + { + "topology_id":{ + "context_id":{ + "context_uuid":{ + "uuid":"admin" + } + }, + "topology_uuid":{ + "uuid":"admin" + } + }, + "device_ids":[ + { + "device_uuid":{ + "uuid":"1.1.1.1" + } + }, + { + "device_uuid":{ + "uuid":"2.2.2.2" + } + } + ], + "link_ids":[ + { + "link_uuid":{ + "uuid":"4.4.4.4/0/0/1-GigabitEthernet0/0/0/1==2.2.2.2/GigabitEthernet2" + } + }, + { + "link_uuid":{ + "uuid":"2.2.2.2/GigabitEthernet2==4.4.4.4/0/0/1-GigabitEthernet0/0/0/1" + } + }, + { + "link_uuid":{ + "uuid":"2.2.2.2/GigabitEthernet1==1.1.1.1/GigabitEthernet1" + } + }, + { + "link_uuid":{ + "uuid":"1.1.1.1/GigabitEthernet1==2.2.2.2/GigabitEthernet1" + } + }, + { + "link_uuid":{ + "uuid":"2.2.2.2/GigabitEthernet4==5.5.5.5/0/0/0-GigabitEthernet0/0/0/0" + } + }, + { + "link_uuid":{ + "uuid":"5.5.5.5/0/0/0-GigabitEthernet0/0/0/0==2.2.2.2/GigabitEthernet4" + } + }, + { + "link_uuid":{ + "uuid":"2.2.2.2/GigabitEthernet3==3.3.3.3/0/0/3-GigabitEthernet0/0/0/3" + } + }, + { + "link_uuid":{ + "uuid":"3.3.3.3/0/0/3-GigabitEthernet0/0/0/3==2.2.2.2/GigabitEthernet3" + } + }, + { + "link_uuid":{ + "uuid":"1.1.1.1/GigabitEthernet2==5.5.5.5/0/0/2-GigabitEthernet0/0/0/2" + } + }, + { + "link_uuid":{ + "uuid":"5.5.5.5/0/0/2-GigabitEthernet0/0/0/2==1.1.1.1/GigabitEthernet2" + } + } + ] + } + ], + "devices":[ + { + "device_id":{ + "device_uuid":{ + "uuid":"1.1.1.1" + } + }, + "device_type":"packet-router", + "device_config":{ + "config_rules":[ + { + "action":1, + "custom":{ + "resource_key":"_connect/address", + "resource_value":"10.60.125.41" + } + }, + { + "action":1, + "custom":{ + "resource_key":"_connect/port", + "resource_value":"830" + } + }, + { + "action":1, + "custom":{ + "resource_key":"_connect/settings", + "resource_value":{ + "username":"cisco", + "password":"cisco12345", + "vendor":"CISCO", + "force_running":false, + "hostkey_verify":false, + "message_renderer":"pyangbind", + "look_for_keys":false, + "allow_agent":false, + "commit_per_rule":true, + "device_params":{ + "name":"default" + }, + "manager_params":{ + "timeout":120 + } + } + } + }, + {"action": 1, "custom": {"resource_key": "/endpoints/endpoint[GigabitEthernet1]", "resource_value": { + "uuid": "GigabitEthernet1", "name": "GigabitEthernet1", "type": "-" + }}}, + {"action": 1, "custom": {"resource_key": "/endpoints/endpoint[GigabitEthernet2]", "resource_value": { + "uuid": "GigabitEthernet2", "name": "GigabitEthernet2", "type": "-" + }}}, + {"action": 1, "custom": {"resource_key": "/endpoints/endpoint[GigabitEthernet3]", "resource_value": { + "uuid": "GigabitEthernet3", "name": "GigabitEthernet3", "type": "-" + }}}, + {"action": 1, "custom": {"resource_key": "/endpoints/endpoint[GigabitEthernet4]", "resource_value": { + "uuid": "GigabitEthernet4", "name": "GigabitEthernet4", "type": "-" + }}}, + {"action": 1, "custom": {"resource_key": "/endpoints/endpoint[GigabitEthernet5]", "resource_value": { + "uuid": "GigabitEthernet5", "name": "GigabitEthernet5", "type": "-" + }}} + ] + }, + "device_operational_status":2, + "device_drivers":[ + 1 + ], + "device_endpoints":[ + {"name": "GigabitEthernet1", "endpoint_type": "-", "endpoint_id": { + "device_id": {"device_uuid": {"uuid": "1.1.1.1"}}, "endpoint_uuid": {"uuid": "GigabitEthernet1"}, + "topology_id": {"context_id": {"context_uuid": {"uuid": "admin"}}, "topology_uuid": {"uuid": "admin"}} + }}, + {"name": "GigabitEthernet2", "endpoint_type": "-", "endpoint_id": { + "device_id": {"device_uuid": {"uuid": "1.1.1.1"}}, "endpoint_uuid": {"uuid": "GigabitEthernet2"}, + "topology_id": {"context_id": {"context_uuid": {"uuid": "admin"}}, "topology_uuid": {"uuid": "admin"}} + }}, + {"name": "GigabitEthernet3", "endpoint_type": "-", "endpoint_id": { + "device_id": {"device_uuid": {"uuid": "1.1.1.1"}}, "endpoint_uuid": {"uuid": "GigabitEthernet3"}, + "topology_id": {"context_id": {"context_uuid": {"uuid": "admin"}}, "topology_uuid": {"uuid": "admin"}} + }}, + {"name": "GigabitEthernet4", "endpoint_type": "-", "endpoint_id": { + "device_id": {"device_uuid": {"uuid": "1.1.1.1"}}, "endpoint_uuid": {"uuid": "GigabitEthernet4"}, + "topology_id": {"context_id": {"context_uuid": {"uuid": "admin"}}, "topology_uuid": {"uuid": "admin"}} + }}, + {"name": "GigabitEthernet5", "endpoint_type": "-", "endpoint_id": { + "device_id": {"device_uuid": {"uuid": "1.1.1.1"}}, "endpoint_uuid": {"uuid": "GigabitEthernet5"}, + "topology_id": {"context_id": {"context_uuid": {"uuid": "admin"}}, "topology_uuid": {"uuid": "admin"}} + }} + ] + }, + { + "device_id":{ + "device_uuid":{ + "uuid":"2.2.2.2" + } + }, + "device_type":"packet-router", + "device_config":{ + "config_rules":[ + { + "action":1, + "custom":{ + "resource_key":"_connect/address", + "resource_value":"10.60.125.42" + } + }, + { + "action":1, + "custom":{ + "resource_key":"_connect/port", + "resource_value":"830" + } + }, + { + "action":1, + "custom":{ + "resource_key":"_connect/settings", + "resource_value":{ + "username":"cisco", + "password":"cisco12345", + "vendor":"CISCO", + "force_running":false, + "hostkey_verify":false, + "message_renderer":"pyangbind", + "look_for_keys":false, + "allow_agent":false, + "commit_per_rule":true, + "device_params":{ + "name":"default" + }, + "manager_params":{ + "timeout":120 + } + } + } + }, + {"action": 1, "custom": {"resource_key": "/endpoints/endpoint[GigabitEthernet1]", "resource_value": { + "uuid": "GigabitEthernet1", "name": "GigabitEthernet1", "type": "-" + }}}, + {"action": 1, "custom": {"resource_key": "/endpoints/endpoint[GigabitEthernet2]", "resource_value": { + "uuid": "GigabitEthernet2", "name": "GigabitEthernet2", "type": "-" + }}}, + {"action": 1, "custom": {"resource_key": "/endpoints/endpoint[GigabitEthernet3]", "resource_value": { + "uuid": "GigabitEthernet3", "name": "GigabitEthernet3", "type": "-" + }}}, + {"action": 1, "custom": {"resource_key": "/endpoints/endpoint[GigabitEthernet4]", "resource_value": { + "uuid": "GigabitEthernet4", "name": "GigabitEthernet4", "type": "-" + }}}, + {"action": 1, "custom": {"resource_key": "/endpoints/endpoint[GigabitEthernet5]", "resource_value": { + "uuid": "GigabitEthernet5", "name": "GigabitEthernet5", "type": "-" + }}} + ] + }, + "device_operational_status":2, + "device_drivers":[ + 1 + ], + "device_endpoints":[ + {"name": "GigabitEthernet1", "endpoint_type": "-", "endpoint_id": { + "device_id": {"device_uuid": {"uuid": "2.2.2.2"}}, "endpoint_uuid": {"uuid": "GigabitEthernet1"}, + "topology_id": {"context_id": {"context_uuid": {"uuid": "admin"}}, "topology_uuid": {"uuid": "admin"}} + }}, + {"name": "GigabitEthernet2", "endpoint_type": "-", "endpoint_id": { + "device_id": {"device_uuid": {"uuid": "2.2.2.2"}}, "endpoint_uuid": {"uuid": "GigabitEthernet2"}, + "topology_id": {"context_id": {"context_uuid": {"uuid": "admin"}}, "topology_uuid": {"uuid": "admin"}} + }}, + {"name": "GigabitEthernet3", "endpoint_type": "-", "endpoint_id": { + "device_id": {"device_uuid": {"uuid": "2.2.2.2"}}, "endpoint_uuid": {"uuid": "GigabitEthernet3"}, + "topology_id": {"context_id": {"context_uuid": {"uuid": "admin"}}, "topology_uuid": {"uuid": "admin"}} + }}, + {"name": "GigabitEthernet4", "endpoint_type": "-", "endpoint_id": { + "device_id": {"device_uuid": {"uuid": "2.2.2.2"}}, "endpoint_uuid": {"uuid": "GigabitEthernet4"}, + "topology_id": {"context_id": {"context_uuid": {"uuid": "admin"}}, "topology_uuid": {"uuid": "admin"}} + }}, + {"name": "GigabitEthernet5", "endpoint_type": "-", "endpoint_id": { + "device_id": {"device_uuid": {"uuid": "2.2.2.2"}}, "endpoint_uuid": {"uuid": "GigabitEthernet5"}, + "topology_id": {"context_id": {"context_uuid": {"uuid": "admin"}}, "topology_uuid": {"uuid": "admin"}} + }} + ] + } + ], + "links":[ + { + "link_id":{ + "link_uuid":{ + "uuid":"4.4.4.4/0/0/1-GigabitEthernet0/0/0/1==2.2.2.2/GigabitEthernet2" + } + }, + "link_endpoint_ids":[ + { + "device_id":{ + "device_uuid":{ + "uuid":"4.4.4.4" + } + }, + "endpoint_uuid":{ + "uuid":"0/0/1-GigabitEthernet0/0/0/1" + } + }, + { + "device_id":{ + "device_uuid":{ + "uuid":"2.2.2.2" + } + }, + "endpoint_uuid":{ + "uuid":"GigabitEthernet2" + } + } + ] + }, + { + "link_id":{ + "link_uuid":{ + "uuid":"2.2.2.2/GigabitEthernet2==4.4.4.4/0/0/1-GigabitEthernet0/0/0/1" + } + }, + "link_endpoint_ids":[ + { + "device_id":{ + "device_uuid":{ + "uuid":"2.2.2.2" + } + }, + "endpoint_uuid":{ + "uuid":"GigabitEthernet2" + } + }, + { + "device_id":{ + "device_uuid":{ + "uuid":"4.4.4.4" + } + }, + "endpoint_uuid":{ + "uuid":"0/0/1-GigabitEthernet0/0/0/1" + } + } + ] + }, + { + "link_id":{ + "link_uuid":{ + "uuid":"2.2.2.2/GigabitEthernet1==1.1.1.1/GigabitEthernet1" + } + }, + "link_endpoint_ids":[ + { + "device_id":{ + "device_uuid":{ + "uuid":"2.2.2.2" + } + }, + "endpoint_uuid":{ + "uuid":"GigabitEthernet1" + } + }, + { + "device_id":{ + "device_uuid":{ + "uuid":"1.1.1.1" + } + }, + "endpoint_uuid":{ + "uuid":"GigabitEthernet1" + } + } + ] + }, + { + "link_id":{ + "link_uuid":{ + "uuid":"1.1.1.1/GigabitEthernet1==2.2.2.2/GigabitEthernet1" + } + }, + "link_endpoint_ids":[ + { + "device_id":{ + "device_uuid":{ + "uuid":"1.1.1.1" + } + }, + "endpoint_uuid":{ + "uuid":"GigabitEthernet1" + } + }, + { + "device_id":{ + "device_uuid":{ + "uuid":"2.2.2.2" + } + }, + "endpoint_uuid":{ + "uuid":"GigabitEthernet1" + } + } + ] + }, + { + "link_id":{ + "link_uuid":{ + "uuid":"2.2.2.2/GigabitEthernet4==5.5.5.5/0/0/0-GigabitEthernet0/0/0/0" + } + }, + "link_endpoint_ids":[ + { + "device_id":{ + "device_uuid":{ + "uuid":"2.2.2.2" + } + }, + "endpoint_uuid":{ + "uuid":"GigabitEthernet4" + } + }, + { + "device_id":{ + "device_uuid":{ + "uuid":"5.5.5.5" + } + }, + "endpoint_uuid":{ + "uuid":"0/0/0-GigabitEthernet0/0/0/0" + } + } + ] + }, + { + "link_id":{ + "link_uuid":{ + "uuid":"5.5.5.5/0/0/0-GigabitEthernet0/0/0/0==2.2.2.2/GigabitEthernet4" + } + }, + "link_endpoint_ids":[ + { + "device_id":{ + "device_uuid":{ + "uuid":"5.5.5.5" + } + }, + "endpoint_uuid":{ + "uuid":"0/0/0-GigabitEthernet0/0/0/0" + } + }, + { + "device_id":{ + "device_uuid":{ + "uuid":"2.2.2.2" + } + }, + "endpoint_uuid":{ + "uuid":"GigabitEthernet4" + } + } + ] + }, + { + "link_id":{ + "link_uuid":{ + "uuid":"2.2.2.2/GigabitEthernet3==3.3.3.3/0/0/3-GigabitEthernet0/0/0/3" + } + }, + "link_endpoint_ids":[ + { + "device_id":{ + "device_uuid":{ + "uuid":"2.2.2.2" + } + }, + "endpoint_uuid":{ + "uuid":"GigabitEthernet3" + } + }, + { + "device_id":{ + "device_uuid":{ + "uuid":"3.3.3.3" + } + }, + "endpoint_uuid":{ + "uuid":"0/0/3-GigabitEthernet0/0/0/3" + } + } + ] + }, + { + "link_id":{ + "link_uuid":{ + "uuid":"3.3.3.3/0/0/3-GigabitEthernet0/0/0/3==2.2.2.2/GigabitEthernet3" + } + }, + "link_endpoint_ids":[ + { + "device_id":{ + "device_uuid":{ + "uuid":"3.3.3.3" + } + }, + "endpoint_uuid":{ + "uuid":"0/0/3-GigabitEthernet0/0/0/3" + } + }, + { + "device_id":{ + "device_uuid":{ + "uuid":"2.2.2.2" + } + }, + "endpoint_uuid":{ + "uuid":"GigabitEthernet3" + } + } + ] + }, + { + "link_id":{ + "link_uuid":{ + "uuid":"1.1.1.1/GigabitEthernet2==5.5.5.5/0/0/2-GigabitEthernet0/0/0/2" + } + }, + "link_endpoint_ids":[ + { + "device_id":{ + "device_uuid":{ + "uuid":"1.1.1.1" + } + }, + "endpoint_uuid":{ + "uuid":"GigabitEthernet2" + } + }, + { + "device_id":{ + "device_uuid":{ + "uuid":"5.5.5.5" + } + }, + "endpoint_uuid":{ + "uuid":"0/0/2-GigabitEthernet0/0/0/2" + } + } + ] + }, + { + "link_id":{ + "link_uuid":{ + "uuid":"5.5.5.5/0/0/2-GigabitEthernet0/0/0/2==1.1.1.1/GigabitEthernet2" + } + }, + "link_endpoint_ids":[ + { + "device_id":{ + "device_uuid":{ + "uuid":"5.5.5.5" + } + }, + "endpoint_uuid":{ + "uuid":"0/0/2-GigabitEthernet0/0/0/2" + } + }, + { + "device_id":{ + "device_uuid":{ + "uuid":"1.1.1.1" + } + }, + "endpoint_uuid":{ + "uuid":"GigabitEthernet2" + } + } + ] + } + ] +} \ No newline at end of file diff --git a/src/templates/descriptor-topology-tid.json b/src/templates/descriptor-topology-tid.json new file mode 100644 index 0000000..588d9e9 --- /dev/null +++ b/src/templates/descriptor-topology-tid.json @@ -0,0 +1,752 @@ +{ + "contexts":[ + { + "context_id":{ + "context_uuid":{ + "uuid":"admin" + } + }, + "topology_ids":[ + + ], + "service_ids":[ + + ] + } + ], + "topologies":[ + { + "topology_id":{ + "context_id":{ + "context_uuid":{ + "uuid":"admin" + } + }, + "topology_uuid":{ + "uuid":"admin" + } + }, + "device_ids":[ + { + "device_uuid":{ + "uuid":"1.1.1.1" + } + }, + { + "device_uuid":{ + "uuid":"2.2.2.2" + } + }, + { + "device_uuid":{ + "uuid":"3.3.3.3" + } + }, + { + "device_uuid":{ + "uuid":"4.4.4.4" + } + }, + { + "device_uuid":{ + "uuid":"5.5.5.5" + } + } + ], + "link_ids":[ + { + "link_uuid":{ + "uuid":"5.5.5.5/0/0/1-GigabitEthernet0/0/0/1==3.3.3.3/0/0/1-GigabitEthernet0/0/0/1" + } + }, + { + "link_uuid":{ + "uuid":"3.3.3.3/0/0/1-GigabitEthernet0/0/0/1==5.5.5.5/0/0/1-GigabitEthernet0/0/0/1" + } + }, + { + "link_uuid":{ + "uuid":"5.5.5.5/0/0/2-GigabitEthernet0/0/0/2==1.1.1.1/0/0/1-GigabitEthernet0/0/0/1" + } + }, + { + "link_uuid":{ + "uuid":"1.1.1.1/0/0/1-GigabitEthernet0/0/0/1==5.5.5.5/0/0/2-GigabitEthernet0/0/0/2" + } + }, + { + "link_uuid":{ + "uuid":"5.5.5.5/0/0/0-GigabitEthernet0/0/0/0==2.2.2.2/0/0/2-GigabitEthernet0/0/0/2" + } + }, + { + "link_uuid":{ + "uuid":"2.2.2.2/0/0/2-GigabitEthernet0/0/0/2==5.5.5.5/0/0/0-GigabitEthernet0/0/0/0" + } + }, + { + "link_uuid":{ + "uuid":"3.3.3.3/0/0/3-GigabitEthernet0/0/0/3==2.2.2.2/0/0/3-GigabitEthernet0/0/0/3" + } + }, + { + "link_uuid":{ + "uuid":"2.2.2.2/0/0/3-GigabitEthernet0/0/0/3==3.3.3.3/0/0/3-GigabitEthernet0/0/0/3" + } + }, + { + "link_uuid":{ + "uuid":"1.1.1.1/0/0/0-GigabitEthernet0/0/0/0==2.2.2.2/0/0/0-GigabitEthernet0/0/0/0" + } + }, + { + "link_uuid":{ + "uuid":"2.2.2.2/0/0/0-GigabitEthernet0/0/0/0==1.1.1.1/0/0/0-GigabitEthernet0/0/0/0" + } + }, + { + "link_uuid":{ + "uuid":"4.4.4.4/0/0/1-GigabitEthernet0/0/0/1==2.2.2.2/0/0/1-GigabitEthernet0/0/0/1" + } + }, + { + "link_uuid":{ + "uuid":"2.2.2.2/0/0/1-GigabitEthernet0/0/0/1==4.4.4.4/0/0/1-GigabitEthernet0/0/0/1" + } + } + ] + } + ], + "devices":[ + { + "device_id":{ + "device_uuid":{ + "uuid":"1.1.1.1" + } + }, + "device_type":"packet-router", + "device_config":{ + "config_rules":[ + { + "action":1, + "custom":{ + "resource_key":"_connect/address", + "resource_value":"10.95.90.41" + } + }, + { + "action":1, + "custom":{ + "resource_key":"_connect/port", + "resource_value":"830" + } + }, + { + "action":1, + "custom":{ + "resource_key":"_connect/settings", + "resource_value":{ + "username":"cisco", + "password":"cisco12345", + "vendor":"CISCO", + "force_running":false, + "hostkey_verify":false, + "message_renderer":"pyangbind", + "look_for_keys":false, + "allow_agent":false, + "commit_per_rule":true, + "device_params":{ + "name":"default" + }, + "manager_params":{ + "timeout":120 + } + } + } + } + ] + }, + "device_operational_status":2, + "device_drivers":[ + 1 + ], + "device_endpoints":[ + + ] + }, + { + "device_id":{ + "device_uuid":{ + "uuid":"2.2.2.2" + } + }, + "device_type":"packet-router", + "device_config":{ + "config_rules":[ + { + "action":1, + "custom":{ + "resource_key":"_connect/address", + "resource_value":"10.95.90.42" + } + }, + { + "action":1, + "custom":{ + "resource_key":"_connect/port", + "resource_value":"830" + } + }, + { + "action":1, + "custom":{ + "resource_key":"_connect/settings", + "resource_value":{ + "username":"cisco", + "password":"cisco12345", + "vendor":"CISCO", + "force_running":false, + "hostkey_verify":false, + "message_renderer":"pyangbind", + "look_for_keys":false, + "allow_agent":false, + "commit_per_rule":true, + "device_params":{ + "name":"default" + }, + "manager_params":{ + "timeout":120 + } + } + } + } + ] + }, + "device_operational_status":2, + "device_drivers":[ + 1 + ], + "device_endpoints":[ + + ] + }, + { + "device_id":{ + "device_uuid":{ + "uuid":"3.3.3.3" + } + }, + "device_type":"packet-router", + "device_config":{ + "config_rules":[ + { + "action":1, + "custom":{ + "resource_key":"_connect/address", + "resource_value":"10.95.90.43" + } + }, + { + "action":1, + "custom":{ + "resource_key":"_connect/port", + "resource_value":"830" + } + }, + { + "action":1, + "custom":{ + "resource_key":"_connect/settings", + "resource_value":{ + "username":"cisco", + "password":"cisco12345", + "vendor":"CISCO", + "force_running":false, + "hostkey_verify":false, + "message_renderer":"pyangbind", + "look_for_keys":false, + "allow_agent":false, + "commit_per_rule":true, + "device_params":{ + "name":"default" + }, + "manager_params":{ + "timeout":120 + } + } + } + } + ] + }, + "device_operational_status":2, + "device_drivers":[ + 1 + ], + "device_endpoints":[ + + ] + }, + { + "device_id":{ + "device_uuid":{ + "uuid":"4.4.4.4" + } + }, + "device_type":"packet-router", + "device_config":{ + "config_rules":[ + { + "action":1, + "custom":{ + "resource_key":"_connect/address", + "resource_value":"10.95.90.44" + } + }, + { + "action":1, + "custom":{ + "resource_key":"_connect/port", + "resource_value":"830" + } + }, + { + "action":1, + "custom":{ + "resource_key":"_connect/settings", + "resource_value":{ + "username":"cisco", + "password":"cisco12345", + "vendor":"CISCO", + "force_running":false, + "hostkey_verify":false, + "message_renderer":"pyangbind", + "look_for_keys":false, + "allow_agent":false, + "commit_per_rule":true, + "device_params":{ + "name":"default" + }, + "manager_params":{ + "timeout":120 + } + } + } + } + ] + }, + "device_operational_status":2, + "device_drivers":[ + 1 + ], + "device_endpoints":[ + + ] + }, + { + "device_id":{ + "device_uuid":{ + "uuid":"5.5.5.5" + } + }, + "device_type":"packet-router", + "device_config":{ + "config_rules":[ + { + "action":1, + "custom":{ + "resource_key":"_connect/address", + "resource_value":"10.95.90.45" + } + }, + { + "action":1, + "custom":{ + "resource_key":"_connect/port", + "resource_value":"830" + } + }, + { + "action":1, + "custom":{ + "resource_key":"_connect/settings", + "resource_value":{ + "username":"cisco", + "password":"cisco12345", + "vendor":"CISCO", + "force_running":false, + "hostkey_verify":false, + "message_renderer":"pyangbind", + "look_for_keys":false, + "allow_agent":false, + "commit_per_rule":true, + "device_params":{ + "name":"default" + }, + "manager_params":{ + "timeout":120 + } + } + } + } + ] + }, + "device_operational_status":2, + "device_drivers":[ + 1 + ], + "device_endpoints":[ + + ] + } + ], + "links":[ + { + "link_id":{ + "link_uuid":{ + "uuid":"5.5.5.5/0/0/1-GigabitEthernet0/0/0/1==3.3.3.3/0/0/1-GigabitEthernet0/0/0/1" + } + }, + "link_endpoint_ids":[ + { + "device_id":{ + "device_uuid":{ + "uuid":"5.5.5.5" + } + }, + "endpoint_uuid":{ + "uuid":"0/0/1-GigabitEthernet0/0/0/1" + } + }, + { + "device_id":{ + "device_uuid":{ + "uuid":"3.3.3.3" + } + }, + "endpoint_uuid":{ + "uuid":"0/0/1-GigabitEthernet0/0/0/1" + } + } + ] + }, + { + "link_id":{ + "link_uuid":{ + "uuid":"3.3.3.3/0/0/1-GigabitEthernet0/0/0/1==5.5.5.5/0/0/1-GigabitEthernet0/0/0/1" + } + }, + "link_endpoint_ids":[ + { + "device_id":{ + "device_uuid":{ + "uuid":"3.3.3.3" + } + }, + "endpoint_uuid":{ + "uuid":"0/0/1-GigabitEthernet0/0/0/1" + } + }, + { + "device_id":{ + "device_uuid":{ + "uuid":"5.5.5.5" + } + }, + "endpoint_uuid":{ + "uuid":"0/0/1-GigabitEthernet0/0/0/1" + } + } + ] + }, + { + "link_id":{ + "link_uuid":{ + "uuid":"5.5.5.5/0/0/2-GigabitEthernet0/0/0/2==1.1.1.1/0/0/1-GigabitEthernet0/0/0/1" + } + }, + "link_endpoint_ids":[ + { + "device_id":{ + "device_uuid":{ + "uuid":"5.5.5.5" + } + }, + "endpoint_uuid":{ + "uuid":"0/0/2-GigabitEthernet0/0/0/2" + } + }, + { + "device_id":{ + "device_uuid":{ + "uuid":"1.1.1.1" + } + }, + "endpoint_uuid":{ + "uuid":"0/0/1-GigabitEthernet0/0/0/1" + } + } + ] + }, + { + "link_id":{ + "link_uuid":{ + "uuid":"1.1.1.1/0/0/1-GigabitEthernet0/0/0/1==5.5.5.5/0/0/2-GigabitEthernet0/0/0/2" + } + }, + "link_endpoint_ids":[ + { + "device_id":{ + "device_uuid":{ + "uuid":"1.1.1.1" + } + }, + "endpoint_uuid":{ + "uuid":"0/0/1-GigabitEthernet0/0/0/1" + } + }, + { + "device_id":{ + "device_uuid":{ + "uuid":"5.5.5.5" + } + }, + "endpoint_uuid":{ + "uuid":"0/0/2-GigabitEthernet0/0/0/2" + } + } + ] + }, + { + "link_id":{ + "link_uuid":{ + "uuid":"5.5.5.5/0/0/0-GigabitEthernet0/0/0/0==2.2.2.2/0/0/2-GigabitEthernet0/0/0/2" + } + }, + "link_endpoint_ids":[ + { + "device_id":{ + "device_uuid":{ + "uuid":"5.5.5.5" + } + }, + "endpoint_uuid":{ + "uuid":"0/0/0-GigabitEthernet0/0/0/0" + } + }, + { + "device_id":{ + "device_uuid":{ + "uuid":"2.2.2.2" + } + }, + "endpoint_uuid":{ + "uuid":"0/0/2-GigabitEthernet0/0/0/2" + } + } + ] + }, + { + "link_id":{ + "link_uuid":{ + "uuid":"2.2.2.2/0/0/2-GigabitEthernet0/0/0/2==5.5.5.5/0/0/0-GigabitEthernet0/0/0/0" + } + }, + "link_endpoint_ids":[ + { + "device_id":{ + "device_uuid":{ + "uuid":"2.2.2.2" + } + }, + "endpoint_uuid":{ + "uuid":"0/0/2-GigabitEthernet0/0/0/2" + } + }, + { + "device_id":{ + "device_uuid":{ + "uuid":"5.5.5.5" + } + }, + "endpoint_uuid":{ + "uuid":"0/0/0-GigabitEthernet0/0/0/0" + } + } + ] + }, + { + "link_id":{ + "link_uuid":{ + "uuid":"3.3.3.3/0/0/3-GigabitEthernet0/0/0/3==2.2.2.2/0/0/3-GigabitEthernet0/0/0/3" + } + }, + "link_endpoint_ids":[ + { + "device_id":{ + "device_uuid":{ + "uuid":"3.3.3.3" + } + }, + "endpoint_uuid":{ + "uuid":"0/0/3-GigabitEthernet0/0/0/3" + } + }, + { + "device_id":{ + "device_uuid":{ + "uuid":"2.2.2.2" + } + }, + "endpoint_uuid":{ + "uuid":"0/0/3-GigabitEthernet0/0/0/3" + } + } + ] + }, + { + "link_id":{ + "link_uuid":{ + "uuid":"2.2.2.2/0/0/3-GigabitEthernet0/0/0/3==3.3.3.3/0/0/3-GigabitEthernet0/0/0/3" + } + }, + "link_endpoint_ids":[ + { + "device_id":{ + "device_uuid":{ + "uuid":"2.2.2.2" + } + }, + "endpoint_uuid":{ + "uuid":"0/0/3-GigabitEthernet0/0/0/3" + } + }, + { + "device_id":{ + "device_uuid":{ + "uuid":"3.3.3.3" + } + }, + "endpoint_uuid":{ + "uuid":"0/0/3-GigabitEthernet0/0/0/3" + } + } + ] + }, + { + "link_id":{ + "link_uuid":{ + "uuid":"1.1.1.1/0/0/0-GigabitEthernet0/0/0/0==2.2.2.2/0/0/0-GigabitEthernet0/0/0/0" + } + }, + "link_endpoint_ids":[ + { + "device_id":{ + "device_uuid":{ + "uuid":"1.1.1.1" + } + }, + "endpoint_uuid":{ + "uuid":"0/0/0-GigabitEthernet0/0/0/0" + } + }, + { + "device_id":{ + "device_uuid":{ + "uuid":"2.2.2.2" + } + }, + "endpoint_uuid":{ + "uuid":"0/0/0-GigabitEthernet0/0/0/0" + } + } + ] + }, + { + "link_id":{ + "link_uuid":{ + "uuid":"2.2.2.2/0/0/0-GigabitEthernet0/0/0/0==1.1.1.1/0/0/0-GigabitEthernet0/0/0/0" + } + }, + "link_endpoint_ids":[ + { + "device_id":{ + "device_uuid":{ + "uuid":"2.2.2.2" + } + }, + "endpoint_uuid":{ + "uuid":"0/0/0-GigabitEthernet0/0/0/0" + } + }, + { + "device_id":{ + "device_uuid":{ + "uuid":"1.1.1.1" + } + }, + "endpoint_uuid":{ + "uuid":"0/0/0-GigabitEthernet0/0/0/0" + } + } + ] + }, + { + "link_id":{ + "link_uuid":{ + "uuid":"4.4.4.4/0/0/1-GigabitEthernet0/0/0/1==2.2.2.2/0/0/1-GigabitEthernet0/0/0/1" + } + }, + "link_endpoint_ids":[ + { + "device_id":{ + "device_uuid":{ + "uuid":"4.4.4.4" + } + }, + "endpoint_uuid":{ + "uuid":"0/0/1-GigabitEthernet0/0/0/1" + } + }, + { + "device_id":{ + "device_uuid":{ + "uuid":"2.2.2.2" + } + }, + "endpoint_uuid":{ + "uuid":"0/0/1-GigabitEthernet0/0/0/1" + } + } + ] + }, + { + "link_id":{ + "link_uuid":{ + "uuid":"2.2.2.2/0/0/1-GigabitEthernet0/0/0/1==4.4.4.4/0/0/1-GigabitEthernet0/0/0/1" + } + }, + "link_endpoint_ids":[ + { + "device_id":{ + "device_uuid":{ + "uuid":"2.2.2.2" + } + }, + "endpoint_uuid":{ + "uuid":"0/0/1-GigabitEthernet0/0/0/1" + } + }, + { + "device_id":{ + "device_uuid":{ + "uuid":"4.4.4.4" + } + }, + "endpoint_uuid":{ + "uuid":"0/0/1-GigabitEthernet0/0/0/1" + } + } + ] + } + ] +} \ No newline at end of file diff --git a/src/templates/descriptor-topology.json b/src/templates/descriptor-topology.json new file mode 100644 index 0000000..e22737b --- /dev/null +++ b/src/templates/descriptor-topology.json @@ -0,0 +1,290 @@ +{ + "contexts":[ + { + "context_id":{ + "context_uuid":{ + "uuid":"admin" + } + }, + "topology_ids":[ + + ], + "service_ids":[ + + ] + } + ], + "topologies":[ + { + "topology_id":{ + "context_id":{ + "context_uuid":{ + "uuid":"admin" + } + }, + "topology_uuid":{ + "uuid":"admin" + } + }, + "device_ids":[ + { + "device_uuid":{ + "uuid":"3.3.3.3" + } + }, + { + "device_uuid":{ + "uuid":"4.4.4.4" + } + }, + { + "device_uuid":{ + "uuid":"5.5.5.5" + } + } + ], + "link_ids":[ + { + "link_uuid":{ + "uuid":"5.5.5.5/0/0/1-GigabitEthernet0/0/0/1==3.3.3.3/0/0/1-GigabitEthernet0/0/0/1" + } + }, + { + "link_uuid":{ + "uuid":"3.3.3.3/0/0/1-GigabitEthernet0/0/0/1==5.5.5.5/0/0/1-GigabitEthernet0/0/0/1" + } + } + ] + } + ], + "devices":[ + { + "device_id":{ + "device_uuid":{ + "uuid":"3.3.3.3" + } + }, + "device_type":"packet-router", + "device_config":{ + "config_rules":[ + { + "action":1, + "custom":{ + "resource_key":"_connect/address", + "resource_value":"10.60.125.43" + } + }, + { + "action":1, + "custom":{ + "resource_key":"_connect/port", + "resource_value":"830" + } + }, + { + "action":1, + "custom":{ + "resource_key":"_connect/settings", + "resource_value":{ + "username":"cisco", + "password":"cisco12345", + "vendor":"CISCO", + "force_running":false, + "hostkey_verify":false, + "message_renderer":"pyangbind", + "look_for_keys":false, + "allow_agent":false, + "commit_per_rule":true, + "device_params":{ + "name":"default" + }, + "manager_params":{ + "timeout":120 + } + } + } + } + ] + }, + "device_operational_status":2, + "device_drivers":[ + 1 + ], + "device_endpoints":[ + + ] + }, + { + "device_id":{ + "device_uuid":{ + "uuid":"4.4.4.4" + } + }, + "device_type":"packet-router", + "device_config":{ + "config_rules":[ + { + "action":1, + "custom":{ + "resource_key":"_connect/address", + "resource_value":"10.60.125.44" + } + }, + { + "action":1, + "custom":{ + "resource_key":"_connect/port", + "resource_value":"830" + } + }, + { + "action":1, + "custom":{ + "resource_key":"_connect/settings", + "resource_value":{ + "username":"cisco", + "password":"cisco12345", + "vendor":"CISCO", + "force_running":false, + "hostkey_verify":false, + "message_renderer":"pyangbind", + "look_for_keys":false, + "allow_agent":false, + "commit_per_rule":true, + "device_params":{ + "name":"default" + }, + "manager_params":{ + "timeout":120 + } + } + } + } + ] + }, + "device_operational_status":2, + "device_drivers":[ + 1 + ], + "device_endpoints":[ + + ] + }, + { + "device_id":{ + "device_uuid":{ + "uuid":"5.5.5.5" + } + }, + "device_type":"packet-router", + "device_config":{ + "config_rules":[ + { + "action":1, + "custom":{ + "resource_key":"_connect/address", + "resource_value":"10.60.125.45" + } + }, + { + "action":1, + "custom":{ + "resource_key":"_connect/port", + "resource_value":"830" + } + }, + { + "action":1, + "custom":{ + "resource_key":"_connect/settings", + "resource_value":{ + "username":"cisco", + "password":"cisco12345", + "vendor":"CISCO", + "force_running":false, + "hostkey_verify":false, + "message_renderer":"pyangbind", + "look_for_keys":false, + "allow_agent":false, + "commit_per_rule":true, + "device_params":{ + "name":"default" + }, + "manager_params":{ + "timeout":120 + } + } + } + } + ] + }, + "device_operational_status":2, + "device_drivers":[ + 1 + ], + "device_endpoints":[ + + ] + } + ], + "links":[ + { + "link_id":{ + "link_uuid":{ + "uuid":"5.5.5.5/0/0/1-GigabitEthernet0/0/0/1==3.3.3.3/0/0/1-GigabitEthernet0/0/0/1" + } + }, + "link_endpoint_ids":[ + { + "device_id":{ + "device_uuid":{ + "uuid":"5.5.5.5" + } + }, + "endpoint_uuid":{ + "uuid":"0/0/1-GigabitEthernet0/0/0/1" + } + }, + { + "device_id":{ + "device_uuid":{ + "uuid":"3.3.3.3" + } + }, + "endpoint_uuid":{ + "uuid":"0/0/1-GigabitEthernet0/0/0/1" + } + } + ] + }, + { + "link_id":{ + "link_uuid":{ + "uuid":"3.3.3.3/0/0/1-GigabitEthernet0/0/0/1==5.5.5.5/0/0/1-GigabitEthernet0/0/0/1" + } + }, + "link_endpoint_ids":[ + { + "device_id":{ + "device_uuid":{ + "uuid":"3.3.3.3" + } + }, + "endpoint_uuid":{ + "uuid":"0/0/1-GigabitEthernet0/0/0/1" + } + }, + { + "device_id":{ + "device_uuid":{ + "uuid":"5.5.5.5" + } + }, + "endpoint_uuid":{ + "uuid":"0/0/1-GigabitEthernet0/0/0/1" + } + } + ] + } + ] +} \ No newline at end of file diff --git a/src/templates/descriptor.json b/src/templates/descriptor.json new file mode 100644 index 0000000..4923ab4 --- /dev/null +++ b/src/templates/descriptor.json @@ -0,0 +1,27 @@ +{ + "contexts": [ + { + "context_id": { + "context_uuid": { + "uuid": "admin" + } + }, + "topology_ids": [], + "service_ids": [] + } + ], + "topologies": [ + { + "topology_id": { + "context_id": { + "context_uuid": { + "uuid": "admin" + } + }, + "topology_uuid": { + "uuid": "admin" + } + } + } + ] + } \ No newline at end of file diff --git a/src/templates/ietfL2VPN_template.json b/src/templates/ietfL2VPN_template.json new file mode 100644 index 0000000..79037c2 --- /dev/null +++ b/src/templates/ietfL2VPN_template.json @@ -0,0 +1,38 @@ +{ + "l2vpn": { + "vpn-services": { + "vpn-service": [ + { + "vpn-id": 100, + "name": "VPN_L2_Example", + "vpn-type": "point-to-point", + "site": [ + { + "site-id": 1, + "site-role": "hub", + "site-location": "R4", + "site-network-access": { + "interface": { + "ip-address": "4.4.4.4", + "encapsulation": "ethernet" + } + } + }, + { + "site-id": 2, + "site-role": "spoke", + "site-location": "R5", + "site-network-access": { + "interface": { + "ip-address": "5.5.5.5", + "encapsulation": "ethernet" + } + } + } + ] + } + ] + } + } + } + \ No newline at end of file diff --git a/src/templates/ietfL3VPN_template.json b/src/templates/ietfL3VPN_template.json new file mode 100644 index 0000000..07ffbe9 --- /dev/null +++ b/src/templates/ietfL3VPN_template.json @@ -0,0 +1,184 @@ +{ + "ietf-l3vpn-svc:l3vpn-svc": { + "sites": { + "site": [ + { + "devices": { + "device": [ + { + "device-id": "4.4.4.4", + "location": "router4" + } + ] + }, + "locations": { + "location": [ + { + "location-id": "router4" + } + ] + }, + "management": { + "type": "ietf-l3vpn-svc:provider-managed" + }, + "routing-protocols": { + "routing-protocol": [ + { + "static": { + "cascaded-lan-prefixes": { + "ipv4-lan-prefixes": [ + { + "lan": "4.4.4.4/24", + "lan-tag": "100", + "next-hop": "2.2.2.2" + } + ] + } + }, + "type": "ietf-l3vpn-svc:static" + } + ] + }, + "site-id": "site_router4", + "site-network-accesses": { + "site-network-access": [ + { + "device-reference": "4.4.4.4", + "ip-connection": { + "ipv4": { + "address-allocation-type": "ietf-l3vpn-svc:static-address", + "addresses": { + "customer-address": "2.2.2.2", + "prefix-length": "24", + "provider-address": "4.4.4.4" + } + } + }, + "service": { + "qos": { + "qos-profile": { + "classes": { + "class": [ + { + "bandwidth": { + "guaranteed-bw-percent": 100 + }, + "class-id": "qos-realtime", + "direction": "ietf-l3vpn-svc:both", + "latency": { + "latency-boundary": 20 + } + } + ] + } + } + }, + "svc-input-bandwidth": 5000000000, + "svc-mtu": 1500, + "svc-output-bandwidth": 1000000000 + }, + "site-network-access-type": "ietf-l3vpn-svc:multipoint", + "vpn-attachment": { + "site-role": "ietf-l3vpn-svc:hub-role", + "vpn-id": "vpn-example" + } + } + ] + } + }, + { + "devices": { + "device": [ + { + "device-id": "5.5.5.5", + "location": "router5" + } + ] + }, + "locations": { + "location": [ + { + "location-id": "router5" + } + ] + }, + "management": { + "type": "ietf-l3vpn-svc:provider-managed" + }, + "routing-protocols": { + "routing-protocol": [ + { + "static": { + "cascaded-lan-prefixes": { + "ipv4-lan-prefixes": [ + { + "lan": "5.5.5.5/24", + "lan-tag": "200", + "next-hop": "2.2.2.2" + } + ] + } + }, + "type": "ietf-l3vpn-svc:static" + } + ] + }, + "site-id": "site_router5", + "site-network-accesses": { + "site-network-access": [ + { + "device-reference": "5.5.5.5", + "ip-connection": { + "ipv4": { + "address-allocation-type": "ietf-l3vpn-svc:static-address", + "addresses": { + "customer-address": "2.2.2.2", + "prefix-length": "24", + "provider-address": "5.5.5.5" + } + } + }, + "service": { + "qos": { + "qos-profile": { + "classes": { + "class": [ + { + "bandwidth": { + "guaranteed-bw-percent": 100 + }, + "class-id": "qos-realtime", + "direction": "ietf-l3vpn-svc:both", + "latency": { + "latency-boundary": 10 + } + } + ] + } + } + }, + "svc-input-bandwidth": 1000000000, + "svc-mtu": 1500, + "svc-output-bandwidth": 5000000000 + }, + "site-network-access-type": "ietf-l3vpn-svc:multipoint", + "vpn-attachment": { + "site-role": "ietf-l3vpn-svc:spoke-role", + "vpn-id": "vpn-example" + } + } + ] + } + } + ] + }, + "vpn-services": { + "vpn-service": [ + { + "vpn-id": "vpn-example" + } + ] + } + } + } + \ No newline at end of file diff --git a/src/templates/ietf_template_empty.json b/src/templates/ietf_template_empty.json new file mode 100644 index 0000000..b4fb81f --- /dev/null +++ b/src/templates/ietf_template_empty.json @@ -0,0 +1,178 @@ +{ + "ietf-network-slice-service:network-slice-services":{ + "slo-sle-templates":{ + "slo-sle-template":[ + { + "id":"", + "description":"", + "slo-policy":{ + "metric-bound":[ + { + "metric-type":"one-way-bandwidth", + "metric-unit":"kbps", + "bound":"" + }, + { + "metric-type":"one-way-delay-maximum", + "metric-unit":"milliseconds", + "bound":"" + } + ] + }, + "sle-policy":{ + "security":"", + "isolation":"", + "path-constraints":{ + "service-functions":"", + "diversity":{ + "diversity":{ + "diversity-type":"" + } + } + } + } + } + ] + }, + "slice-service":[ + { + "id":"5GSliceMapping", + "description":"example 5G Slice mapping", + "service-tags":{ + "tag-type":{ + "tag-type":"", + "value":"" + } + }, + "slo-sle-policy":{ + "slo-sle-template":"" + }, + "status":{ + + }, + "sdps":{ + "sdp":[ + { + "id":"01", + "geo-location":"", + "node-id":"", + "sdp-ip-address":"", + "tp-ref":"", + "service-match-criteria":{ + "match-criterion":[ + { + "index":1, + "match-type":"", + "value":[ + + ], + "target-connection-group-id":"" + } + ] + }, + "incoming-qos-policy":"", + "outgoing-qos-policy":"", + "sdp-peering":{ + "peer-sap-id":"", + "protocols":"" + }, + "ac-svc-ref":[ + + ], + "attachment-circuits":{ + "attachment-circuit":[ + { + "id":"100", + "ac-ipv4-address":"", + "ac-ipv4-prefix-length":0, + "sdp-peering":{ + "peer-sap-id":"" + }, + "status":{ + + } + } + ] + }, + "status":{ + + }, + "sdp-monitoring":"" + }, + { + "id":"02", + "geo-location":"", + "node-id":"", + "sdp-ip-address":"", + "tp-ref":"", + "service-match-criteria":{ + "match-criterion":[ + { + "index":1, + "match-type":"", + "value":[ + + ], + "target-connection-group-id":"" + } + ] + }, + "incoming-qos-policy":"", + "outgoing-qos-policy":"", + "sdp-peering":{ + "peer-sap-id":"", + "protocols":"" + }, + "ac-svc-ref":[ + + ], + "attachment-circuits":{ + "attachment-circuit":[ + { + "id":"200", + "ac-ipv4-address":"", + "ac-ipv4-prefix-length":0, + "sdp-peering":{ + "peer-sap-id":"" + }, + "status":{ + + } + } + ] + }, + "status":{ + + }, + "sdp-monitoring":"" + } + ] + }, + "connection-groups":{ + "connection-group":[ + { + "id":"", + "connectivity-type":"ietf-vpn-common:any-to-any", + "connectivity-construct":[ + { + "id":1, + "a2a-sdp":[ + { + "sdp-id":"01" + }, + { + "sdp-id":"02" + } + ] + } + ], + "status":{ + + } + } + ] + } + } + ] + } +} \ No newline at end of file diff --git a/src/templates/ietf_template_example.json b/src/templates/ietf_template_example.json new file mode 100644 index 0000000..8278220 --- /dev/null +++ b/src/templates/ietf_template_example.json @@ -0,0 +1,158 @@ +{ + "ietf-network-slice-service:network-slice-services": { + "slo-sle-templates": { + "slo-sle-template": [ + { + "id": "A", + "description": "", + "slo-policy": { + "metric-bound": [ + { + "metric-type": "one-way-bandwidth", + "metric-unit": "kbps", + "bound": 2 + }, + { + "metric-type": "one-way-delay-maximum", + "metric-unit": "milliseconds", + "bound": 20 + } + ] + }, + "sle-policy": { + "security": "", + "isolation": "", + "path-constraints": { + "service-functions": "", + "diversity": { + "diversity": { + "diversity-type": "" + } + } + } + } + } + ] + }, + "slice-service": [ + { + "id": "slice-service-366e05b7-34e6-4597-9e28-e580abaeda71", + "description": "Transport network slice mapped with 3GPP slice NetworkSlice1", + "service-tags": { + "tag-type": { + "tag-type": "", + "value": "" + } + }, + "slo-sle-policy": { + "slo-sle-template": "A" + }, + "status": {}, + "sdps": { + "sdp": [ + { + "id": "01", + "geo-location": "", + "node-id": "CU-N2", + "sdp-ip-address": "10.60.60.105", + "tp-ref": "", + "service-match-criteria": { + "match-criterion": [ + { + "index": 1, + "match-type": "VLAN", + "value": "100", + "target-connection-group-id": "CU-N2_AMF-N2" + } + ] + }, + "incoming-qos-policy": "", + "outgoing-qos-policy": "", + "sdp-peering": { + "peer-sap-id": "", + "protocols": "" + }, + "ac-svc-ref": [], + "attachment-circuits": { + "attachment-circuit": [ + { + "id": "100", + "ac-ipv4-address": "10.60.60.105", + "ac-ipv4-prefix-length": 0, + "sdp-peering": { + "peer-sap-id": "5.5.5.5" + }, + "status": {} + } + ] + }, + "status": {}, + "sdp-monitoring": "" + }, + { + "id": "02", + "geo-location": "", + "node-id": "AMF-N2", + "sdp-ip-address": "10.60.11.3", + "tp-ref": "", + "service-match-criteria": { + "match-criterion": [ + { + "index": 1, + "match-type": "VLAN", + "value": "100", + "target-connection-group-id": "CU-N2_AMF-N2" + } + ] + }, + "incoming-qos-policy": "", + "outgoing-qos-policy": "", + "sdp-peering": { + "peer-sap-id": "", + "protocols": "" + }, + "ac-svc-ref": [], + "attachment-circuits": { + "attachment-circuit": [ + { + "id": "200", + "ac-ipv4-address": "10.60.11.3", + "ac-ipv4-prefix-length": 0, + "sdp-peering": { + "peer-sap-id": "4.4.4.4" + }, + "status": {} + } + ] + }, + "status": {}, + "sdp-monitoring": "" + } + ] + }, + "connection-groups": { + "connection-group": [ + { + "id": "CU-N2_AMF-N2", + "connectivity-type": "ietf-vpn-common:any-to-any", + "connectivity-construct": [ + { + "id": 1, + "a2a-sdp": [ + { + "sdp-id": "01" + }, + { + "sdp-id": "02" + } + ] + } + ], + "status": {} + } + ] + } + } + ] + } +} \ No newline at end of file diff --git a/src/templates/ietf_template_filled.json b/src/templates/ietf_template_filled.json new file mode 100644 index 0000000..e7a525e --- /dev/null +++ b/src/templates/ietf_template_filled.json @@ -0,0 +1,152 @@ +{ + "ietf-network-slice-service:network-slice-services":{ + "slo-sle-templates":{ + "slo-sle-template":[ + { + "id":"MidhaulId", + "slo-policy":{ + "metric-bound":[ + { + "metric-type":"one-way-bandwidth", + "metric-unit":"kbps", + "bound":300 + }, + { + "metric-type":"one-way-delay-maximum", + "metric-unit":"milliseconds", + "bound":1 + } + ] + }, + "sle-policy":{ + "security":[ + + ], + "isolation":[ + + ], + "steering-constraints":{ + "path-constraints":"", + "service-function":"" + } + } + } + ] + }, + "slice-service":[ + { + "id":"5GSliceMapping", + "description":"example 5G Slice mapping", + "slo-sle-template":"MidhaulId", + "status":{ + + }, + "sdps":{ + "sdp":[ + { + "id":"01", + "node-id":"DU1", + "sdp-ip-address":"1.1.1.2", + "service-match-criteria":{ + "match-criterion":[ + { + "index":1, + "match-type":"vlan-match", + "value":[ + "100" + ], + "target-connection-group-id":"DU-CU" + } + ] + }, + "sdp-peering":{ + "peer-sap-id":"", + "protocols":"" + }, + "ac-svc-name":[ + + ], + "attachment-circuits":{ + "attachment-circuit":[ + { + "id":"100", + "ac-ipv4-address":"1.1.1.1", + "ac-ipv4-prefix-length":0, + "sdp-peering":{ + "peer-sap-id":"1.1.1.254" + }, + "status":{ + + } + } + ] + }, + "status":{ + + } + }, + { + "id":"02", + "node-id":"CU-UP1", + "sdp-ip-address":"100.1.1.2", + "service-match-criteria":{ + "match-criterion":[ + { + "index":1, + "match-type":"vlan-match", + "value":[ + "100" + ], + "target-connection-group-id":"DU-CU" + } + ] + }, + "attachment-circuits":{ + "attachment-circuit":[ + { + "id":"200", + "ac-ipv4-address":"100.1.1.1", + "ac-ipv4-prefix-length":0, + "sdp-peering":{ + "peer-sap-id":"100.1.1.254" + }, + "status":{ + + } + } + ] + }, + "status":{ + + } + } + ] + }, + "connection-groups":{ + "connection-group":[ + { + "id":"DU-CU", + "connectivity-type":"ietf-vpn-common:any-to-any", + "connectivity-construct":[ + { + "id":1, + "a2a-sdp":[ + { + "sdp-id":"01" + }, + { + "sdp-id":"02" + } + ] + } + ], + "status":{ + + } + } + ] + } + } + ] + } +} \ No newline at end of file diff --git a/src/templates/ips.json b/src/templates/ips.json new file mode 100644 index 0000000..c041c4c --- /dev/null +++ b/src/templates/ips.json @@ -0,0 +1,18 @@ +{ + "CU":[ + {"prefix":"100.1.1.2", "node-name":"CU-UP1" }, + {"prefix":"100.1.2.2", "node-name":"CU-UP2" } + ], + "DU":[ + {"prefix":"1.1.1.2", "node-name":"DU1" }, + {"prefix":"1.1.2.2", "node-name":"DU2" }, + {"prefix":"1.1.3.2", "node-name":"DU3" } + ], + "public-prefixes":[ + {"prefix":"10.95.90.125", "node-name":"HL5-2-2" }, + {"prefix":"10.95.90.126", "node-name":"HL5-1-2" }, + {"prefix":"10.95.86.167", "node-name":"HL5-3-2" }, + {"prefix":"10.95.86.107", "node-name":"HL4-1-2" }, + {"prefix":"10.95.90.85", "node-name":"HL4-2-2" } + ] +} diff --git a/src/templates/test_service.json b/src/templates/test_service.json new file mode 100644 index 0000000..bd956b7 --- /dev/null +++ b/src/templates/test_service.json @@ -0,0 +1,93 @@ +{ + "services": [ + { + "service_id": { + "context_id": { + "context_uuid": { + "uuid": "admin" + } + }, + "service_uuid": { + "uuid": "l2-acl-svc-17387469754519430" + } + }, + "service_type": 2, + "service_status": { + "service_status": 1 + }, + "service_endpoint_ids": [ + { + "device_id": { + "device_uuid": { + "uuid": "172.16.185.31" + } + }, + "endpoint_uuid": { + "uuid": "eth-1/0/22" + } + }, + { + "device_id": { + "device_uuid": { + "uuid": "172.16.185.32" + } + }, + "endpoint_uuid": { + "uuid": "eth-1/0/6" + } + } + ], + "service_constraints": [ + { + "custom": { + "constraint_type": "bandwidth[kbps]", + "constraint_value": "20" + } + }, + { + "custom": { + "constraint_type": "latency[ms]", + "constraint_value": "20" + } + } + ], + "service_config": { + "config_rules": [ + { + "action": 1, + "custom": { + "resource_key": "/settings", + "resource_value": {} + } + }, + { + "action": 1, + "custom": { + "resource_key": "/device[172.16.185.31]/endpoint[eth-1/0/22]/settings", + "resource_value": { + "sub_interface_index": 0, + "vlan_id": 100, + "circuit_id": "100", + "remote_router": "172.16.185.32", + "ni_name": "ELAN100" + } + } + }, + { + "action": 1, + "custom": { + "resource_key": "/device[172.16.185.32]/endpoint[eth-1/0/6]/settings", + "resource_value": { + "sub_interface_index": 0, + "vlan_id": 100, + "circuit_id": "100", + "remote_router": "172.16.185.31", + "ni_name": "ELAN100" + } + } + } + ] + } + } + ] + } \ No newline at end of file diff --git a/swagger/models/create_models.py b/swagger/models/create_models.py new file mode 100644 index 0000000..3dac63b --- /dev/null +++ b/swagger/models/create_models.py @@ -0,0 +1,324 @@ +# Copyright 2025 Telefonica Innovación Digital S.L. + +# 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_restx import fields + +def create_gpp_nrm_28541_model(slice_ns): + # 3GPP NRM TS28.541 Data models + logical_interface_info_model = slice_ns.model( + "LogicalInterfaceInfo", + { + "logicalInterfaceType": fields.String( + description="Type of logical interface", example="VLAN" + ), + "logicalInterfaceId": fields.String( + description="Identifier of the logical interface", example="300" + ), + }, + ) + + ep_transport_model = slice_ns.model( + "EpTransport", + { + "IpAddress": fields.String( + description="IP address of the endpoint", example="100.1.1.1" + ), + "logicalInterfaceInfo": fields.Nested( + logical_interface_info_model, description="Logical interface details" + ), + "NextHopInfo": fields.String( + description="Next hop information", example="100.1.1.254" + ), + "qosProfile": fields.String(description="QoS profile", example="5QI100"), + "EpApplicationRef": fields.List( + fields.String, + description="References to associated applications", + example=["EP_F1U CU-UP1"], + ), + }, + ) + + slice_profile_model = slice_ns.model( + "SliceProfile", + { + "sliceProfileId": fields.String( + description="ID of the slice profile", example="TopId" + ), + "pLMNInfoList": fields.Raw( + description="PLMN information list (nullable)", example=None + ), + "TopSliceSubnetProfile": fields.Nested( + slice_ns.model( + "TopSliceSubnetProfile", + { + "dLThptPerSliceSubnet": fields.Nested( + slice_ns.model( + "DLThpt", + { + "GuaThpt": fields.Integer( + description="Guaranteed throughput", example=200 + ), + "MaxThpt": fields.Integer( + description="Maximum throughput", example=400 + ), + }, + ), + description="Downlink throughput details", + ), + "uLThptPerSliceSubnet": fields.Nested( + slice_ns.model( + "ULThpt", + { + "GuaThpt": fields.Integer( + description="Guaranteed throughput", example=200 + ), + "MaxThpt": fields.Integer( + description="Maximum throughput", example=400 + ), + }, + ), + description="Uplink throughput details", + ), + "dLLatency": fields.Integer( + description="Downlink latency", example=20 + ), + "uLLatency": fields.Integer( + description="Uplink latency", example=20 + ), + }, + ), + description="Top slice subnet profile details", + ), + }, + ) + + subnet_model = slice_ns.model( + "Subnet", + { + "operationalState": fields.String( + description="Operational state of the subnet", example="" + ), + "administrativeState": fields.String( + description="Administrative state of the subnet", example="" + ), + "nsInfo": fields.Raw( + description="Network slice information (object)", example={} + ), + "managedFunctionRef": fields.List( + fields.Raw, description="Managed function references", example=[] + ), + "networkSliceSubnetType": fields.String( + description="Type of the subnet", example="TOP_SLICESUBNET" + ), + "SliceProfileList": fields.List( + fields.Nested(slice_profile_model), + description="List of slice profiles for the subnet", + ), + "networkSliceSubnetRef": fields.List( + fields.String, + description="References to other subnets", + example=["CNSliceSubnet1", "RANSliceSubnet1"], + ), + }, + ) + + gpp_network_slice_request_model = slice_ns.model( + "NetworkSliceRequest", + { + "NetworkSlice1": fields.Nested( + subnet_model, + description="Top-level slice details", + ), + "TopSliceSubnet1": fields.Nested( + subnet_model, description="Details of the top slice subnet" + ), + "CNSliceSubnet1": fields.Nested( + subnet_model, description="Details of the CN slice subnet" + ), + "RANSliceSubnet1": fields.Nested( + subnet_model, description="Details of the RAN slice subnet" + ), + "MidhaulSliceSubnet1": fields.Nested( + subnet_model, description="Details of the midhaul slice subnet" + ), + "BackhaulSliceSubnet1": fields.Nested( + subnet_model, description="Details of the backhaul slice subnet" + ), + "EpTransport CU-UP1": fields.Nested( + ep_transport_model, description="Details of the transport endpoint CU-UP1" + ), + "EP_F1U CU-UP1": fields.Nested( + slice_ns.model( + "EPF1U", + { + "localAddress": fields.String( + description="Local address", example="100.1.1.2" + ), + "remoteAddress": fields.String( + description="Remote address", example="1.1.3.2" + ), + "epTransportRef": fields.List( + fields.String, + description="References to transport endpoints", + example=["EpTransport CU-UP1"], + ), + }, + ), + description="Details of the application endpoint F1U", + ), + }, + ) + return gpp_network_slice_request_model + +def create_ietf_network_slice_nbi_yang_model(slice_ns): + # IETF draft-ietf-teas-ietf-network-slice-nbi-yang Data models + slo_policy_model = slice_ns.model('SloPolicy', { + 'metric-bound': fields.List(fields.Nested(slice_ns.model('MetricBound', { + 'metric-type': fields.String(), + 'metric-unit': fields.String(), + 'bound': fields.Integer() + }))) + }) + + sle_policy_model = slice_ns.model('SlePolicy', { + 'security': fields.String(), + 'isolation': fields.String(), + 'path-constraints': fields.Nested(slice_ns.model('PathConstraints', { + 'service-functions': fields.String(), + 'diversity': fields.Nested(slice_ns.model('Diversity', { + 'diversity-type': fields.String() + })) + })) + }) + + slo_sle_template_model = slice_ns.model('SloSleTemplate', { + 'id': fields.String(), + 'description': fields.String(), + 'slo-policy': fields.Nested(slo_policy_model), + 'sle-policy': fields.Nested(sle_policy_model) + }) + + service_match_criteria_model = slice_ns.model('ServiceMatchCriteria', { + 'match-criterion': fields.List(fields.Nested(slice_ns.model('MatchCriterion', { + 'index': fields.Integer(), + 'match-type': fields.String(), + 'value': fields.String(), + 'target-connection-group-id': fields.String() + }))) + }) + + attachment_circuit_model = slice_ns.model('AttachmentCircuit', { + 'id': fields.String(), + 'ac-ipv4-address': fields.String(), + 'ac-ipv4-prefix-length': fields.Integer(), + 'sdp-peering': fields.Nested(slice_ns.model('SdpPeering', { + 'peer-sap-id': fields.String() + })), + 'status': fields.String() + }) + + sdp_model = slice_ns.model('Sdp', { + 'id': fields.String(), + 'geo-location': fields.String(), + 'node-id': fields.String(), + 'sdp-ip-address': fields.String(), + 'tp-ref': fields.String(), + 'service-match-criteria': fields.Nested(service_match_criteria_model), + 'incoming-qos-policy': fields.String(), + 'outgoing-qos-policy': fields.String(), + 'sdp-peering': fields.Nested(slice_ns.model('SdpPeering', { + 'peer-sap-id': fields.String(), + 'protocols': fields.String() + })), + 'ac-svc-ref': fields.List(fields.String()), + 'attachment-circuits': fields.List(fields.Nested(attachment_circuit_model)), + 'status': fields.String(), + 'sdp-monitoring': fields.String() + }) + + connection_group_model = slice_ns.model('ConnectionGroup', { + 'id': fields.String(), + 'connectivity-type': fields.String(), + 'connectivity-construct': fields.List(fields.Nested(slice_ns.model('ConnectivityConstruct', { + 'id': fields.Integer(), + 'a2a-sdp': fields.List(fields.Nested(slice_ns.model('A2ASdp', { + 'sdp-id': fields.String() + }))) + }))), + 'status': fields.String() + }) + + slice_service_model = slice_ns.model('SliceService', { + 'id': fields.String(), + 'description': fields.String(), + 'service-tags': fields.Nested(slice_ns.model('ServiceTags', { + 'tag-type': fields.Nested(slice_ns.model('TagType', { + 'tag-type': fields.String(), + 'value': fields.String() + })) + })), + 'slo-sle-policy': fields.Nested(slice_ns.model('SloSlePolicy', { + 'slo-sle-template': fields.String() + })), + 'status': fields.String(), + 'sdps': fields.Nested(slice_ns.model('Sdps', { + 'sdp': fields.List(fields.Nested(sdp_model)) + })), + 'connection-groups': fields.Nested(slice_ns.model('ConnectionGroups', { + 'connection-group': fields.List(fields.Nested(connection_group_model)) + })) + }) + + ietf_network_slice_request_model = slice_ns.model('NetworkSliceService', { + 'ietf-network-slice-service:network-slice-services': fields.Nested(slice_ns.model('NetworkSliceServices', { + 'slo-sle-templates': fields.Nested(slice_ns.model('SloSleTemplates', { + 'slo-sle-template': fields.List(fields.Nested(slo_sle_template_model)) + })), + 'slice-service': fields.List(fields.Nested(slice_service_model)) + })) + }) + + slice_ddbb_model = slice_ns.model('ddbb_model', { + 'slice_id': fields.String(), + 'intent': fields.List(fields.Nested(ietf_network_slice_request_model)) + }) + + + slice_response_model = slice_ns.model( + "SliceResponse", + { + "status": fields.String(description="Status of the request", example="success"), + "slices": fields.List( + fields.Nested( + slice_ns.model( + "SliceDetails", + { + "id": fields.String(description="Slice ID", example="CU-UP1_DU1"), + "source": fields.String(description="Source IP", example="100.2.1.2"), + "destination": fields.String(description="Destination IP", example="100.1.1.2"), + "vlan": fields.String(description="VLAN ID", example="100"), + "bandwidth(Mbps)": fields.Integer( + description="Bandwidth in Mbps", example=120 + ), + "latency(ms)": fields.Integer( + description="Latency in milliseconds", example=4 + ), + }, + ) + ), + description="List of slices", + ), + }, + ) + return slice_ddbb_model, slice_response_model \ No newline at end of file diff --git a/swagger/slice_namespace.py b/swagger/slice_namespace.py new file mode 100644 index 0000000..6585163 --- /dev/null +++ b/swagger/slice_namespace.py @@ -0,0 +1,126 @@ +# Copyright 2025 Telefonica Innovación Digital S.L. + +# 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 import request +from flask_restx import Namespace, Resource, fields, reqparse +from src.network_slice_controller import NSController +import json +from swagger.models.create_models import create_gpp_nrm_28541_model, create_ietf_network_slice_nbi_yang_model + +slice_ns = Namespace( + "slice", + description="Operations related to transport network slices" +) + +# 3GPP NRM TS28.541 Data models +gpp_network_slice_request_model = create_gpp_nrm_28541_model(slice_ns) + +# IETF draft-ietf-teas-ietf-network-slice-nbi-yang Data models + +slice_ddbb_model, slice_response_model = create_ietf_network_slice_nbi_yang_model(slice_ns) + +upload_parser = reqparse.RequestParser() +upload_parser.add_argument('file', location='files', type='FileStorage', help="Archivo a subir") +upload_parser.add_argument('json_data', location='form', help="Datos JSON en formato string") + +# Namespace Controllers +@slice_ns.route("/") +class SliceList(Resource): + @slice_ns.doc(summary="Return all transport network slices", description="Returns all transport network slices from the slice controller.") + @slice_ns.response(200, "Slices returned", slice_ddbb_model) + @slice_ns.response(404, "Transport network slices not found") + @slice_ns.response(500, "Internal server error") + def get(self): + """Retrieve all slices""" + controller = NSController() + return controller.get_flows() + + @slice_ns.doc(summary="Submit a transport network slice request", description="This endpoint allows clients to submit transport network slice requests using a JSON payload.") + @slice_ns.response(200, "Slice request successfully processed", slice_response_model) + @slice_ns.response(400, "Invalid request format") + @slice_ns.response(500, "Internal server error") + @slice_ns.expect(upload_parser) + def post(self): + """Submit a new slice request with a file""" + + json_data = None + + # Try to get the JSON data from the uploaded file + uploaded_file = request.files.get('file') + if uploaded_file: + if not uploaded_file.filename.endswith('.json'): + return {"error": "Only JSON files allowed"}, 400 + + try: + json_data = json.load(uploaded_file) # Convert file to JSON + except json.JSONDecodeError: + return {"error": "JSON file not valid"}, 400 + + # If no file was uploaded, try to get the JSON data from the form + if json_data is None: + raw_json = request.form.get('json_data') + if raw_json: + try: + json_data = json.loads(raw_json) # Convert string to JSON + except json.JSONDecodeError: + return {"error": "JSON file not valid"}, 400 + + # If no JSON data was found, return an error + if json_data is None: + return {"error": "No data sent"}, 400 + + # Process the JSON data with the NSController + controller = NSController() + return controller.add_flow(json_data) + + @slice_ns.doc(summary="Delete all transport network slices", description="Deletes all transport network slices from the slice controller.") + @slice_ns.response(200, "All transport network slices deleted successfully.") + @slice_ns.response(500, "Internal server error") + def delete(self): + """Delete all slices""" + controller = NSController() + return controller.delete_flows() + + +@slice_ns.route("/<string:slice_id>") +@slice_ns.doc(params={"slice_id": "The ID of the slice to retrieve or modify"}) +class Slice(Resource): + @slice_ns.doc(summary="Return a specific transport network slice", description="Returns specific information related to a slice by providing its id") + @slice_ns.response(200, "Slice returned", slice_ddbb_model) + @slice_ns.response(404, "Transport network slice not found.") + @slice_ns.response(500, "Internal server error") + def get(self, slice_id): + """Retrieve a specific slice""" + controller = NSController() + return controller.get_flows(slice_id) + + @slice_ns.doc(summary="Delete a specific transport network slice", description="Deletes a specific transport network slice from the slice controller based on the provided `slice_id`.") + @slice_ns.response(200, "Transport network slice deleted successfully.") + @slice_ns.response(404, "Transport network slice not found.") + @slice_ns.response(500, "Internal server error") + def delete(self, slice_id): + """Delete a slice""" + controller = NSController() + return controller.delete_flows(slice_id) + + @slice_ns.expect(slice_ddbb_model, validate=True) + @slice_ns.doc(summary="Modify a specific transport network slice", description="Returns a specific slice that has been modified") + @slice_ns.response(200, "Slice modified", slice_ddbb_model) + @slice_ns.response(404, "Transport network slice not found.") + @slice_ns.response(500, "Internal server error") + def put(self, slice_id): + """Modify a slice""" + json_data = request.get_json() + controller = NSController() + return controller.modify_flow(slice_id, json_data) -- GitLab