tl;dr
YAMAHA ネットワーク機器の Firmware 更新情報が RSS で配信されていたらいいのになあと思っていたら, 有志の方が RSS を配信するサイト (https://rtxpro.com/) を作られていたので, そのサイトを利用させて頂いて, 対象機器の Firmware が更新されたら Slack に通知する Lambda ファンクションを作りましたので共有させて頂きます.
こんな通知が Slack の指定したチャンネルに通知されます.
作ったもの
リポジトリ
デプロイには serverless framework が必要です.
処理の流れ
以下のような感じで動きます.
使い方
ファイル
リポジトリには以下のファイルが含まれています.
$ tree -L 1 . ├── README.md ├── docs ├── env-dev.yml ├── handler.py ├── node_modules ├── package-lock.json ├── package.json ├── requirements.txt └── serverless.yml 2 directories, 7 files
設定ファイル env-dev.yml の修正
設定ファイルというか, 環境変数を定義した YAML ファイル (env-dev.yml) を環境に応じて修正します.
SLACK_CHANNEL: "#your-slack-channel" SLACK_USERNAME: "YAMAHA Firmware Release Check" SLACK_ICON_EMOJI: ":police_car:" FIRMWARE_RELEASE_URL: "https://rtxpro.com/?feed=rss2" YAMAHA_URL: "http://www.rtpro.yamaha.co.jp/RT/firmware/" SSM_PARAMETER_NAME: "your-ssm-parameter-name" MACHINES: "RTX1200,WLX402,SWX2100" DYNAMODB_TABLE: "yamaha-firmware-notify"
Slack の Incomming Webhook URL を利用するので事前に払い出しておきましょう. また, Incomming Webhook URL は AWS Systems Manager パラメータストアに登録して Lambda から利用します. パラメータストアへのデータ登録は以下のように pstore という拙作のツールを使うと便利だと思います!(さり気なく宣伝)
$ pstore -put -name=your-ssm-parameter-name -value=https://hooks.slack.com/services/XXXXXX/YYYYYYYYYY/ZzZzZzZzZzZzZzZzZzZzZzZz -secure
MACHINES
には利用している YAMAHA ネットワーク機器の機種名を設定します. 以下のように, 複数の機器を対象にする場合には ,
(カンマ区切り) で設定します.
MACHINES: "RTX1200,WLX402,SWX2100"
あとはデプロイ
以下のようにデプロイします.
$ sls deploy --stage=dev
簡単ですね. デプロイ時に DynamoDB のテーブルも一緒に作成されますのでご了承下さい.
CloudWatch Events で定期的 (一日に一回) に https://rtxpro.com/?feed=rss2 をチェックして, MACHINES
に指定された機器の更新通知があれば Slack に通知されます.
メモ
なんで DynamoDB 使っているのか
同じ通知が何度も飛んでしまうことを防ぐ為, 通知済みの更新情報を登録する目的で DynamoDB を利用しています. 以下のようなデータが登録されます.
また, データをテーブルに書き込む際 (put_item
) に DynamoDB の重複排除処理を利用して通知済みかを判断しています. 以下のような処理の流れになるかと思います.
以下, コードの一部です.
def write_table(machine, rev): dynamodb = boto3.client('dynamodb', region_name=region) try: dynamodb.put_item( TableName=dynamodb_table, Item={ 'machine': {'S': machine}, 'revision': {'S': rev} }, Expected={ 'revision': { 'Exists': False } } ) except ClientError as e: if e.response['Error']['Code'] == 'ConditionalCheckFailedException': print('duplicate key') return False else: raise else: return True
条件パラメータとして Expected
を利用していて, 同じ revision
が登録されていた場合, 例外処理として write_table 関数は false
を返すようにしています. 尚, 以下のドキュメントよると Expected
の代替えとして ConditionExpression
を利用するようにと書かれています.
以上
メモでした.
最後になりますが, https://rtxpro.com/ を公開してくださっている管理者の方には大変感謝しております. 有難うございます.