起こったこと
担当プロダクトの本番データをマスクするツールの開発が必要になりました。
なお、私はモバイルエンジニアでiOSのビルドを行うため、使用するPCはMacです。
本番環境は特定のPCからのみ接続可能で、取得したデータはマスクした状態で転送しなければいけません。
本番環境に接続できるPCはWindowsです。
つまり、Macで開発できて、Windowsで起動できる 必要がありました。
また、本番データはXMLやJSON形式で保持しているため、
そういったデータフォーマットを処理できる必要がありました。
まずは、採用技術の検討...
- batファイル...Macで開発できるのか?そもそも使いたくない。
- shell...WSLなら実行できる?でも、XMLやJSONの処理は大変そう
- Electron...XML、JSONを扱える。環境も問わなそう
- PowerShell...Macでも使えるし、Shell Scriptの知識を活かせる
このあたりを検討して、今回は軽量で使いたいこと、ShellScriptの知識を応用できることで
PowerShellを採用することにしました!
やったこと、分かったこと
ツールとしては、PowerShellでXML or JSONを読み込み、特定の項目を「*」で潰す(マスクする)ものです。
以下は、PowerShellを使ってみて、分かったことを備忘録的にまとめています。
XMLをオブジェクトとして読み込める
$xmldoc = [xml]::new()
$xmldoc.Load($targetFilePath)
色々やり方を調べましたが、この方法が一番よさそうでした。
参照: https://qiita.com/mueru/items/c84408f82550d4e8cb2f
読み込んだ後は、こんな感じで参照、編集できます。
# 名前のmask
$xmldoc.Body.PersonalInfo.Name = "** **"
繰り返しや条件分岐もできます。
# 住所のマスク(都道府県、詳細、マンションに分かれていて、詳細とマンションはマスクする)
$ref = $xmldoc.Body.PersonalInfo.Address
foreach ($address in $ref) {
if ($address.detail -ne $null) {
$address.detail = "*"
}
if ($address.mansion -ne $null) {
$address.mansion = "*"
}
}
JSONもオブジェクトとして読み込める
$obj = Get-Content $targetFilePath -Raw | ConvertFrom-Json -AsHashtable
こちらは、読み込んだ後に、JSONに変換→さらにHashTableへの変換を行い、
コード上でオブジェクトのように扱えるようにしています。
こちらもXML読み込みと同じようにオブジェクトの参照、繰り返し処理、条件分岐を使用できました。
デバッグできる
今回、一番驚いたのは、こちらです。
公式ページにある通り、IDEと比較しても見劣らないほどにデバッガーは充実していました。
少なくとも、Shell開発していた時のprintログをほとんど挟まなくて良かったのが助かりました。
また、シェルスクリプトではなく、コマンドラインからでもXMLの読み込みなどを行い、
値の確認ができることはかなり良かったです(気軽に動作確認やデータの確認ができる)
my@mac ~ % pwsh
PowerShell 7.4.1
PS /Users/my> $xmldoc = [xml]::new()
PS /Users/my> $xmldoc.Load("./my.xml")
PS /Users/my> $xmldoc.Body.PersonalInfo.Name
テスト太郎
上記では伝わりにくいですが、「.」を入力すると、使用できるプロパティやメソッドをサジェストしてくれます。
ファイルの出力(作成)
マスクしたデータを最後、マスク後の状態でファイル出力しました。
xml
$maskedFilePath=$targetFilePath.replace(".xml", "_masked.xml")
$xmldoc.Save($maskedFilePath)
json
ConvertTo-Json $obj -Depth 100 | Out-File "./my_masked.json" -Encoding utf8
json の方はDepthを指定しないと、途中の階層がない状態で出力されるのは罠でした..
不満、気になった点
- HashTableを使えるが、参照渡しはやりにくかった
HashTableに直接マスクした状態を保持したかったのですが、
Power Shellの参照渡しの制約が参照渡しするオブジェクトそのものを参照渡しする必要があり、
HashTableで使うのは難しかったです。
(説明が難しい)
- 関数も作れるが、個人的には使いにくかった
関数を作って、処理の構造化・DRYの実現もできるのですが、
スクリプト言語らしく、関数を上に宣言しないといけないことや参照渡しを使いにくいことで、
関数の使用や長い処理を書くには向いていないな...という気持ちになりました。
まとめ
無事、PowerShellをMacで作って、Windowsで実行できました。
今回、初めてPowerShellを使いましたが、非常に機能が豊富で今後ちょっと複雑だけど、
シェルでできるんじゃないか?という処理をするにはPowerShellを使おうと思います!