てくなべ (tekunabe)

ansible / network automation / 学習メモ

[NetBox] Model のグラフ図を出力する

はじめに

NetBox には Device や Rack などの様々な管理単位のオブジェクトがあります。Django の Model で定義されいるようなので、その Model を図に出力できたら面白いなと思いました。

調べてみると、やり方がありました。

hideharaaws.hatenablog.com

django-extensions というものの機能の一部のようです。

django-extensions.readthedocs.io

早速試してみました。

  • 動作確認環境
    • NetBox 2.8.9 (docker-compose 版)

準備

以下のコンテナのうち、netbox-docker_nginx_1 に入ります。

[root@netbox ~]# docker ps
CONTAINER ID        IMAGE                           COMMAND                  CREATED             STATUS              PORTS                             NAMES
84b25dc18293        nginx:1.17-alpine               "nginx -c /etc/net..."   2 days ago          Up 2 days           80/tcp, 0.0.0.0:32778->8080/tcp   netbox-docker_nginx_1
db4e7e7ead02        netboxcommunity/netbox:latest   "/opt/netbox/docke..."   2 days ago          Up 2 days                                             netbox-docker_netbox_1
dde0687a981e        netboxcommunity/netbox:latest   "python3 /opt/netb..."   2 days ago          Up 2 days                                             netbox-docker_netbox-worker_1
cf6d29e883e9        redis:5-alpine                  "docker-entrypoint..."   2 days ago          Up 2 days           6379/tcp                          netbox-docker_redis-cache_1
dde441168569        redis:5-alpine                  "docker-entrypoint..."   2 days ago          Up 2 days           6379/tcp                          netbox-docker_redis_1
5581bc82df10        postgres:11-alpine              "docker-entrypoint..."   2 days ago          Up 2 days           5432/tcp                          netbox-docker_postgres_1
[root@netbox ~]# docker exec -it --user root netbox-docker_netbox_1 /bin/bash

graphviz と pydotplus、 django-extensions をインストールしておきます。(作業ログが飛んでしまい、少し手順があいまいです。すみません・・・。)

今回使った docker-compose 版の NetBox では /opt/netbox/netboxDjango 的なファイルやディレクトリがあります。

bash-5.0# ls -al
total 16
drwxr-xr-x    1 root     root           156 Oct  1 13:58 .
drwxr-xr-x    1 root     root            20 Aug  6 05:56 ..
drwxr-xr-x    1 root     root            36 Oct  1 13:24 circuits
drwxr-xr-x    1 root     root            50 Oct  1 13:24 dcim
drwxr-xr-x    1 root     root            85 Oct  1 13:24 extras
-rwxr-xr-x    1 root     root           305 Aug  6 05:48 generate_secret_key.py
drwxr-xr-x    1 root     root            36 Oct  1 13:24 ipam
-rwxr-xr-x    1 root     root           249 Aug  6 05:48 manage.py
drwxrwxr-x    4 root     root            56 Oct  1 13:49 media
drwxr-xr-x    1 root     root            44 Oct  1 13:24 netbox
drwxr-xr-x   13 root     root           234 Aug  6 05:48 project-static
drwxr-xr-x    2 root     root            25 Aug  6 05:48 reports
drwxr-xr-x    2 root     root            25 Aug  6 05:48 scripts
drwxr-xr-x    1 root     root            56 Oct  1 13:24 secrets
drwxrwxr-x   19 root     root          4096 Aug  7 13:52 static
drwxr-xr-x   15 root     root          4096 Aug  6 05:48 templates
drwxr-xr-x    1 root     root            36 Oct  1 13:24 tenancy
drwxr-xr-x    1 root     root            36 Oct  1 13:24 users
drwxr-xr-x    1 root     root            45 Oct  1 13:24 utilities
drwxr-xr-x    1 root     root            36 Oct  1 13:24 virtualization

このなかの netbox/setting.pyINSTALLED_APPSdjango_extensions を追記します。

INSTALLED_APPS = [
    'django.contrib.admin',
    // ...(略)...
    'django_extensions'   // 追記
]

図の生成

以下のコマンドで図を生成します。

bash-5.0# pwd
/opt/netbox/netbox
bash-5.0# python manage.py graph_models -a -o myapp_models.png
bash-5.0#

何もエラーが表示されなければ成功です。

今回はこんな図が生成されました。

github.com

おわりに

このまま読むのは厳しいので、できるのであれば出力を制限したいできるといいかもしれません。

おまけ

図ではなく --json とするとJSON になります。

