source: people/peter.buschman/backup_monitoring/backmon/lib/environment.py@ 1191

Last change on this file since 1191 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: 17.6 KB
Line 
1###
2### backmon.lib.environment
3###
4
5import sys
6import os.path
7import glob
8import time
9
10import backup_monitoring.builtins
11
12from backup_monitoring.parsing.exceptions import ParseError
13from backup_monitoring.parsing.routines import strip_domain
14
15from backup_monitoring.parsing.parsers import nbemmcmd
16from backup_monitoring.parsing.parsers import bpstulist
17from backup_monitoring.parsing.parsers import df
18from backup_monitoring.parsing.parsers import dsu_ls_l
19from backup_monitoring.parsing.parsers import nbstlutil
20from backup_monitoring.parsing.parsers import bpdbjobs
21from backup_monitoring.parsing.parsers import nbdevquery
22from backup_monitoring.parsing.parsers import vmpool
23from backup_monitoring.parsing.parsers import vmquery
24from backup_monitoring.parsing.parsers import bpmedialist
25from backup_monitoring.parsing.parsers import bpplclients
26from backup_monitoring.parsing.parsers import bpretlevel
27from backup_monitoring.parsing.parsers import bppllist
28
29from .exceptions import BackmonError
30from .updates import *
31
32class Environment(object):
33
34 def __init__(self, name, logger, updates, master, media, tz=None):
35
36 self.name = name
37 self.logger = logger
38 self.tz = tz
39 self.alias = name.lower()
40 self.master = master
41 self.media_servers = media
42 self.updates = ExtendedDict()
43 self.buffers = ExtendedDict()
44 self.aliases = ExtendedDict()
45 self.stunits = ExtendedDict()
46 self.df_data = ExtendedDict()
47 self.dsu_contents = ExtendedDict()
48 self.lifecycle_images = ExtendedDict()
49 self.jobs = ExtendedDict()
50 self.disk_pools = ExtendedDict()
51 self.pools = ExtendedDict()
52 self.volumes = ExtendedDict()
53 self.media = ExtendedDict()
54 self.scratch_pool = ''
55 self.clients = ExtendedDict()
56 self.retlevels = ExtendedDict()
57 self.policies = ExtendedDict()
58
59 self.logger.debug('name=%s, alias=%s, master=%s' % (self.name, self.alias, self.master))
60
61 for server in self.media_servers:
62 self.logger.debug('media=%s' % (server))
63
64 if not os.path.isdir(updates):
65 raise BackmonError('Updates directory %s does not exist!' % (updates))
66 else:
67 for path in glob.glob(os.path.join(updates, '*')):
68 server = os.path.basename(path)
69 self.logger.debug('+ %s -> %s' % (server, path))
70 self.updates[server] = Updates(logger, path)
71
72 #
73 # feed() - wrapper interface to server updates objects feed methods
74 #
75 def feed(self, server, feed):
76
77 try:
78
79 return self.updates[server].feed(feed)
80
81 except Exception, e:
82
83 raise BackmonError, e
84
85 #
86 # buffer() - buffer feed in memory
87 #
88 def buffer(self, server, feed):
89
90 try:
91
92 buffer = '%s.%s' % (server, feed)
93 self.logger.debug('buffering %s...' % (buffer))
94 self.buffers[buffer] = self.feed(server, feed)
95
96 except Exception, e:
97
98 raise BackmonError, e
99
100 #
101 # refresh() - refresh buffers
102 #
103 def refresh(self, objects=[]):
104
105 try:
106
107 master = self.master
108
109 if 'aliases' in objects:
110
111 self.buffer(master, 'nbemmcmd_machinealias_getaliases')
112
113 if 'jobs' in objects:
114
115 self.buffer(master, 'bpdbjobs_most_columns')
116
117 except Exception, e:
118
119 raise BackmonError, e
120
121 #
122 # load_feeds() - load a set of input feeds in preparation for parsing
123 #
124 def load_feeds(self, master=[], media=[], client=[]):
125
126 self.logger.debug('%s - loading feeds..' % (self.name))
127
128 try:
129
130 server = self.master
131
132 for feed in master:
133 self.buffer(server, feed)
134
135 for feed in media:
136 for server in self.media_servers:
137 self.buffer(server, feed)
138
139 except Exception, e:
140
141 raise BackmonError, e
142
143 #
144 # parse_aliases() - parse aliases
145 #
146 def parse_aliases(self):
147
148 self.logger.debug('%s - parsing aliases..' % (self.name))
149
150 master = self.master
151
152 try:
153
154 buffer = '%s.nbemmcmd_machinealias_getaliases' % (master)
155
156 if buffer in self.buffers:
157
158 self.aliases = ExtendedDict()
159
160 stream = nbemmcmd.stream(self.buffers[buffer], format='nbemmcmd -machinealias -getaliases')
161
162 for record in stream:
163
164 alias, aliases = nbemmcmd.parse(record, format='nbemmcmd -machinealias -getaliases', tz=self.tz)
165
166 self.aliases[alias] = aliases
167
168 else:
169
170 raise BackmonError, 'buffer %s is empty!' % (buffer)
171
172 except ParseError, e:
173 raise BackmonError, e
174
175 #
176 # resolve_alias() - resolve alias to server receiving updates
177 #
178 def resolve_alias(self, alias):
179
180 try:
181
182 if alias not in self.aliases:
183 return strip_domain(alias)
184 else:
185 for server in self.aliases[alias]:
186 if server in self.updates:
187 return server
188
189 return strip_domain(alias)
190
191 except Exception, e:
192 raise BackmonError, e
193
194 #
195 # parse_stunits() - parse storage units
196 #
197 def parse_stunits(self):
198
199 self.logger.debug('%s - parsing stunits..' % (self.name))
200
201 master = self.master
202
203 try:
204
205 buffer = '%s.bpstulist' % (master)
206
207 if buffer in self.buffers:
208
209 self.stunits = ExtendedDict()
210
211 stream = bpstulist.stream(self.buffers[buffer])
212
213 for record in stream:
214
215 stunit = bpstulist.parse(record, tz=self.tz)
216
217 #self.logger.debug(stunit.label)
218
219 self.stunits[stunit.label] = stunit
220
221 del self.buffers[buffer]
222
223 else:
224
225 raise BackmonError, 'buffer %s is empty!' % (buffer)
226
227 except ParseError, e:
228 raise BackmonError, e
229
230 #
231 # parse_df_data() - parse df data
232 #
233 def parse_df_data(self):
234
235 self.logger.debug('%s - parsing df_data..' % (self.name))
236
237 servers = [self.master]
238 servers.extend(self.media_servers)
239
240 try:
241
242 self.df_data = ExtendedDict()
243
244 for server in servers:
245
246 if server not in self.df_data:
247
248 self.df_data[server] = ExtendedDict()
249
250 buffer = '%s.df' % (server)
251
252 if buffer in self.buffers:
253
254 stream = df.stream(self.buffers[buffer])
255
256 for record in stream:
257
258 fs = df.parse(record, tz=self.tz)
259
260 self.logger.debug('%s:%s' % (server, fs.mountpoint))
261
262 self.df_data[server][fs.mountpoint] = fs
263
264 del self.buffers[buffer]
265
266 else:
267
268 raise BackmonError, 'buffer %s is empty!' % (buffer)
269
270 except ParseError, e:
271 raise BackmonError, e
272
273 #
274 # parse_dsu_contents() - parse disk storage unit contents (from ls -l)
275 #
276 def parse_dsu_contents(self):
277
278 self.logger.debug('%s - parsing dsu_contents..' % (self.name))
279
280 servers = self.media_servers
281
282 try:
283
284 self.dsu_contents = ExtendedDict()
285
286 for server in servers:
287
288 if server not in self.dsu_contents:
289 self.dsu_contents[server] = ExtendedDict()
290
291 buffer = '%s.dsu_ls_l' % (server)
292
293 if buffer in self.buffers:
294
295 stream = dsu_ls_l.stream(self.buffers[buffer])
296
297 for record in stream:
298
299 dir = dsu_ls_l.parse(record, tz=self.tz)
300
301 self.logger.debug('%s:%s' % (server, dir.path))
302
303 self.dsu_contents[server][dir.path] = dir
304
305 del self.buffers[buffer]
306
307 else:
308
309 raise BackmonError, 'buffer %s is empty!' % (buffer)
310
311 except ParseError, e:
312 raise BackmonError, e
313
314 #
315 # parse_lifecycle_images() - parse images processed by storage lifecycles
316 #
317 def parse_lifecycle_images(self):
318
319 self.logger.debug('%s - parsing lifecycle_images..' % (self.name))
320
321 master = self.master
322
323 try:
324
325 buffer = '%s.nbstlutil_list' % (master)
326
327 if buffer in self.buffers:
328
329 self.lifecycle_images = ExtendedDict()
330
331 stream = nbstlutil.stream(self.buffers[buffer], format='nbstlutil list -U')
332
333 for record in stream:
334
335 image = nbstlutil.parse(record, format='nbstlutil list -U', tz=self.tz)
336 image_id = image.backup_id
337
338 #self.logger.debug(image_id)
339
340 self.lifecycle_images[image_id] = image
341
342 del self.buffers[buffer]
343
344 else:
345
346 raise BackmonError, 'buffer %s is empty!' % (buffer)
347
348 except ParseError, e:
349 raise BackmonError, e
350
351 #
352 # parse_jobs() - parse jobs
353 #
354 def parse_jobs(self):
355
356 self.logger.debug('%s - parsing jobs..' % (self.name))
357
358 master = self.master
359
360 try:
361
362 buffer = '%s.bpdbjobs_most_columns' % (master)
363
364 if buffer in self.buffers:
365
366 self.jobs = ExtendedDict()
367
368 stream = bpdbjobs.stream(self.buffers[buffer])
369
370 for record in stream:
371
372 job = bpdbjobs.parse(record, tz=self.tz)
373
374 #self.logger.debug(job.jobid)
375
376 self.jobs[job.jobid] = job
377
378 del self.buffers[buffer]
379
380 else:
381
382 raise BackmonError, 'buffer %s is empty!' % (buffer)
383
384 except ParseError, e:
385 raise BackmonError, e
386
387 #
388 # parse_disk_pools() - parse disk_pools
389 #
390 def parse_disk_pools(self):
391
392 self.logger.debug('%s - parsing disk pools..' % (self.name))
393
394 master = self.master
395
396 self.disk_pools = ExtendedDict()
397
398 for feed in ['nbdevquery_listdv_stype_basicdisk', 'nbdevquery_listdv_stype_advanceddisk', 'nbdevquery_listdv_stype_puredisk']:
399
400 try:
401
402 buffer = '%s.%s' % (master, feed)
403
404 if buffer in self.buffers:
405
406 stream = nbdevquery.stream(self.buffers[buffer])
407
408 for record in stream:
409
410 if len(record) == 1 and record[0] == 'no disk volumes found!':
411 break
412
413 pool = nbdevquery.parse(record, tz=self.tz)
414
415 #self.logger.debug(pool.disk_pool_name)
416
417 self.disk_pools[pool.disk_pool_name] = pool
418
419 del self.buffers[buffer]
420
421 else:
422
423 raise BackmonError, 'buffer %s is empty!' % (buffer)
424
425 except ParseError, e:
426 raise BackmonError, e
427
428 #
429 # parse_pools() - parse volume manager pools
430 #
431 def parse_pools(self):
432
433 self.logger.debug('%s - parsing pools..' % (self.name))
434
435 master = self.master
436
437 try:
438
439 buffer = '%s.vmpool' % (master)
440
441 if buffer in self.buffers:
442
443 self.pools = ExtendedDict()
444
445 stream = vmpool.stream(self.buffers[buffer])
446
447 for record in stream:
448
449 pool = vmpool.parse(record, tz=self.tz)
450
451 self.logger.debug(pool.pool_name)
452
453 self.pools[pool.pool_name] = pool
454
455 del self.buffers[buffer]
456
457 else:
458
459 raise BackmonError, 'buffer %s is empty!' % (buffer)
460
461 except ParseError, e:
462 raise BackmonError, e
463
464 #
465 # parse_scratch() - parse volume manager scratch pool
466 #
467 def parse_scratch(self):
468
469 self.logger.debug('%s - parsing scratch pool..' % (self.name))
470
471 master = self.master
472
473 try:
474
475 buffer = '%s.vmpool_list_scratch' % (master)
476
477 if buffer in self.buffers:
478
479 self.pools = ExtendedDict()
480
481 stream = vmpool.stream(self.buffers[buffer], format='vmpool -list_scratch')
482
483 for record in stream:
484
485 pool = vmpool.parse(record, format='vmpool -list_scratch', tz=self.tz)
486
487 self.logger.debug(pool)
488
489 self.scratch_pool = pool
490
491 del self.buffers[buffer]
492
493 else:
494
495 raise BackmonError, 'buffer %s is empty!' % (buffer)
496
497 except ParseError, e:
498 raise BackmonError, e
499
500
501 #
502 # parse_volumes() - parse volume manager volumes
503 #
504 def parse_volumes(self):
505
506 self.logger.debug('%s - parsing volumes..' % (self.name))
507
508 master = self.master
509
510 try:
511
512 buffer = '%s.vmquery' % (master)
513
514 if buffer in self.buffers:
515
516 self.volumes = ExtendedDict()
517
518 stream = vmquery.stream(self.buffers[buffer])
519
520 i = 0
521
522 for record in stream:
523
524 i += 1
525
526 volume = vmquery.parse(record, tz=self.tz)
527
528 if i % 100 == 0:
529 self.logger.debug(i)
530
531 self.volumes[volume.media_id] = volume
532
533 del self.buffers[buffer]
534
535 else:
536
537 raise BackmonError, 'buffer %s is empty!' % (buffer)
538
539 except ParseError, e:
540 raise BackmonError, e
541
542 #
543 # parse_media() - parse media list
544 #
545 def parse_media(self):
546
547 self.logger.debug('%s - parsing media..' % (self.name))
548
549 master = self.master
550
551 try:
552
553 buffer = '%s.bpmedialist' % (master)
554
555 if buffer in self.buffers:
556
557 self.media = ExtendedDict()
558
559 stream = bpmedialist.stream(self.buffers[buffer])
560
561 i = 0
562
563 for record in stream:
564
565 i += 1
566
567 media = bpmedialist.parse(record, tz=self.tz)
568
569 if i % 100 == 0:
570 self.logger.debug(i)
571
572 self.media[media.media_id] = media
573
574 del self.buffers[buffer]
575
576 else:
577
578 raise BackmonError, 'buffer %s is empty!' % (buffer)
579
580 except ParseError, e:
581 raise BackmonError, e
582
583 #
584 # parse_clients() - parse clients
585 #
586 def parse_clients(self):
587
588 self.logger.debug('%s - parsing clients..' % (self.name))
589
590 master = self.master
591
592 try:
593
594 buffer = '%s.bpplclients' % (master)
595
596 if buffer in self.buffers:
597
598 self.clients = ExtendedDict()
599
600 stream = bpplclients.stream(self.buffers[buffer])
601
602 for record in stream:
603
604 client = bpplclients.parse(record, tz=self.tz)
605
606 #self.logger.debug(client.name)
607
608 self.clients[client.name] = client
609
610 del self.buffers[buffer]
611
612 else:
613
614 raise BackmonError, 'buffer %s is empty!' % (buffer)
615
616 except ParseError, e:
617 raise BackmonError, e
618
619 #
620 # parse_retlevels() - parse retention levels
621 #
622 def parse_retlevels(self):
623
624 self.logger.debug('%s - parsing retlevels..' % (self.name))
625
626 master = self.master
627
628 try:
629
630 buffer = '%s.bpretlevel' % (master)
631
632 if buffer in self.buffers:
633
634 self.retlevels = ExtendedDict()
635
636 stream = bpretlevel.stream(self.buffers[buffer])
637
638 for record in stream:
639
640 retlevel = bpretlevel.parse(record, tz=self.tz)
641
642 #self.logger.debug(retlevel.retention_level)
643
644 self.retlevels[retlevel.retention_level] = retlevel
645
646 del self.buffers[buffer]
647
648 else:
649
650 raise BackmonError, 'buffer %s is empty!' % (buffer)
651
652 except ParseError, e:
653 raise BackmonError, e
654
655 #
656 # parse_policies() - parse policies
657 #
658 def parse_policies(self):
659
660 self.logger.debug('%s - parsing policies..' % (self.name))
661
662 master = self.master
663
664 try:
665
666 buffer = '%s.bppllist' % (master)
667
668 if buffer in self.buffers:
669
670 self.policies = ExtendedDict()
671
672 stream = bppllist.stream(self.buffers[buffer])
673
674 for record in stream:
675
676 policy = bppllist.parse(record, tz=self.tz)
677
678 #self.logger.debug(policy.policy_name)
679
680 self.policies[policy.policy_name] = policy
681
682 del self.buffers[buffer]
683
684 else:
685
686 raise BackmonError, 'buffer %s is empty!' % (buffer)
687
688 except ParseError, e:
689 raise BackmonError, e
Note: See TracBrowser for help on using the repository browser.