SSIDとパスワードを生成し、QRコードにして Slack にぶん投げる。

# ゲスト用無線 LAN の SSID とパスワードの更新作業を自動化したい
ゲスト用無線 LAN 設定の更新作業が面倒なため、この作業を自動化しようと思います。

## できること
 - スクリプトを実行すると Slack へ 無線 LAN の設定情報が載った QR コードが発行される
 - slack に発行された QR コードを iPhone や Android 端末で読み取ると無線 LAN の接続を提案する

画像で言うなら、これができるようにします。
<img width="375" alt="写真 2020-01-01 17 49 24.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/54900/4d6ff7d8-8ac2-5e86-8303-daee0f602833.png">

## 仕組みの概要
0. SSIDとパスワードを生成する
1. 生成された情報をQRコードの画像にする
2. SSIDとパスワードの情報を画像にする
3. 上記の内容を Slack にぶん投げる

## 環境
 - CentOS Linux release 7.7.1908 (Core)
 - Python 3.6.8

## 実装
[Github に書いたコードを参照ください](https://github.com/nlog2n2/rice_cooker/blob/master/rice_cooker.py)

## 使ってみる
### Slack の設定（Tokenが取得できればOK）
0. slack で app を選択し bot を追加する
![スクリーンショット 2020-01-01 13.56.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/54900/6c90fc0c-7653-d597-e4fc-d05545c8b9e5.png)
![スクリーンショット 2020-01-01 13.56.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/54900/a4a5a37a-993c-93c7-a6f6-2a0cd706af9c.png)

0. bot に名前を設定する
![スクリーンショット 2020-01-01 13.58.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/54900/ed11230a-8f9e-5211-5860-db2879883116.png)

2. bot に対する Token を取得する（このトークンは後で設定します）
![スクリーンショット 2020-01-01 13.58.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/54900/bc6fe5b6-df56-d2a6-9365-c0edb8e2cb2e.png)

### python のコードに設定
```python:rice_cooker.py(8行目～13行目)
# Please Write Your Wi-Fi Setting & Slack Token & Font Path
CONPANY_NAME        = 'GUEST'
ENCRYPTION_METHOD   = 'WPA'
SLACK_TOKEN         = ''
SLACK_CHANNEL       = 'freewifi-dev'
FONT_PATH           = '/usr/share/fonts/dejavu/DejaVuSans.ttf'
```

下記の項目を入力します。

- 設定項目
    - CONPANY_NAME        = 'SSID の先頭の文字列を入力します'
    - ENCRYPTION_METHOD   = '無線 LAN の暗号化方式を入力します'
    - SLACK_TOKEN         = 'QRコードを投下する Slack に投下するためのトークンを入力します'
    - SLACK_CHANNEL       = 'QRコードを投下する Slack のチャンネルを指定します'
    - FONT_PATH           = 'CentOS 上にあるフォントの位置を指定します'

### Slack へ QR コードの投下と確認
0. python3 rice_cooker.py で実行する
![スクリーンショット 2020-01-01 15.21.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/54900/0c30e774-6405-e2f4-f7fd-435ea28c8870.png)

0. slack で QR コード、SSID、パスワードを確認する
![スクリーンショット 2020-01-01 15.22.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/54900/b84c49d0-4163-7ba4-e469-52bf2d64eca4.png)

### iOS から Wi-Fi 接続
0. iPhone を立ち上げて、 QR コードを読み取る
<img width="375" alt="写真 2020-01-01 17 44 50.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/54900/dcc69535-82c3-22ad-44b7-40dfb08b2f12.png">

0. ネットワークに接続することを促されるので、接続をタップする
<img width="375" alt="写真 2020-01-01 17 49 24.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/54900/4d6ff7d8-8ac2-5e86-8303-daee0f602833.png">

0. 無線 LAN に接続されていることを確認する
<img width="375" alt="写真 2020-01-01 16 08 08.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/54900/34861194-8db6-7709-9137-a29a4f33cf8c.png">

無事、接続されました！

## ネットワーク設定自動化について
本来は、この処理の後に、 SSH で AP に接続し、無線 LAN の設定(SSID,Password)を追加および削除するコードが入っていました。
Ansible か Netmiko で実装しようかと思いましたが、使っていた無線 LAN の端末が Aruba製品 で、それらが使えず Python の expect で対応しました。
モチベーションが残っていれば expect でのネットワーク設定自動化についても書いていこうかと思います。

## ハマる点
 - Pillow の Image.width は正しく処理されないことがあり、 Image.size[0]　に処理を入れ替えてお茶を濁しました。

## 参考
- パスワード作成の参考
    - [python でテキトーにパスワード生成](https://qiita.com/soundkitchen/items/bec5ba87d92457543823)
- QR コードの発行
    - [Python, Pillow, qrcodeでQRコード画像を生成、保存](https://note.nkmk.me/python-pillow-qrcode/)
- 画像の生成、結合
    - [Python, Pillowで画像の上下左右に余白を追加しサイズ変更](https://note.nkmk.me/python-pillow-add-margin-expand-canvas/)
    - [Python, Pillowで画像に別の画像を貼り付けるpaste](https://note.nkmk.me/python-pillow-paste/)
    - [Pythonで画像を編集したり、文字を入れたりする](https://qiita.com/xKxAxKx/items/2599006005098dc2e299)
    - [Pythonの画像処理ライブラリPillow(PIL)の使い方](https://note.nkmk.me/python-pillow-basic/)
- slack への通知機能
    - [PythonでSlackに画像をアップロードする方法](https://qiita.com/tottu22/items/594e8c506ece0f8cc87c)
    - [Docs » Reference » Image Module](https://pillow.readthedocs.io/en/3.1.x/reference/Image.html)
    - [slack - api chat.postMessage](https://api.slack.com/methods/chat.postMessage)
    - [slack - api files.upload](https://api.slack.com/methods/files.upload)