-
Notifications
You must be signed in to change notification settings - Fork 0
/
devices.py
138 lines (124 loc) · 4.25 KB
/
devices.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
import json
import urllib2
import socket
import config as cfg
class Dev():
# test if given list of strings is a prefix of this device's kind
def kind_prefix(self, pfx):
if not self.kind or type(pfx) != list:
return False
if len(self.kind) < len(pfx):
return False
return all(map(lambda x: x[0] == x[1], zip(self.kind, pfx)))
# syntax: ? matches any (single) module, * matches any number of modules
# examples:
# kind_match(['juniper', '*']) is the same as kind_prefix(['juniper'])
# TODO
# TODO: extend to regexps
def kind_match(self, match_list):
return False
def set_kind(self, kind):
if type(kind) == list:
self.model = kind[0]
self.kind = kind
else:
self.model = kind
if kind:
if '.' in kind:
self.kind = kind.split('.')
else:
self.kind = [kind]
else:
self.kind = None
def __init__(self, hostname=None, kind=None, autodetect_model=True, name=None):
self.hostname = hostname
if name is not None:
self.name = name
else: # set name based on hostname
try:
socket.inet_pton(socket.AF_INET, hostname)
# we have an IP address as hostname
self.name = hostname
except AttributeError:
if hostname is not None and '.' in hostname:
self.name = hostname.split('.')[0]
else:
self.name = hostname
self.autodetect_model = autodetect_model
self.set_kind(kind)
def __str__(self):
return str({'name': self.name, 'hostname': self.hostname, 'model': self.model, 'kind': self.kind})
def __repr__(self):
return self.__str__()
def read_dev_file(filename):
f = open(filename, 'r')
lines = f.readlines()
devices = []
for l in lines:
l = l.strip()
if len(l) == 0:
continue
if l[0] == '#':
continue
record = l.split()
if len(record) < 2:
continue
hostname = record[0].strip()
kind = record[1].split('.')
kind = map(lambda s: s.strip(), kind)
name = None
if len(record) > 2:
name = record[2]
if len(hostname) == 0:
continue
for k in kind:
if len(k) == 0:
continue
devices.append(Dev(hostname, kind, name=name))
return devices
def read_dev_url(url):
response = urllib2.urlopen(url)
response_body = response.read()
raw_list = json.loads(response_body)
devices = []
for dev in raw_list:
if 'name' and 'address' in dev:
d = Dev()
d.hostname = dev['address']
d.name = dev['name']
if 'model' in dev:
d.model = dev['model']
devices.append(d)
return devices
def get_dev_list():
source = cfg.get('devices', 'dev_source')
default_type = 'hp'
dev_list = []
name_blacklist = cfg.get_list('devices', 'name_blacklist')
if source == 'config':
hostnames = cfg.get_list('devices', 'devs')
types = [s.split('.') for s in cfg.get_list('devices', 'types')]
dev_list = [Dev(h[0], h[1]) for h in zip(hostnames, types)]
elif source == 'rancidfile':
filename = cfg.get('devices', 'rancidfile')
rancidfile = open(filename, 'r')
lines = rancidfile.readlines()
for l in lines:
if len(l.strip()) > 0:
record = l.split(':')
if record[2].startswith('up'):
dev_list.append(Dev(record[0], [record[1]]))
elif source == 'file':
filename = cfg.get('devices', 'file')
dev_list = read_dev_file(filename)
elif source == 'url':
url = cfg.get('devices', 'url')
dev_list = read_dev_url(url)
else:
raise Exception('Unknown devices source in the config file: ' + str(source))
# leave only the devices which names do not contain strings from the
# blacklist
dev_list = [d for d in dev_list if not any(
[name in d.hostname for name in name_blacklist])]
print dev_list
return dev_list