public Topology.MPLS.Topology LoadMPLSTopology()
        {
            Topology.MPLS.Topology topology = new Topology.MPLS.Topology();

            foreach (var record in GetMPLSTopology())
            {
                var path = record.Values["p"].As <IPath>();

                Dictionary <long, string> nodeIPv4RouterIdentifiersByDatabaseId = new Dictionary <long, string>();
                Dictionary <long, string> nodePCCByDatabaseId = new Dictionary <long, string>();

                foreach (var node in path.Nodes)
                {
                    string ipv4RouterIdentifier = TryGetNodePropertyAsString(node, "IPv4_Router_Identifier");
                    string pcc = TryGetNodePropertyAsString(node, "PCC");

                    if (!string.IsNullOrWhiteSpace(ipv4RouterIdentifier))
                    {
                        nodeIPv4RouterIdentifiersByDatabaseId.Add(node.Id, ipv4RouterIdentifier);
                        nodePCCByDatabaseId.Add(node.Id, pcc);

                        Topology.Node.Node n = new Topology.Node.Node()
                        {
                            IPv4RouterIdentifier = TryGetNodePropertyAsString(node, "IPv4_Router_Identifier"),
                            PCC = pcc,
                            //NodeName = TryGetNodePropertyAsString(node, "Node_Name"),
                            FirstSeen = TryGetNodeProperty <long>(node, "First_Seen"),
                            //LastEvent = TryGetNodeProperty<long>(node, "Last_Event"),
                            OperationalStatus = true
                        };

                        n.IsPseudonode = false;
                        n.NodeCost     = 1;

                        topology.Update(n);
                    }
                }

                foreach (var lsp in path.Relationships)
                {
                    var symbolicPathName = TryGetRelPropertyAsString(lsp, "Symbolic_Path_Name");

                    if (symbolicPathName.Contains("/"))
                    {
                        var hierarchicalSymbolicPathName = symbolicPathName.Split("/".ToCharArray());

                        Topology.MPLS.HierarchicalLabelSwitchedPath.HierarchicalLabelSwitchedPath parent = new Topology.MPLS.HierarchicalLabelSwitchedPath.HierarchicalLabelSwitchedPath(hierarchicalSymbolicPathName[0])
                        {
                            IPv4TunnelSenderAddress   = nodeIPv4RouterIdentifiersByDatabaseId[lsp.StartNodeId],
                            IPv4TunnelEndpointAddress = nodeIPv4RouterIdentifiersByDatabaseId[lsp.EndNodeId]
                        };

                        topology.Update(parent);

                        Topology.MPLS.LabelSwitchedPath.LabelSwitchedPath child = new Topology.MPLS.LabelSwitchedPath.LabelSwitchedPath(parent.Id)
                        {
                            PCC = nodePCCByDatabaseId[lsp.StartNodeId], // Gets the PCC parameter from the StartNode instead of the LSP property, SHIFT PCEP listener is behind Docker Swarm NAT(PAT).
                            IPv4TunnelSenderAddress          = nodeIPv4RouterIdentifiersByDatabaseId[lsp.StartNodeId],
                            IPv4TunnelEndpointAddress        = nodeIPv4RouterIdentifiersByDatabaseId[lsp.EndNodeId],
                            SymbolicPathName                 = symbolicPathName,
                            TunnelIdentifier                 = TryGetRelPropertyAsString(lsp, "Tunnel_Identifier"),
                            ExtendedTunnelIdentifier         = TryGetRelPropertyAsString(lsp, "Extended_Tunnel_Identifier"),
                            ExtendedTunnelIdentifierTunnelId = TryGetRelPropertyAsString(lsp, "Extended_Tunnel_Identifier_tunnel_id"),
                            LspIdentifier     = TryGetRelPropertyAsString(lsp, "LSP_Identifier"),
                            ReservedBandwidth = TryGetRelProperty <long>(lsp, "Reserved_Bandwidth"),
                            Administrative    = TryGetRelProperty <bool>(lsp, "Administrative"),
                            Delegate          = TryGetRelProperty <bool>(lsp, "Delegate"),
                            Operational       = TryGetRelProperty <bool>(lsp, "Operational"),
                            Remove            = TryGetRelProperty <bool>(lsp, "Remove"),
                            Sync = TryGetRelProperty <bool>(lsp, "Sync"),
                            RecordRouteObject = TryGetRelPropertyAsArray <string>(lsp, "Record_Route_Object"),
                            FirstSeen         = TryGetRelProperty <long>(lsp, "First_Seen"),
                            LastEvent         = TryGetRelProperty <long>(lsp, "Last_Event")
                        };

                        topology.Update(child);
                    }
                    else
                    {
                        Topology.MPLS.LabelSwitchedPath.LabelSwitchedPath l = new Topology.MPLS.LabelSwitchedPath.LabelSwitchedPath(null)
                        {
                            PCC = TryGetRelPropertyAsString(lsp, "PCC"),
                            IPv4TunnelSenderAddress          = nodeIPv4RouterIdentifiersByDatabaseId[lsp.StartNodeId],
                            IPv4TunnelEndpointAddress        = nodeIPv4RouterIdentifiersByDatabaseId[lsp.EndNodeId],
                            SymbolicPathName                 = symbolicPathName,
                            TunnelIdentifier                 = TryGetRelPropertyAsString(lsp, "Tunnel_Identifier"),
                            ExtendedTunnelIdentifier         = TryGetRelPropertyAsString(lsp, "Extended_Tunnel_Identifier"),
                            ExtendedTunnelIdentifierTunnelId = TryGetRelPropertyAsString(lsp, "Extended_Tunnel_Identifier_tunnel_id"),
                            LspIdentifier     = TryGetRelPropertyAsString(lsp, "LSP_Identifier"),
                            ReservedBandwidth = TryGetRelProperty <long>(lsp, "Reserved_Bandwidth"),
                            Administrative    = TryGetRelProperty <bool>(lsp, "Administrative"),
                            Delegate          = TryGetRelProperty <bool>(lsp, "Delegate"),
                            Operational       = TryGetRelProperty <bool>(lsp, "Operational"),
                            Remove            = TryGetRelProperty <bool>(lsp, "Remove"),
                            Sync = TryGetRelProperty <bool>(lsp, "Sync"),
                            RecordRouteObject = TryGetRelPropertyAsArray <string>(lsp, "Record_Route_Object"),
                            FirstSeen         = TryGetRelProperty <long>(lsp, "First_Seen"),
                            LastEvent         = TryGetRelProperty <long>(lsp, "Last_Event")
                        };

                        topology.Update(l);
                    }
                }
            }

            return(topology);
        }
        public static void IntentProcessor(object result, Topology.MPLS.Topology mpls_topology, Topology.IGP.Topology igp_topology,
                                           string controller_uri, string controller_username, string controller_password,
                                           string ansible_tower_uri, string ansible_tower_username, string ansible_tower_password)
        {
            if (result != null)
            {
                if (result.GetType() == typeof(Topology.MPLS.HierarchicalLabelSwitchedPath.HierarchicalLabelSwitchedPath))
                {
                    Topology.MPLS.HierarchicalLabelSwitchedPath.HierarchicalLabelSwitchedPath hlsp =
                        (Topology.MPLS.HierarchicalLabelSwitchedPath.HierarchicalLabelSwitchedPath)result;

                    HLSP_Processor(
                        hlsp,
                        igp_topology, mpls_topology,
                        controller_uri, controller_username, controller_password,
                        ansible_tower_uri, ansible_tower_username, ansible_tower_password
                        );
                }
                else
                {
                    if (result.GetType() == typeof(List <Topology.MPLS.HierarchicalLabelSwitchedPath.HierarchicalLabelSwitchedPath>))
                    {
                        List <Topology.MPLS.HierarchicalLabelSwitchedPath.HierarchicalLabelSwitchedPath> hlsps =
                            (List <Topology.MPLS.HierarchicalLabelSwitchedPath.HierarchicalLabelSwitchedPath>)result;

                        HLSP_Processor(
                            hlsps,
                            igp_topology, mpls_topology,
                            controller_uri, controller_username, controller_password,
                            ansible_tower_uri, ansible_tower_username, ansible_tower_password
                            );
                    }
                }
            }
        }
            public Topology.MPLS.HierarchicalLabelSwitchedPath.HierarchicalLabelSwitchedPath ComputeModel(Topology.MPLS.HierarchicalLabelSwitchedPath.HierarchicalLabelSwitchedPath HierarchicalLabelSwitchedPath)
            {
                var source_node = this.Nodes.Where(n => n.Value.IPv4RouterIdentifier == HierarchicalLabelSwitchedPath.IPv4TunnelSenderAddress).SingleOrDefault();
                var target_node = this.Nodes.Where(n => n.Value.IPv4RouterIdentifier == HierarchicalLabelSwitchedPath.IPv4TunnelEndpointAddress).SingleOrDefault();


                if (source_node.Value != null && target_node.Value != null)
                {
                    Tunnel tunnel = new Tunnel();

                    this.HoffmanPavley.Compute(source_node.Key, target_node.Key);

                    List <Path> computedPaths = new List <Path>();

                    foreach (var path in this.HoffmanPavley.ComputedShortestPaths)
                    {
                        computedPaths.Add(new Path()
                        {
                            Hops = path.Select(h => h.Tag).ToList()
                        });
                    }

                    #region Return Optimisation

                    if (HierarchicalLabelSwitchedPath.Children.Count <= computedPaths.Count)
                    {
                        for (int i = 0; i < HierarchicalLabelSwitchedPath.Children.Count; i++)
                        {
                            // Select only the actual next hops, for point to point and point to multipoint IGP links
                            List <Topology.IGP.Link.Link> actual_next_hops = new List <Topology.IGP.Link.Link>();

                            for (int j = 0; j < computedPaths[i].Hops.Count; j++)
                            {
                                var current_hop             = computedPaths[i].Hops[j];
                                var current_hop_target_node = this.Nodes[current_hop.TargetNode];

                                if (current_hop_target_node.IsPseudonode)
                                {
                                    int k = j + 1;
                                    if (k < computedPaths[i].Hops.Count)
                                    {
                                        var next_hop = computedPaths[i].Hops[k];
                                        actual_next_hops.Add(next_hop);
                                        j++;
                                    }
                                }
                                else
                                {
                                    actual_next_hops.Add(current_hop);
                                }
                            }

                            string[] computedHops = actual_next_hops.Select(h => h.IPv4InterfaceAddress).ToArray();

                            HierarchicalLabelSwitchedPath.Children[i].ComputedExplicitRouteObject = computedHops;
                        }
                    }
                    else
                    {
                        for (int i = 0; i < computedPaths.Count; i++)
                        {
                            // Select only the actual next hops, for point to point and point to multipoint IGP links
                            List <Topology.IGP.Link.Link> actual_next_hops = new List <Topology.IGP.Link.Link>();

                            for (int j = 0; j < computedPaths[i].Hops.Count; j++)
                            {
                                var current_hop             = computedPaths[i].Hops[j];
                                var current_hop_target_node = this.Nodes[current_hop.TargetNode];

                                if (current_hop_target_node.IsPseudonode)
                                {
                                    int k = j + 1;
                                    if (k < computedPaths[i].Hops.Count)
                                    {
                                        var next_hop = computedPaths[i].Hops[k];
                                        actual_next_hops.Add(next_hop);
                                        j++;
                                    }
                                }
                                else
                                {
                                    actual_next_hops.Add(current_hop);
                                }
                            }

                            string[] computedHops = actual_next_hops.Select(h => h.IPv4InterfaceAddress).ToArray();

                            HierarchicalLabelSwitchedPath.Children[i].ComputedExplicitRouteObject = computedHops;
                        }
                    }
                    #endregion
                }

                return(HierarchicalLabelSwitchedPath);
            }
        private static void HLSP_Processor(
            Topology.MPLS.HierarchicalLabelSwitchedPath.HierarchicalLabelSwitchedPath hlsp,
            Topology.IGP.Topology igp_topology, Topology.MPLS.Topology mpls_topology,
            string controller_uri, string controller_username, string controller_password,
            string ansible_tower_uri, string ansible_tower_username, string ansible_tower_password)
        {
            if (string.IsNullOrWhiteSpace(hlsp.PCC))
            {
                hlsp.PCC = hlsp.IPv4TunnelSenderAddress;
            }
            if (string.IsNullOrWhiteSpace(hlsp.AnsibleTowerHost))
            {
                hlsp.AnsibleTowerHost = hlsp.PCC;
            }

            // Check if HLSP needs to be removed from configuration
            if (!hlsp.Delete)
            {
                // SDN Controller API Client
                Controllers.OpenDayLight.Nitrogen.ODLClient nitrogen = new Controllers.OpenDayLight.Nitrogen.ODLClient(controller_uri, controller_username, controller_password);


                // Check if HLSP does not exist or is marked as requiring a config update and launch Ansible Tower job to deploy (or update) base HLSP (including children)
                if ((mpls_topology.HierarchicalLabelSwitchedPaths.Where(h => h.SymbolicPathName == hlsp.SymbolicPathName).Count() == 0 || hlsp.UpdateConfiguration) && hlsp.Configure)
                {
                    // Ansible Tower Client
                    Ansible.TowerClient tc = new Ansible.TowerClient(ansible_tower_uri, ansible_tower_username, ansible_tower_password);

                    var hlsps = new List <Topology.MPLS.HierarchicalLabelSwitchedPath.HierarchicalLabelSwitchedPath>();
                    hlsps.Add(hlsp);

                    dynamic payload = new ExpandoObject();
                    payload.AnsibleTowerHost = hlsp.AnsibleTowerHost;
                    payload.HierarchicalLabelSwitchedPaths = hlsps;

                    var jobId = tc.LaunchJob(hlsp.AnsibleTowerJobTemplateId, payload, hlsp.AnsibleTowerHost);

                    if (jobId != -1)
                    {
                        // Check if job is completed, max 60 times * 5 seconds = 5 min
                        Console.WriteLine("Ansible Tower checking for job {0}.", jobId);
                        var jobCompleted = tc.CheckJobCompleted(jobId);

                        for (int i = 0; i < 60; i++)
                        {
                            Console.WriteLine("Ansible Tower checking for job {0}.", jobId);
                            jobCompleted = tc.CheckJobCompleted(jobId);

                            if (jobCompleted)
                            {
                                Console.WriteLine("Ansible Tower job {0} completed.", jobId);

                                if (tc.CheckJobSuccessful(jobId))
                                {
                                    Console.WriteLine("Ansible Tower job {0} successful.", jobId);

                                    // Update paths through SDN controller
                                    foreach (var lsp in hlsp.Children)
                                    {
                                        if (lsp.Optimise)
                                        {
                                            nitrogen.UpdateLabelSwitchedPath(lsp);
                                        }
                                    }
                                }
                                else
                                {
                                    Console.WriteLine("Ansible Tower job " + jobId + " failed.");
                                }

                                break;
                            }

                            System.Threading.Thread.Sleep(1000 * 5);
                        }

                        if (!jobCompleted)
                        {
                            Console.WriteLine("Timed out checking for Ansible Tower job " + jobId + ". Please check Ansible Tower logs.");
                        }
                    }
                    else
                    {
                        Console.WriteLine("Unable to start Ansible Tower job.");
                    }
                }
                else
                {
                    // Update paths through SDN controller
                    foreach (var lsp in hlsp.Children)
                    {
                        if (lsp.Optimise)
                        {
                            nitrogen.UpdateLabelSwitchedPath(lsp);
                        }
                    }
                }
            }
            else
            {
                if (hlsp.Configure)
                {
                    // Ansible Tower Client
                    Ansible.TowerClient tc = new Ansible.TowerClient(ansible_tower_uri, ansible_tower_username, ansible_tower_password);

                    var hlsps = new List <Topology.MPLS.HierarchicalLabelSwitchedPath.HierarchicalLabelSwitchedPath>();
                    hlsps.Add(hlsp);

                    dynamic payload = new ExpandoObject();
                    payload.AnsibleTowerHost = hlsp.AnsibleTowerHost;
                    payload.HierarchicalLabelSwitchedPaths = hlsps;

                    var jobId = tc.LaunchJob(hlsp.AnsibleTowerJobTemplateId, payload, hlsp.AnsibleTowerHost);

                    if (jobId != -1)
                    {
                        // Check if job is completed, max 60 times * 5 seconds = 5 min
                        Console.WriteLine("Ansible Tower checking for job {0}.", jobId);
                        var jobCompleted = tc.CheckJobCompleted(jobId);

                        for (int i = 0; i < 60; i++)
                        {
                            Console.WriteLine("Ansible Tower checking for job {0}.", jobId);
                            jobCompleted = tc.CheckJobCompleted(jobId);

                            if (jobCompleted)
                            {
                                Console.WriteLine("Ansible Tower job {0} completed.", jobId);

                                if (tc.CheckJobSuccessful(jobId))
                                {
                                    Console.WriteLine("Ansible Tower job {0} successful.", jobId);
                                }
                                else
                                {
                                    Console.WriteLine("Ansible Tower job " + jobId + " failed.");
                                }

                                break;
                            }

                            System.Threading.Thread.Sleep(1000 * 5);
                        }

                        if (!jobCompleted)
                        {
                            Console.WriteLine("Timed out checking for Ansible Tower job " + jobId + ". Please check Ansible Tower logs.");
                        }
                    }
                    else
                    {
                        Console.WriteLine("Unable to start Ansible Tower job.");
                    }
                }
            }
        }
