暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

酷炫的网络拓扑可视化工具NeXt UI - Powered by Cisco

非资深老网工 2021-04-02
4996

题图由 Helena Sushitskaya 在 Pixabay 上发布

---------------------


很久之前我就发现 Cisco SDN 产品的网络拓扑非常漂亮,而且性能极佳,尤其是 Cisco Crosswork Optimization Engine,但不知道是怎么做出来的。最近在 Cisco DevNet 网站上发现一个网络拓扑可视化工具的教程,工具的名字叫做 NeXt UI,非常酷,原来那些拓扑就是用它来实现的。


链接在:

https://developer.cisco.com/site/neXt/


里面有 2 个视频,如果你不能访问油管,我把它们搬过来了。第 1 个是宣传片,很明显这是五年前 OpenDayLight 正如日中天的时候发布的,当时开发的目的是作为 ODL 的一个 App。虽然现在 ODL 日渐式微,但 NeXt UI 在 C 记的 SDN 家族中焕发了新生。



第 2 个是 Demo 视频:



只要去 Cisco 官网注册一个 CCO 账号就可以访问 DevNet 网站。如果不想注册,用 Github 账号也可以。但我个人感觉 Github 上面的 NeXt 教程读起来更舒服一些。网址:


https://github.com/NeXt-UI/next-tutorials


另外,有位俄罗斯的客户写了一个 Blog 介绍 Nornir + NeXt,很详细,推荐各位阅读:


https://habr.com/en/post/534716/


下面是我的笔记,如果您更喜欢读中文,可以用来做参考。但是建议先了解怎样使用 Nornir:


Nornir2 介绍


Nornir3 介绍


-----------------------------------


1. 安装 NeXt


