redmineでPlantUMLを表示する際にサーバー側で画像を生成させる方法

概要

PlantUMLは便利ですが画像生成をするアプローチに苦慮します。
記述している内容を秘匿する必要がある場合は尚更です。
今回はredmineプラグインplantuml-redmine-macroに手を加えて社内サーバーで画像を生成させ、それをHTTPレスポンスに含めるやり方を説明したいと思います。

やり方

まずはプラグインのご紹介。

bitbucket.org

このままだと公式サーバーの方に情報が流れてしまうので社内サーバーを立てます。
今回もDockerで手軽に立てましょう。docker-hubはこちらになります。
ポート番号などは任意で。

$ docker run -d -p 8000:8080 plantuml/plantuml-server

次にredmineプラグインの設定(管理→プラグイン→PlantUML Macro plugin→設定)から「PlantUML Server URL」の項目に立てたサーバーのURLを設定します。
「適用」ボタンをクリックするのを忘れずに。

設定例
http://192.168.0.200:8000/

さて、ここまでの内容でredmineに下記のような記述でPlantUMLの画像が埋め込まれる仕組みが出来ました。

{{plantuml
    Bob -> Alice : hello
}}

しかし、このままだとHTTPレスポンスにはimgタグが含まれるだけで、クライアント側では改めてPlantUMLサーバー(設定値のURL)に問い合わせる事で画像を手に入れます。
そこでinit.rbの内容を下記のように書き換える事でWEBサーバー側で画像を生成してHTTPレスポンスに含めて返す事ができます。
※設定したURLでredmineサーバーからPlantUMLサーバーへアクセスできる必要があります
※このPlantUMLサーバーへのアクセス経路がプライベートネットワークであれば侵入されない限り漏えいしません

require 'redmine'
require 'uri'
require 'plantuml'
require 'open-uri'
require 'base64'

Redmine::Plugin.register :plantuml_macro do
  name 'PlantUML Macro plugin'
  author 'Denis Nelubin'
  description 'This is a plugin for Redmine to convert PlantUML text into link to the image on PlantUML server'
  version '0.0.1'
  url 'https://bitbucket.org/gelin/plantuml-redmine-macro'
  author_url 'http://google.com/+DenisNelubin'

  settings :default => { 'plantuml_url' => 'http://plantuml.com/plantuml/' },
           :partial => 'settings/plantuml_macro_settings'

  Redmine::WikiFormatting::Macros.register do

    desc "Converts PlantUML text into link to the image on PlantUML server. Example:\n\n" +
         "  {{plantuml\n" +
           "  Bob -> Alice : hello\n" +
           "}}"
    macro :plantuml do |obj, args, text|
      url = URI.join(Setting.plugin_plantuml_macro['plantuml_url'] + '/', 'png/')
      encoded = PlantUML.encode(text)
      base64image = ''
      open(URI.join(url, encoded).to_s) do |file|
         base64image = Base64.strict_encode64(file.read)
      end
      image_tag("data:image/png;base64," + base64image)
    end

  end

end