Example #5
0
        public static void ValidatePathsUsingDijkstra(Topology.IGP.Topology igp_topology, Topology.MPLS.HierarchicalLabelSwitchedPath.HierarchicalLabelSwitchedPath hlsp)
        {
            Console.WriteLine("\n====Validating Paths====\n");

            List <yggdrasil2.Topology.Node.Node>     nodes_copy = igp_topology.Nodes.DeepClone();
            List <yggdrasil2.Topology.IGP.Link.Link> links_copy = igp_topology.Links.DeepClone();

            BidirectionalGraph <string, TaggedEdge <string, yggdrasil2.Topology.IGP.Link.Link> > graph =
                new BidirectionalGraph <string, TaggedEdge <string, yggdrasil2.Topology.IGP.Link.Link> >();

            Dictionary <TaggedEdge <string, yggdrasil2.Topology.IGP.Link.Link>, double> cost =
                new Dictionary <TaggedEdge <string, yggdrasil2.Topology.IGP.Link.Link>, double>();


            var start = nodes_copy.Where(n => n.IPv4RouterIdentifier == hlsp.IPv4TunnelSenderAddress).SingleOrDefault();
            var end   = nodes_copy.Where(n => n.IPv4RouterIdentifier == hlsp.IPv4TunnelEndpointAddress).SingleOrDefault();

            if (start != null && end != null)
            {
                foreach (var lsp in hlsp.Children)
                {
                    graph.Clear();

                    foreach (var node in nodes_copy)
                    {
                        graph.AddVertex(node.Id);
                    }

                    if (!start.IsPseudonode)  // it will never be a pseudonode, get rid of this
                    {
                        var nodeLinks = links_copy.Where(l => l.SourceNode == start.Id).ToList();

                        foreach (var l in nodeLinks)
                        {
                            if (!graph.ContainsEdge(l.SourceNode, l.TargetNode))
                            {
                                if (l.OperationalStatus)
                                {
                                    var forwardEdge = new TaggedEdge <string, yggdrasil2.Topology.IGP.Link.Link>(l.SourceNode, l.TargetNode, l);
                                    graph.AddEdge(forwardEdge);
                                    cost.Add(forwardEdge, 1);
                                }
                            }
                        }
                    }

                    foreach (var hop in lsp.ComputedExplicitRouteObject)
                    {
                        var link = links_copy.Where(l => l.IPv4InterfaceAddress == hop).SingleOrDefault();

                        if (link != null)
                        {
                            if (!graph.ContainsEdge(link.SourceNode, link.TargetNode))
                            {
                                if (link.OperationalStatus)
                                {
                                    var backwardEdge = new TaggedEdge <string, yggdrasil2.Topology.IGP.Link.Link>(link.TargetNode, link.SourceNode, link);
                                    graph.AddEdge(backwardEdge);
                                    cost.Add(backwardEdge, 1);
                                }

                                //var srcNode = nodes_copy.Where(n => n.IgpRouterIdentifier == link.SourceNode).SingleOrDefault();
                                var dstNode = nodes_copy.Where(n => n.IgpRouterIdentifier == link.TargetNode).SingleOrDefault();

                                //if (srcNode != null)
                                //{

                                //    if (srcNode.IsPseudonode)
                                //    {
                                //        var nodeLinks = links_copy.Where(l => l.TargetNode == srcNode.Id).ToList();

                                //        foreach (var l in nodeLinks)
                                //        {

                                //            if (!graph.ContainsEdge(l.SourceNode, l.TargetNode))
                                //            {
                                //                if (l.OperationalStatus)
                                //                {
                                //                    var forwardEdge = new TaggedEdge<string, yggdrasil2.Topology.IGP.Link.Link>(l.SourceNode, l.TargetNode, l);
                                //                    graph.AddEdge(forwardEdge);
                                //                    cost.Add(forwardEdge, 1);
                                //                }
                                //            }
                                //        }
                                //    }

                                //}

                                if (dstNode != null)
                                {
                                    if (dstNode.IsPseudonode)
                                    {
                                        var nodeLinks = links_copy.Where(l => l.TargetNode == dstNode.Id).ToList();

                                        foreach (var l in nodeLinks)
                                        {
                                            if (!graph.ContainsEdge(l.SourceNode, l.TargetNode))
                                            {
                                                if (l.OperationalStatus)
                                                {
                                                    var forwardEdge = new TaggedEdge <string, yggdrasil2.Topology.IGP.Link.Link>(l.SourceNode, l.TargetNode, l);
                                                    graph.AddEdge(forwardEdge);
                                                    cost.Add(forwardEdge, 1);
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }

                    DijkstraShortestPathAlgorithm <string, TaggedEdge <string, yggdrasil2.Topology.IGP.Link.Link> > dijkstra =
                        new DijkstraShortestPathAlgorithm <string, TaggedEdge <string, yggdrasil2.Topology.IGP.Link.Link> >(graph,
                                                                                                                            AlgorithmExtensions.GetIndexer <TaggedEdge <string, yggdrasil2.Topology.IGP.Link.Link>, double>(cost));

                    dijkstra.Compute(start.Id);

                    if (dijkstra.Distances.ContainsKey(end.Id) && dijkstra.Distances[end.Id] != double.MaxValue)
                    {
                        lsp.Feasible = true;
                        Console.WriteLine("Path {0} is \u001b[32mFEASIBLE\u001b[0m.\n\t{1} is REACHABLE from {2} in {3} hops (includes pseudonodes).",
                                          lsp.SymbolicPathName, lsp.IPv4TunnelEndpointAddress, lsp.IPv4TunnelSenderAddress, dijkstra.Distances[end.Id]);
                    }
                    else
                    {
                        lsp.Feasible = false;
                        Console.WriteLine("Path {0} is \u001b[31mNOT FEASIBLE\u001b[0m.\n\t{1} is UREACHABLE from {2}.",
                                          lsp.SymbolicPathName, lsp.IPv4TunnelEndpointAddress, lsp.IPv4TunnelSenderAddress);
                    }
                }
            }
        }