source: people/peter.buschman/backup_monitoring/parsing/parsers/bppllist/_bppllist.py

Last change on this file was 976, checked in by peter, on Dec 6, 2011 at 10:19:33 AM

Raw checkin of current NetBackup / TSM parsing code.

File size: 8.5 KB
Line 
1import re
2import pytz
3import dateutil
4import dateutil.parser
5
6from ....builtins import *
7
8from ...exceptions import *
9from ...expressions import *
10from ...autotype import *
11from ...streams import *
12
13from .. import bpplclients
14
15re_cannot_connect_on_socket = re.compile('^cannot connect on socket.*$')
16
17##
18## bppllist has records separated by blank lines
19##
20def stream(stream, format='bppllist -L'):
21
22 if format in ['bppllist -L']:
23 return BlankLineStream(stream, header=1)
24 else:
25 raise ParseError, 'Unknown format %s' % (format)
26
27
28##
29## Parse a bppllist record
30##
31## bppllist -L
32##
33def parse(record, format='bppllist -L', version=None, tz=None):
34
35 re_pair = re.compile('^\s*([^:]+):\s*(.*)$')
36 re_type_id = re.compile('^(.+)\s+\((\d+)\)$')
37 re_nbu_datetime = re.compile('^.*\d\d:\d\d:\d\d\s+\((\d+)\)$')
38
39 policy = ExtendedDict()
40
41 clients = ExtendedDict()
42 includes = []
43 excludes = []
44
45 policy['clients'] = clients
46 policy['includes'] = includes
47 policy['excludes'] = excludes
48
49 if re_cannot_connect_on_socket.match(record[0]):
50 return None
51
52 if format == 'bppllist -L':
53
54 header = True
55
56 try:
57
58 i = 0
59
60 #
61 # process policy header
62 #
63 while header and i < len(record):
64
65 line = record[i]
66
67 match = re_pair.match(line)
68
69 key = match.group(1)
70 value = match.group(2)
71 key = key.lower()
72 key = key.replace(' ', '_')
73 key = key.replace('.', '')
74 key = key.replace('/', '_')
75
76 if key == 'schedule':
77 header = False
78 else:
79
80 #
81 # match timestamp with Unix time in parentheses
82 #
83 match = re_nbu_datetime.match(line)
84 if match:
85 value = datetime.datetime.fromtimestamp(float(match.group(1)), tz)
86
87 #
88 # clients (entire line can be parsed with bpplclients parser)
89 #
90 elif key == 'client_hw_os_pri':
91 client = bpplclients.parse(line)
92 clients[client.client] = client
93 key = None
94
95 #
96 # no clients defined
97 #
98 elif key == 'clients' and value == '(none defined)':
99 value = []
100
101 #
102 # options
103 #
104 elif key == 'options':
105 value = int(value, 16) # convert to integer from hexadecimal string
106
107 #
108 # includes
109 #
110 elif key == 'include':
111 includes.append(value)
112 key = None
113
114 #
115 # excludes
116 #
117 elif key == 'exclude':
118 if value != '(none defined)':
119 excludes.append(value)
120 key = None
121
122 #
123 # effective date does not include a Unix timestamp
124 #
125 elif key == 'effective_date':
126 value = dateutil.parser.parse(value).replace(tzinfo=tz)
127
128 #
129 # separate type and id
130 #
131 elif re_type_id.match(value):
132 match = re_type_id.match(value)
133 idkey = '%s_id' % (key)
134 value = match.group(1)
135 policy[idkey] = int(match.group(2))
136
137 #
138 # values to replace with Python None datatype
139 #
140 elif value in ['(none)', '(none specified)', '(none defined)']:
141 value = None
142
143 #
144 # ..otherwise autodetect
145 #
146 else:
147 value = autotype(value)
148
149 #
150 #
151 #
152 if key is not None:
153 policy[key] = value
154
155 i += 1
156
157 #
158 # parse schedules
159 #
160 schedules = ExtendedDict()
161
162 while i < len(record):
163
164 line = record[i]
165
166 match = re_pair.match(line)
167
168 #
169 # this is typical key:value metadata
170 #
171 if match:
172
173 key = match.group(1)
174 value = match.group(2)
175 key = key.lower()
176 key = key.replace(' ', '_')
177 key = key.replace('-', '_')
178 key = key.replace('/', '_')
179
180 #
181 # identify current schedule
182 #
183 if key == 'schedule':
184
185 schedule = ExtendedDict()
186
187 schedule['schedule'] = value
188
189 schedules[value] = schedule
190
191 #
192 # type and type_id
193 #
194 elif key == 'type':
195 re_type_id.match(value)
196 match = re_type_id.match(value)
197 idkey = '%s_id' % (key)
198 value = match.group(1)
199 schedule[idkey] = int(match.group(2))
200
201 #
202 # daily windows
203 #
204 elif key == 'daily_windows':
205
206 daily_windows = ExtendedDict()
207
208 re_daily_window_labels = re.compile('\s+')
209 re_daily_window = re.compile('\s+')
210
211 i += 1
212 line = record[i]
213 labels = []
214 for label in re_daily_window_labels.split(line):
215 if label != '':
216 label = label.lower()
217 label = label.replace('-','_')
218 labels.append(label)
219 label_count = len(labels)
220
221 i += 1
222 for line in record[i:i+7]:
223
224 daily_window = ExtendedDict()
225
226 items = []
227 for item in re_daily_window.split(line):
228 if item != '':
229 item = item.lower()
230 items.append(item)
231
232 item_count = len(items)
233 for index in range(label_count):
234 label = labels[index]
235 if index < item_count:
236 item = items[index]
237 else:
238 item = None
239 daily_window[label] = item
240
241 daily_windows[daily_window.day] = daily_window
242
243 i += 7
244
245 value = daily_windows
246
247 #
248 # values to replace with Python None datatype
249 #
250 elif value in ['(none)', '(none specified)', '(none defined)']:
251 value = None
252
253 #
254 # ..otherwise autodetect
255 #
256 else:
257 value = autotype(value)
258
259 #
260 #
261 #
262 if key is not None:
263 schedule[key] = value
264
265 #
266 # this is not typical key:value metadata
267 #
268 else:
269 pass
270
271 i += 1
272
273 policy['schedules'] = schedules
274
275 return policy
276
277 except Exception, e:
278
279 for line in record:
280 print line
281
282 raise ParseError, e
283
284 else:
285
286 raise ParseError, 'Unknown format %s' % (format)
287
Note: See TracBrowser for help on using the repository browser.