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

Merge branch 'develop' of https://labs.etsi.org/rep/tfs/controller into develop

parents e9e294e3 19e30211
No related branches found
No related tags found
1 merge request!235Release TeraFlowSDN 3.0
......@@ -14,7 +14,7 @@
import grpc, json, logging
from typing import List, Tuple, Union
from bgpls_speaker.service.tools.DiscoveredDBManager import DiscoveredDBManager, GetContextDevices
from bgpls_speaker.service.tools.DiscoveredDBManager import DiscoveredDBManager, GetContextDevices, getEndpointFromIpInterface
from bgpls_speaker.service.tools.GrpcServer import GrpcServer
from common.method_wrappers.Decorator import MetricsPool, safe_and_metered_rpc_method
from common.proto.context_pb2 import DeviceId, Empty, EndPointId, Link, LinkId, Uuid
......@@ -25,19 +25,6 @@ from common.proto.bgpls_pb2 import (
)
from common.proto.bgpls_pb2_grpc import BgplsServiceServicer
def json_to_list(json_str : str) -> List[Union[str, Tuple[str, str]]]:
try:
data = json.loads(json_str)
except: # pylint: disable=bare-except
return [('item', str(json_str))]
if isinstance(data, dict):
return [('kv', (key, value)) for key, value in data.items()]
elif isinstance(data, list):
return [('item', ', '.join(data))]
else:
return [('item', str(data))]
LOGGER = logging.getLogger(__name__)
METRICS_POOL = MetricsPool('Service', 'RPC')
......@@ -121,12 +108,14 @@ class BgplsServiceServicerImpl(BgplsServiceServicer):
"""
When a node is added to context via bgpls module this function checks if there are other nodes in the
topology connected by links discovered via bgpls. Then, if the link exist adds it to the context.
TODO: get endpoints from pce module
"""
node_name=request.nodeName
node_igp=self.discoveredDB.GetIgpIdFromNodeName(node_name)
LOGGER.debug("(NotifyAddNodeToContext) Find links to nodes ")
nodes_conected=self.discoveredDB.FindConnectedNodes(node_igp)
LOGGER.debug("(NotifyAddNodeToContext) Find links to nodes %s:%s",node_name,node_igp)
# Get nodes connected and links were the igpID appears
nodes_conected, links_local, links_remote=self.discoveredDB.FindConnectedNodes(node_igp)
o=[LOGGER.debug("(NotifyAddNodeToContext) Links local: %s %s",link_local.local_id, link_local.remote_id) for link_local in links_local]
o=[LOGGER.debug("(NotifyAddNodeToContext) Links remote: %s %s",links_remote.local_id,links_remote.remote_id) for links_remote in links_remote]
# Check if nodes are in context
context_client=ContextClient()
context_client.connect()
......@@ -138,55 +127,52 @@ class BgplsServiceServicerImpl(BgplsServiceServicer):
LOGGER.debug("(NotifyAddNodeToContext) nodes_conected_in_context: %s", nodes_conected_in_context)
# TODO: next to function
for remote_node in nodes_conected_in_context:
# TODO: get endpoints connected to remote ip (pce¿)
end_point1="eth-1/0/20"
end_point2="eth-1/0/20"
end_point_uuid1=Uuid(uuid=end_point1)
end_point_uuid2=Uuid(uuid=end_point2)
link_name_src_dest=node_name+"/"+end_point1+"=="+remote_node+"/"+end_point2
LOGGER.info("(NotifyAddNodeToContext) creating link to...: %s", remote_node)
remote_igp=self.discoveredDB.GetIgpIdFromNodeName(remote_node)
# Get source device from name
device_uuid_src=DeviceId(device_uuid=Uuid(uuid=node_name))
device_src=context_client.GetDevice(device_uuid_src)
link_name_dest_src=remote_node+"/"+end_point2+"=="+node_name+"/"+end_point1
# Get destination device from name
device_uuid_dest=DeviceId(device_uuid=Uuid(uuid=remote_node))
device_dest=context_client.GetDevice(device_uuid_dest)
self.getEndpointFromIpInterface(device_src,link.local_ipv4_id)
self.getEndpointFromIpInterface(device_dest,link.remote_ipv4_id)
# LOGGER.debug("(NotifyAddNodeToContext) Source: %s Destination: %s", device_src,device_dest)
end_point_id1=EndPointId(endpoint_uuid=end_point_uuid1,device_id=device_uuid_src)
end_point_id2=EndPointId(endpoint_uuid=end_point_uuid2,device_id=device_uuid_dest)
end_point_ids_src_dest=[end_point_id1,end_point_id2]
end_point_ids_dest_src=[end_point_id2,end_point_id1]
link_id_src=context_client.SetLink(Link(link_id=LinkId(link_uuid=Uuid(uuid=link_name_src_dest)),
link_endpoint_ids=end_point_ids_src_dest))
link_id_dst=context_client.SetLink(Link(link_id=LinkId(link_uuid=Uuid(uuid=link_name_dest_src)),
link_endpoint_ids=end_point_ids_dest_src))
# Here I assume one link will always have same link in other direction
# First direction for link
# Get endpoints associated to link between devices
for link_local in links_local:
LOGGER.debug("(NotifyAddNodeToContext) local: %s %s", link_local.local_id,link_local.remote_id)
LOGGER.debug("(NotifyAddNodeToContext) matches: %s %s", node_igp,remote_igp)
if link_local.local_id == node_igp and link_local.remote_id == remote_igp:
LOGGER.debug("(NotifyAddNodeToContext) local_ipv4_id: %s", link_local.local_ipv4_id)
end_point1,ip_1=getEndpointFromIpInterface(device_src,link_local.local_ipv4_id)
LOGGER.debug("(NotifyAddNodeToContext) end_point1: %s", end_point1)
LOGGER.debug("(NotifyAddNodeToContext) remote_ipv4_id: %s", link_local.remote_ipv4_id)
end_point2,ip_2=getEndpointFromIpInterface(device_dest,link_local.remote_ipv4_id)
LOGGER.debug("(NotifyAddNodeToContext) end_point2: %s", end_point2)
# LOGGER.debug("(NotifyAddNodeToContext) Source: %s Destination: %s", end_point1,end_point2)
link_name_src_dest=node_name+"/"+end_point1+"=="+remote_node+"/"+end_point2
end_point_uuid1=Uuid(uuid=end_point1)
end_point_uuid2=Uuid(uuid=end_point2)
end_point_id1=EndPointId(endpoint_uuid=end_point_uuid1,device_id=device_uuid_src)
link_name_dest_src=remote_node+"/"+end_point2+"=="+node_name+"/"+end_point1
end_point_id2=EndPointId(endpoint_uuid=end_point_uuid2,device_id=device_uuid_dest)
end_point_ids_src_dest=[end_point_id1,end_point_id2]
end_point_ids_dest_src=[end_point_id2,end_point_id1]
link_id_src=context_client.SetLink(Link(link_id=LinkId(link_uuid=Uuid(uuid=link_name_src_dest)),
link_endpoint_ids=end_point_ids_src_dest))
link_id_dst=context_client.SetLink(Link(link_id=LinkId(link_uuid=Uuid(uuid=link_name_dest_src)),
link_endpoint_ids=end_point_ids_dest_src))
LOGGER.debug("(NotifyAddNodeToContext) Link set id src--->dst: %s", link_id_src)
context_client.close()
return Empty()
def getEndpointFromIpInterface(self,device,ipv4):
"""
Get TFS endpoint from interface IPv4.
"""
for config in device.device_config.config_rules:
if config.WhichOneof('config_rule') == 'custom':
for item_type, item in json_to_list(config.custom.resource_value):
if item_type == 'kv':
# LOGGER.debug("(getEndpointFromIpInterface) item: %s",item)
endpoint=item
LOGGER.debug("(getEndpointFromIpInterface) config: %s",config.custom.resource_key)
if "/interface" in config.custom.resource_key:
interface=config.custom.resource_key.split("/interface")[1].strip("[]")
LOGGER.debug("(getEndpointFromIpInterface) interface: %s",interface)
if ipv4 in config.custom.resource_value:
LOGGER.debug("(getEndpointFromIpInterface) value: %s",config.custom.resource_value)
return endpoint
\ No newline at end of file
......@@ -97,16 +97,16 @@ public class grpcClient {
strIgpL=link.getLocalNodeIGPId().toString();
}
String ipv4R;
if(link.getiPv4RouterIDNeighborNodeLATLV()==null)
if(link.getiPv4RouterIDLocalNodeLATLV()==null)
ipv4R="-";
else {
ipv4R=link.getiPv4RouterIDNeighborNodeLATLV();
ipv4R=link.getiPv4RouterIDLocalNodeLATLV();
}
String ipv4L;
if(link.getiPv4RouterIDLocalNodeLATLV()==null)
if(link.getiPv4RouterIDNeighborNodeLATLV()==null)
ipv4L="-";
else {
ipv4L=link.getiPv4RouterIDLocalNodeLATLV();
ipv4L=link.getiPv4RouterIDNeighborNodeLATLV();
}
// Build link for grpc message. need non null values in some cases
......
......@@ -12,7 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
from typing import List
from typing import List, Tuple, Union
from bgpls_speaker.service.tools.Tools import UpdateRequest,NodeInfo,LinkInfo
from common.proto.bgpls_pb2 import NodeDescriptors
from common.proto.context_pb2 import ContextId, ContextList,Topology,TopologyId,Device,DeviceDriverEnum,ContextId,Empty, TopologyList
......@@ -20,9 +20,22 @@ from common.Constants import DEFAULT_CONTEXT_NAME
from common.tools.object_factory.Context import json_context_id
from context.client.ContextClient import ContextClient
import logging
import logging,json
LOGGER = logging.getLogger(__name__)
def json_to_list(json_str : str) -> List[Union[str, Tuple[str, str]]]:
try:
data = json.loads(json_str)
except: # pylint: disable=bare-except
return [('item', str(json_str))]
if isinstance(data, dict):
return [('kv', (key, value)) for key, value in data.items()]
elif isinstance(data, list):
return [('item', ', '.join(data))]
else:
return [('item', str(data))]
class DiscoveredDBManager:
def __init__(self):
self.discoveredDB=[]
......@@ -37,15 +50,16 @@ class DiscoveredDBManager:
# Check if node info message
if(self.checkIfNodeInUpdate(update_request)):
# Check if node exists
to_add=True
node_count=len(update_request.nodes)
for node in update_request.nodes:
if(self.CheckIfNodeNameInDb(node) or CheckIfNodeInContext(node.node_name)):
# Replace info from node if exists
LOGGER.debug("(AddToDB) Node already in DB!!!")
to_add=False
update_request.nodes.remove(node)
node_count=node_count-1
else:
LOGGER.debug("(AddToDB) Node NOT in DB!!!")
if(to_add):
if(node_count>0):
self.discoveredDB.append(update_request)
else:
# is a link
......@@ -127,7 +141,9 @@ class DiscoveredDBManager:
Return the IGP ID given a node name if exists in the discoveredDB.
"""
for update in self.discoveredDB:
LOGGER.debug("(GetIgpIdFromNodeName)checking update: %s",update.toString())
for node in update.nodes:
LOGGER.debug("(GetIgpIdFromNodeName)checking nodes: %s",node.node_name)
if(node.node_name==name):
return node.igp_id
return None
......@@ -165,6 +181,8 @@ class DiscoveredDBManager:
# find links where the node appears
links_to_node=[]
nodes_conected=[]
link_local=[]
link_remote=[]
for update in self.discoveredDB:
for link in update.links:
LOGGER.debug("(FindConnectedNodes) link in up:%s %s",
......@@ -173,14 +191,16 @@ class DiscoveredDBManager:
if(link.local_id == new_node):
links_to_node.append(link)
nodes_conected.append(link.remote.node_name)
link_local.append(link)
if(link.remote_id == new_node):
links_to_node.append(link)
nodes_conected.append(link.local.node_name)
link_remote.append(link)
if(nodes_conected):
LOGGER.debug("(FindConnectedNodes) links to local node:%s",new_node)
LOGGER.debug("(FindConnectedNodes) %s", nodes_conected)
return nodes_conected
return nodes_conected, link_local, link_remote
LOGGER.debug("(FindConnectedNodes) NO LINKS TO OTHER NODES")
return None
......@@ -263,3 +283,36 @@ def CheckIfNodeInContext(node_name) -> bool:
return True
LOGGER.info("(CheckIfNodeInContext) Node NOT in context")
return False
def getEndpointFromIpInterface(device,ipv4):
"""
Get TFS endpoint uuid drom given device having the IPv4 interface.
"""
for config in device.device_config.config_rules:
if config.WhichOneof('config_rule') == 'custom':
# for item_type, item in json_to_list(config.custom.resource_value):
# if item_type == 'kv':
# # LOGGER.debug("(getEndpointFromIpInterface) item: %s",item)
# endpoint_item=item
# LOGGER.debug("(getEndpointFromIpInterface) config: %s",config.custom.resource_key)
if "/interface" in config.custom.resource_key:
iface=config.custom.resource_key.split("/interface")[1].strip("[]")
LOGGER.debug("(getEndpointFromIpInterface) interface: %s",iface)
if ipv4 in config.custom.resource_value:
LOGGER.debug("(getEndpointFromIpInterface) value: %s",config.custom.resource_value)
resource_dict=json.loads(config.custom.resource_value)
interface = resource_dict['name']
resource_ip=resource_dict['address_ip']
# Search for endpoint uuid assigned to interface
for config in device.device_config.config_rules:
if config.WhichOneof('config_rule') == 'custom':
if "/endpoints/endpoint" in config.custom.resource_key:
key=config.custom.resource_key.split("/endpoints/endpoint")[1].strip("[]")
LOGGER.debug("(getEndpointFromIpInterface) key: %s",key)
if interface in key:
LOGGER.debug("(getEndpointFromIpInterface) value: %s",config.custom.resource_value)
endpoint=config.custom.resource_key.split("/endpoints/endpoint")[1].strip("[]")
resource_dict_endpoint=json.loads(config.custom.resource_value)
return resource_dict_endpoint['uuid'],resource_ip
return None,ipv4
\ No newline at end of file
......@@ -47,12 +47,13 @@ class UpdateRequest:
)
def toString(self):
# Debug purposes
out = ""
out = " "
out+=self.address_family_id
out+=self.next_hop
out+=self.as_path_segment
for node in self.nodes:
out+="name"
out+=node.node_name
out+=node.igp_id
out+=str(node.bgpls_id)
......@@ -84,7 +85,15 @@ class NodeInfo:
self.bgpls_id = bgpls_id.strip("/")
self.as_id = as_id
self.learnt_from=learnt_from
def toString(self):
# Debug purposes
out = "name"
out+=self.node_name
out+=self.igp_id
out+=str(self.bgpls_id)
out+=str(self.as_id)
out+=self.learnt_from
@classmethod
def from_proto(cls, proto_node):
return cls(
......
......@@ -77,7 +77,7 @@
</tr>
{% endif %}
</tbody>
<tbody>
<!-- <tbody>
{% if dislink %}
{% for link in dislink %}
<tr>
......@@ -100,7 +100,7 @@
<td colspan="3">No devices found</td>
</tr>
{% endif %}
</tbody>
</tbody> -->
</table>
<script src="https://d3js.org/d3.v4.min.js"></script>
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment