Skip to content

Instantly share code, notes, and snippets.

@mochipon
Last active February 21, 2018 16:41
Show Gist options
  • Save mochipon/70262738ec54e0321f4f155882aab72a to your computer and use it in GitHub Desktop.
Save mochipon/70262738ec54e0321f4f155882aab72a to your computer and use it in GitHub Desktop.
checkipam
gitdb2==2.0.3
GitPython==2.1.8
joblib==0.11
slackweb==1.0.5
smmap2==2.0.3
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import csv
import ipaddress
import logging
import os
import subprocess
from tempfile import TemporaryDirectory
from git import Repo, Git
from joblib import Parallel, delayed
from slackweb import Slack
logging.basicConfig(level=logging.DEBUG)
logger = logging.getLogger(__name__)
# Global vars
targets = [
'172.16.0.0/24', # mgmt_for_vms
'172.16.101.0/24', # mgmt.tky1
'172.16.102.0/24', # mgmt.tky2
'172.16.103.0/24', # mgmt.tky3
'172.16.104.0/24', # mgmt.tky4
'153.16.71.160/28', # LISP
'153.16.71.176/28', # LISP
'103.202.216.192/26', # Sukiyaki Global Address
'2403:bd80:c002::/48' # Sukiyaki Global Address
]
slack_webhookurl = '<snip>'
git_ssh_identity_filepath = os.path.dirname(os.path.abspath(__file__)) + '/id_rsa'
def get_records():
records = []
git_ssh_cmd = 'ssh -i %s' % git_ssh_identity_filepath
with TemporaryDirectory() as temp_path:
Repo.clone_from(
'git@github.com:sukiyaki/sukiyaki.git',
temp_path,
env={
'GIT_SSH_COMMAND': git_ssh_cmd
})
csv_filepath = '%s/ipam_backup.csv' % temp_path
with open(csv_filepath, 'r', encoding='utf-8') as c:
reader = csv.DictReader(c)
for record in reader:
# Check only 'Active' addresses
if record['status'] != 'Active': continue
# Simply copy the record
records.append(record)
return records
def get_targethosts(records):
targethosts = []
# IPAddr matching check (Step 1): Calculate the netmask upfront
# Note that we may evaluate a lot of addresses,
# simple methods like 'ip_address(hoge) in ip_network(fuga)' could take long time
targetsubnets = []
for target in targets:
n = ipaddress.ip_network(target)
targetsubnets.append({
'network': int(n.network_address),
'mask': int(n.netmask)
})
for record in records:
# IPAddr matching check (Step 2): calculate the binary representation
addr_str = record['address'].split('/')[0]
addr_int = int(ipaddress.ip_address(addr_str))
# IPAddr matching check (Step 3)
for targetsubnet in targetsubnets:
ip_in_network = (
addr_int & targetsubnet['mask']) == targetsubnet['network']
if ip_in_network:
targethosts.append(record)
break
return targethosts
def do_ping(host):
if ipaddress.ip_address(host).version == 4:
return subprocess.call(
"/sbin/ping -q -c 1 %s > /dev/null" % host, shell=True) == 0
else:
return subprocess.call(
"/sbin/ping6 -q -c 1 %s > /dev/null" % host, shell=True) == 0
def check_alive(host):
addr_str = host['address'].split('/')[0]
if not do_ping(addr_str):
return {'address': addr_str, 'description': host['description']}
else:
return None
def notify_slack(deadhosts):
slack = Slack(url=slack_webhookurl)
attachments = []
for deadhost in deadhosts:
attachment = {
'color': 'danger',
'title': deadhost['address'],
'text': deadhost['description']
}
attachments.append(attachment)
if len(attachments) == 0:
attachment = {'color': 'good', 'title': 'すべてのホストに疎通性がありました'}
attachments.append(attachment)
slack.notify(channel="#pingdead", attachments=attachments)
def main():
records = get_records()
logger.debug('get_records: Got %d records from GitHub' % len(records))
targethosts = get_targethosts(records)
logger.debug('get_targethosts: Filtered %d/%d' % (len(targethosts),
len(records)))
deadhosts = Parallel(n_jobs=6)(
[delayed(check_alive)(host) for host in targethosts])
deadhosts = [x for x in deadhosts if x] # Remove 'None' from a list
logger.debug('check_alive: deadhosts->%d' % len(deadhosts))
notify_slack(deadhosts)
logger.debug('notify_slack: Done')
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment