MySQLのユーザー管理ツールを作った[Mysqlman]

# TL;DR
- Mysqlman っていうMySQLの権限&ユーザー管理ツールを作った
  - [onunu/mysqlman](https://github.com/onunu/mysqlman)
- イケてるし、使いやすいはずだから使ってみてくれ
- gemとして公開しているから `gem install mysqlman`ってやってくれ

# Mysqlman とは
こんにちは、花粉が辛いonunuです。
MySQLのユーザー、権限管理って辛くないですか?
管理ツールの決定版がどうやらないみたいだったので作りました。gemとして配布しています。

- Github: [onunu/mysqlman](https://github.com/onunu/mysqlman)
- RubyGems: [mysqlman](https://rubygems.org/gems/mysqlman)

# 使い方
基本的にはリポジトリのREADMEに書いています。拙い英語で書いているので、読みにくいかもしれません(ごめんなさい)
なので、Qiitaには日本語で記事を書いていきます。

# 初期化
## install
Gemfileに以下を追加するか、

```ruby:Gemfile
gem 'mysqlman'
```

以下のコマンドを実行してください

```shell
$ gem install mysqlman
```

## initialize
まず、初期化を行います。初期化では以下の作業が行われます。

1. 既存ユーザーを管理対象外ユーザーに追加
2. 各種設定ディレクトリの生成

コマンド実行ディレクトリから、`config/manager.yml`を作成し、マネージャーとしてMySQLに接続する設定を書きます。

```yaml:config/manager.yml
---
host: 127.0.0.1
username: root
password: passw0rd
```

マネージャとして使用するユーザーは以下のschema, table, columnへのSELECT権限が必要です。
(もちろん、被管理ユーザーに付与する予定の権限をGRANT OPTION付きで持っている必要があります)

|schema|table|columns|
|:-----|:----|:------|
|mysql | user|User, Host|
|information_schema|USER_PRIVILEGES|PRIVILEGE_TYPE, IS_GRANTABLE|
|information_schema|SCHEMA_PRIVILEGES|PRIVILEGE_TYPE, IS_GRANTABLE, TABLE_SCHEMA|
|information_schema|TABLE_PRIVILEGES|PRIVILEGE_TYPE, IS_GRANTABLE, TABLE_SCHEMA, TABLE_NAME|

初期化を行うためのコマンドは以下です。

```shell
$ mysqlman init
```

実行すると、以下のようにディレクトリとファイルが生成されます。

```
.
├── config
│   └── manager.yml
├── excludes.d
│   └── default.yml
├── roles.d
└── users.d
```

`excludes.d/default.yml`には、管理対象外ユーザーの情報が記載されます。initコマンドを実行した時点で存在するユーザーが記載されるので、管理したいユーザーが記載されている場合、管理したくないユーザーがいる場合などは適宜編集してください。

# 各種設定の書き方
## Role
Roleは権限のまとまりです。後述するユーザーは一つのRoleに基づいて権限を付与されます。
各権限はglobal, schema, tableのレベルで設定します。該当する権限がない場合は書かなくても大丈夫です。

```yaml:roles.d/engineer.yml
---
engineer: # 必須: Roleの名前
  global: # 任意: global権限
    - select
  schema: # 任意: schema権限
    example_schema1: # (schema権限を設定する場合)必須: schemaの名前
      - update
      - insert
    example_schema2:
      - update
  table: # optional: # 任意: table権限
    example_schema1: # (table権限を設定する場合)必須: schemaの名前
      example_table: # (table権限を設定する場合)必須: tableの名前
        - delete
```
### 書き方
権限の文字列は最終的に __大文字に__ 変換され、 `_` は __半角スペースに変換__ されます。

- OK:
  - create user
  - create_user
  - CREATE USER
  - CREATE_USER
- NG:
  - CREATEUSER
  

### 特殊な権限
Roleで設定できる権限について、特殊な権限が2つあります。

- `ALL`
  - 複数の権限のaliasです。レベルによって変化します
  - `ALL`を付与した場合、他の権限(GRANT OPTIONを除く)は評価されません
  - 詳細はこちらを確認してください: [All privs](https://github.com/onunu/mysqlman/blob/master/lib/mysqlman/all_privileges.yml)
- `GRANT OPTION`
  - `ALL`とは別に付与する必要があります
  
`ALL` 不安定なので使わないほうがいいです。

## User
UserはMySQLに接続するアカウントの単位です。username, hostの組で記述しますが、hostは省略可能です。その場合、ワイルドカードである`%`がデフォルト値として設定されます。

```yaml:users.d/engineers.yml
---
engineer: # 必須: roleの名前
  - onunu: # 必須: username
  - application_user:
    host: 10.0.0.1 # 任意: 接続可能IP
```

# 適用
設定が書き終わったら適用します。
適用を行う際、dryrunで実際に変更を行わずに適用される変更を確認することができます。

```bash
$ bundle exec mysqlman dryrun
I, [2018-03-22T21:51:42.899215 #57086]  INFO -- : GRANT DELETE ON test.test TO 'onunu'@'%'
```

確認した結果でよければ`apply`コマンドを実行して変更を確定させます。

```bash
$ bundle exec mysqlman apply
I, [2018-03-22T21:52:42.899215 #57086]  INFO -- : GRANT DELETE ON test.test_accounts TO 'onunu'@'%'
```

# まとめ
以上でmysqlmanの使い方はあらかた書き終えました。まだ至らない箇所あるかと思いますが、より多くの方に使っていただけると嬉しいです。
もし不具合や改善提案等ありましたら、Githubのissueとかに書いてもらえれば順次対応していきます。
よろしくお願いします。