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,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