Commit 7d9b2734b8f0ccb81d95421029a58257729769c9
Committed by
Eduardo Santos
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,6 +50,18 @@ class ScanCommands(command.Command): | ||
| 50 | help='Full scan or regular scan' | 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 | def __init__(self, name): | 65 | def __init__(self, name): |
| 54 | """ | 66 | """ |
| 55 | Constructor method | 67 | Constructor method |
| @@ -100,6 +112,9 @@ class ScanCommands(command.Command): | @@ -100,6 +112,9 @@ class ScanCommands(command.Command): | ||
| 100 | if cmd == 'export_printers': | 112 | if cmd == 'export_printers': |
| 101 | self.export_printers() | 113 | self.export_printers() |
| 102 | return | 114 | return |
| 115 | + if cmd == 'get_printer_attribute': | ||
| 116 | + self.get_printer_attribute() | ||
| 117 | + return | ||
| 103 | else: | 118 | else: |
| 104 | log.error('Command "%s" not recognized' % (cmd,)) | 119 | log.error('Command "%s" not recognized' % (cmd,)) |
| 105 | 120 | ||
| @@ -246,7 +261,13 @@ class ScanCommands(command.Command): | @@ -246,7 +261,13 @@ class ScanCommands(command.Command): | ||
| 246 | done_queue = Queue() | 261 | done_queue = Queue() |
| 247 | 262 | ||
| 248 | session = self.cocar.Session | 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 | for printer in results: | 271 | for printer in results: |
| 251 | log.info("Coletando informacoes da impressora %s", printer.network_ip) | 272 | log.info("Coletando informacoes da impressora %s", printer.network_ip) |
| 252 | #printer.network_ip = printer.ip_network | 273 | #printer.network_ip = printer.ip_network |
| @@ -326,6 +347,107 @@ class ScanCommands(command.Command): | @@ -326,6 +347,107 @@ class ScanCommands(command.Command): | ||
| 326 | log.info("Exportando impressora %s", printer.network_ip) | 347 | log.info("Exportando impressora %s", printer.network_ip) |
| 327 | printer.export_printer(server_url=self.cocar.config.get('cocar', 'server_url'), session=session) | 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 | def make_query(host): | 452 | def make_query(host): |
| 331 | """This does the actual snmp query | 453 | """This does the actual snmp query |
cocar/session.py
| @@ -33,6 +33,17 @@ class SnmpSession(object): | @@ -33,6 +33,17 @@ class SnmpSession(object): | ||
| 33 | Community="public", | 33 | Community="public", |
| 34 | Verbose=True, | 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 | self.oid = oid | 47 | self.oid = oid |
| 37 | self.Version = Version | 48 | self.Version = Version |
| 38 | self.DestHost = DestHost | 49 | self.DestHost = DestHost |
| @@ -42,11 +53,15 @@ class SnmpSession(object): | @@ -42,11 +53,15 @@ class SnmpSession(object): | ||
| 42 | self.hostrec = Host() | 53 | self.hostrec = Host() |
| 43 | self.hostrec.hostname = self.DestHost | 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 | def query(self): | 66 | def query(self): |
| 52 | """Creates SNMP query | 67 | """Creates SNMP query |
| @@ -71,10 +86,14 @@ class SnmpSession(object): | @@ -71,10 +86,14 @@ class SnmpSession(object): | ||
| 71 | Retorna status full da impressora, com todos os atributos | 86 | Retorna status full da impressora, com todos os atributos |
| 72 | """ | 87 | """ |
| 73 | status = self.query() | 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 | def printer_status(self): | 98 | def printer_status(self): |
| 80 | """ | 99 | """ |
| @@ -88,68 +107,65 @@ class SnmpSession(object): | @@ -88,68 +107,65 @@ class SnmpSession(object): | ||
| 88 | 4 - testing | 107 | 4 - testing |
| 89 | 5 - down | 108 | 5 - down |
| 90 | """ | 109 | """ |
| 91 | - status = None | ||
| 92 | for elm in self.status: | 110 | for elm in self.status: |
| 93 | - self.oid = elm | 111 | + self.var = netsnmp.Varbind(elm, iid=None) |
| 94 | status = self.query() | 112 | status = self.query() |
| 95 | # A primeira vez que conseguir retornar um status, para | 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 | def printer_counter(self): | 122 | def printer_counter(self): |
| 104 | """ | 123 | """ |
| 105 | Retorna contador da impressora | 124 | Retorna contador da impressora |
| 106 | """ | 125 | """ |
| 107 | - status = None | ||
| 108 | for elm in self.counter: | 126 | for elm in self.counter: |
| 109 | - self.oid = elm | 127 | + self.var = netsnmp.Varbind(elm, iid=None) |
| 110 | status = self.query() | 128 | status = self.query() |
| 111 | # A primeira vez que conseguir retornar um status, para | 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 | def printer_model(self): | 138 | def printer_model(self): |
| 121 | """ | 139 | """ |
| 122 | Retorna contador da impressora | 140 | Retorna contador da impressora |
| 123 | """ | 141 | """ |
| 124 | - status = None | ||
| 125 | for elm in self.model: | 142 | for elm in self.model: |
| 126 | - self.oid = elm | 143 | + self.var = netsnmp.Varbind(elm, iid=None) |
| 127 | status = self.query() | 144 | status = self.query() |
| 128 | # A primeira vez que conseguir retornar um status, para | 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 | def printer_serial(self): | 154 | def printer_serial(self): |
| 138 | """ | 155 | """ |
| 139 | Retorna contador da impressora | 156 | Retorna contador da impressora |
| 140 | """ | 157 | """ |
| 141 | - status = None | ||
| 142 | for elm in self.serial: | 158 | for elm in self.serial: |
| 143 | - self.oid = elm | 159 | + self.var = netsnmp.Varbind(elm, iid=None) |
| 144 | status = self.query() | 160 | status = self.query() |
| 145 | # A primeira vez que conseguir retornar um status, para | 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 | def printer_dict(self): | 170 | def printer_dict(self): |
| 155 | """ | 171 | """ |
| @@ -162,14 +178,15 @@ class SnmpSession(object): | @@ -162,14 +178,15 @@ class SnmpSession(object): | ||
| 162 | status = self.printer_status() | 178 | status = self.printer_status() |
| 163 | 179 | ||
| 164 | return_dict = { | 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 | 'network_ip': self.DestHost | 186 | 'network_ip': self.DestHost |
| 171 | } | 187 | } |
| 172 | 188 | ||
| 189 | + log.debug("COLETA DE IMPRESSORAS CONCLUÍDA!!! Retornando dicionário de informações") | ||
| 173 | log.debug(return_dict) | 190 | log.debug(return_dict) |
| 174 | 191 | ||
| 175 | return return_dict | 192 | return return_dict |