Ejemplo n.º 1
0
 def from_trace_file(source_filename):
     parrot_filename = None
     if source_filename.endswith(".trace"):
         parrot_filename = NSO_Trace_Parrot_Builder(source_filename).build()
     if parrot_filename:
         return parrot_filename
     Logger.fatal(
         f"Parrot Builder, unrecognized trace file type: {source_filename}")
Ejemplo n.º 2
0
 def __init__(self, source_filename, target_filename=None):
     self.source_filename = pathlib.Path(source_filename)
     if not target_filename:
         target_filename = source_filename + ".parrot.xml"
     self.target_filename = pathlib.Path(target_filename)
     if not self.source_filename.exists():
         Logger.fatal(
             f"Parrot Builder, can't find trace file: {source_filename}")
     self.catalog = {}
     self.catalog_meta = {}
Ejemplo n.º 3
0
 def reply(self, incoming_message):
     try:
         response_msg = self.template.render(
             request=incoming_message,
             message_id=incoming_message.get_message_id(),
             session_id="4711",  #FIXME str(self.session_id),
         )
         return response_msg.strip()
     except Exception as ex:
         Logger.fatal(
             f"Template rendering error, {self.template}, {incoming_message.get_xml_text()}: {ex}"
         )
Ejemplo n.º 4
0
    def run(self, host, port, parrot_file):
        Logger.info(f"Parroting {parrot_file}")
        try:
            parrot_path = pathlib.Path(parrot_file)
            env = Environment(loader=FileSystemLoader([parrot_path.parent],
                                                      followlinks=True),
                              autoescape=select_autoescape(['xml']))

            self.server.set_template(env.get_template(str(parrot_path.name)))
            self.server.set_host_port(host, port)
            self.server.serve()
        except Exception as e:
            traceback.print_exc()
            Logger.fatal(f"Top level exception: {str(e)}")
Ejemplo n.º 5
0
    def run_command_line(self, sys_argv=sys.argv):
        def usage(sys_argv):
            print(f'{sys_argv[0]} --netconf=[host:]port parrot-file.xml')

        verbosity = 4
        host = "localhost"
        port = 8888
        template_dirs = []
        trace_files = []
        parrot_file = None
        try:
            opts, args = getopt.getopt(
                sys_argv[1:], "hd:vt:m:",
                ["help", "debug=", "verbose", "netconf=", "template-dir="])
        except getopt.GetoptError:
            usage(sys_argv)
            sys.exit(2)
        for opt, arg in opts:
            if opt in ('-h', '--help'):
                usage(sys_argv)
                sys.exit()
            elif opt in ("--netconf"):
                self.server = Parrot.NETCONF_Parrot()
                if ":" in arg:
                    (host, port_str) = arg.split(":")
                    port = int(port_str)
                else:
                    port = int(arg)
            elif opt in ("-t", "--template-dir"):
                template_dirs += [arg]
            elif opt in ("-d", "--debug"):
                verbosity = int(arg)
            elif opt in ("-m", "--make-parrot"):
                trace_files += [arg]
            elif opt in ("-v", "--verbose"):
                verbosity += 1
            else:
                Logger.fatal(f'Unknown option "{opt}".')
                sys.exit(2)

        for trace_file_name in trace_files:
            parrot_file = Parrot_Builder.from_trace_file(trace_file_name)

        if not parrot_file:
            if len(args) != 1:
                usage(sys_argv)
                Logger.fatal(f"{len(args)} parrot files given.", code=2)
            parrot_file = args[0]

        if not self.server:
            usage(sys_argv)
            Logger.fatal(f"{len(args)} server specified.", code=2)

        Logger.set_verbosity(verbosity)

        self.run(host, port, parrot_file)
Ejemplo n.º 6
0
 def _record_message(self, message, meta):
     # This method should maybe parse the XML properly, but since
     # we also want this to work with potentially malformed XML,
     # it is instead making some assumptions about the XML encoding
     direction = NSO_Trace_Parrot_Builder._meta_dir(meta)
     if not direction:
         Logger.fatal(f"Message meta malformed: {meta}")
     message_id_attr_str = "message-id="
     # Assume first occurrence of message-id is the NETCONF message-id
     pos = message.find(message_id_attr_str)
     if pos >= 0:
         pos += len(message_id_attr_str)
         delimiter = message[pos]
         # Assume message-id value is properly delimited
         if delimiter not in ['"', "'"]:
             Logger.fatal(f"Attribute message-id= malformed (1): {meta}")
         pos += 1
         endpos = message[pos:].find(delimiter)
         # Assume message-id value is at most 100 chars
         if endpos < 0 or endpos > 100:
             Logger.fatal(f"Attribute message-id= malformed (2): {meta}")
         message_id = message[pos:pos + endpos]
         self.catalog[(direction, message_id)] = message
         self.catalog_meta[(direction, message_id)] = meta
         print(
             f"Recorded message {direction} {message_id} = {message[:40]}..."
         )
     # Assume hello message is not namespaced, and has no redundant whitespace
     elif message.startswith("<hello "):
         self.catalog[(direction, "hello")] = message
         self.catalog_meta[(direction, "hello")] = meta
     elif direction == "meta":
         self.catalog[(direction, meta)] = message
         self.catalog_meta[(direction, meta)] = meta
         pass
     elif not message:
         pass
     else:
         Logger.fatal(f"Message not hello and lacks message-id: {meta}")
Ejemplo n.º 7
0
  def listen(self):
    NETCONF_Server.set_instance(self)
    try:
      sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
      sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
      #sock.bind(('', self.port))
      sock.bind((self.host, self.port))
    except Exception as e:
      Logger.fatal('Bind failed: ' + str(e))

    try:
      sock.listen(100)
    except Exception as e:
      Logger.fatal('Listen failed: ' + str(e))
    Logger.info(f'Listening for connections on port {self.port}...')

    host_key = None
    try:
      host_key = RSAKey(filename=self.host_key_filename)
    except:
      pass
    if not host_key:
      Logger.info(f'Generating new host key')
      host_key = RSAKey.generate(2048)
      if self.host_key_filename:
        host_key.write_private_key_file(self.host_key_filename, password=None)
        Logger.info(f"Wrote host key to file, '{self.host_key_filename}'")

    while True:
      try:
        Logger.info(f'Waiting for client to connect')
        client, addr = sock.accept()
      except Exception as e:
        Logger.fatal('Accept failed: ' + str(e))
      self.sock = client
      (ip, port) = addr
      Logger.info(f'Client {ip}:{port} connected')
      self.handle_connection(host_key)
      Logger.info(f'Client {ip}:{port} disconnected')