예제 #1
0
    def check(self):
        try:
            network = ConfigObj(self.netfile)
        except ConfigObjError as err:
            raise NetemError("Syntax error in the network file: %s" % err)

        # first, be sure we can record images and configs
        image_dir = os.path.join(
            os.path.dirname(self.netfile), network["config"]["image_dir"])
        config_dir = os.path.join(
            os.path.dirname(self.netfile), network["config"]["config_dir"])
        for path in (image_dir, config_dir):
            if not os.path.isdir(path):
                os.mkdir(path)

        # check network files before start it
        errors = check_network(network, self.daemon)
        if len(errors) > 0:
            msg = ""
            for e_mod in errors:
                err_msg = "\n\t".join(errors[e_mod]["errors"])
                msg += "%s:\n\t%s\n" % (errors[e_mod]["desc"], err_msg)
            raise NetemError("The network file has errors\n  %s" % msg)

        return network
예제 #2
0
파일: server.py 프로젝트: mroy31/pynetem
    def handle(self):
        cmd = self.request.recv(1024).decode("utf-8").strip()
        logging.debug("Receive data: %s" % cmd)

        msg = ""
        try:
            cmd_args = cmd.split()
            if len(cmd_args) < 1:
                raise NetemError("The sent command is empty")

            cmd_name = cmd_args[0]
            if cmd_name not in CMD_LIST:
                raise NetemError("Unknown command %s" % cmd)
            cmd_regexp = CMD_LIST[cmd_name]
            # verify arguments
            match_obj = re.match(cmd_regexp, cmd)
            if match_obj is None:
                raise NetemError("Wrong number of args for "
                                 "command %s" % cmd_name)
            # execute command
            ret = getattr(self, cmd_name)(*match_obj.groups())
        except NetemError as err:
            msg = "%s" % err
        except Exception:
            logging.error(get_exc_desc())
            msg = "Unknown exception happen see log for details"
        else:
            msg = "OK"
            if ret is not None:
                msg += " %s" % ret
        self.request.sendall(msg.encode("utf-8"))
예제 #3
0
    def do_copy(self, source, dest):
        def get_path_type(p):
            docker_re = r"^(\w+):([^\0]+)$"
            args = re.match(docker_re, p)
            if args is None:
                return "host", None, p
            else:
                return "docker", args.group(1), args.group(2)

        def get_node(name):
            node = self.project.topology.get_node(name)
            if node is None:
                raise NetemError("Node {} does not exist".format(name))
            elif node.get_type() != "node.docker":
                raise NetemError("Copy cmd works only with docker nodes")
            return node

        s_type, s_name, s_path = get_path_type(source)
        d_type, d_name, d_path = get_path_type(dest)
        if s_type == d_type:
            raise NetemError("Can not do copy {0}/{0}".format(s_type))

        if s_type == "docker":  # d_type = host
            node = get_node(s_name)
            node.source_copy(s_path, d_path)

        else:  # s_type = host
            if not os.path.exists(s_path):
                raise NetemError("Host path {} does not exist".format(d_path))
            node = get_node(d_name)
            node.dest_copy(s_path, d_path)
예제 #4
0
 def get_node(name):
     node = self.project.topology.get_node(name)
     if node is None:
         raise NetemError("Node {} does not exist".format(name))
     elif node.get_type() != "node.docker":
         raise NetemError("Copy cmd works only with docker nodes")
     return node
예제 #5
0
    async def __send_rpc_cmd(self, cmd_name, args=[]):
        request = RPCRequest(cmd_name, args)
        loop = asyncio.get_running_loop()
        on_answer = loop.create_future()

        transport, _ = await loop.create_connection(
            lambda: NetemClientProtocol(request, self.__on_signal, on_answer),
            "127.0.0.1",
            self.s_port,
        )

        result = await on_answer
        transport.close()

        if result is None:
            raise NetemError("No valid answer has been received from server")
        elif result["state"] == "error":
            raise NetemError(result["content"])
        elif result["state"] == "interrupt":
            # command has been interrupt by user
            self.pwarning(
                "Running command {} has been interrupt".format(cmd_name)
            )
            return None

        return result["content"]
