概要
現在私はvCenterなどの証明書の期限をNextCloudのカレンダー上で現在管理しています。
ただし、都度手動で追加の運用をしていますが、中々手間な部分もあります。
そこで今回はNextCloudのカレンダーを操作できるCalDAVがあるのでそれを利用して自動化してみようと思います。
本記事の対象
- NextCloudのカレンダー操作をプログラムから実行したい方
構成する環境
今回は以下のようなイメージを構成してみます。
NextCloudのカレンダーを操作するためのAPIをFlaskで構成してDocker上で常に動作させておきます。
そして証明書を取得してAPIに登録処理を促すスクリプトをコンテナとしてCronで都度起動させる形にします。
なお今回はある程度汎用性を持たせるように、APIやスクリプトの中身は作成しています。
実施順番
以下順番で実施していきます。
- NextCloudのカレンダー操作用APIの作成
- Docker上でAPIを起動
- API呼び出し用Python スクリプトの作成
- Cronの設定
カレンダー操作用APIの作成
まず対象のカレンダーの仕組みを確認します。
NextCloudではカレンダーにイベントとして以下画像のようにスケジュールが登録されます。
上記のイベントの情報はWebDAVでは以下のようなiCalendarフォーマットとして扱われます。
BEGIN:VCALENDAR
CALSCALE:GREGORIAN
VERSION:2.0
PRODID:-//IDN nextcloud.com//Calendar app 5.0.0//EN
BEGIN:VEVENT
CREATED:20241002T124846Z
DTSTAMP:20241002T124954Z
LAST-MODIFIED:20241002T124954Z
SEQUENCE:3
UID:8f9c219f-34c7-440c-acba-95e27d093808
DTSTART;TZID=Asia/Tokyo:20241004T000000
DTEND;TZID=Asia/Tokyo:20241004T010000
STATUS:CONFIRMED
SUMMARY:example_123
DESCRIPTION:test_123
CATEGORIES:system_created
END:VEVENT
BEGIN:VTIMEZONE
TZID:Asia/Tokyo
BEGIN:STANDARD
TZOFFSETFROM:+0900
TZOFFSETTO:+0900
TZNAME:JST
DTSTART:19700101T000000
END:STANDARD
END:VTIMEZONE
END:VCALENDAR
今回はパラメータの対象を絞って、以下を設定するようにします。
一部必須で一部任意のパラメータを想定しています。
項目 | APIパラメータの受取 |
---|---|
UID | 自動生成 |
DTSTAMP | 自動生成 |
DTSTART;TZID | 必須 |
DTEND;TZD | 必須 |
SUMMARY | 必須 |
DESCRIPTION | 任意 |
TZID | 任意 (デフォルトAsia/Tokyo) |
今回APIに必要なものとしては、上記のパラメータを用いて以下2つの処理ができれば、問題はないかという感じです。
- カレンダーにイベントを追加
- カレンダーにイベントがすでにあるか
上記の内容をもとにNextCloudのカレンダー操作用のAPIをFlaskベースで用意しました。
細かいコードの説明は省きますが、 /add_event
というAPIでイベントを追加、 /event_exists
というAPIでイベントの存在確認を行ったりするようにしています。
(汎用性のため他にもAPIは作成しています)
例えば以下のようなリクエストでイベントを追加できます。
curl -X POST "http://localhost:5000/add_event" \
-H "Content-Type: application/json" \
-d '{
"calendar_name": "System",
"start_time": "2024-10-05T09:00:00",
"end_time": "2024-10-05T10:00:00",
"summary": "test",
"description": "Hello"
}'
一旦これでAPIのコードの準備は出来たため、Docker展開して起動させます。
Docker上でAPIを起動
ここはすごくシンプルで、先程のコードをコンテナとして起動するだけとなります。
Dockerが実行できるマシンにgit clone
します。
git clone https://github.com/murajo/NextcloudCalenderManage.git
そしてDockerfileの準備を行います。
今回はAPI側は環境変数としてNextCloudの認証情報を受取るようにしています。
そのため、コンテナ側に環境変数をもたせる必要があるため、ENVのところは環境に合わせて書き換えます。
(コンテナ起動時にパラメータで指定することも可)
FROM python:3.12
ENV NEXTCLOUD_URL='https://<your_nextcloud_domain>/remote.php/dav'
ENV NEXTCLOUD_USERNAME='<your_nextcloud_username>'
ENV NEXTCLOUD_PASSWORD='<your_nextcloud_password>'
ENV VERIFY_SSL='False'
WORKDIR /app
COPY . .
RUN pip install --no-cache-dir -r requirements.txt
CMD ["python", "app.py"]
続いてDockerfileを用いてbuild
します。
docker build -t nextcloud-calendar-api .
docker imagesでイメージが作成されたことを確認します。
docker images
## 出力
REPOSITORY TAG IMAGE ID CREATED SIZE
nextcloud-calendar-api latest d65149633b0c 29 seconds ago 1.04GB
最後に以下で起動します。
今回は5000のポート番号を使って起動しています。
(-eを用いることで、ここで環境変数の指定もできます)
docker run -d -p 5000:5000 --name nextcloud-calendar-api nextcloud-calendar-api:latest
docker psで起動されていることを確認します。
docker ps
## 出力
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
53d094321788 nextcloud-calendar-api:latest "python app.py" 25 seconds ago Up 25 seconds 0.0.0.0:5000->5000/tcp, :::5000->5000/tcp nextcloud-calendar-api
一応curlを飛ばして、動作していることも確認できます。
curl -X POST "http://192.168.0.115:5000/add_event" \
-H "Content-Type: application/json" \
-d '{
"calendar_name": "System",
"start_time": "2024-10-05T09:00:00",
"end_time": "2024-10-05T10:00:00",
"summary": "test_event",
"description": "Hello-world"
}'
## 出力
{"message":"Event added to System"}
以上でAPIの準備は完了です。
API呼び出し用Pythonスクリプトの作成
続いて先程のAPIを呼び出して、証明書のスケジュールを登録するスクリプトの準備を行います。
今回はお試しでvCenterのSSL証明書を登録するようにします。
(一応ドメインを指定するだけなので、何でも大丈夫)
登録するイベントとしては以下のような構成にします。
summaryを証明書ごとに一意とするため、証明書のCNに証明書の発行日を加えるようにします。
- start_time: 証明書の期限の0時
- end_time: 証明書の期限の0時
- summary: 証明書のCN+証明書の発行日
- description: "SSL Certificate valid from" + 証明書の発行日 + "to" + 証明書の期限
続いて用意すべき処理としては大きく以下3つとなります
- 証明書の情報の取得
- イベントが登録済みかのチェック
- イベントの追加実施
こちらも細かいコードの説明は省きますが、上記を元にスクリプトを作成しておきました。
今回の目的はvCenterだけではありましたが、複数ドメインに対して確認できるよう汎用性を持たせています。
各設定はconfig.yamlに入れておくようにして、ここを変えれば使えるようにしています。
nextcloud:
api_url: "http://<your-nextcloud-calendar-mangae-api-url>:<port>"
calendar_name: "<your-calendar-name>"
domains:
- example.com
- example.org
試しにvCenterのドメインを入れて実行してみて、
以下のようにカレンダーに追加されることが確認できました。
ここまでで処理としては全て完成となります。
最後にこのスクリプトをCronからDockerコンテナとして定期的に実行させようと思います。
Cronの設定
今回は先程のスクリプトをコンテナとして実行させる予定です。
ただし、コンテナはCronにて都度起動させて、処理を終えたら削除させるようにします。
まずDocker環境に先程のスクリプトを持っていきます。
git clone https://github.com/murajo/certificate-expiration-date-to-nextcloud-calendar
Dockerfileも一緒に格納されているので、そのままbuildします。
docker build -t ssl-certificate-add-to-calendar .
続いてドメイン情報等を持っているconfig.yaml
の作成を行っておきます。
パラメータの変更を追従できるように、コンテナイメージには持たせず、都度コンテナにマウントさせて起動するようにしておきます。
実行コマンドは以下で、-rm
で実行完了後削除されるようにしています。
docker run --rm -v <作成したconfig.yamlの置いてあるパス>/config.yaml:/app/config.yaml ssl-certificate-add-to-calendar
それでは最後に上記のコマンドをCronに入れます
まず以下コマンドでcronジョブの編集画面に移ります。
crontab -e
そして開かれた画面に行を追加します。
例えば今回は毎日0時に実行するように設定しておきます。
0 0 * * * docker run --rm -v /path/to/config_my.yaml:/app/config.yaml ssl-certificate-add-to-calendar
これでcronにて都度コンテナが起動して、カレンダーに証明書の期限を入れてくれるようになりました。
まとめ
今回はNextCloudのカレンダーへの自動イベント追加を行ってみました。
普段わりと手動でやってしまいがちですが、マシン数も増えてきて管理する証明書が多くなってきたのでちょうど良かったです。
なお、あとから記事書きながら思ったこととして、対象とするドメインを今回config.yaml
に追記する形ですが、DNSサーバーの設定から取れるようにしたほうがより自動化になるなって感じですね。
参考にした記事