NeXt 是基于 JavaScript 框架开发的,如果要做成 App 对外提供服务,需要完整安装 NeXt 和 JavaScript 环境。macOS 需要使用 bower 或者 npm 来安装 NeXt。


    brew update
    brew install node
    npm install -g bower
    bower install NeXt


    也可以直接使用 npm 安装 NeXt:


      brew update
      brew install node
      npm install next-ui


      如果你已经有 JavaScript 环境,也可以直接从 GitHub 克隆源码,将 CSS/JS/Fonts 等文件夹复制到工作目录。


        git clone https://github.com/NeXt-UI/next-bower.git


        然后新建一个 HTML 文件,写一个 Hello world。注意要根据你的文件存储位置来修改 index.html 里面的相对路径。


          <!DOCTYPE html>
          <html>
          <head>
            <link rel="stylesheet" href="next-bower/css/next.css">
            <script type="text/javascript" src="next-bower/js/next.js"></script>
          </head>
          <body>
          Hello NeXt
          </body>
          </html>


          然后浏览器打开 index.html 验证一下。



          2. 制作一个拓扑


          2.1. NeXt 的文件结构


          我们刚才在工作目录安装 NeXt 生成了 next-bower/ 文件夹,又在工作目录(也是 Web-service 的根目录)创建了 index.html 文件。接下来还需要创建 2 个重要的 JavaScript 文件 app.jsdata.js。我把它们放在 app/ 文件夹里面,当然也可以放到其他目录。


            app/
                app.js
                data.js
            next-bower/
                css/
                fonts/
                js/
            index.html


            其中 data.js 存储拓扑的节点信息和链路信息;app.js 利用 data.js 的数据生成拓扑实例。


            2.2. data.js


            制作拓扑需要我们了解一些 JavaScript 变量和函数的写法,这对于我这种没有编程功底的菜鸟来说蛮挑战的。推荐菜鸟教程,关于 JS 函数的部分。

            https://www.runoob.com/js/js-function-definition.html


            data.js 很简单,就是一个变量。这里我们将这个变量命名为 topologyData,它的值是一个 json 格式的数列。它包含 3 个主 key: nodeslinks,和一个可选的 nodeSet。注意结尾要有一个分号。


              var topologyData = {
              "nodes": [
              {
              "id": 0,
              "name": "Beijing"
              },
              {
              "id": 1,
              "name": "Shanghai"
              },
              {
              "id": 2,
              "name": "Guangzhou"
              }
              ],
              "links": [
              {
              "source": 0,
              "target": 1
              },
              {
              "source": 0,
              "target": 2
              }
              ],
              "nodeSet": [
              {
                    "id"3// 不能和 node ID 重复
              "nodes": [1, 2]
              }
              ]
              };


              nodes 包含 6 个属性,其中:

              • idname 用于标识节点,建议自定义,但需要保证唯一性

              • xy 是坐标,可以不提供,因为 NeXt 支持自动 layout

              • typecolor 用于自定义节点的图标和颜色,可以采用默认的设置



              links 包含 3 个属性,其中:

              • id 用于标识链路,如果自定义,需要保证唯一性,但可以和 node id 重复

              • sourcetarget 用于指定 link 的起始节点。这也是为什么建议自定义 node id 的原因,否则很难对 link 进行交互式的操作



              nodeSet 的作用是把拓扑上的几个节点折叠成一个图标,并且提供展开的按钮,还支持多层折叠。如果看过上面的视频,就会知道我在说什么了。因为折叠不是必须的,所以 nodeSet 也不是必须的。但要注意 nodeSet id 不能和 node id 重复。



              2.3. JavaScript 函数的语法


              JavaScript 支持 2 种函数的定义方式。一种是声明式的函数:


                // JavaScript
                function myFunction(a, b) {
                return a * b;
                }


                上面这段代码等同于:


                  # Python
                  def myFunction(a, b):
                  return a * b


                  另外一种函数定义方式是函数表达式,将函数赋值给一个变量:


                    // JavaScript
                    var x = function (a, b) {return a * b};


                    上面的代码等同于:


                      # Python
                      x = lambda a, b: a * b


                      JavaScript 表达式函数支持自调用,这一点和 Python 很不一样。下面 2 段代码会返回相同的结果(注意第一段代码以分号结尾):


                        // JavaScript
                        (function(a, b){
                        return a * b
                        })(23);


                          # Python
                          x = lambda a, b: a * b
                          x(2, 3)


                          此外,如果在 Python 中,要为一个对象创建一个实例,直接赋值变量即可。但是在 JavaScript 中,必须用 new 关键字来声明这是一个基于 Object 创建的 instance


                          2.4. app.js


                          app.js 稍微复杂一点,并且需要调用若干 NeXt 的 API。API 参考手册在本地

                          ./bower_components/next-bower/doc/index.html,直接用浏览器打开即可。



                          撰写一个基本的 app.js 分为以下几个步骤:


                          1. 定义一个自调用的表达式函数,参数为 nx

                          2. 实例化一个 nx.ui.Application() 类,并赋值给一个变量 A

                          3. 定义一个拓扑配置文件并赋值给一个变量 B

                          4. 利用第 3 步的变量 B,实例化一个 nx.graphic.Topology() 类,并赋值给一个变量 C

                          5. 变量 Cdata.js 中加载拓扑数据(C 本身是一个 instance)

                          6. NeXt 应用实例(变量 A)绑定到拓扑实例(变量 C

                          7. 指定 NeXt 应用实例(变量 A)运行在一个 DOM (Document Object Model) container


                          下面是一个 app.js 的例子:


                            // 1. 定义一个自调用的表达式函数,参数为 nx
                            (function(nx){


                              // 2. 实例化一个 nx.ui.Application() 类,并赋值给一个变量 app
                            var app = new nx.ui.Application();


                            // 3. 定义一个拓扑配置文件并赋值给一个变量 topologyConfig
                            var topologyConfig = {
                            // 指定 nodes 的配置,以 name 作为标签显示在拓扑上,图标是 “router”
                            "nodeConfig": {
                            "label": "model.name",
                            "iconType": "router"


                            },
                            // 指定 links 的配置
                            "linkConfig": {
                            "linkType": "curve"
                            },
                                // true 则显示图标,false 则显示一个点。注意 t 和 f 是小写的,与 Python 不同
                            "showIcon": true,
                                // 自动计算节点的位置,不需要指定 x 和 y 坐标
                            "dataProcessor": "force"


                            };


                              // 4. 利用第 3 步的变量 topologyConfig,实例化一个 nx.graphic.Topology() 类,并赋值给变量 topology
                            var topology = new nx.graphic.Topology(topologyConfig);


                              // 5. 变量 topology 从 data.js 中加载拓扑数据(topology 本身是一个 instance)
                            topology.data(topologyData);


                              // 6. 将 NeXt 应用实例(变量 app)绑定到拓扑实例(变量 topology)
                            topology.attach(app);


                              // 7. 指定 NeXt 应用实例(变量 app)运行在一个 BOM container。ID 是可以自定义的
                            app.container(document.getElementById("topology-container"));


                            })(nx);


                            2.5. 补充 index.html 的 body


                            在 index.html 的 <body></body> 里面要指定 data.jsapp.js 的路径,还有 DOM container 的 ID。注意这个 ID 必须和 app.js 里面定义的相同。


                              <!DOCTYPE html>
                              <html>
                              <head>
                              <title>My first NeXt topology!</title>
                              <link rel="stylesheet" href="next-bower/css/next.css">
                              <script type="text/javascript" src="next-bower/js/next.js"></script>
                              </head>
                              <body>
                              <div id="topology-container"></div>
                              <script type="text/javascript" src="app/data.js"></script>
                              <script type="text/javascript" src="app/app.js"></script>
                              </body>
                              </html>


                              2.6. Done


                              拓扑搞定,打开本地的 index.html 验证:



                              3. 交互式拓扑的思路


                              现在咱们来梳理以下拓扑应用的工作流。在了解 NeXt 的使用方法之后,我们可以发现应用的关键是自动化修改 data.js;而 data.js 的数据来源可以从 LLDP/BGP-LS/PCEP 等协议获取;而 LLDP/BGP-LS/PCEP 的数据则可以利用 Nornir/Ansible 自动化获取。


                              这就是我们下一篇要研究的内容。

                              文章转载自非资深老网工,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

                              评论