Commit 7d9b2734b8f0ccb81d95421029a58257729769c9

Authored by Eduardo Santos
Committed by Eduardo Santos
2 parents 5a399ad1 6abb16d8
Exists in master

Adiciona MIB's e corrige bugs nas definições dos atributos SNMP

Showing 2 changed files with 186 additions and 47 deletions   Show diff stats
cocar/commands/scan_commands.py
... ... @@ -50,6 +50,18 @@ class ScanCommands(command.Command):
50 50 help='Full scan or regular scan'
51 51 )
52 52  
  53 + parser.add_option('-i', '--ip',
  54 + action='store',
  55 + dest='hosts',
  56 + help='Hosts list to scan'
  57 + )
  58 +
  59 + parser.add_option('-q', '--query',
  60 + action='store',
  61 + dest='query',
  62 + help='SNMP query to execute'
  63 + )
  64 +
53 65 def __init__(self, name):
54 66 """
55 67 Constructor method
... ... @@ -100,6 +112,9 @@ class ScanCommands(command.Command):
100 112 if cmd == 'export_printers':
101 113 self.export_printers()
102 114 return
  115 + if cmd == 'get_printer_attribute':
  116 + self.get_printer_attribute()
  117 + return
103 118 else:
104 119 log.error('Command "%s" not recognized' % (cmd,))
105 120  
... ... @@ -246,7 +261,13 @@ class ScanCommands(command.Command):
246 261 done_queue = Queue()
247 262  
248 263 session = self.cocar.Session
249   - results = session.query(Printer).all()
  264 + if self.options.hosts is None:
  265 + results = session.query(Printer).all()
  266 + else:
  267 + results = session.query(Printer).filter(
  268 + Printer.network_ip.in_(self.options.hosts)
  269 + ).all()
  270 +
250 271 for printer in results:
251 272 log.info("Coletando informacoes da impressora %s", printer.network_ip)
252 273 #printer.network_ip = printer.ip_network
... ... @@ -326,6 +347,107 @@ class ScanCommands(command.Command):
326 347 log.info("Exportando impressora %s", printer.network_ip)
327 348 printer.export_printer(server_url=self.cocar.config.get('cocar', 'server_url'), session=session)
328 349  
  350 + def get_printer_attribute(self):
  351 + """
  352 + Retorna e grava um atributo n o valor da impressora
  353 + """
  354 + session = self.cocar.Session
  355 + if self.options.hosts is None:
  356 + results = session.query(Printer).all()
  357 + elif type(self.options.hosts) == list:
  358 + results = session.query(Printer).filter(
  359 + Printer.network_ip.in_(self.options.hosts)
  360 + ).all()
  361 + else:
  362 + results = session.query(Printer).filter(
  363 + Printer.network_ip == self.options.hosts
  364 + ).all()
  365 +
  366 + for printer in results:
  367 + log.info("Coletando informacoes da impressora %s", printer.network_ip)
  368 + #printer.network_ip = printer.ip_network
  369 + snmp_session = SnmpSession(
  370 + DestHost=printer.network_ip
  371 + )
  372 + if snmp_session is None:
  373 + log.error("Erro na coleta SNMP da impressora %s", printer.network_ip)
  374 + continue
  375 + else:
  376 + printer_dict = dict()
  377 + if type(self.options.query != list):
  378 + test = self.options.query
  379 + self.options.query = list()
  380 + self.options.query.append(test)
  381 +
  382 + for i in range(len(self.options.query)):
  383 + if self.options.query[i] == 'description':
  384 + status = snmp_session.printer_full()
  385 + printer_dict['description'] = status
  386 + elif self.options.query[i] == 'serial':
  387 + status = snmp_session.printer_serial()
  388 + printer_dict['serial'] = status
  389 + elif self.options.query[i] == 'model':
  390 + status = snmp_session.printer_model()
  391 + printer_dict['model'] = status
  392 + elif self.options.query[i] == 'counter':
  393 + status = snmp_session.printer_counter()
  394 + printer_dict['counter'] = status
  395 + elif self.options.query[i] == 'status':
  396 + status = snmp_session.printer_status()
  397 + printer_dict['status'] = status
  398 + log.debug(printer_dict)
  399 + try:
  400 + log.debug("Atualizando informacoes da impressora %s", printer.network_ip)
  401 + log.debug(printer_dict)
  402 +
  403 + if printer_dict.get('counter') is not None:
  404 +
  405 + printer_counter = PrinterCounter(
  406 + ip_address=printer.network_ip,
  407 + counter=printer_dict['counter'],
  408 + counter_time=time.time()
  409 + )
  410 +
  411 + if printer_dict.get('model') is not None:
  412 + printer_counter.model = printer_dict['model']
  413 + printer.model = printer_dict['model']
  414 +
  415 + if printer_dict.get('serial') is not None:
  416 + printer_counter.serial = printer_dict['serial']
  417 + printer.serial = printer_dict['serial']
  418 +
  419 + if printer_dict.get('description') is not None:
  420 + printer_counter.description = printer_dict['description']
  421 + printer.description = printer_dict['description']
  422 +
  423 + # Para esse caso atualiza o contador
  424 + printer_counter.update_counter(session)
  425 + else:
  426 + # Nesse caso só atualizo a impressora
  427 + if printer_dict.get('model') is not None:
  428 + printer.model = printer_dict['model']
  429 +
  430 + if printer_dict.get('serial') is not None:
  431 + printer.serial = printer_dict['serial']
  432 +
  433 + if printer_dict.get('description') is not None:
  434 + printer.description = printer_dict['description']
  435 +
  436 + session.execute(
  437 + Printer.__table__.update().values(
  438 + model=printer.model,
  439 + description=printer.description,
  440 + serial=printer.serial
  441 + ).where(
  442 + Printer.__table__.c.network_ip == printer.network_ip
  443 + )
  444 + )
  445 + session.flush()
  446 +
  447 + except IntegrityError, e:
  448 + log.error("Erro na atualizacao das informacoes para a impressora %s\n%s", printer.network_ip, e.message)
  449 + continue
  450 +
329 451  
330 452 def make_query(host):
331 453 """This does the actual snmp query
... ...
cocar/session.py
... ... @@ -33,6 +33,17 @@ class SnmpSession(object):
33 33 Community="public",
34 34 Verbose=True,
35 35 ):
  36 + """
  37 + Sessão SNMP. Links úteis:
  38 + Lista de MIB's para impressoras: http://www.lprng.com/DISTRIB/SNMPTOOLS/snmp_stuff/test_printer/npstatlib.pm
  39 +
  40 + :param oid: MIB SNMP
  41 + :param iid: Não sei
  42 + :param Version: Versão do protocolo
  43 + :param DestHost: Endereço para consulta
  44 + :param Community: Community para consulta
  45 + :param Verbose: Verbose
  46 + """
