久しぶりの投稿ですが生きております。
ふと Embulk のプラグインを見よう見まねで作ってみました。
Embulk で転送かけるデータのカラムを指定して *
で置換を行うフィルタープラグインです。
センシティブな情報なのでマスクしたい、がカラムごと削ってしまうと入力有無がわからなくて困る…あるいは JSON の一部分だけ不要なんだけど他は連携する必要がある…などの時に使えるかなと思い作りました。
README にもある通り、例えば
first_name | last_name | gender | age | contact |
---|---|---|---|---|
Benjamin | Bell | male | 30 | bell.benjamin_dummy@example.com |
Lucas | Duncan | male | 20 | lucas.duncan_dummy@example.com |
Elizabeth | May | female | 25 | elizabeth.may_dummy@example.com |
Christian | Reid | male | 15 | christian.reid_dummy@example.com |
Amy | Avery | female | 40 | amy.avercy_dummy@example.com |
というデータを input に食わせた時、
filters: - type: mask columns: - { name: last_name} - { name: age} - { name: contact, pattern: email, length: 5}
という設定を embulk の config に記述しておくと
first_name | last_name | gender | age | contact |
---|---|---|---|---|
Benjamin | **** | male | ** | *****@example.com |
Lucas | ****** | male | ** | *****@example.com |
Elizabeth | *** | female | ** | *****@example.com |
Christian | **** | male | ** | *****@example.com |
Amy | ***** | female | ** | *****@example.com |
このようなデータが output に渡されます。
カラム名を指定しただけの状態では単純に文字数分の *
に置換されますが、例えばlength
オプションで5文字と指定することで一律 *****
とすることも可能です。文字長に意味を持たせたくないときなどによろしいかと思います。
あとは、pattern: email
とするとメールアドレスのドメイン部分(@
以降)は残したままでマスクを行います(デフォルトは pattern: all
の全文字置換)。
JSON 型のサポートもしており、
{ "full_name": { "first_name": "Benjamin", "last_name": "Bell" }, "gender": "male", "age": 30, "email": "test_mail@example.com" }
という構造のデータが入っている user
というカラムがあった時、
filters: - type: mask columns: - { name: user, paths: [{key: $.full_name.first_name}, {key: $.email, pattern: email}]}
などとすると $.full_name.first_name
と $.email
の二つの JSONPath に合致するノードをマスクします。
またこの時、前述の pattern
や length
オプションも個別に指定が可能なので、上記の例の出力は
{ "full_name": { "first_name": "********", "last_name": "Bell" }, "gender": "male", "age": 30, "email": "*********@example.com" }
のようになります。
指定されたカラムの value が文字列以外の型だった場合は一回文字列に変換したものを置換します。例えば [0, 1, 2, 3]
のような配列は *********
になります。
あるいは上の例で $.full_name
などと指定すると
{ "first_name": "Benjamin", "last_name": "Bell" }
の部分が単なる文字列として解釈されてまるっと *
になります。
だいぶ乱暴というか投げやりなのでこの辺は今後直して各ノードの value 部分だけをマスクして
{ "first_name": "********", "last_name": "****" }
などとできるようにしたいところです。
JSONPath については
を内部で使っていますので、そこで解釈できるパスであれば基本的に動作すると思います。
また今回プラグインの作り方、特にテストの書き方や JSON の扱い方などは
や、その中でも題材にされている embulk-filter-expand_json プラグイン
を参考にさせていただきました。ありがとうございました!