# Copyright 2022-2025 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/) # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # http://www.apache.org/licenses/LICENSE-2.0 # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. #This file is an original contribution from Telefonica Innovación Digital S.L. 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)), 'controller': fields.String() }) slice_response_model = slice_ns.model( "SliceResponse", { "success": fields.Boolean(description="Indicates if the request was successful", example=True), "data": fields.Nested( slice_ns.model( "SliceData", { "slices": fields.List( fields.Nested( slice_ns.model( "SliceDetails", { "id": fields.String(description="Slice ID", example="slice-service-11327140-7361-41b3-aa45-e84a7fb40be9"), "source": fields.String(description="Source IP", example="10.60.11.3"), "destination": fields.String(description="Destination IP", example="10.60.60.105"), "vlan": fields.String(description="VLAN ID", example="100"), "requirements": fields.List( fields.Nested( slice_ns.model( "SliceRequirement", { "constraint_type": fields.String(description="Type of constraint", example="one-way-bandwidth[kbps]"), "constraint_value": fields.String(description="Constraint value", example="2000") } ) ), description="List of requirements for the slice" ) } ) ), description="List of slices" ), "setup_time": fields.Float(description="Slice setup time in milliseconds", example=12.57), } ) ), "error": fields.String(description="Error message if request failed", example=None) } ) return slice_ddbb_model, slice_response_model