36 47 self.oid = oid
37 48 self.Version = Version
38 49 self.DestHost = DestHost
... ... @@ -42,11 +53,15 @@ class SnmpSession(object):
42 53 self.hostrec = Host()
43 54 self.hostrec.hostname = self.DestHost
44 55  
45   - self.status = ['1.3.6.1.2.1.25.3.5.1.1.1']
46   - self.serial = ['1.3.6.1.2.1.43.5.1.1.17']
47   - self.model = ['1.3.6.1.2.1.25.3.2.1.3.1']
48   - self.counter = ['1.3.6.1.2.1.43.10.2.1.4.1.1']
49   - self.messages = ['1.3.6.1.2.1.43.18.1.1.8']
  56 + self.status = ['.1.3.6.1.2.1.25.3.5.1.1.1']
  57 + self.serial = ['.1.3.6.1.2.1.43.5.1.1.17',
  58 + '.1.3.6.1.2.1.43.5.1.1.17.1',
  59 + '1.3.6.1.4.1.641.2.1.2.1.6.1',
  60 + '1.3.6.1.4.1.11.2.3.9.4.2.1.1.3.3.0']
  61 + self.model = ['.1.3.6.1.2.1.25.3.2.1.3.1',
  62 + '.1.3.6.1.4.1.641.2.1.2.1.2.1']
  63 + self.counter = ['.1.3.6.1.2.1.43.10.2.1.4.1.1']
  64 + self.messages = ['.1.3.6.1.2.1.43.18.1.1.8']