예제 #6
0
def build_node_instance(prj_id, p2p_sw, img_dir, conf_dir, n_name, n_config):
    logging.debug("Create node instance %s" % n_name)
    if "type" in n_config:
        nc_type = n_config["type"].split('.', 1)
        n_type, n_image = "qemu", None
        if len(nc_type) == 1:
            n_image = nc_type[0]
        elif len(nc_type) == 2:
            n_type, n_image = nc_type
        else:
            raise NetemError("type args for node %s has wrong format" % n_name)

        # create instance based on type field
        if n_type == "qemu":
            return QEMUInstance(p2p_sw, prj_id, img_dir, n_image, n_name,
                                n_config)
        if n_type == "junos":
            return JunosInstance(p2p_sw, prj_id, conf_dir, n_image, n_name,
                                 n_config)
        if n_type == "docker":
            try:
                return DOCKER_NODES[n_image](p2p_sw, prj_id, conf_dir, n_name,
                                             n_config)
            except KeyError:
                raise NetemError("docker image %s does not exist" % n_image)

    raise NetemError("Type is not specified for %s" % n_name)
예제 #7
0
파일: utils.py 프로젝트: mroy31/pynetem
def test_project(prj_path):
    _, ext = os.path.splitext(prj_path)
    if ext.lower() != ".pnet":
        raise NetemError("Project %s has wrong ext" % prj_path)
    if not os.path.isfile(prj_path):
        raise NetemError("Project %s does not exist" % prj_path)
    if not zipfile.is_zipfile(prj_path):
        raise NetemError("Project %s is not a zip file" % prj_path)
예제 #8
0
파일: __init__.py 프로젝트: mroy31/pynetem
 def _command(self, cmd_line, check_output=True, shell=False):
     args = shlex.split(cmd_line)
     try:
         return subprocess.run(args,
                               shell=shell,
                               stdout=subprocess.PIPE,
                               stderr=subprocess.PIPE,
                               check=True)
     except subprocess.CalledProcessError as err:
         msg = "%s --> %s" % (err.cmd, err.stderr)
         raise NetemError(msg)
     except FileNotFoundError as err:
         raise NetemError(str(err))
예제 #9
0
파일: server.py 프로젝트: mroy31/pynetem
 def docker_pull(image_name):
     client = docker.from_env()
     try:
         client.images.pull(image_name)
     except docker.errors.APIError as ex:
         raise NetemError("Unable to pull {} image: {}".format(
             image_name, ex))
예제 #10
0
파일: __init__.py 프로젝트: mroy31/pynetem
def build_sw_instance(prj_id, sw_name, sw_config):
    logging.debug("Create switch instance %s" % sw_name)
    try:
        sw_type = sw_config["type"]
        s_inst = SWITCH_CLASSES[sw_type](prj_id, sw_name, sw_config)
    except KeyError:
        raise NetemError("Wrong switch type for %s" % sw_name)
    return s_inst
예제 #11
0
    def save(self, conf_file):
        try:
            tn = telnetlib.Telnet("localhost", port=self.port, timeout=5)
        except (ConnectionRefusedError, TimeoutError):
            raise NetemError("Unable to connect to %s router" % self.name)

        if not self.logout(tn):
            raise NetemError("Unable to save %s router, perhaps you forget to "
                             "commit your configuration" % self.name)

        self.login(tn, self.name.encode("ascii"))
        tn.write(b"configure\n")
        with open(conf_file, "bw") as hd:
            tn.write(b"save terminal\n")
            data = tn.read_until(b"Wrote")
            hd.write(self.__format_conf(data))
        tn.close()
예제 #12
0
파일: utils.py 프로젝트: mroy31/pynetem
def cmd_run_app(cmd_line):
    args = shlex.split(cmd_line)
    try:
        return subprocess.Popen(args,
                                shell=False,
                                env={"DISPLAY": get_x11_env()})
    except FileNotFoundError as err:
        raise NetemError(str(err))
예제 #13
0
파일: server.py 프로젝트: mroy31/pynetem
def run_command(cmd_line, check_output=False, shell=False):
    args = shlex.split(cmd_line)
    if check_output:
        try:
            result = subprocess.check_output(args, shell=shell)
        except subprocess.CalledProcessError:
            msg = "Unable to execute command %s" % (cmd_line, )
            logging.error(msg)
            raise NetemError(msg)
        except FileNotFoundError as err:
            raise NetemError(str(err))
        return result.decode("utf-8").strip("\n")
    else:
        ret = subprocess.call(args, shell=shell)
        if ret != 0:
            msg = "Unable to excecute command %s" % (cmd_line, )
            logging.error(msg)
            raise NetemError(msg)
