Commit 55a73f12f2d9a0b09e25505f60baf2d9e2ba4019
Committed by
Eduardo Santos
Exists in
master
Versão que já é capaz de armazenar as impressoras e seus contadores no banco de dados.
Showing
8 changed files
with
433 additions
and
16 deletions
Show diff stats
cocar/commands/scan_commands.py
| ... | ... | @@ -4,13 +4,20 @@ __author__ = 'eduardo' |
| 4 | 4 | import logging |
| 5 | 5 | import os |
| 6 | 6 | import os.path |
| 7 | +import lxml.etree | |
| 8 | +import time | |
| 9 | +import pickle | |
| 7 | 10 | from paste.script import command |
| 8 | 11 | from .. import Cocar |
| 9 | 12 | from ..model import Base |
| 10 | 13 | from ..model.network import Network |
| 14 | +from ..model.printer import Printer, PrinterCounter | |
| 15 | +from ..model.host import Host | |
| 16 | +from ..model.computer import Computer | |
| 11 | 17 | from ..csv_utils import NetworkCSV |
| 12 | -from ..session import NmapSession | |
| 18 | +from ..session import NmapSession, SnmpSession | |
| 13 | 19 | from multiprocessing import Process, Queue |
| 20 | +from ..xml_utils import NmapXML | |
| 14 | 21 | |
| 15 | 22 | log = logging.getLogger() |
| 16 | 23 | |
| ... | ... | @@ -26,7 +33,7 @@ class ScanCommands(command.Command): |
| 26 | 33 | paster scan networks -c <path to config file> |
| 27 | 34 | - Faz a busca das redes |
| 28 | 35 | |
| 29 | - Os comandos devem ser executados a partir da raiz do módulo Cocar | |
| 36 | + Os comandos devem ser executados a partir da raiz do modulo Cocar | |
| 30 | 37 | """ |
| 31 | 38 | max_args = 1 |
| 32 | 39 | min_args = 1 |
| ... | ... | @@ -77,6 +84,15 @@ class ScanCommands(command.Command): |
| 77 | 84 | if cmd == 'scan_networks': |
| 78 | 85 | self.scan_networks() |
| 79 | 86 | return |
| 87 | + if cmd == 'load_network_files': | |
| 88 | + self.load_network_files() | |
| 89 | + return | |
| 90 | + if cmd == 'get_printers': | |
| 91 | + self.get_printers() | |
| 92 | + return | |
| 93 | + if cmd == 'continous_scan': | |
| 94 | + self.continuous_scan() | |
| 95 | + return | |
| 80 | 96 | else: |
| 81 | 97 | log.error('Command "%s" not recognized' % (cmd,)) |
| 82 | 98 | |
| ... | ... | @@ -148,6 +164,123 @@ class ScanCommands(command.Command): |
| 148 | 164 | for i in range(processes): |
| 149 | 165 | task_queue.put('STOP') |
| 150 | 166 | |
| 167 | + def load_network_files(self): | |
| 168 | + """ | |
| 169 | + Load printers from networks files | |
| 170 | + :return: | |
| 171 | + """ | |
| 172 | + onlyfiles = [ f for f in os.listdir(self.networks_dir) if os.path.isfile(os.path.join(self.networks_dir, f)) ] | |
| 173 | + for i in range(len(onlyfiles)): | |
| 174 | + network_file = self.networks_dir + "/" + onlyfiles[i] | |
| 175 | + log.info("Processando arquivo de rede %s", network_file) | |
| 176 | + nmap_xml = NmapXML(network_file) | |
| 177 | + try: | |
| 178 | + host_dict = nmap_xml.parse_xml() | |
| 179 | + except AttributeError, e: | |
| 180 | + log.error("Erro realizando parsing do arquivo %s\n%s", network_file, e.message) | |
| 181 | + continue | |
| 182 | + except lxml.etree.XMLSyntaxError, e: | |
| 183 | + log.error("Erro realizando parsing do arquivo %s\n%s", network_file, e.message) | |
| 184 | + continue | |
| 185 | + | |
| 186 | + if not host_dict: | |
| 187 | + log.error("File %s not found", network_file) | |
| 188 | + continue | |
| 189 | + session = self.cocar.Session | |
| 190 | + for hostname in nmap_xml.hosts.keys(): | |
| 191 | + host = nmap_xml.identify_host(hostname) | |
| 192 | + if isinstance(host, Printer): | |
| 193 | + # Vê se a impressora já está na base | |
| 194 | + results = session.query(Printer).filter(Printer.network_ip == hostname).first() | |
| 195 | + if results is None: | |
| 196 | + log.info("Inserindo impressora com o IP %s", hostname) | |
| 197 | + session.add(host) | |
| 198 | + else: | |
| 199 | + log.info("Impressora com o IP %s já cadastrada", hostname) | |
| 200 | + elif isinstance(host, Computer): | |
| 201 | + # Vê se o host já está na base | |
| 202 | + results = session.query(Computer).filter(Computer.network_ip == hostname).first() | |
| 203 | + if results is None: | |
| 204 | + log.info("Inserindo computador com o IP %s", hostname) | |
| 205 | + session.add(host) | |
| 206 | + else: | |
| 207 | + log.info("Computador com o IP %s já cadastrado", hostname) | |
| 208 | + else: | |
| 209 | + # Insere host genérico | |
| 210 | + results = session.query(Host).filter(Host.network_ip == hostname).first() | |
| 211 | + if results is None: | |
| 212 | + log.info("Inserindo host genérico com o IP %s", hostname) | |
| 213 | + session.add(host) | |
| 214 | + else: | |
| 215 | + log.info("Host genérico com o IP %s já cadastrado", hostname) | |
| 216 | + | |
| 217 | + session.flush() | |
| 218 | + | |
| 219 | + def get_printers(self): | |
| 220 | + """ | |
| 221 | + Read printers SNMP Information | |
| 222 | + :return: | |
| 223 | + """ | |
| 224 | + processes = int(self.cocar.config.get('cocar', 'processes')) | |
| 225 | + # Create queues | |
| 226 | + task_queue = Queue() | |
| 227 | + done_queue = Queue() | |
| 228 | + | |
| 229 | + session = self.cocar.Session | |
| 230 | + results = session.query(Printer).all() | |
| 231 | + for printer in results: | |
| 232 | + log.info("Coletando informacoes da impressora %s", printer.network_ip) | |
| 233 | + #printer.network_ip = printer.ip_network | |
| 234 | + snmp_session = SnmpSession( | |
| 235 | + DestHost=printer.network_ip | |
| 236 | + ) | |
| 237 | + if snmp_session is None: | |
| 238 | + log.error("Erro na coleta SNMP da impressora %s", printer.network_ip) | |
| 239 | + continue | |
| 240 | + else: | |
| 241 | + task_queue.put(snmp_session) | |
| 242 | + | |
| 243 | + #Start worker processes | |
| 244 | + for i in range(processes): | |
| 245 | + Process(target=worker_printer, args=(task_queue, done_queue)).start() | |
| 246 | + | |
| 247 | + # Get and print results | |
| 248 | + log.debug('Unordered results:') | |
| 249 | + for i in range(len(results)): | |
| 250 | + printer_dict = done_queue.get() | |
| 251 | + log.debug(printer_dict) | |
| 252 | + if printer_dict['counter'] is None: | |
| 253 | + log.error("Nao foi possivel ler o contador da impressora %s", printer_dict['network_ip']) | |
| 254 | + continue | |
| 255 | + | |
| 256 | + try: | |
| 257 | + log.debug("Gravando contador = %s para a impressora = %s serial = %s", printer_dict['counter'], printer_dict['network_ip'], printer_dict['serial']) | |
| 258 | + printer = PrinterCounter( | |
| 259 | + ip_address=printer_dict['network_ip'], | |
| 260 | + model=printer_dict['model'], | |
| 261 | + serial=printer_dict['serial'], | |
| 262 | + description=printer_dict['description'], | |
| 263 | + counter=printer_dict['counter'], | |
| 264 | + counter_time=time.time() | |
| 265 | + ) | |
| 266 | + printer.update_counter(session) | |
| 267 | + except AttributeError, e: | |
| 268 | + log.error("Erro na inserção do contador para a impressora %s\n%s", printer_dict['network_ip'], e.message) | |
| 269 | + continue | |
| 270 | + | |
| 271 | + # Tell child processes to stop | |
| 272 | + for i in range(processes): | |
| 273 | + task_queue.put('STOP') | |
| 274 | + | |
| 275 | + def continuous_scan(self): | |
| 276 | + """ | |
| 277 | + Fica varrendo a rede até parar por execução forçada | |
| 278 | + """ | |
| 279 | + print("*** Aperente CTRL+C para encerrar a execução ***") | |
| 280 | + | |
| 281 | + while True: | |
| 282 | + self.scan_networks() | |
| 283 | + | |
| 151 | 284 | |
| 152 | 285 | def make_query(host): |
| 153 | 286 | """This does the actual snmp query |
| ... | ... | @@ -160,8 +293,26 @@ def make_query(host): |
| 160 | 293 | return host.scan() |
| 161 | 294 | |
| 162 | 295 | |
| 296 | +def make_query_printer(host): | |
| 297 | + """This does the actual snmp query | |
| 298 | + | |
| 299 | + This is a bit fancy as it accepts both instances | |
| 300 | + of SnmpSession and host/ip addresses. This | |
| 301 | + allows a user to customize mass queries with | |
| 302 | + subsets of different hostnames and community strings | |
| 303 | + """ | |
| 304 | + return host.printer_dict() | |
| 305 | + | |
| 306 | + | |
| 163 | 307 | # Function run by worker processes |
| 164 | 308 | def worker(inp, output): |
| 165 | 309 | for func in iter(inp.get, 'STOP'): |
| 166 | 310 | result = make_query(func) |
| 311 | + output.put(result) | |
| 312 | + | |
| 313 | + | |
| 314 | +# Function run by worker processes | |
| 315 | +def worker_printer(inp, output): | |
| 316 | + for func in iter(inp.get, 'STOP'): | |
| 317 | + result = make_query_printer(func) | |
| 167 | 318 | output.put(result) |
| 168 | 319 | \ No newline at end of file | ... | ... |
cocar/model/host.py
| ... | ... | @@ -47,9 +47,15 @@ class Host(Base): |
| 47 | 47 | |
| 48 | 48 | # Parâmetros do SQLAlchemy |
| 49 | 49 | self.network_ip = str(self.ip_address) |
| 50 | - self.ports = ','.join(map(str, self.open_ports.keys())) | |
| 51 | - if len(self.hostname.values()) > 0: | |
| 52 | - self.name = self.hostname.values()[0] | |
| 50 | + if self.open_ports is not None: | |
| 51 | + self.ports = ','.join(map(str, self.open_ports.keys())) | |
| 52 | + else: | |
| 53 | + self.ports = None | |
| 54 | + if self.hostname is not None: | |
| 55 | + if len(self.hostname.values()) > 0: | |
| 56 | + self.name = self.hostname.values()[0] | |
| 57 | + else: | |
| 58 | + self.name = None | |
| 53 | 59 | else: |
| 54 | 60 | self.name = None |
| 55 | 61 | ... | ... |
cocar/model/printer.py
| 1 | 1 | #!/bin/env python |
| 2 | 2 | # -*- coding: utf-8 -*- |
| 3 | 3 | __author__ = 'eduardo' |
| 4 | - | |
| 4 | +import logging | |
| 5 | 5 | from .host import Host |
| 6 | 6 | from sqlalchemy import ForeignKey |
| 7 | 7 | from sqlalchemy.schema import Column |
| 8 | 8 | from sqlalchemy.types import String, Integer |
| 9 | +from sqlalchemy import and_, insert, update | |
| 10 | + | |
| 11 | +log = logging.getLogger() | |
| 9 | 12 | |
| 10 | 13 | |
| 11 | 14 | class Printer(Host): |
| ... | ... | @@ -14,12 +17,11 @@ class Printer(Host): |
| 14 | 17 | """ |
| 15 | 18 | __tablename__ = 'printer' |
| 16 | 19 | network_ip = Column(String(16), ForeignKey("host.network_ip"), nullable=False, primary_key=True) |
| 17 | - counter = Column(Integer) | |
| 20 | + model = Column(String) | |
| 18 | 21 | serial = Column(String(50)) |
| 19 | 22 | description = Column(String) |
| 20 | 23 | |
| 21 | 24 | def __init__(self, |
| 22 | - counter=None, | |
| 23 | 25 | model=None, |
| 24 | 26 | serial=None, |
| 25 | 27 | description=None, |
| ... | ... | @@ -32,7 +34,62 @@ class Printer(Host): |
| 32 | 34 | :param serial: Número de série da impressora |
| 33 | 35 | """ |
| 34 | 36 | Host.__init__(self, *args, **kwargs) |
| 35 | - self.counter = counter | |
| 36 | 37 | self.model = model |
| 37 | 38 | self.serial = serial |
| 38 | - self.description = description | |
| 39 | 39 | \ No newline at end of file |
| 40 | + self.description = description | |
| 41 | + | |
| 42 | + | |
| 43 | +class PrinterCounter(Printer): | |
| 44 | + """ | |
| 45 | + Classe que armazena o contador das impressoras | |
| 46 | + """ | |
| 47 | + __tablename__ = 'printer_counter' | |
| 48 | + network_ip = Column(String(16), ForeignKey("printer.network_ip"), nullable=False) | |
| 49 | + counter = Column(Integer, nullable=False, primary_key=True) | |
| 50 | + counter_time = Column(String(50), nullable=False, primary_key=True) | |
| 51 | + | |
| 52 | + def __init__(self, | |
| 53 | + counter, | |
| 54 | + counter_time, | |
| 55 | + *args, | |
| 56 | + **kwargs | |
| 57 | + ): | |
| 58 | + super(PrinterCounter, self).__init__(*args, **kwargs) | |
| 59 | + self.counter = counter | |
| 60 | + self.counter_time = counter_time | |
| 61 | + | |
| 62 | + def update_counter(self, session): | |
| 63 | + """ | |
| 64 | + Atualiza contador da impressora | |
| 65 | + :param session: SQLAlchemy session | |
| 66 | + :return boolean: True if inserted | |
| 67 | + """ | |
| 68 | + results = session.query(self.__table__).filter( | |
| 69 | + and_( | |
| 70 | + self.__table__.c.counter == self.counter, | |
| 71 | + self.__table__.c.counter_time == self.counter_time) | |
| 72 | + ).first() | |
| 73 | + print(results) | |
| 74 | + if results is None: | |
| 75 | + log.debug("Inserindo contador para impressora %s serial %s", self.network_ip, self.serial) | |
| 76 | + session.execute( | |
| 77 | + self.__table__.insert().values( | |
| 78 | + network_ip=self.network_ip, | |
| 79 | + counter=self.counter, | |
| 80 | + counter_time=self.counter_time | |
| 81 | + ) | |
| 82 | + ) | |
| 83 | + return True | |
| 84 | + | |
| 85 | + session.execute( | |
| 86 | + Printer.__table__.update().values( | |
| 87 | + model=self.model, | |
| 88 | + description=self.description, | |
| 89 | + serial=self.serial | |
| 90 | + ).where( | |
| 91 | + Printer.__table__.c.network_ip == self.network_ip | |
| 92 | + ) | |
| 93 | + ) | |
| 94 | + | |
| 95 | + session.flush() | |
| 96 | + return False | |
| 40 | 97 | \ No newline at end of file | ... | ... |
cocar/session.py
| ... | ... | @@ -23,7 +23,7 @@ class Host(object): |
| 23 | 23 | self.query = query |
| 24 | 24 | |
| 25 | 25 | |
| 26 | -class SnmpSession(Cocar): | |
| 26 | +class SnmpSession(object): | |
| 27 | 27 | """A SNMP Session""" |
| 28 | 28 | def __init__(self, |
| 29 | 29 | oid=".1.3.6.1.2.1.1.1.0", |
| ... | ... | @@ -33,7 +33,6 @@ class SnmpSession(Cocar): |
| 33 | 33 | Community="public", |
| 34 | 34 | Verbose=True, |
| 35 | 35 | ): |
| 36 | - Cocar.__init__(self) | |
| 37 | 36 | self.oid = oid |
| 38 | 37 | self.Version = Version |
| 39 | 38 | self.DestHost = DestHost |
| ... | ... | @@ -43,6 +42,12 @@ class SnmpSession(Cocar): |
| 43 | 42 | self.hostrec = Host() |
| 44 | 43 | self.hostrec.hostname = self.DestHost |
| 45 | 44 | |
| 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'] | |
| 50 | + | |
| 46 | 51 | def query(self): |
| 47 | 52 | """Creates SNMP query |
| 48 | 53 | |
| ... | ... | @@ -61,6 +66,114 @@ class SnmpSession(Cocar): |
| 61 | 66 | finally: |
| 62 | 67 | return self.hostrec |
| 63 | 68 | |
| 69 | + def printer_full(self): | |
| 70 | + """ | |
| 71 | + Retorna status full da impressora, com todos os atributos | |
| 72 | + """ | |
| 73 | + status = self.query() | |
| 74 | + if status is None: | |
| 75 | + return None | |
| 76 | + else: | |
| 77 | + return status.query | |
| 78 | + | |
| 79 | + def printer_status(self): | |
| 80 | + """ | |
| 81 | + Retorna status da impressora | |
| 82 | + | |
| 83 | + Opções de status: | |
| 84 | + | |
| 85 | + 1 - unknown | |
| 86 | + 2 - runnning | |
| 87 | + 3 - warning | |
| 88 | + 4 - testing | |
| 89 | + 5 - down | |
| 90 | + """ | |
| 91 | + status = None | |
| 92 | + for elm in self.status: | |
| 93 | + self.oid = elm | |
| 94 | + status = self.query() | |
| 95 | + # 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 | |
| 102 | + | |
| 103 | + def printer_counter(self): | |
| 104 | + """ | |
| 105 | + Retorna contador da impressora | |
| 106 | + """ | |
| 107 | + status = None | |
| 108 | + for elm in self.counter: | |
| 109 | + self.oid = elm | |
| 110 | + status = self.query() | |
| 111 | + # A primeira vez que conseguir retornar um status, para | |
| 112 | + if status is not None: | |
| 113 | + break | |
| 114 | + | |
| 115 | + if status is None: | |
| 116 | + return None | |
| 117 | + else: | |
| 118 | + return status.query | |
| 119 | + | |
| 120 | + def printer_model(self): | |
| 121 | + """ | |
| 122 | + Retorna contador da impressora | |
| 123 | + """ | |
| 124 | + status = None | |
| 125 | + for elm in self.model: | |
| 126 | + self.oid = elm | |
| 127 | + status = self.query() | |
| 128 | + # A primeira vez que conseguir retornar um status, para | |
| 129 | + if status is not None: | |
| 130 | + break | |
| 131 | + | |
| 132 | + if status is None: | |
| 133 | + return None | |
| 134 | + else: | |
| 135 | + return status.query | |
| 136 | + | |
| 137 | + def printer_serial(self): | |
| 138 | + """ | |
| 139 | + Retorna contador da impressora | |
| 140 | + """ | |
| 141 | + status = None | |
| 142 | + for elm in self.serial: | |
| 143 | + self.oid = elm | |
| 144 | + status = self.query() | |
| 145 | + # A primeira vez que conseguir retornar um status, para | |
| 146 | + if status is not None: | |
| 147 | + break | |
| 148 | + | |
| 149 | + if status is None: | |
| 150 | + return None | |
| 151 | + else: | |
| 152 | + return status.query | |
| 153 | + | |
| 154 | + def printer_dict(self): | |
| 155 | + """ | |
| 156 | + Retorna o status de todos os atributos em um dicionário | |
| 157 | + """ | |
| 158 | + full = self.printer_full() | |
| 159 | + serial = self.printer_serial() | |
| 160 | + model = self.printer_model() | |
| 161 | + counter = self.printer_counter() | |
| 162 | + status = self.printer_status() | |
| 163 | + | |
| 164 | + return_dict = { | |
| 165 | + 'description': full[0], | |
| 166 | + 'serial': serial[0], | |
| 167 | + 'model': model[0], | |
| 168 | + 'counter': counter[0], | |
| 169 | + 'status': status[0], | |
| 170 | + 'network_ip': self.DestHost | |
| 171 | + } | |
| 172 | + | |
| 173 | + log.debug(return_dict) | |
| 174 | + | |
| 175 | + return return_dict | |
| 176 | + | |
| 64 | 177 | |
| 65 | 178 | class NmapSession(object): |
| 66 | 179 | """ |
| ... | ... | @@ -103,7 +216,7 @@ class NmapSession(object): |
| 103 | 216 | "nmap", |
| 104 | 217 | "-PE", |
| 105 | 218 | "-PP", |
| 106 | - "-PS21,22,23,25,80,443,3306,3389,8080", | |
| 219 | + "-PS21,22,23,25,80,443,631,3306,3389,8080,9100", | |
| 107 | 220 | "-O", |
| 108 | 221 | str(self.host), |
| 109 | 222 | "-oX", | ... | ... |
cocar/tests/__init__.py
| ... | ... | @@ -4,16 +4,25 @@ __author__ = 'eduardo' |
| 4 | 4 | from .. import Cocar |
| 5 | 5 | import os |
| 6 | 6 | import os.path |
| 7 | +import logging | |
| 7 | 8 | from ..model import Base |
| 8 | 9 | |
| 9 | 10 | cocar = Cocar(environment='test') |
| 10 | 11 | test_dir = os.path.dirname(os.path.realpath(__file__)) |
| 12 | +log = logging.getLogger() | |
| 11 | 13 | |
| 12 | 14 | |
| 13 | 15 | def setup_package(): |
| 14 | 16 | """ |
| 15 | 17 | Setup test data for the package |
| 16 | 18 | """ |
| 19 | + log.debug("Diretório de dados do Cocar: %s", cocar.cocar_data_dir) | |
| 20 | + test_dir = cocar.cocar_data_dir + "/tests" | |
| 21 | + if not os.path.isdir(test_dir): | |
| 22 | + log.info("Criando diretório de testes %s", test_dir) | |
| 23 | + os.mkdir(test_dir) | |
| 24 | + | |
| 25 | + log.info(cocar.engine) | |
| 17 | 26 | Base.metadata.create_all(cocar.engine) |
| 18 | 27 | pass |
| 19 | 28 | ... | ... |
cocar/tests/test_persistence.py
| ... | ... | @@ -4,10 +4,11 @@ __author__ = 'eduardo' |
| 4 | 4 | |
| 5 | 5 | import unittest |
| 6 | 6 | import cocar.tests |
| 7 | +import time | |
| 7 | 8 | from ..xml_utils import NmapXML |
| 8 | 9 | from..csv_utils import NetworkCSV |
| 9 | 10 | from ..model.computer import Computer |
| 10 | -from ..model.printer import Printer | |
| 11 | +from ..model.printer import Printer, PrinterCounter | |
| 11 | 12 | from ..model.network import Network |
| 12 | 13 | |
| 13 | 14 | |
| ... | ... | @@ -107,6 +108,82 @@ class TestPersistence(unittest.TestCase): |
| 107 | 108 | results = self.session.query(Network).first() |
| 108 | 109 | self.assertIsNotNone(results) |
| 109 | 110 | |
| 111 | + def test_printer_counter(self): | |
| 112 | + """ | |
| 113 | + Testa inserção do contador em uma impressora | |
| 114 | + """ | |
| 115 | + hostname = '10.72.168.4' | |
| 116 | + ports = { | |
| 117 | + "9100": { | |
| 118 | + "state": "open", | |
| 119 | + "protocol": "tcp", | |
| 120 | + "service": "vnc-http" | |
| 121 | + }, | |
| 122 | + "631": { | |
| 123 | + "state": "open", | |
| 124 | + "protocol": "tcp", | |
| 125 | + "service": "vnc-http" | |
| 126 | + } | |
| 127 | + } | |
| 128 | + | |
| 129 | + # Agora verifica a inserção do contador | |
| 130 | + counter = PrinterCounter( | |
| 131 | + ip_address=hostname, | |
| 132 | + mac_address=None, | |
| 133 | + hostname=None, | |
| 134 | + inclusion_date=time.time(), | |
| 135 | + open_ports=ports, | |
| 136 | + scantime='3600', | |
| 137 | + model='Samsung SCX-6x55X Series', | |
| 138 | + serial='Z7EUBQBCB03539E', | |
| 139 | + description='Samsung SCX-6x55X Series; V2.00.03.01 03-23-2012;Engine 0.41.69;NIC V5.01.82(SCX-6x55X) 02-28-2012;S/N Z7EUBQBCB03539E', | |
| 140 | + counter=1280, | |
| 141 | + counter_time=time.time() | |
| 142 | + ) | |
| 143 | + | |
| 144 | + self.assertIsInstance(counter, PrinterCounter) | |
| 145 | + self.assertEqual(counter.counter, 1280) | |
| 146 | + self.assertEqual(counter.network_ip, hostname) | |
| 147 | + | |
| 148 | + self.session.add(counter) | |
| 149 | + self.session.flush() | |
| 150 | + # Tenta ver se gravou | |
| 151 | + results = self.session.query(PrinterCounter).first() | |
| 152 | + self.assertIsNotNone(results) | |
| 153 | + | |
| 154 | + def test_update_counter(self): | |
| 155 | + """ | |
| 156 | + Testa inserção dos parâmetros do contador em impressora existente | |
| 157 | + """ | |
| 158 | + hostname = '10.72.168.3' | |
| 159 | + nmap_xml = NmapXML(self.printer_file) | |
| 160 | + host = nmap_xml.parse_xml() | |
| 161 | + assert host | |
| 162 | + | |
| 163 | + printer = nmap_xml.identify_host(hostname) | |
| 164 | + self.assertIsInstance(printer, Printer) | |
| 165 | + | |
| 166 | + printer_counter = PrinterCounter( | |
| 167 | + ip_address=printer.ip_address, | |
| 168 | + mac_address=printer.mac_address, | |
| 169 | + hostname=printer.hostname, | |
| 170 | + inclusion_date=printer.inclusion_date, | |
| 171 | + open_ports=printer.open_ports, | |
| 172 | + scantime=printer.scantime, | |
| 173 | + model='Samsung SCX-6x55X Series', | |
| 174 | + serial='Z7EUBQBCB03539E', | |
| 175 | + description='Samsung SCX-6x55X Series; V2.00.03.01 03-23-2012;Engine 0.41.69;NIC V5.01.82(SCX-6x55X) 02-28-2012;S/N Z7EUBQBCB03539E', | |
| 176 | + counter=1280, | |
| 177 | + counter_time=time.time() | |
| 178 | + ) | |
| 179 | + | |
| 180 | + result = printer_counter.update_counter(self.session) | |
| 181 | + assert result | |
| 182 | + | |
| 183 | + # Aqui não pode inserir de novo | |
| 184 | + result = printer_counter.update_counter(self.session) | |
| 185 | + self.assertFalse(result) | |
| 186 | + | |
| 110 | 187 | def tearDown(self): |
| 111 | 188 | """ |
| 112 | 189 | Remove dados | ... | ... |
cocar/xml_utils.py
| ... | ... | @@ -50,10 +50,14 @@ class NmapXML(object): |
| 50 | 50 | ports = element.find('ports') |
| 51 | 51 | self.hosts[host]['ports'] = dict() |
| 52 | 52 | for port_xml in ports.findall('port'): |
| 53 | + if port_xml.find('service') is not None: | |
| 54 | + service = port_xml.find('service').get('name') | |
| 55 | + else: | |
| 56 | + service = None | |
| 53 | 57 | self.hosts[host]['ports'][port_xml.get('portid')] = { |
| 54 | 58 | 'protocol': port_xml.get('protocol'), |
| 55 | 59 | 'state': port_xml.find('state').get('state'), |
| 56 | - 'service': port_xml.find('service').get('name'), | |
| 60 | + 'service': service, | |
| 57 | 61 | } |
| 58 | 62 | |
| 59 | 63 | # OS Matches | ... | ... |