Based on @kthare10 code add to FIM sliver diff methods that can be used in the Broker, which doesn't have access to ASM and can't use its diff method.
#!/usr/bin/env python3
from fabric_mb.message_bus.messages.abc_message_avro import AbcMessageAvro
from fim.slivers.base_sliver import BaseSliver
from fim.slivers.network_node import NodeSliver
from fim.slivers.network_service import NetworkServiceSliver
from fim.user import ComponentType
from fim.user.topology import TopologyDiff, TopologyDiffTuple
from fabric_cf.actor.security.pdp_auth import ActionId
def sliver_to_str(*, sliver: BaseSliver):
if isinstance(sliver, NodeSliver):
return node_sliver_to_str(sliver=sliver)
if isinstance(sliver, NetworkServiceSliver):
return ns_sliver_to_str(sliver=sliver)
def dict_diff(dict_a, dict_b, show_value_diff=False):
result = {'added': {k: dict_b[k] for k in set(dict_b) - set(dict_a)},
'removed': {k: dict_a[k] for k in set(dict_a) - set(dict_b)}}
if show_value_diff:
common_keys = set(dict_a) & set(dict_b)
result['value_diffs'] = {
k: (dict_a[k], dict_b[k])
for k in common_keys
if dict_a[k] != dict_b[k]
}
return result
def sliver_diff(*, sliver1: BaseSliver, sliver2: BaseSliver) -> TopologyDiff or None:
if isinstance(sliver1, NodeSliver) and isinstance(sliver2, NodeSliver):
return node_sliver_diff(sliver1=sliver1, sliver2=sliver2)
elif isinstance(sliver1, NetworkServiceSliver) and isinstance(sliver2, NetworkServiceSliver):
return ns_sliver_diff(sliver1=sliver1, sliver2=sliver2)
else:
raise Exception("Incorrect Instance type")
def node_sliver_diff(*, sliver1: NodeSliver, sliver2: NodeSliver) -> TopologyDiff or None:
if sliver1 is not None and sliver2 is not None:
comp_added = set()
comp_removed = set()
ns_added = set()
ns_removed = set()
if sliver1.attached_components_info is not None and sliver2.attached_components_info is not None:
diff_comps = dict_diff(sliver1.attached_components_info.devices,
sliver2.attached_components_info.devices)
comp_added = set(diff_comps['added'].keys())
comp_removed = set(diff_comps['removed'].keys())
if sliver1.attached_components_info is None and sliver2.attached_components_info is not None:
comp_added = set(sliver2.attached_components_info.devices.keys())
if sliver1.attached_components_info is not None and sliver2.attached_components_info is None:
comp_removed = set(sliver1.attached_components_info.devices.keys())
if sliver1.network_service_info is not None and sliver2.network_service_info is not None:
diff_ns = dict_diff(sliver1.network_service_info.services,
sliver2.network_service_info.services)
ns_added = set(diff_ns['added'].keys())
ns_removed = set(diff_ns['removed'].keys())
if sliver1.network_service_info is None and sliver2.network_service_info is not None:
ns_added = set(sliver2.network_service_info.services.keys())
if sliver1.network_service_info is not None and sliver2.network_service_info is None:
ns_removed = set(sliver1.network_service_info.services.keys())
if len(comp_added) > 0 or len(comp_removed) > 0 or len(ns_removed) > 0 or len(ns_added) > 0:
return TopologyDiff(added=TopologyDiffTuple(components=comp_added, services=ns_added, interfaces=set(),
nodes=set()),
removed=TopologyDiffTuple(components=comp_removed, services=ns_removed,
interfaces=set(), nodes=set()))
return None
def ns_sliver_diff(*, sliver1: NetworkServiceSliver, sliver2: NetworkServiceSliver) -> TopologyDiff or None:
if sliver1 is not None and sliver2 is not None:
ifs_added = set()
ifs_removed = set()
if sliver1.interface_info is not None and sliver2.interface_info is not None:
diff_comps = dict_diff(sliver1.interface_info.interfaces,
sliver2.interface_info.interfaces)
ifs_added = set(diff_comps['added'].keys())
ifs_removed = set(diff_comps['removed'].keys())
if sliver1.interface_info is None and sliver2.interface_info is not None:
ifs_added = set(sliver2.interface_info.interfaces.keys())
if sliver1.interface_info is not None and sliver2.interface_info is None:
ifs_removed = set(sliver1.interface_info.interfaces.keys())
if len(ifs_added) > 0 or len(ifs_removed) > 0:
return TopologyDiff(added=TopologyDiffTuple(components=set(), services=set(), interfaces=ifs_added,
nodes=set()),
removed=TopologyDiffTuple(components=set(), services=set(),
interfaces=ifs_removed, nodes=set()))
return None
def node_sliver_to_str(*, sliver: NodeSliver):
result = str(sliver)
nic_types = [ComponentType.SharedNIC, ComponentType.SmartNIC]
if sliver.attached_components_info is not None:
for c in sliver.attached_components_info.devices.values():
result += f"\nComponent: {c}"
if c.get_type() not in nic_types:
continue
if c.network_service_info is not None and c.network_service_info.network_services is not None:
for ns in c.network_service_info.network_services.values():
result += f"\nNS: {ns}"
if ns.interface_info is not None and ns.interface_info.interfaces is not None:
for i in ns.interface_info.interfaces.values():
result += f"\nIFS: {i}"
return result
def ns_sliver_to_str(*, sliver: NetworkServiceSliver):
result = str(sliver)
for interface in sliver.interface_info.interfaces.values():
result += f"\nIFS: {interface}"
return result
```
Based on @kthare10 code add to FIM sliver diff methods that can be used in the Broker, which doesn't have access to ASM and can't use its diff method.