50 65  
51 66 def query(self):
52 67 """Creates SNMP query
... ... @@ -71,10 +86,14 @@ class SnmpSession(object):
71 86 Retorna status full da impressora, com todos os atributos
72 87 """
73 88 status = self.query()
74   - if status is None:
75   - return None
76   - else:
77   - return status.query
  89 +
  90 + if status.query is not None:
  91 + for response in status.query:
  92 + if response is not None:
  93 + return response
  94 +
  95 + # Se chegou até aqui não encontrou nenhum resultado
  96 + return None
78 97  
79 98 def printer_status(self):
80 99 """
... ... @@ -88,68 +107,65 @@ class SnmpSession(object):
88 107 4 - testing
89 108 5 - down
90 109 """
91   - status = None
92 110 for elm in self.status:
93   - self.oid = elm
  111 + self.var = netsnmp.Varbind(elm, iid=None)
94 112 status = self.query()
95 113 # A primeira vez que conseguir retornar um status, para
96   - if status is not None:
97   - break
98   - if status is None:
99   - return None
100   - else:
101   - return status.query
  114 + if status.query is not None:
  115 + for response in status.query:
  116 + if response is not None:
  117 + return response
  118 +
  119 + # Se chegou até aqui não encontrou nenhum resultado
  120 + return None
102 121  
103 122 def printer_counter(self):
104 123 """
105 124 Retorna contador da impressora
106 125 """
107   - status = None
108 126 for elm in self.counter:
109   - self.oid = elm
  127 + self.var = netsnmp.Varbind(elm, iid=None)
110 128 status = self.query()
111 129 # A primeira vez que conseguir retornar um status, para
112   - if status is not None:
113   - break
  130 + if status.query is not None:
  131 + for response in status.query:
  132 + if response is not None:
  133 + return response
114 134  
115   - if status is None:
116   - return None
117   - else:
118   - return status.query
  135 + # Se chegou até aqui não encontrou nenhum resultado
  136 + return None
119 137  
120 138 def printer_model(self):
121 139 """
122 140 Retorna contador da impressora
123 141 """
124   - status = None
125 142 for elm in self.model:
126   - self.oid = elm
  143 + self.var = netsnmp.Varbind(elm, iid=None)
127 144 status = self.query()
128 145 # A primeira vez que conseguir retornar um status, para
129   - if status is not None:
130   - break
  146 + if status.query is not None:
  147 + for response in status.query:
  148 + if response is not None:
  149 + return response
131 150  
132   - if status is None:
133   - return None
134   - else:
135   - return status.query
  151 + # Se chegou até aqui não encontrou nenhum resultado
  152 + return None
136 153  
137 154 def printer_serial(self):
138 155 """
139 156 Retorna contador da impressora
140 157 """
141   - status = None
142 158 for elm in self.serial:
143   - self.oid = elm
  159 + self.var = netsnmp.Varbind(elm, iid=None)
144 160 status = self.query()
145 161 # A primeira vez que conseguir retornar um status, para
146   - if status is not None:
147   - break
  162 + if status.query is not None:
  163 + for response in status.query:
  164 + if response is not None:
  165 + return response
148 166  
149   - if status is None:
150   - return None
151   - else:
152   - return status.query
  167 + # Se chegou até aqui não encontrou nenhum resultado
  168 + return None
153 169  
154 170 def printer_dict(self):
155 171 """
... ... @@ -162,14 +178,15 @@ class SnmpSession(object):
162 178 status = self.printer_status()
163 179  
164 180 return_dict = {
165   - 'description': full[0],
166   - 'serial': serial[0],
167   - 'model': model[0],
168   - 'counter': counter[0],
169   - 'status': status[0],
  181 + 'description': full,
  182 + 'serial': serial,
  183 + 'model': model,
  184 + 'counter': counter,
  185 + 'status': status,
170 186 'network_ip': self.DestHost
171 187 }
172 188  
  189 + log.debug("COLETA DE IMPRESSORAS CONCLUÍDA!!! Retornando dicionário de informações")
173 190 log.debug(return_dict)
174 191  
175 192 return return_dict
... ...