예제 #14
0
    def cmd_func(self, *args):
        logging.debug("Call daemon command: %s -> %s" % (cmd, args))
        if len(args) != nb_args:
            raise NetemError("Wrong number of arguments for cmd %s" % cmd)

        cmd_line = "%s %s" % (cmd, " ".join(args))
        sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
        try:
            sock.connect(self.socket_path)
        except socket.error as err:
            raise NetemError("Unable to connect to daemon: %s" % err)

        sock.sendall(cmd_line.encode("utf-8"))
        ans = sock.recv(1024).decode("utf-8").strip()
        sock.close()
        if not ans.startswith("OK"):
            raise NetemError("Daemon returns an error:\n\t%s" % ans)
        return ans.replace("OK ", "")
예제 #15
0
파일: docker.py 프로젝트: mroy31/pynetem
 def set_if_state(self, if_number, state):
     if len(self.interfaces) > if_number:
         if_entry = self.interfaces[if_number]
         if_name = if_entry["target_if"]
         self._docker_exec("ip link set {} {}".format(if_name, state))
         if_entry["state"] = state
     else:
         raise NetemError("%s: interface %d does not "
                          "exist" % (self.name, if_number))
예제 #16
0
    def __get_node_if(self, if_id):
        if_ids = if_id.rsplit(".", 1)
        if len(if_ids) == 2:
            node_id, if_number = if_ids
            node = self.get_node(node_id)
            if node is None:
                raise NetemError("Node %s does not exist" % node_id)
            try:
                if_number = int(if_number)
            except (TypeError, ValueError):
                raise NetemError(
                    "%s is not a correct interface identifier" % if_number
                )
        else:
            raise NetemError(
                "if_name must follow the syntax <host>.<if_number>"
            )

        return node, if_number
예제 #17
0
파일: server.py 프로젝트: mroy31/pynetem
 def ifdown(cls, if_name):
     logging.debug("Ifdown %s" % if_name)
     with IPDB() as ipdb:
         if if_name not in ipdb.interfaces:
             raise NetemError("interface %s does not exist" % if_name)
         # be sure that host if is UP
         if_obj = ipdb.interfaces[if_name]
         if if_obj.operstate == 'UP':
             if_obj.freeze()
             if_obj.down().commit()
             if_obj.unfreeze()
예제 #18
0
파일: __init__.py 프로젝트: mroy31/pynetem
 def stop(self):
     if self.is_started:
         self.is_started = False
         self.watch_thread.join()
         try:
             self.process.terminate()
             self.process.wait()
         except OSError as e:
             raise NetemError("Unable to stop %s -> %s" % (self.name, e))
         finally:
             self.process = None
             self.watch_thread = None
예제 #19
0
파일: docker.py 프로젝트: mroy31/pynetem
    def capture(self, if_number):
        if not shutil.which("wireshark"):
            raise NetemError(
                "Unable to start capture -> Wireshark is not installed on"
                " your computer")

        if len(self.interfaces) <= if_number:
            raise NetemError("%s: interface %d does not "
                             "exist" % (self.name, if_number))

        if_name = "eth%s" % if_number
        if CAPTURE_PROCESS == "daemon":
            # capture is launch by the daemon
            display = get_x11_env()
            self.daemon.docker_capture(display, self.container_name, if_name)

        else:  # user
            cmd = "/bin/bash -c 'docker exec {0} tcpdump -s 0 -U -w - -i {1} "\
                "2>/dev/null | wireshark -o 'gui.window_title:{1}@{2}' "\
                "-k -i - &'".format(self.container_name, if_name, self.name)
            cmd_run_app(cmd)
예제 #20
0
파일: rpc.py 프로젝트: mroy31/pynetem
def loads_request(request, **kws):
    err = NetemError("Malformed request")
    try:
        unmarshalled = json.loads(request, **kws)
    except ValueError:
        raise err

    if (isinstance(unmarshalled, dict)):
        for key in ("method", "params", "id"):
            if key not in unmarshalled:
                raise err
        return unmarshalled
    raise err
예제 #21
0
파일: rpc.py 프로젝트: mroy31/pynetem
def loads_response(response, **kws):
    err = NetemError("Malformed response")
    try:
        unmarshalled = json.loads(response, **kws)
    except ValueError:
        raise err

    if (isinstance(unmarshalled, dict)):
        for key in ("type", "id"):
            if key not in unmarshalled:
                raise err
        return unmarshalled
    raise err
