0.はじめに
kintone アプリでサイト情報を管理していて、
監視サービスである Site24x7 と StatusCake と連携させたいな、
と思い、やってみました。
図で書くとこんな感じですかね。
1.前提条件
- Kintone
サイト情報を管理するアプリを作成しておきます。
フィールドコードは、以下を用意。
* $id : ※デフォルト * ステータス : 「プロセス管理」の設定 * Category : グルーピング、タグの設定 (「文字列」や「ドロップダウン」) * Title : サイトのタイトル (「文字列」) * Url : サイトの URL (「文字列」) * Notification : 監視サービスの設定 (「複数選択」や「チェックボックス」) * Users : 通知先のユーザー (「ユーザー選択」)
1. Site24x7 Site24x7 は有料のサービスですが、トライアルで利用出来るのでサインアップして、API キーを取得しておきます。
* [Webサイト監視サービス、はじめの30日間ですべての機能を評価でサインアップ Site24x7](https://www.site24x7.com/ja/website-monitor.html) * [Site24x7 での API キーの取得のやり方 \- Qiita](http://qiita.com/kusokamayarou/items/e2eec05d8ea2acf43594)
1. StatusCake Site24x7 はフリープランもあります。ただ、API の有効回数制限がありますので、ご注意を。有料版も安いやつがあるので、そちらを利用してもいいかも。サインアップしたら、API キーを取得しておきます。 * [Our Pricing – StatusCake – Website Monitoring](https://www.statuscake.com/pricing/) * [StatusCake での API キーの取得のやり方 \- Qiita](http://qiita.com/kusokamayarou/items/f4bd7daed45fb13d0662)
2.プログラム
-
とりあえず、Python で書いてみました。
「長えよッ!!」との声が聞こえてきそうですが…。すいません…。
解説を後述しておきます。SetSiteMonitorsFromCybozu.py#!/usr/bin/python3.4 -tt # -*- coding: utf-8 -*- # ---1----+----2----+----3----+----4----+----5----+----6----+----7----+----8---- # ============================================================================== # # SetSiteMonitorsFromCybozu.py # # * ex) $ ./SetSiteMonitorsFromCybozu.py # # ============================================================================== import sys import re import os import logging import codecs import json import datetime import requests import hashlib import subprocess import smtplib from urllib.parse import urlparse from email.mime.text import MIMEText from email.header import Header mypath=os.path.dirname(os.path.abspath(__file__)) myname=os.path.basename(__file__) mybase,myext=os.path.splitext(myname) sys.stdout = codecs.getwriter('utf_8')(sys.stdout) logging.basicConfig(level=logging.DEBUG, format="[%(asctime)s] %(levelname)-8s %(filename)-20.20s (%(lineno)06d) %(funcName)-12.12s | %(message)s", datefmt='%Y-%m-%d %H:%M:%S', filename=(__file__ + ".log"), filemode='w') sh = logging.StreamHandler() sh.setLevel(logging.DEBUG) formatter = logging.Formatter("[%(asctime)s] %(levelname)-8s (%(lineno)06d) | %(message)s") sh.setFormatter(formatter) logging.getLogger().addHandler(sh) logging.debug("<<<<<<<< %s Start >>>>>>>>", __file__) # ------------------------------------------------------------------------------ # Constant # ------------------------------------------------------------------------------ nowdt = datetime.datetime.today() tmp_today = datetime.datetime.today() tmp_today_string = tmp_today.strftime('%Y-%m-%d %H:%M:%S') tmp_today_day_string = tmp_today.strftime('%d') # Mail HostSMTP = '[メールサーバ:ポート番号]' MailFrom = '[送信元メールアドレス]' MailTo = '[送信先メールアドレス]' LoginAccount = '[認証アカウント]' LoginPassword = '[認証パスワード]' # cybozu.com Cybozu_Url_Base = 'https://[取得したサブドメイン].cybozu.com' Cybozu_Auth_Headers_UserAPI = { 'X-Cybozu-Authorization':'[APIキー]', 'If-Modified-Since' : 'Thu, 01 Jun 1970 00:00:00 GMT'} Cybozu_Auth_Headers_KintoneAPI = { 'X-Cybozu-API-Token' : '[KintoneのAPIトークンキー]', 'Content-Type' : 'application/json; charset=UTF-8', 'If-Modified-Since' : 'Thu, 01 Jun 1970 00:00:00 GMT'} # Site24x7 Site24x7_Url_Base = 'https://www.site24x7.com/api' Site24x7_Auth_Headers = { 'Content-Type' : 'application/json; charset=UTF-8', 'Accept' : 'application/json; version=2.0', 'Authorization' : '[APIキー]', 'If-Modified-Since' : 'Thu, 01 Jun 1970 00:00:00 GMT'} # StatusCake StatusCake_Url_Base = 'https://app.statuscake.com/API' StatusCake_Auth_Headers = {'API':'[APIキー]', 'Username' : '[ユーザーID]', 'Content-Type' : 'application/json; charset=UTF-8', 'If-Modified-Since' : 'Thu, 01 Jun 1970 00:00:00 GMT'} StatusCake_StatusCodes = ["204","205","206","303","400","401","403","404","405","406","408","410","429","444","494","495","496","499","500","501","502","504","505","506","507","511","598","599"] # ------------------------------------------------------------------------------ # Variables # ------------------------------------------------------------------------------ dic_users = {} dic_usergroups = {} dic_monitorgroups = {} dic_monitors = {'Web' : {}, '???' : {}, 'SSL':{}, 'DNS':{}} dic_cybozu_mail_user_s = {} dic_site24x7_user_mail_s = {} dic_site24x7_mail_user_s = {} # ------------------------------------------------------------------------------ # Function # ------------------------------------------------------------------------------ def getCybozuUsers(): """Get Cybozu Users""" logging.debug("==== cybozu.com - Get Users Json ====") cybozu_users = requests.get(Cybozu_Url_Base + "/v1/users.json", headers=Cybozu_Auth_Headers_UserAPI) cybozu_users_json = cybozu_users.json()['users'] logging.debug("cybozu_users_json:[%s]", cybozu_users_json) # logging.debug("==== cybozu.com - Set Users Dictionary ====") for n, k in enumerate(list(cybozu_users_json)): logging.debug("(%04d/%04d) cybozu.com - User | " \ "ID:[%s] [%d] Code:[%s] Name:[%s] Mail:[%s] Tel:[%s]", n + 1, len(cybozu_users_json), cybozu_users_json[n]['id'], cybozu_users_json[n]['valid'], cybozu_users_json[n]['code'], cybozu_users_json[n]['name'], cybozu_users_json[n]['email'], cybozu_users_json[n]['phone']) user_id = cybozu_users_json[n]['code'] if len(user_id) == 0: continue if user_id in dic_users: logging.error("OverLap | user_id:[%s]", user_id) continue dic_users[user_id] = {} dic_users[user_id]['cybozu'] = { 'id' : cybozu_users_json[n]['id'], 'valid' : cybozu_users_json[n]['valid'], 'name' : cybozu_users_json[n]['name'], 'email' : cybozu_users_json[n]['email'], 'phone' : cybozu_users_json[n]['phone'], } mail = "" if cybozu_users_json[n]['email'] is None else cybozu_users_json[n]['email'] if len(mail) == 0: continue if mail in dic_cybozu_mail_user_s: logging.warn("OverLap | MAIL:[%s]", mail) continue dic_cybozu_mail_user_s[mail] = user_id def getCybozuMonitors(): """Get Cybozu Monitors""" logging.debug("==== cybozu.com - Get Monitors Json ====") cybozu_monitors = requests.get(Cybozu_Url_Base + "/k/v1/records.json", headers=Cybozu_Auth_Headers_KintoneAPI, data=json.dumps({ "app": [Kintone アプリの ID], "query": "$id > 0 order by $id asc limit 500", "fields": [ "$id", "ステータス", "Category", "Title", "Url", "Notification", "Users"], "totalCount": "true" }) ) cybozu_monitors_json = cybozu_monitors.json()['records'] logging.debug("cybozu_monitors_json:[%s]", cybozu_monitors_json) # logging.debug("==== cybozu.com - Set UserGroups & Monitors Dictionary ====") for n, k in enumerate(list(cybozu_monitors_json)): cybozu_monitors_json_ipaddress = "" if 'IP-Address' in cybozu_monitors_json[n]: cybozu_monitors_json_ipaddress = cybozu_monitors_json[n]['IP-Address']['value'] cybozu_monitors_json_users = [] cybozu_monitors_json_mails = [] cybozu_monitors_json_phones = [] for user in cybozu_monitors_json[n]['Users']['value']: cybozu_monitors_json_users.append(user['code']) if dic_users[user['code']]['cybozu']['email']: if not dic_users[user['code']]['cybozu']['email'] in cybozu_monitors_json_mails: cybozu_monitors_json_mails.append(dic_users[user['code']]['cybozu']['email']) if dic_users[user['code']]['cybozu']['phone']: if not dic_users[user['code']]['cybozu']['phone'] in cybozu_monitors_json_phones: cybozu_monitors_json_phones.append(dic_users[user['code']]['cybozu']['phone']) dic_users[user['code']]['cybozu']['used'] = True logging.debug("(%04d/%04d) cybozu.com - Monitors | " \ "ID:[%s] Category:[%s] Title:[%s] Stuta:[%s] Url:[%s] IP:[%s] Notification:[%s] Users:[%s]", n + 1, len(cybozu_monitors_json), cybozu_monitors_json[n]['$id']['value'], cybozu_monitors_json[n]['Category']['value'], cybozu_monitors_json[n]['Title']['value'], cybozu_monitors_json[n]['ステータス']['value'], cybozu_monitors_json[n]['Url']['value'], cybozu_monitors_json_ipaddress, cybozu_monitors_json[n]['Notification']['value'], cybozu_monitors_json_users) # usergroup_id = "" if len(cybozu_monitors_json_mails) > 0: usergroup_id = hashlib.md5(":".join(sorted(cybozu_monitors_json_mails)).encode('utf-8')).hexdigest() if len(usergroup_id) > 0: if usergroup_id in dic_usergroups: pass else: dic_usergroups[usergroup_id] = {} dic_usergroups[usergroup_id]['mails'] = sorted(cybozu_monitors_json_mails) dic_usergroups[usergroup_id]['phones'] = sorted(cybozu_monitors_json_phones) dic_usergroups[usergroup_id]['cybozu'] = { 'users' : sorted(cybozu_monitors_json_users) } # parsed = urlparse(cybozu_monitors_json[n]['Url']['value']) # web_id = cybozu_monitors_json[n]['Url']['value'].rstrip('/') key = 'Web' if parsed.scheme in {"http", "https"} else '???' if len(web_id) > 0: if web_id in dic_monitors[key]: logging.warn("OverLap | URL:[%s]", web_id) pass else: dic_monitors[key][web_id] = {} dic_monitors[key][web_id]['usergroup_ids'] = [usergroup_id] dic_monitors[key][web_id]['cybozu'] = { 'id' : cybozu_monitors_json[n]['$id']['value'], 'Category' : cybozu_monitors_json[n]['Category']['value'], 'Title' : cybozu_monitors_json[n]['Title']['value'], 'Status' : cybozu_monitors_json[n]['ステータス']['value'], 'Url' : cybozu_monitors_json[n]['Url']['value'], 'IP-Address' : cybozu_monitors_json_ipaddress, 'Notification' : cybozu_monitors_json[n]['Notification']['value'], 'users' : cybozu_monitors_json_users } # ssl_id = "" if parsed.hostname is not None: if not parsed.hostname.endswith(".cybozu.com"): ssl_id = parsed.hostname key = 'SSL' if len(ssl_id) > 0: if ssl_id in dic_monitors[key]: if not 'web_ids' in dic_monitors[key][ssl_id]: dic_monitors[key][ssl_id]['web_ids'] = [] if not web_id in dic_monitors[key][ssl_id]['web_ids']: dic_monitors[key][ssl_id]['web_ids'].append(web_id) if not 'usergroup_ids' in dic_monitors[key][ssl_id]: dic_monitors[key][ssl_id]['usergroup_ids'] = [] if not usergroup_id in dic_monitors[key][ssl_id]['usergroup_ids']: dic_monitors[key][ssl_id]['usergroup_ids'].append(usergroup_id) else: dic_monitors[key][ssl_id] = {} dic_monitors[key][ssl_id]['web_ids'] = [web_id] dic_monitors[key][ssl_id]['usergroup_ids'] = [usergroup_id] # dns_id = "" if ssl_id.endswith(".com"): dns_id = ".".join(ssl_id.split(".")[-2:]) elif ssl_id.endswith(".info"): dns_id = ".".join(ssl_id.split(".")[-2:]) elif ssl_id.endswith(".co.jp"): dns_id = ".".join(ssl_id.split(".")[-3:]) elif ssl_id.endswith(".go.jp"): dns_id = ".".join(ssl_id.split(".")[-3:]) else: dns_id = ".".join(ssl_id.split(".")[-2:]) key = 'DNS' if len(dns_id) > 0: if dns_id in dic_monitors[key]: if not 'web_ids' in dic_monitors[key][dns_id]: dic_monitors[key][dns_id]['web_ids'] = [] if not web_id in dic_monitors[key][dns_id]['web_ids']: dic_monitors[key][dns_id]['web_ids'].append(web_id) if not 'usergroup_ids' in dic_monitors[key][dns_id]: dic_monitors[key][dns_id]['usergroup_ids'] = [] if not usergroup_id in dic_monitors[key][dns_id]['usergroup_ids']: dic_monitors[key][dns_id]['usergroup_ids'].append(usergroup_id) else: dic_monitors[key][dns_id] = {} dic_monitors[key][dns_id]['web_ids'] = [web_id] dic_monitors[key][dns_id]['usergroup_ids'] = [usergroup_id] # monitorgroup_id = cybozu_monitors_json[n]['Category']['value'] if len(monitorgroup_id) > 0: if not monitorgroup_id in dic_monitorgroups: dic_monitorgroups[monitorgroup_id] = {} if not 'cybozu' in dic_monitorgroups[monitorgroup_id]: dic_monitorgroups[monitorgroup_id]['cybozu'] = {} dic_monitorgroups[monitorgroup_id]['cybozu']['monitors'] = [] if not web_id in dic_monitorgroups[monitorgroup_id]['cybozu']['monitors']: dic_monitorgroups[monitorgroup_id]['cybozu']['monitors'].append(web_id) def getSite24x7Users(): """Get Site24x7 Users""" logging.debug("==== Site24x7 - Get Users Json ====") site24x7_users = requests.get(Site24x7_Url_Base + "/users", headers=Site24x7_Auth_Headers) site24x7_users_json = site24x7_users.json()['data'] logging.debug("site24x7_users_json:[%s]", site24x7_users_json) # logging.debug("==== Site24x7 - Set Users Dictionary ====") for n, k in enumerate(list(site24x7_users_json)): logging.debug("(%04d/%04d) Site24x7 - Users | " \ "ID:[%s] Role:[%d] Name:[%s] Mail:[%s] Tel:[%s] Groups:[%s]", n + 1, len(site24x7_users_json), site24x7_users_json[n]['user_id'], site24x7_users_json[n]['user_role'], site24x7_users_json[n]['display_name'], site24x7_users_json[n]['email_address'], site24x7_users_json[n]['mobile_settings'].get('mobile_number'), site24x7_users_json[n]['user_groups']) cybozu_user_id = "" if site24x7_users_json[n]['email_address'] in dic_cybozu_mail_user_s: cybozu_user_id = dic_cybozu_mail_user_s[site24x7_users_json[n]['email_address']] if len(cybozu_user_id) > 0: if cybozu_user_id in dic_users: dic_users[cybozu_user_id]['Site24x7'] = site24x7_users_json[n] else: dic_users[cybozu_user_id] = {} dic_users[cybozu_user_id]['Site24x7'] = site24x7_users_json[n] site24x7_user_id = site24x7_users_json[n]['user_id'] if len(site24x7_user_id) > 0: if site24x7_user_id in dic_site24x7_user_mail_s: logging.wran("OverLap | USERID:[%s]", site24x7_user_id) pass else: dic_site24x7_user_mail_s[site24x7_user_id] = site24x7_users_json[n]['email_address'] def setSite24x7Users(): """Set Site24x7 Users""" logging.debug("==== Site24x7 - Set Users to System ====") del_users = [] for n, k in enumerate(list(dic_users)): logging.debug("(%04d/%04d) Users - [%s]:[%s]", n + 1, len(dic_users), k, dic_users[k]) Site24x7_Url_Users = Site24x7_Url_Base + "/users" site24x7_users_res = "" if 'cybozu' in dic_users[k] and 'used' in dic_users[k]['cybozu'] and dic_users[k]['cybozu']['used']: mobile_number = re.sub('[-() ]', '',dic_users[k]['cybozu']['phone']).lstrip('0') if mobile_number: if mobile_number[1:2] == "0": pass else: mobile_number = "" else: mobile_number = "" Site24x7_Payload_Users_Update = { "user_role": "3", "mobile_settings": { "country_code": "81", "mobile_number": mobile_number }, "alert_settings":{ "email_format":0, "dont_alert_on_days":[], "alerting_period":{ "start_time":"00:00", "end_time":"24:00" }, "down":[1,2,3], "trouble":[1,2,3], "up":[1,2,3] }, "display_name":dic_users[k]['cybozu']['name'], "email_address":dic_users[k]['cybozu']['email'], "notify_medium":[1,2,3] } if 'Site24x7' in dic_users[k]: if dic_users[k]['Site24x7']['user_role'] != 0: Site24x7_Payload_Users_Update['user_role'] = dic_users[k]['Site24x7']['user_role'] update_flag = False if dic_users[k]['Site24x7']['mobile_settings'].get('mobile_number') != Site24x7_Payload_Users_Update['mobile_settings'].get('mobile_number'): update_flag = True if dic_users[k]['Site24x7'].get('alert_settings') != Site24x7_Payload_Users_Update.get('alert_settings'): update_flag = True if dic_users[k]['Site24x7'].get('email_address') != Site24x7_Payload_Users_Update.get('email_address'): update_flag = True if dic_users[k]['Site24x7'].get('display_name') != Site24x7_Payload_Users_Update.get('display_name'): update_flag = True if update_flag: logging.info("Site24x7 - User - Update") logging.info("dic_users[k]:[%s]",dic_users[k]['Site24x7']) logging.info("Site24x7_Payload_Users_Update:[%s]",Site24x7_Payload_Users_Update) Site24x7_Url_Users += "/" + dic_users[k]['Site24x7']['user_id'] Site24x7_Payload_Users_Update['user_role'] = dic_users[k]['Site24x7']['user_role'] if len(dic_users[k]['Site24x7']['user_groups']) > 0: Site24x7_Payload_Users_Update['user_groups'] = dic_users[k]['Site24x7']['user_groups'] logging.debug("Site24x7_Url_Users:[%s]", Site24x7_Url_Users) logging.debug("Site24x7_Payload_Users_Update:[%s]", Site24x7_Payload_Users_Update) site24x7_users_res = requests.put(Site24x7_Url_Users, data=json.dumps(Site24x7_Payload_Users_Update), headers=Site24x7_Auth_Headers) site24x7_users_res_json = site24x7_users_res.json() logging.debug("site24x7_users_res_json:[%s]", site24x7_users_res_json) if site24x7_users_res_json['message'] == 'success': dic_users[k]['Site24x7'] = site24x7_users_res_json['data'] else: logging.error("site24x7_users_res_json:[%s]", site24x7_users_res_json) else: logging.info("Site24x7 - User - Insert") logging.debug("Site24x7_Url_Users:[%s]", Site24x7_Url_Users) logging.debug("Site24x7_Payload_Users_Update:[%s]", Site24x7_Payload_Users_Update) site24x7_users_res = requests.post(Site24x7_Url_Users, data=json.dumps(Site24x7_Payload_Users_Update), headers=Site24x7_Auth_Headers) site24x7_users_res_json = site24x7_users_res.json() logging.debug("site24x7_users_res_json:[%s]", site24x7_users_res_json) if site24x7_users_res_json['message'] == 'success': dic_users[k]['Site24x7'] = site24x7_users_res_json['data'] site24x7_user_id = site24x7_users_res_json['data']['user_id'] if len(site24x7_user_id) > 0: if site24x7_user_id in dic_site24x7_user_mail_s: logging.warn("OverLap | USERID:[%s]", site24x7_user_id) pass else: dic_site24x7_user_mail_s[site24x7_user_id] = site24x7_users_res_json['data']['email_address'] else: logging.error("site24x7_users_res_json:[%s]", site24x7_users_res_json) else: if 'Site24x7' in dic_users[k]: if 'user_role' in dic_users[k]['Site24x7']: if dic_users[k]['Site24x7']['user_role'] < 1 or dic_users[k]['Site24x7']['user_role'] > 2: del_users.append(k) return del_users def unsetSite24x7Users(del_users): """UnSet Site24x7 Users""" logging.debug("==== Site24x7 - UnSet Users to System ====") for n, k in enumerate(del_users): logging.debug("(%04d/%04d) Users - [%s]:[%s]", n + 1, len(del_users), k, dic_users[k]) Site24x7_Url_Users = Site24x7_Url_Base + "/users" logging.info("Site24x7 - User - Delete") Site24x7_Url_Users += "/" + dic_users[k]['Site24x7']['user_id'] logging.info("Site24x7_Url_Users:[%s]", Site24x7_Url_Users) site24x7_users_res = requests.delete(Site24x7_Url_Users, headers=Site24x7_Auth_Headers) site24x7_users_res_json = site24x7_users_res.json() logging.info("site24x7_users_res_json:[%s]", site24x7_users_res_json) if site24x7_users_res_json['message'] == 'success': val = dic_users[k].pop('Site24x7') site24x7_user_id = val['user_id'] if len(site24x7_user_id) > 0: if site24x7_user_id in dic_site24x7_user_mail_s: dic_site24x7_user_mail_s.pop(site24x7_user_id) else: logging.warn("Not | USERID:[%s]", site24x7_user_id) pass else: logging.error("site24x7_users_res_json:[%s]", site24x7_users_res_json) def getSite24x7UserGroups(): """Get Site24x7 UserGroups""" logging.debug("==== Site24x7 - Get UserGroups Json ====") site24x7_usergroups = requests.get(Site24x7_Url_Base + "/user_groups", headers=Site24x7_Auth_Headers) site24x7_usergroups_json = site24x7_usergroups.json()['data'] logging.debug("site24x7_usergroups_json:[%s]", site24x7_usergroups_json) for n, k in enumerate(list(site24x7_usergroups_json)): logging.debug("(%04d/%04d) Site24x7 - UserGroups | ID:[%s] Master:[%d] Name:[%s] Users:[%s]", n + 1, len(site24x7_usergroups_json), site24x7_usergroups_json[n]['user_group_id'], site24x7_usergroups_json[n]['is_master_group'], site24x7_usergroups_json[n]['display_name'], site24x7_usergroups_json[n]['users']) usergroup_id = site24x7_usergroups_json[n]['display_name'] if len(usergroup_id) > 0: if not usergroup_id in dic_usergroups: dic_usergroups[usergroup_id] = {} if not 'Site24x7' in dic_usergroups[usergroup_id]: dic_usergroups[usergroup_id]['Site24x7'] = {} dic_usergroups[usergroup_id]['Site24x7'][site24x7_usergroups_json[n]['user_group_id']] = site24x7_usergroups_json[n] def setSite24x7UserGroups(): """Set Site24x7 UserGroups""" logging.debug("==== Site24x7 - Set UserGroups to System ====") del_usergroups = {} for n, k in enumerate(list(dic_usergroups)): logging.debug("(%04d/%04d) UserGroups - [%s]:[%s]", n + 1, len(dic_usergroups), k, dic_usergroups[k]) site24x7_usergroups_res = "" if 'cybozu' in dic_usergroups[k]: if 'Site24x7' in dic_usergroups[k]: nn = 0 for kk in list(dic_usergroups[k]['Site24x7']): if nn == 0: logging.debug("Site24x7 - UserGroups - Update") pass else: logging.info("Site24x7 - UserGroups - Delete") site24x7_usergroups_res = requests.delete(Site24x7_Url_Base + "/user_groups/" + kk, headers=Site24x7_Auth_Headers) site24x7_usergroups_res_json = site24x7_usergroups_res.json() logging.debug("site24x7_usergroups_res_json:[%s]", site24x7_usergroups_res_json) if site24x7_usergroups_res_json['message'] == 'success': dic_usergroups[k]['Site24x7'].pop(kk) else: logging.error("site24x7_usergroups_res_json:[%s]", site24x7_usergroups_res_json) nn += 1 else: logging.info("Site24x7 - UserGroups - Insert") users = [] dic_usergroups[k]['Site24x7'] = {} dic_site24x7_mail_user_s = {vvv:kkk for kkk, vvv in dic_site24x7_user_mail_s.items()} for mail in dic_usergroups[k]['mails']: user = dic_site24x7_mail_user_s[mail] logging.debug("(%04d) UserGroups - [%s]:[%s]", n, mail, user) users.append(user) Site24x7_Payload_UserGroups_Insert = { "display_name": k, "users": users, } logging.debug("Site24x7_Payload_UserGroups_Insert:[%s]", Site24x7_Payload_UserGroups_Insert) site24x7_usergroups_res = requests.post(Site24x7_Url_Base + "/user_groups", data=json.dumps(Site24x7_Payload_UserGroups_Insert), headers=Site24x7_Auth_Headers) site24x7_usergroups_res_json = site24x7_usergroups_res.json() logging.debug("site24x7_usergroups_res_json:[%s]", site24x7_usergroups_res_json) if site24x7_usergroups_res_json['message'] == 'success': dic_usergroups[k]['Site24x7'][site24x7_usergroups_res_json['data']['user_group_id']] = site24x7_usergroups_res_json['data'] else: logging.error("site24x7_usergroups_res_json:[%s]", site24x7_usergroups_res_json) else: if 'Site24x7' in dic_usergroups[k]: for kk in list(dic_usergroups[k]['Site24x7']): if dic_usergroups[k]['Site24x7'][kk]['display_name'] in {"管理グループ", "ネットワークチーム", "アプリケーションチーム"}: pass else: del_usergroups[kk] = k return del_usergroups def unsetSite24x7UserGroups(del_usergroups): """UnSet Site24x7 UserGroups""" logging.debug("==== Site24x7 - UnSet UserGroups to System ====") logging.debug("del_usergroups:[%s]", del_usergroups) for n, kk in enumerate(del_usergroups.keys()): logging.debug("(%04d/%04d) UserGroups - [%s]:[%s]", n + 1, len(del_usergroups), kk, del_usergroups[kk]) k = del_usergroups[kk] logging.info("Site24x7 - UserGroups - Delete") site24x7_usergroups_res = requests.delete(Site24x7_Url_Base + "/user_groups/" + kk, headers=Site24x7_Auth_Headers) site24x7_usergroups_res_json = site24x7_usergroups_res.json() logging.info("site24x7_usergroups_res_json:[%s]", site24x7_usergroups_res_json) if site24x7_usergroups_res_json['message'] == 'success': dic_usergroups[k]['Site24x7'].pop(kk) else: logging.error("site24x7_usergroups_res_json:[%s]", site24x7_usergroups_res_json) def getSite24x7MonitorGroups(): """Get Site24x7 MonitorGroups""" logging.debug("==== Site24x7 - Get MonitorGroups Json ====") site24x7_monitorgroups = requests.get(Site24x7_Url_Base + "/monitor_groups", headers=Site24x7_Auth_Headers) site24x7_monitorgroups_json = site24x7_monitorgroups.json()['data'] logging.debug("site24x7_monitorgroups_json:[%s]", site24x7_monitorgroups_json) for n, k in enumerate(list(site24x7_monitorgroups_json)): logging.debug("(%04d/%04d) Site24x7 - MonitorsGroups | ID:[%s] Name:[%s] Count:[%04d] Monitors:[%s]", n + 1, len(site24x7_monitorgroups_json), site24x7_monitorgroups_json[n]['group_id'], site24x7_monitorgroups_json[n]['display_name'], site24x7_monitorgroups_json[n]['health_threshold_count'], site24x7_monitorgroups_json[n]['monitors'] if 'monitors' in site24x7_monitorgroups_json[n] else []) monitorgroup_id = site24x7_monitorgroups_json[n]['group_id'] monitorgroup_name = site24x7_monitorgroups_json[n]['display_name'] if not monitorgroup_name in dic_monitorgroups: dic_monitorgroups[monitorgroup_name] = {} if not 'Site24x7' in dic_monitorgroups[monitorgroup_name]: dic_monitorgroups[monitorgroup_name]['Site24x7'] = {} if not monitorgroup_id in dic_monitorgroups[monitorgroup_name]['Site24x7']: dic_monitorgroups[monitorgroup_name]['Site24x7'][monitorgroup_id] = site24x7_monitorgroups_json[n] def setSite24x7MonitorGroups(): """Set Site24x7 MonitorGroups""" logging.debug("==== Site24x7 - Set MonitorGroups to System ====") del_monitorgroups = {} for n, k in enumerate(list(dic_monitorgroups)): logging.debug("(%04d/%04d) Site24x7 - MonitorGroups - [%s]:[%s]", n + 1, len(dic_monitorgroups), k, dic_monitorgroups[k]) site24x7_monitorgroups_res = "" if 'cybozu' in dic_monitorgroups[k]: if 'Site24x7' in dic_monitorgroups[k]: nn = 0 for kk in list(dic_monitorgroups[k]['Site24x7']): if nn == 0: logging.debug("Site24x7 - MonitorGroups - Update") pass else: del_monitorgroups[kk] = k nn += 1 else: logging.info("Site24x7 - MonitorGroups - Insert") Site24x7_Payload_MonitorGroups_Insert = { "display_name": k, "description": k, "monitors": [], } logging.debug("Site24x7_Payload_MonitorGroups_Insert:[%s]", Site24x7_Payload_MonitorGroups_Insert) site24x7_monitorgroups_res = requests.post(Site24x7_Url_Base + "/monitor_groups", data=json.dumps(Site24x7_Payload_MonitorGroups_Insert), headers=Site24x7_Auth_Headers) site24x7_monitorgroups_res_json = site24x7_monitorgroups_res.json() logging.debug("site24x7_monitorgroups_res_json:[%s]", site24x7_monitorgroups_res_json) if site24x7_monitorgroups_res_json['message'] == 'success': dic_monitorgroups[k]['Site24x7'][site24x7_usergroups_res_json['data']['group_id']] = site24x7_usergroups_res_json['data'] else: logging.error("site24x7_monitorgroups_res_json:[%s]", site24x7_monitorgroups_res_json) else: if 'Site24x7' in dic_monitorgroups[k]: for kk in list(dic_monitorgroups[k]['Site24x7']): del_monitorgroups[kk] = k else: pass return del_monitorgroups def unsetSite24x7MonitorGroups(del_monitorgroups): """UnSet Site24x7 MonitorGroups""" logging.debug("==== Site24x7 - UnSet MonitorGroups to System ====") for n, kk in enumerate(del_monitorgroups.keys()): logging.debug("(%04d/%04d) Site24x7 - MonitorGroups - [%s]:[%s]", n + 1, len(dic_monitorgroups), kk, del_monitorgroups[kk]) k = del_monitorgroups[kk] logging.info("Site24x7 - MonitorGroups - Delete") site24x7_monitorgroups_res = requests.delete(Site24x7_Url_Base + "/monitor_groups/" + kk, headers=Site24x7_Auth_Headers) site24x7_monitorgroups_res_json = site24x7_monitorgroups_res.json() logging.info("site24x7_monitorgroups_res_json:[%s]", site24x7_monitorgroups_res_json) if site24x7_monitorgroups_res_json['message'] == 'success': dic_monitorgroups[k]['Site24x7'].pop(kk) else: logging.error("site24x7_monitorgroups_res_json:[%s]", site24x7_monitorgroups_res_json) def getSite24x7Monitors(): """Get Site24x7 Monitors""" logging.debug("==== Site24x7 - Get Monitors Json ====") site24x7_monitors = requests.get(Site24x7_Url_Base + "/monitors", headers=Site24x7_Auth_Headers) site24x7_monitors_json = site24x7_monitors.json()['data'] logging.debug("site24x7_monitors_json:[%s]", site24x7_monitors_json) for n, k in enumerate(list(site24x7_monitors_json)): logging.debug("(%04d) Site24x7 - Monitors:[%s]", n, json.dumps(site24x7_monitors_json[n])) key = "???" tgt = "" if site24x7_monitors_json[n]['type'] in {"URL"}: key = "Web" tgt = site24x7_monitors_json[n]['website'].rstrip('/') elif site24x7_monitors_json[n]['type'] in {"HOMEPAGE"}: key = "???" tgt = site24x7_monitors_json[n]['website'].rstrip('/') elif site24x7_monitors_json[n]['type'] in {"DNS"}: key = "DNS" tgt = site24x7_monitors_json[n]['domain_name'].rstrip('/') elif site24x7_monitors_json[n]['type'] in {"PORT-SMTP"}: key = "???" tgt = site24x7_monitors_json[n]['host_name'].rstrip('/') elif site24x7_monitors_json[n]['type'] in {"SSL_CERT"}: key = "SSL" tgt = site24x7_monitors_json[n]['domain_name'].rstrip('/') else: pass logging.debug("(%04d/%04d) Site24x7 - Monitors | " \ "ID:[%s] State:[%d] Type:[%s] Name:[%s] Tgt:[%s] AlertGroups:[%s]", n + 1, len(site24x7_monitors_json), site24x7_monitors_json[n]['monitor_id'], site24x7_monitors_json[n]['state'], site24x7_monitors_json[n]['type'], site24x7_monitors_json[n]['display_name'], tgt, site24x7_monitors_json[n]['user_group_ids']) if len(tgt) > 0: if tgt in dic_monitors[key]: dic_monitors[key][tgt]['Site24x7'] = site24x7_monitors_json[n] else: dic_monitors[key][tgt] = {} dic_monitors[key][tgt]['Site24x7'] = site24x7_monitors_json[n] def setSite24x7Monitors(): """Set Site24x7 Monitors""" logging.debug("==== Site24x7 - Set Monitors (Web) to System ====") del_monitors = [] for n, k in enumerate(list(dic_monitors['Web'])): logging.debug("(%04d/%04d) Site24x7 - Monitors (Web) - [%s]:[%s]", n + 1, len(dic_monitors['Web']), k, dic_monitors['Web'][k]) site24x7_monitors_res = "" site24x7_monitors_res_json = None if 'cybozu' in dic_monitors['Web'][k]: monitor_groups = list(dic_monitorgroups[dic_monitors['Web'][k]['cybozu']['Category']]['Site24x7'].keys()) logging.debug("monitor_groups:[%s]", monitor_groups) user_group_ids = [] for usergroup_id in dic_monitors['Web'][k]['usergroup_ids']: if not usergroup_id in dic_usergroups: continue if not 'Site24x7' in dic_usergroups[usergroup_id]: continue logging.debug("dic_usergroups[usergroup_id]['Site24x7']:[%s]", dic_usergroups[usergroup_id]['Site24x7']) for kk in dic_usergroups[usergroup_id]['Site24x7'].keys(): user_group_ids.append(dic_usergroups[usergroup_id]['Site24x7'][kk]['user_group_id']) if len(user_group_ids) == 0: user_group_ids = ['215015000000025003'] logging.debug("user_group_ids:[%s]", user_group_ids) Site24x7_Payload_Monitors_Update = { "display_name": k, "type": 'URL', "website": k, "check_frequency": '5', "timeout": 15, "location_profile_id": "215015000004406005", "notification_profile_id": "215015000000025063", "threshold_profile_id": "215015000000025114", "user_group_ids": user_group_ids, "http_method": "G", "monitor_groups": monitor_groups, "use_ipv6": False, "match_case": True, "probe_proxy_enabled": False, "auth_method": 'B', "ssl_protocol": 'Auto', "use_name_server": False, } if 'Site24x7' in dic_monitors['Web'][k] \ and 'type' in dic_monitors['Web'][k]['Site24x7'] \ and dic_monitors['Web'][k]['Site24x7']['type'] == 'URL': if dic_monitors['Web'][k]['Site24x7']['display_name'] != Site24x7_Payload_Monitors_Update["display_name"] \ or dic_monitors['Web'][k]['Site24x7']['website'] != Site24x7_Payload_Monitors_Update["website"] \ or dic_monitors['Web'][k]['Site24x7']['check_frequency'] != Site24x7_Payload_Monitors_Update["check_frequency"] \ or dic_monitors['Web'][k]['Site24x7']['timeout'] != Site24x7_Payload_Monitors_Update["timeout"] \ or dic_monitors['Web'][k]['Site24x7']['location_profile_id'] != Site24x7_Payload_Monitors_Update["location_profile_id"] \ or dic_monitors['Web'][k]['Site24x7']['notification_profile_id'] != Site24x7_Payload_Monitors_Update["notification_profile_id"] \ or dic_monitors['Web'][k]['Site24x7']['threshold_profile_id'] != Site24x7_Payload_Monitors_Update["threshold_profile_id"] \ or dic_monitors['Web'][k]['Site24x7']['user_group_ids'] != Site24x7_Payload_Monitors_Update["user_group_ids"] \ or dic_monitors['Web'][k]['Site24x7']['http_method'] != Site24x7_Payload_Monitors_Update["http_method"] \ or dic_monitors['Web'][k]['Site24x7']['monitor_groups'] != Site24x7_Payload_Monitors_Update["monitor_groups"] \ or dic_monitors['Web'][k]['Site24x7']['use_ipv6'] != Site24x7_Payload_Monitors_Update["use_ipv6"] \ or dic_monitors['Web'][k]['Site24x7']['match_case'] != Site24x7_Payload_Monitors_Update["match_case"] \ or dic_monitors['Web'][k]['Site24x7']['probe_proxy_enabled'] != Site24x7_Payload_Monitors_Update["probe_proxy_enabled"] \ or dic_monitors['Web'][k]['Site24x7']['auth_method'] != Site24x7_Payload_Monitors_Update["auth_method"] \ or dic_monitors['Web'][k]['Site24x7']['ssl_protocol'] != Site24x7_Payload_Monitors_Update["ssl_protocol"] \ or dic_monitors['Web'][k]['Site24x7']['use_name_server'] != Site24x7_Payload_Monitors_Update["use_name_server"]: logging.info("Site24x7 - Monitors (Web) - Update") logging.info("dic_monitors['Web'][k]['Site24x7']:[%s]", dic_monitors['Web'][k]['Site24x7']) logging.info("Site24x7_Payload_Monitors_Update:[%s]", Site24x7_Payload_Monitors_Update) site24x7_monitors_res = requests.put(Site24x7_Url_Base + "/monitors/" + dic_monitors['Web'][k]['Site24x7']['monitor_id'], data=json.dumps(Site24x7_Payload_Monitors_Update), headers=Site24x7_Auth_Headers) site24x7_monitors_res_json = site24x7_monitors_res.json() logging.info("site24x7_monitors_res_json:[%s]", site24x7_monitors_res_json) if site24x7_monitors_res_json['message'] == 'success': site24x7_monitors_res_json['data']['state'] = dic_monitors['Web'][k]['Site24x7']['state'] dic_monitors['Web'][k]['Site24x7'] = site24x7_monitors_res_json['data'] else: logging.error("site24x7_monitors_res_json:[%s]", site24x7_monitors_res_json) logging.error("Site24x7_Payload_Monitors_Update:[%s]", Site24x7_Payload_Monitors_Update) else: logging.info("Site24x7 - Monitors (Web) - Insert") logging.info("Site24x7_Payload_Monitors_Update:[%s]", Site24x7_Payload_Monitors_Update) site24x7_monitors_res = requests.post(Site24x7_Url_Base + "/monitors", data=json.dumps(Site24x7_Payload_Monitors_Update), headers=Site24x7_Auth_Headers) site24x7_monitors_res_json = site24x7_monitors_res.json() if site24x7_monitors_res_json['message'] == 'success': site24x7_monitors_res_json['data']['state'] = 5 dic_monitors['Web'][k]['Site24x7'] = site24x7_monitors_res_json['data'] else: logging.error("site24x7_monitors_res_json:[%s]", site24x7_monitors_res_json) logging.error("Site24x7_Payload_Monitors_Update:[%s]", Site24x7_Payload_Monitors_Update) site24x7_monitors_res = requests.get(Site24x7_Url_Base + "/current_status/" + dic_monitors['Web'][k]['Site24x7']['monitor_id'], headers=Site24x7_Auth_Headers) site24x7_monitors_res_json = site24x7_monitors_res.json() logging.debug("site24x7_monitors_res_json:[%s]", site24x7_monitors_res_json) if site24x7_monitors_res_json['message'] == 'success': if 'status' in site24x7_monitors_res_json['data']: if dic_monitors['Web'][k]['Site24x7']['state'] == 5: # ID Status # 0 Down # 1 Up # 2 Trouble # 5 Suspended # 7 Maintenance # 9 Discovery # 10 Configuration Error if site24x7_monitors_res_json['data']['status'] == 9 \ or site24x7_monitors_res_json['data']['status'] == 10: dic_monitors['Web'][k]['Site24x7']['state'] = site24x7_monitors_res_json['data']['status'] else: logging.error("site24x7_monitors_res_json:[%s]", site24x7_monitors_res_json) logging.error("Site24x7_Payload_Monitors_Update:[%s]", Site24x7_Payload_Monitors_Update) if dic_monitors['Web'][k]['cybozu']['Status'] == '運用中' \ and any(s.startswith('Site24x7') for s in dic_monitors['Web'][k]['cybozu']['Notification']): state = 0 if dic_monitors['Web'][k]['Site24x7']['state'] != state: logging.info("Site24x7 - Monitors (Web) - Activate") site24x7_monitors_res = requests.put( Site24x7_Url_Base + "/monitors/activate/" + dic_monitors['Web'][k]['Site24x7']['monitor_id'], headers=Site24x7_Auth_Headers) site24x7_monitors_res_json = site24x7_monitors_res.json() logging.debug("site24x7_monitors_res_json:[%s]", site24x7_monitors_res_json) if site24x7_monitors_res_json['message'] == 'success': dic_monitors['Web'][k]['Site24x7']['state'] = state else: logging.error("site24x7_monitors_res_json:[%s]", site24x7_monitors_res_json) else: state = 5 if dic_monitors['Web'][k]['Site24x7']['state'] != state: logging.info("Site24x7 - Monitors (Web) - Suspend") site24x7_monitors_res = requests.put( Site24x7_Url_Base + "/monitors/suspend/" + dic_monitors['Web'][k]['Site24x7']['monitor_id'], headers=Site24x7_Auth_Headers) site24x7_monitors_res_json = site24x7_monitors_res.json() logging.debug("site24x7_monitors_res_json:[%s]", site24x7_monitors_res_json) if site24x7_monitors_res_json['message'] == 'success': dic_monitors['Web'][k]['Site24x7']['state'] = state else: logging.error("site24x7_monitors_res_json:[%s]", site24x7_monitors_res_json) else: if 'Site24x7' in dic_monitors['Web'][k] \ and 'type' in dic_monitors['Web'][k]['Site24x7'] \ and dic_monitors['Web'][k]['Site24x7']['type'] == 'URL': del_monitors.append(k) else: pass return del_monitors def unsetSite24x7Monitors(del_monitors): """UnSet Site24x7 Monitors""" logging.debug("==== Site24x7 - UnSet Monitors (Web) to System ====") for n, k in enumerate(del_monitors): logging.debug("(%04d/%04d) Site24x7 - Monitors (Web) - [%s]:[%s]", n + 1, len(dic_monitors['Web']), k, dic_monitors['Web'][k]) logging.info("Site24x7 - Monitors (Web) - Delete") site24x7_monitors_res = requests.delete(Site24x7_Url_Base + "/monitors/" + dic_monitors['Web'][k]['Site24x7']['monitor_id'], headers=Site24x7_Auth_Headers) site24x7_monitors_res_json = site24x7_monitors_res.json() logging.info("site24x7_monitors_res_json:[%s]", site24x7_monitors_res_json) if site24x7_monitors_res_json['message'] == 'success': dic_monitors['Web'][k].pop('Site24x7') else: logging.error("site24x7_monitors_res_json:[%s]", site24x7_monitors_res_json) def getStatusCakeContactGroups(): """Get StatusCake ContactGroups""" logging.debug("==== StatusCake - Get ContactGroups Json ====") statucake_contactgroups = requests.get(StatusCake_Url_Base + '/ContactGroups?Mobiles=true', headers=StatusCake_Auth_Headers) statucake_contactgroups_json = statucake_contactgroups.json() logging.debug("statucake_contactgroups_json:[%s]", statucake_contactgroups_json) for n, k in enumerate(list(statucake_contactgroups_json)): logging.debug("(%04d/%04d) StatusCake - ContactGroups | " \ "ID:[%s] Name:[%s] Mails:[%s] Mobiles:[%s]", n + 1, len(statucake_contactgroups_json), statucake_contactgroups_json[n]['ContactID'], statucake_contactgroups_json[n]['GroupName'], statucake_contactgroups_json[n]['Emails'], statucake_contactgroups_json[n]['Mobiles']) usergroup_id = statucake_contactgroups_json[n]['GroupName'] if len(usergroup_id) == 0: continue if not usergroup_id in dic_usergroups: dic_usergroups[usergroup_id] = {} if not 'StatusCake' in dic_usergroups[usergroup_id]: dic_usergroups[usergroup_id]['StatusCake'] = {} dic_usergroups[usergroup_id]['StatusCake'][statucake_contactgroups_json[n]['ContactID']] = statucake_contactgroups_json[n] def setStatusCakeContactGroups(): """Set StatusCake ContactGroups""" logging.debug("==== StatusCake - Set ContactGroups to System ====") for n, k in enumerate(list(dic_usergroups)): logging.debug("(%04d/%04d) UserGroups - [%s]:[%s]", n + 1, len(dic_usergroups), k, dic_usergroups[k]) statucake_usergroups_res = "" mobiles = [] if 'phones' in dic_usergroups[k]: for phone in dic_usergroups[k]['phones']: phone = re.sub('[-() ]', '',phone).lstrip('0') if not phone: continue if phone[1:2] != "0": continue mobiles.append("81" + phone) if 'cybozu' in dic_usergroups[k]: if 'StatusCake' in dic_usergroups[k]: for nn, kk in enumerate(list(dic_usergroups[k]['StatusCake'])): if nn == 0: StatusCake_Payload_ContactGroups_Update = { 'GroupName' : k, 'DesktopAlert' : 0, 'Email' : ','.join(sorted(dic_usergroups[k]['mails'])), 'Boxcar' : '', 'Pushover' : '', 'PingURL' : '', 'Mobile' : ",".join(sorted(mobiles)), 'ContactID' : kk, } logging.info("StatusCake - UserGroups - Update") logging.debug("StatusCake_Payload_ContactGroups_Update:[%s]", StatusCake_Payload_ContactGroups_Update) statucake_usergroups_res = requests.put( StatusCake_Url_Base + "/ContactGroups/Update/?ContactID=" + str(dic_usergroups[k]['StatusCake'][kk]['ContactID']), data=StatusCake_Payload_ContactGroups_Update, headers=StatusCake_Auth_Headers) statucake_usergroups_res_json = statucake_usergroups_res.json() logging.debug("statucake_usergroups_res_json:[%s]", statucake_usergroups_res_json) if statucake_usergroups_res_json['Success']: dic_usergroups[k]['StatusCake'][kk] = StatusCake_Payload_ContactGroups_Update elif statucake_usergroups_res_json['Message'].startswith('No update made. Given:'): logging.warn("statucake_usergroups_res_json:[%s]", statucake_usergroups_res_json) else: logging.error("statucake_usergroups_res_json:[%s]", statucake_usergroups_res_json) continue # logging.info("StatusCake - UserGroups - Delete") statucake_usergroups_res = requests.delete( StatusCake_Url_Base + "/ContactGroups/Update/?ContactID=" + str(dic_usergroups[k]['StatusCake'][kk]['ContactID']), headers=StatusCake_Auth_Headers) statucake_usergroups_res_json = statucake_usergroups_res.json() logging.debug("statucake_usergroups_res_json:[%s]", statucake_usergroups_res_json) if statucake_usergroups_res_json['Success']: del(dic_usergroups[k]['StatusCake'][kk]) else: logging.error("statucake_usergroups_res_json:[%s]", statucake_usergroups_res_json) else: logging.info("StatusCake - UserGroups - Insert") StatusCake_Payload_ContactGroups_Insert = { 'GroupName' : k, 'DesktopAlert' : 0, 'Email' : ','.join(sorted(dic_usergroups[k]['mails'])), 'Boxcar' : '', 'Pushover' : '', 'PingURL' : '', 'Mobile' : ",".join(sorted(mobiles)), } logging.debug("StatusCake_Payload_ContactGroups_Insert:[%s]", StatusCake_Payload_ContactGroups_Insert) statucake_usergroups_res = requests.put(StatusCake_Url_Base + '/ContactGroups/Update', data=StatusCake_Payload_ContactGroups_Insert, headers=StatusCake_Auth_Headers) statucake_usergroups_res_json = statucake_usergroups_res.json() logging.debug("statucake_usergroups_res_json:[%s]", statucake_usergroups_res_json) if statucake_usergroups_res_json['Success']: dic_usergroups[k]['StatusCake'] = {} dic_usergroups[k]['StatusCake'][statucake_usergroups_res_json['InsertID']] = statucake_usergroups_res_json['Data'] dic_usergroups[k]['StatusCake'][statucake_usergroups_res_json['InsertID']]['ContactID'] = statucake_usergroups_res_json['InsertID'] else: logging.error("statucake_usergroups_res_json:[%s]", statucake_usergroups_res_json) else: if 'StatusCake' in dic_usergroups[k]: for nn, kk in enumerate(list(dic_usergroups[k]['StatusCake'])): if dic_usergroups[k]['StatusCake'][kk]['GroupName'] in {"Paused"}: continue logging.info("StatusCake - UserGroups - Delete") statucake_usergroups_res = requests.delete( StatusCake_Url_Base + "/ContactGroups/Update/?ContactID=" + str(dic_usergroups[k]['StatusCake'][kk]['ContactID']), headers=StatusCake_Auth_Headers) statucake_usergroups_res_json = statucake_usergroups_res.json() logging.debug("statucake_usergroups_res_json:[%s]", statucake_usergroups_res_json) if statucake_usergroups_res_json['Success']: del(dic_usergroups[k]['StatusCake'][kk]) else: logging.error("statucake_usergroups_res_json:[%s]", statucake_usergroups_res_json) def getStatusCakeTests(): """Get StatusCake Tests""" logging.debug("==== StatusCake - Get Tests Json ====") statucake_tests = requests.get(StatusCake_Url_Base + '/Tests', headers=StatusCake_Auth_Headers) statucake_tests_json = statucake_tests.json() logging.debug("statucake_tests_json:[%s]", statucake_tests_json) for n, k in enumerate(list(statucake_tests_json)): logging.debug("(%04d/%04d) StatusCake - Tests | " \ "ID:[%08d] Pause:[%d] Public:[%d] NmlRes:[%d] Uptime:[%03d] Status:[%s] Type:[%s] Name:[%s] Groups:[%s]", n + 1, len(statucake_tests_json), statucake_tests_json[n]['TestID'], statucake_tests_json[n]['Paused'], statucake_tests_json[n]['Public'], statucake_tests_json[n]['NormalisedResponse'], 0 if statucake_tests_json[n]['Uptime'] is None else statucake_tests_json[n]['Uptime'], statucake_tests_json[n]['Status'], statucake_tests_json[n]['TestType'], statucake_tests_json[n]['WebsiteName'], ",".join(statucake_tests_json[n]['ContactGroup'])) statucake_tests_details = requests.get(StatusCake_Url_Base + '/Tests/Details', params={'TestID':str(statucake_tests_json[n]['TestID'])}, headers=StatusCake_Auth_Headers) statucake_tests_details = statucake_tests_details.json() logging.debug("StatusCake - Details - [%s]", statucake_tests_details) logging.debug("StatusCake - Details - Name:[%s] Url:[%s]", statucake_tests_details['WebsiteName'], statucake_tests_details['URI']) key = "???" tgt = "" if statucake_tests_json[n]['TestType'] in {"HTTP"}: key = "Web" tgt = statucake_tests_details['URI'].rstrip('/') elif statucake_tests_json[n]['TestType'] in {"DNS"}: key = "DNS" tgt = statucake_tests_details['URI'].rstrip('/') elif statucake_tests_json[n]['TestType'] in {"HEAD", "TCP", "SMTP", "SSH", "PING", "PUSH"}: pass else: pass if len(tgt) > 0: if tgt in dic_monitors[key]: dic_monitors[key][tgt]['StatusCake'] = statucake_tests_details else: dic_monitors[key][tgt] = {} dic_monitors[key][tgt]['StatusCake'] = statucake_tests_details def setStatusCakeTests(): """Set StatusCake Tests""" logging.debug("==== StatusCake - Set Tests to System ====") for n, k in enumerate(list(dic_monitors['Web'])): logging.debug("(%04d/%04d) StatusCake - Tests - [%s]:[%s]", n + 1, len(dic_monitors['Web']), k, dic_monitors['Web'][k]) statuscake_tests_res = "" if 'cybozu' in dic_monitors['Web'][k]: paused = True if dic_monitors['Web'][k]['cybozu']['Status'] == '運用中' \ and any(s.startswith('StatusCake') for s in dic_monitors['Web'][k]['cybozu']['Notification']): paused = False user_group_ids = [] for usergroup_id in dic_monitors['Web'][k]['usergroup_ids']: if not usergroup_id in dic_usergroups: continue if not 'StatusCake' in dic_usergroups[usergroup_id]: continue logging.debug("dic_usergroups[usergroup_id]['StatusCake']:[%s]", dic_usergroups[usergroup_id]['StatusCake']) for kk in list(dic_usergroups[usergroup_id]['StatusCake']): user_group_ids.append(dic_usergroups[usergroup_id]['StatusCake'][kk]['ContactID']) if paused: user_group_ids.append(list(dic_usergroups['Paused']['StatusCake'].keys())[0]) if 'StatusCake' in dic_monitors['Web'][k] \ and 'TestType' in dic_monitors['Web'][k]['StatusCake'] \ and dic_monitors['Web'][k]['StatusCake']['TestType'] == 'HTTP': StatusCake_Payload_Tests_Update = "" if dic_monitors['Web'][k]['StatusCake']['URI'] != k: StatusCake_Payload_Tests_Update += "&WebsiteURL=" + k if dic_monitors['Web'][k]['StatusCake']['Paused'] != paused: StatusCake_Payload_Tests_Update += "&Paused=" + str(int(paused)) contactgroup_ids = [] for contactgroup in dic_monitors['Web'][k]['StatusCake']['ContactGroups']: contactgroup_ids.append(contactgroup['ID']) if sorted(contactgroup_ids) != sorted(user_group_ids): StatusCake_Payload_Tests_Update += "&ContactGroup=" + ','.join(sorted(map(str,user_group_ids))) if dic_monitors['Web'][k]['StatusCake']['WebsiteName'] != k: StatusCake_Payload_Tests_Update += "&WebsiteName=" + k if dic_monitors['Web'][k]['StatusCake']['CheckRate'] != 300: StatusCake_Payload_Tests_Update += "&CheckRate=300" if dic_monitors['Web'][k]['StatusCake']['Timeout'] != 15: StatusCake_Payload_Tests_Update += "&Timeout=15" if dic_monitors['Web'][k]['StatusCake']['NodeLocations'] != ['JP1']: StatusCake_Payload_Tests_Update += "&NodeLocations=JP1" if dic_monitors['Web'][k]['StatusCake']['Tags'] != [dic_monitors['Web'][k]['cybozu']['Category']]: StatusCake_Payload_Tests_Update += "&TestTags=" + dic_monitors['Web'][k]['cybozu']['Category'] if sorted(dic_monitors['Web'][k]['StatusCake']['StatusCodes']) != sorted(StatusCake_StatusCodes): StatusCake_Payload_Tests_Update += "&StatusCodes=" + ",".join(sorted(StatusCake_StatusCodes)) if StatusCake_Payload_Tests_Update != "": logging.info("StatusCake - Monitors (Web) - Update") StatusCake_Payload_Tests_Update = "TestID=" + str(dic_monitors['Web'][k]['StatusCake']['TestID']) + StatusCake_Payload_Tests_Update logging.info("StatusCake_Payload_Tests_Update:[%s]", StatusCake_Payload_Tests_Update) statuscake_tests_res = requests.put(StatusCake_Url_Base + '/Tests/Update', #data=StatusCake_Payload_Tests_Update, data=StatusCake_Payload_Tests_Update.encode('utf-8'), headers=StatusCake_Auth_Headers) statuscake_tests_res_json = statuscake_tests_res.json() logging.info("statuscake_tests_res_res_json:[%s]", statuscake_tests_res_json) if statuscake_tests_res_json['Success'] == True: dic_monitors['Web'][k]['StatusCake'] = StatusCake_Payload_Tests_Update elif statuscake_tests_res_json['Message'].startswith('No data has been updated (is any data different?) Given:'): logging.warn("statuscake_tests_res_res_json:[%s]", statuscake_tests_res_json) else: logging.error("statuscake_tests_res_res_json:[%s]", statuscake_tests_res_json) else: StatusCake_Payload_Tests_Insert = "TestType=HTTP&CheckRate=300&Timeout=15&NodeLocations=JP1" StatusCake_Payload_Tests_Insert += "&WebsiteURL=" + k StatusCake_Payload_Tests_Insert += "&Paused=" + str(int(paused)) StatusCake_Payload_Tests_Insert += "&WebsiteName=" + k StatusCake_Payload_Tests_Insert += "&TestTags=" + dic_monitors['Web'][k]['cybozu']['Category'] StatusCake_Payload_Tests_Insert += "&StatusCodes=" + ",".join(sorted(StatusCake_StatusCodes)) if len(user_group_ids) > 0: StatusCake_Payload_Tests_Insert += "&ContactGroup=" + ','.join(sorted(map(str,user_group_ids))) logging.info("StatusCake - Monitors (Web) - Insert") logging.info("StatusCake_Payload_Tests_Insert:[%s]", StatusCake_Payload_Tests_Insert) statuscake_tests_res = requests.put(StatusCake_Url_Base + '/Tests/Update', data=StatusCake_Payload_Tests_Insert.encode('utf-8'), headers=StatusCake_Auth_Headers) statuscake_tests_res_json = statuscake_tests_res.json() logging.info("statuscake_tests_res_res_json:[%s]", statuscake_tests_res_json) if statuscake_tests_res_json['Success'] == True: dic_monitors['Web'][k]['StatusCake'] = statuscake_tests_res_json['Data'] dic_monitors['Web'][k]['StatusCake']['TestID'] = statuscake_tests_res_json['InsertID'] else: logging.error("statuscake_tests_res_res_json:[%s]", statuscake_tests_res_json) else: if 'StatusCake' in dic_monitors['Web'][k] \ and 'TestType' in dic_monitors['Web'][k]['StatusCake'] \ and dic_monitors['Web'][k]['StatusCake']['TestType'] == 'HTTP': logging.info("StatusCake - Tests (Web) - Delete") statuscake_tests_res = requests.delete(StatusCake_Url_Base + '/Tests/Details', params={'TestID':str(dic_monitors['Web'][k]['StatusCake']['TestID'])}, headers=StatusCake_Auth_Headers) statuscake_tests_res_json = statuscake_tests_res.json() logging.info("statuscake_tests_res_json:[%s]", statuscake_tests_res_json) if statuscake_tests_res_json['Success'] == True: dic_monitors['Web'][k].pop('StatusCake') else: logging.error("statuscake_tests_res_res_json:[%s]", statuscake_tests_res_json) else: pass # ------------------------------------------------------------------------------ # Program Start # ------------------------------------------------------------------------------ if __name__ == '__main__': getCybozuUsers() getCybozuMonitors() getSite24x7Users() del_users = setSite24x7Users() getSite24x7UserGroups() del_usergroups = setSite24x7UserGroups() getSite24x7MonitorGroups() del_monitorgroups = setSite24x7MonitorGroups() getSite24x7Monitors() del_monitors = setSite24x7Monitors() unsetSite24x7MonitorGroups(del_monitorgroups) unsetSite24x7Monitors(del_monitors) unsetSite24x7UserGroups(del_usergroups) unsetSite24x7Users(del_users) getStatusCakeContactGroups() setStatusCakeContactGroups() getStatusCakeTests() setStatusCakeTests() # -------------------------------------------------------------------------- # Mail - Create Message # -------------------------------------------------------------------------- stadt = nowdt enddt = datetime.datetime.today() # Subject subject = """[%s] Set Site Monitors From Cybozu""" % (nowdt) logging.debug("subject : [%s]", subject) # Message cmd = "grep -v DEBUG " + __file__ + ".log" logging.debug("cmd : [%s]", cmd) p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) stdout_data, stderr_data = p.communicate() msg = """\ %s - %s ---- 【ジョブ実行結果】 %s """ % (stadt, enddt, str(stdout_data, encoding='utf-8')) # logging.debug("msg : [%s]", msg) #sys.exit() # -------------------------------------------------------------------------- # Mail - Send # -------------------------------------------------------------------------- message = MIMEText(msg, 'plain', 'utf-8') message['Subject'] = Header(subject, 'utf-8') message['From'] = MailFrom message['To'] = MailTo con = smtplib.SMTP(HostSMTP) con.set_debuglevel(True) con.starttls() con.login(LoginAccount, LoginPassword) con.sendmail(MailFrom, MailTo, message.as_string()) con.close() # ------------------------------------------------------------------------------ # Program End # ------------------------------------------------------------------------------ logging.debug("<<<<<<<< %s End >>>>>>>>", __file__) # ---1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----
1. プログラムの動作としては、以下の様な感じです。基本的には、main 処理の流れです。
1. cybozu から、ユーザー情報を取得する。 2. cybozu (Kintone のサイト管理用アプリ) から、サイト情報を取得する。 3. Site24x7 から、ユーザー情報を取得する。 4. cybozu の情報を元に、Site24x7 へ、ユーザー情報を設定する。 5. Site24x7 から、ユーザーグループ情報を取得する。 6. cybozu の情報を元に、Site24x7 へ、ユーザーグループ情報を設定する。 7. Site24x7 から、モニターグループ情報を取得する。 8. cybozu の情報を元に、Site24x7 へ、モニターグループ情報を設定する。 9. Site24x7 から、モニター情報を取得する。 10. cybozu の情報を元に、Site24x7 へ、モニター情報を設定する。 11. Site24x7 から、不要なモニターグループ情報を削除する。 12. Site24x7 から、不要なモニター情報を削除する。 13. Site24x7 から、不要なユーザーグループ情報を削除する。 14. Site24x7 から、不要なユーザー情報を削除する。 15. StatusCake から、コンタクトグループ情報を取得する。 16. cybozu の情報を元に、StatusCake へ、コンタクトグループ情報を設定する。 17. StatusCake から、テスト情報を取得する。 18. cybozu の情報を元に、StatusCake へ、テスト情報を設定する。 19. 結果をメールで通知する。
1. 基本的な考え方として、
* cybozu の情報がマスタであり、各監視サービスの設定はそれに合わせる。 * 当プログラムを日次で実行し、各監視サービスの設定を更新する。 * 設定に変更が無い場合は、API を投げない。
1. 以下は、メール絡みの情報ですので、設定して下さい。
* 当方は、587 ポートで利用していたので、それ以外のやり方だと問題出るかもしれません。
```bash
# Mail
HostSMTP = '[メールサーバ:ポート番号]'
MailFrom = '[送信元メールアドレス]'
MailTo = '[送信先メールアドレス]'
LoginAccount = '[認証アカウント]'
LoginPassword = '[認証パスワード]'
```
1. 以下は、cybozu 絡みの情報ですので、設定して下さい。
* わからない場合は、以下を参照のこと。 * [kintone REST APIの共通仕様 – cybozu developer network](https://developer.cybozu.io/hc/ja/articles/201941754)
```bash
# cybozu.com
Cybozu_Url_Base = 'https://[取得したサブドメイン].cybozu.com'
Cybozu_Auth_Headers_UserAPI = {
'X-Cybozu-Authorization':'[APIキー]',
'If-Modified-Since' : 'Thu, 01 Jun 1970 00:00:00 GMT'}
Cybozu_Auth_Headers_KintoneAPI = {
'X-Cybozu-API-Token' : '[KintoneのAPIトークンキー]',
'Content-Type' : 'application/json; charset=UTF-8',
'If-Modified-Since' : 'Thu, 01 Jun 1970 00:00:00 GMT'}
```
1. 以下は、Site24x7 絡みの情報ですので、設定して下さい。
* わからない場合は、以下を参照のこと。 * [Site24x7 \| API Reference](https://www.site24x7.com/help/api/)
```bash
# Site24x7
Site24x7_Url_Base = 'https://www.site24x7.com/api'
Site24x7_Auth_Headers = {
'Content-Type' : 'application/json; charset=UTF-8',
'Accept' : 'application/json; version=2.0',
'Authorization' : '[APIキー]',
'If-Modified-Since' : 'Thu, 01 Jun 1970 00:00:00 GMT'}
```
1. 以下は、StatusCake 絡みの情報ですので、設定して下さい。
* わからない場合は、以下を参照のこと。 * [StatusCake API Documentation](https://www.statuscake.com/api/)
```bash
# StatusCake
StatusCake_Url_Base = 'https://app.statuscake.com/API'
StatusCake_Auth_Headers = {'API':'[APIキー]',
'Username' : '[ユーザーID]',
'Content-Type' : 'application/json; charset=UTF-8',
'If-Modified-Since' : 'Thu, 01 Jun 1970 00:00:00 GMT'}
StatusCake_StatusCodes = ["204","205","206","303","400","401","403","404","405","406","408","410","429","444","494","495","496","499","500","501","502","504","505","506","507","511","598","599"]
```
- 以下は、Site24x7 絡みの情報ですので、設定して下さい。
* わからない場合は、以下を参照のこと。 * [Site24x7 \| API Reference](https://www.site24x7.com/help/api/)
```bash
# Site24x7
Site24x7_Url_Base = 'https://www.site24x7.com/api'
Site24x7_Auth_Headers = {
'Content-Type' : 'application/json; charset=UTF-8',
'Accept' : 'application/json; version=2.0',
'Authorization' : '[APIキー]',
'If-Modified-Since' : 'Thu, 01 Jun 1970 00:00:00 GMT'}
```
1. getCybozuMonitors の以下のステップについて、
* Kintone アプリの ID を設定して下さい。 * あと、フィールドコードを変更した場合は、それに合わせてこちらも変更して下さい。 * ※ もしかしたら、他にも色々変更が必要になるかもしれません…。
```bash
cybozu_monitors = requests.get(Cybozu_Url_Base + "/k/v1/records.json",
headers=Cybozu_Auth_Headers_KintoneAPI,
data=json.dumps({
"app": [Kintone アプリの ID],
"query": "$id > 0 order by $id asc limit 500",
"fields": [
"$id",
"ステータス",
"Category",
"Title",
"Url",
"Notification",
"Users"],
"totalCount": "true"
})
)
```
1. setSite24x7Monitors の以下のステップについて、
* デフォルトで設定するユーザーグループを設定します。 * ID が異なることもあると思うので、ご注意を。
```bash
if len(user_group_ids) == 0:
user_group_ids = ['215015000000025003']
```
* 基本的にはデフォルトの設定をそのまま設定しています。
* ID が異なることもあると思うので、ご注意を。
```bash
Site24x7_Payload_Monitors_Update = {
"display_name": k,
"type": 'URL',
"website": k,
"check_frequency": '5',
"timeout": 15,
"location_profile_id": "215015000004406005",
"notification_profile_id": "215015000000025063",
"threshold_profile_id": "215015000000025114",
"user_group_ids": user_group_ids,
"http_method": "G",
"monitor_groups": monitor_groups,
"use_ipv6": False,
"match_case": True,
"probe_proxy_enabled": False,
"auth_method": 'B',
"ssl_protocol": 'Auto',
"use_name_server": False,
}
```
2−1.【2019.12.02 追記】
以下の記事に記載しましたが、Site24x7 の API 認証が変更になったので、
以下の変更が必要です。
こちらの関数を追加し、
def getSite24x7Token():
"""Set Site24x7 Token"""
logger.debug("==== Site24x7 - Set Token Json ====")
url = "https://accounts.zoho.com/oauth/v2/token"
headers = {
'Content-Type' : 'application/json; charset=UTF-8',
'Accept' : 'application/json; version=2.0',
'If-Modified-Since' : 'Thu, 01 Jun 1970 00:00:00 GMT'
}
payload = {
'client_id': '[Client ID]',
'client_secret': '[Client Secret]',
'refresh_token': '[リフレッシュトークン]',
'grant_type': 'refresh_token'
}
site24x7_token = requests.post(url, headers=headers, params=payload)
logger.debug("site24x7_token:[%s]", site24x7_token)
site24x7_token_json = site24x7_token.json()
logger.debug("site24x7_token_json:[%s]", site24x7_token_json)
return site24x7_token_json['access_token']
そして、lambda_handler
の最初の方に、こちらの処理を追加します。
token = getSite24x7Token()
global Site24x7_Auth_Headers
Site24x7_Auth_Headers['Authorization'] = 'Zoho-oauthtoken ' + token
logger.debug("Site24x7_Auth_Headers:[%s]", Site24x7_Auth_Headers)
99.ハマりポイント
- 今回も色々ハマりました…。
- Site24x7 のモニター情報の登録は出来たものの、停止状態が反映されず、結構悩みました。Active / Suspend の別の API を利用いなければいけないことがわかるまで、かなりの時間をつぎ込みました。
- StatusCake のコンタクトグループ情報を取得するも、モバイル情報が空で返されて、これもかなり悩みました。確認したところ、セキュリティ上の観点から空にしているとのこと。変更された場合のみ、更新する仕様としているので、毎回更新されワーニングが返る様になっています…。
- あと、これは私が悪いんですが、StatusCake の更新 API は基本的に、パラメタ渡しなんですが、json 渡しでもいけるだろとやってみたら出来たので、そのままプログラムを組んでいたら、Insert は問題ないんですが、どうも Update がうまくいかなくて、色々悩んだ挙句、パラメタ渡しに戻すことになり、この辺でも大分時間を使ってしまいました。やはり、ドキュメントに記載されている通りにしないとダメだよね。と反省…。
XX.まとめ
長々とプログラムを書いていますが、
とりあえずやりたいことは出来たので、ひとまず良かったです。