bash-5.0# python manage.py graph_models -a --json
{"created_at": "2020-10-01 14:40", "cli_options": "-a --json", "disable_fields": false, "disable_abstract_fields": false, "use_subgraph": false, "graphs": [{"True": true, "False": false, "None": null, "name": "\"django.contrib.admin\"", "app_name": "django.contrib.admin", "cluster_app_name": "cluster_django_contrib_admin", "models": [{"app_name": "django_contrib_admin_models", "name": "LogEntry", "abstracts": [], "fields": [{"name": "id", "label": "id", "type": "AutoField", "blank": true, "abstract": false, "relation": false, "primary_key": true}, {"name": "content_type", "label": "content_type", "type": "ForeignKey (id)", "blank": true, "abstract": false, "relation": true, "primary_key": false}, {"name": "user", "label": "user", 
...(略)...

graph_models のヘルプ

bash-5.0# python manage.py graph_models --help
usage: manage.py graph_models [-h] [--pygraphviz] [--pydot] [--dot] [--json]
                              [--disable-fields] [--disable-abstract-fields]
                              [--group-models] [--all-applications]
                              [--output OUTPUTFILE] [--layout LAYOUT]
                              [--theme THEME] [--verbose-names]
                              [--language LANGUAGE]
                              [--exclude-columns EXCLUDE_COLUMNS]
                              [--exclude-models EXCLUDE_MODELS]
                              [--include-models INCLUDE_MODELS]
                              [--inheritance] [--no-inheritance]
                              [--hide-relations-from-fields]
                              [--disable-sort-fields] [--hide-edge-labels]
                              [--arrow-shape {box,crow,curve,icurve,diamond,dot,inv,none,normal,tee,vee}]
                              [--version] [-v {0,1,2,3}] [--settings SETTINGS]
                              [--pythonpath PYTHONPATH] [--traceback]
                              [--no-color] [--force-color] [--skip-checks]
                              [app_label [app_label ...]]

Creates a GraphViz dot file for the specified app names. You can pass multiple
app names and they will all be combined into a single model. Output is usually
directed to a dot file.

positional arguments:
  app_label

optional arguments:
  -h, --help            show this help message and exit
  --pygraphviz          Output graph data as image using PyGraphViz.
  --pydot               Output graph data as image using PyDot(Plus).
  --dot                 Output graph data as raw DOT (graph description
                        language) text data.
  --json                Output graph data as JSON
  --disable-fields, -d  Do not show the class member fields
  --disable-abstract-fields
                        Do not show the class member fields that were
                        inherited
  --group-models, -g    Group models together respective to their application
  --all-applications, -a
                        Automatically include all applications from
                        INSTALLED_APPS
  --output OUTPUTFILE, -o OUTPUTFILE
                        Render output file. Type of output dependend on file
                        extensions. Use png or jpg to render graph to image.
  --layout LAYOUT, -l LAYOUT
                        Layout to be used by GraphViz for visualization.
                        Layouts: circo dot fdp neato nop nop1 nop2 twopi
  --theme THEME, -t THEME
                        Theme to use. Supplied are 'original' and
                        'django2018'. You can create your own by creating dot
                        templates in
                        'django_extentions/graph_models/themename/' template
                        directory.
  --verbose-names, -n   Use verbose_name of models and fields
  --language LANGUAGE, -L LANGUAGE
                        Specify language used for verbose_name localization
  --exclude-columns EXCLUDE_COLUMNS, -x EXCLUDE_COLUMNS
                        Exclude specific column(s) from the graph. Can also
                        load exclude list from file.
  --exclude-models EXCLUDE_MODELS, -X EXCLUDE_MODELS
                        Exclude specific model(s) from the graph. Can also
                        load exclude list from file. Wildcards (*) are
                        allowed.
  --include-models INCLUDE_MODELS, -I INCLUDE_MODELS
                        Restrict the graph to specified models. Wildcards (*)
                        are allowed.
  --inheritance, -e     Include inheritance arrows (default)
  --no-inheritance, -E  Do not include inheritance arrows
  --hide-relations-from-fields, -R
                        Do not show relations as fields in the graph.
  --disable-sort-fields, -S
                        Do not sort fields
  --hide-edge-labels    Do not showrelations labels in the graph.
  --arrow-shape {box,crow,curve,icurve,diamond,dot,inv,none,normal,tee,vee}
                        Arrow shape to use for relations. Default is dot.
                        Available shapes: box, crow, curve, icurve, diamond,
                        dot, inv, none, normal, tee, vee.
  --version             show program's version number and exit
  -v {0,1,2,3}, --verbosity {0,1,2,3}
                        Verbosity level; 0=minimal output, 1=normal output,
                        2=verbose output, 3=very verbose output
  --settings SETTINGS   The Python path to a settings module, e.g.
                        "myproject.settings.main". If this isn't provided, the
                        DJANGO_SETTINGS_MODULE environment variable will be
                        used.
  --pythonpath PYTHONPATH
                        A directory to add to the Python path, e.g.
                        "/home/djangoprojects/myproject".
  --traceback           Raise on CommandError exceptions
  --no-color            Don't colorize the command output.
  --force-color         Force colorization of the command output.
  --skip-checks         Skip system checks.
bash-5.0#