예제 #22
0
파일: project.py 프로젝트: mroy31/pynetem
    def __init__(self, daemon, netid, prj_path):
        self.__id = netid
        self.daemon = daemon
        self.prj_path = prj_path
        self.tmp_folder = tempfile.mkdtemp(prefix=netid)
        with zipfile.ZipFile(prj_path) as prj_zip:
            prj_zip.extractall(path=self.tmp_folder)

        # init topology
        topology_file = os.path.join(self.tmp_folder, TOPOLOGY_FILE)
        if not os.path.isfile(topology_file):
            raise NetemError("Project %s does not contain "
                             "a topology file" % prj_path)
        self.topology = TopologyManager(self.__id, topology_file, daemon)
예제 #23
0
파일: qemu.py 프로젝트: mroy31/pynetem
 def open_shell(self, bash=False):
     if self.shell_process is not None \
             and self.shell_process.poll() is None:
         raise NetemError("The console is already opened")
     term_cmd = NetemConfig.instance().get("general", "terminal") % {
         "title": self.name,
         "cmd": "telnet localhost %d" % self.telnet_port,
     }
     args = shlex.split(term_cmd)
     self.shell_process = subprocess.Popen(args,
                                           stdin=subprocess.PIPE,
                                           stdout=subprocess.PIPE,
                                           stderr=subprocess.PIPE,
                                           shell=False)
예제 #24
0
파일: qemu.py 프로젝트: mroy31/pynetem
    def capture(self, if_number):
        if len(self.interfaces) > if_number:
            if if_number in self.capture_processes:
                process = self.capture_processes[if_number]
                if process.poll() is None:
                    raise NetemError("Capture process is already running")

            w_options = "-o 'gui.window_title:{}.{}'".format(
                self.name, if_number)
            if_obj = self.interfaces[if_number]
            if if_obj["peer"] == "switch" \
                    and if_obj["peer_instance"] is not None:
                sw_type = if_obj["peer_instance"].get_type()
                if sw_type == "switch.ovs":
                    if_name = if_obj["tap"]
                elif sw_type == "switch.vde":
                    if_name = if_obj["peer_instance"].get_tap_name()
                    if if_name is None:
                        raise NetemError("Unable to launch capture, no tap"
                                         "if exists on this switch")
                cmd_ln = shlex.split("wireshark -k %s -i %s" %
                                     (w_options, if_name))
                self.capture_processes[if_number] = subprocess.Popen(cmd_ln)

            elif if_obj["peer"] in ("bridge", "node"):
                if_name = if_obj["tap"]
                cmd_ln = shlex.split("wireshark -k %s -i %s" %
                                     (w_options, if_name))
                self.capture_processes[if_number] = subprocess.Popen(cmd_ln)

            else:
                raise NetemError("%s: interface %d is not "
                                 "plugged" % (self.name, if_number))
        else:
            raise NetemError("%s: interface %d does not "
                             "exist" % (self.name, if_number))
예제 #25
0
파일: server.py 프로젝트: mroy31/pynetem
 def docker_shell(cls, c_name, name, shell, display, term_cmd):
     logging.debug("Docker open shell for container %s" % c_name)
     term_cmd = term_cmd % {
         "title": name,
         "cmd": "docker exec -it %s %s" % (c_name, shell)
     }
     args = shlex.split(term_cmd)
     try:
         subprocess.Popen(args,
                          shell=False,
                          env={
                              "DISPLAY": display,
                              "HOME": "/root"
                          })
     except FileNotFoundError as err:
         raise NetemError(str(err))
예제 #26
0
 def cmd_func(self, *args, **kwargs):
     # test args
     if len(cmd_args) != len(args):
         raise NetemError("Wrong number of arguments")
     # run original func
     return func(self, *args, **kwargs)
예제 #27
0
 def do_config(self, conf_path):
     conf_path = os.path.abspath(conf_path)
     if not os.path.isdir(conf_path):
         raise NetemError("%s is not a valid path" % conf_path)
     self.project.save_config(conf_path)
예제 #28
0
파일: qemu.py 프로젝트: mroy31/pynetem
 def set_if_state(self, if_number, state):
     raise NetemError("ifstate command is not supported for qemu nodes.")
예제 #29
0
 def __open_shell(self, node_id, bash):
     nodes = self.__get_nodes(node_id)
     if len(nodes) == 0:
         raise NetemError("Node '%s' does not exist" % node_id)
     for node in nodes:
         node.open_shell(bash=bash)
예제 #30
0
파일: server.py 프로젝트: mroy31/pynetem
 def chown(host_path, uid, gid):
     logging.debug("chown %s:%s %s" % (uid, gid, host_path))
     if not os.path.exists(host_path):
         raise NetemError("Path %s does not exist" % host_path)
     cmd = "chown -R %s:%s \"%s\"" % (uid, gid, host_path)
     run_command(cmd)