Exemple #1
0
 def start(self, nameserver=False, localhost_only=False):
     if self._started:
         raise RuntimeError("already started")
     try:
         ip.ipv4_enable_forwarding()
         self.vpn.start()
         self.router.start()
         if nameserver:
             for e in self._get_nameserver_entries():
                 self.registry.nameserver.assert_record(**e)
             basedir = self._basedir / UvnDefaults["nameserver"]["run_dir"]
             self.registry.nameserver.start(basedir, localhost_only=localhost_only)
         self.participant.start()
         self._started = True
         self._ts_started = Timestamp.now()
         self._proc = AgentProc(self)
         self._proc.start()
         logger.info("[started] UVN agent: {}", self.agent_id())
         libuno.log.global_prefix(self.agent_id(brief=True))
     except Exception as e:
         logger.exception(e)
         logger.error("failed to start agent")
         # Try to reset state
         self.stop()
         raise e
Exemple #2
0
    def _load(self):
        (self._vpn_cls,
         self._vpn_extra) = self._get_vpn_class()
        (self._router_cls,
         self._router_extra) = self._get_router_class()
        (self._participant_cls,
         self._participant_extra,) = self._get_participant_class()
        self._connection_test_peers = self._get_connection_test_peers()

        self.vpn = self._create_vpn(self._vpn_cls, self._vpn_extra)
        self.router = self._create_router(self._router_cls, self._router_extra)
        self.participant = self._create_participant(
             self._participant_cls, self._participant_extra)
        self.connection_test = self._create_connection_test(
            self._connection_test_peers)
        # register agent as the nameserver's listener
        self.registry.nameserver.listener = self
        # Determine default gateway
        self._default_gw = ip.ipv4_default_gateway()
        # Read network interfaces to determine the list of networks to which
        # the agent is attached
        self._local_sites = self._list_local_sites()
        # Determine list of private addresses on which to listen
        self._private_ports = {n["address"] for n in self._local_sites}
        self._loaded = True
        self._ts_loaded = Timestamp.now()
        logger.info("[loaded] UVN agent: {}", self.agent_id())

        if self.registry.packaged:
            if not self.registry.bootstrapped:
                logger.warning("no deployment loaded")
            elif not self.registry.deployed_cell_config:
                raise UvnException(f"configuration not found: {self.registry.deployed_cell.id.name}@{self.registry.deployment_id}")
Exemple #3
0
 def _list_handshakes(self):
     result = exec_command(["wg", "show", str(self.interface), "latest-handshakes"],
         quiet=True,
         root=True,
         fail_msg="failed to get latest handshakes for interface: {}".format(self.interface),
         exception=WireGuardError)
     handshakes = {}
     for line in decode_output(result.stdout):
         l_split = list(filter(len, line.split()))
         handshakes[l_split[0]] = Timestamp.unix(l_split[1])
     logger.trace("current handshakes [{}]: {}", self.interface, handshakes)
     return handshakes
Exemple #4
0
 def _tracepath_test(self, peer_count, peer_i, p_name, p_rec):
     ts_check = Timestamp.now()
     result = exec_command(
         ["tracepath", "-c", str(self._ping_count), str(p_rec["address"])],
         fail_msg="failed to ping peer: {} [{}]".format(p_name, p_rec["address"]),
         # don't throw an exception on error
         noexcept=True,
         # don't print any error message
         quiet=True)
     peer_ok = result.returncode == 0
     if not peer_ok:
         unavail_peers.add(p_name)
     self._update_and_notify(peer_i, peer_count, p_name, peer_ok, ts_check)
Exemple #5
0
 def __init__(self, registry, assert_period, keep=False, daemon=False,
         interfaces=[],
         basedir=UvnDefaults["registry"]["agent"]["basedir"],
         logfile=UvnDefaults["registry"]["agent"]["log_file"]):
     # Try to create and lock a pid file to guarantee that only one
     # uvn agent is running on the system
     self.registry = registry
     self._basedir = pathlib.Path(basedir)
     self._logfile = self._basedir / logfile
     self._daemon = daemon
     if not daemon:
         libuno.log.output_file(self._logfile)
     self._interfaces = list(interfaces)
     self._keep = keep
     self._loaded = False
     self._started = False
     self._sem_wait = threading.Semaphore()
     self._sem_wait.acquire()
     self._sem_reload = threading.Semaphore()
     self._sem_reload.acquire()
     self._sem_deploy = threading.Semaphore()
     self._sem_deploy.acquire()
     self._sem_exit = threading.Semaphore()
     self._sem_exit.acquire()
     self._lock = threading.RLock()
     self._ts_created = Timestamp.now()
     self._ts_loaded = None
     self._ts_started = None
     self.vpn = None
     self.connection_test = None
     self.router = None
     self.participant = None
     self._rs = None
     self._peers = UvnPeerManager(listener=self)
     self._reload_queue = []
     self._deploy_queue = []
     self._status = PeerStatus.CREATED
     self._local_sites = []
     self._private_ports = set()
     self._proc = None
     self._assert_period = assert_period
     self._default_gw = None
     logger.debug("loading uvn agent")
     self._load()
Exemple #6
0
    def deploy(self, strategy=None):
        if (strategy is None):
            strategy = DeploymentStrategy.strategies()[0]
        elif (isinstance(strategy, str)):
            strategy = DeploymentStrategy.by_name(strategy)

        strategy = strategy()

        (cells, psks, deployed_cells,
         address_range) = deploy_backbone(self, strategy)

        deploy_time = Timestamp.now()
        deployment = UvnDeployment(strategy=strategy,
                                   deploy_time=deploy_time,
                                   address_range=address_range,
                                   cells=cells,
                                   deployed_cells=deployed_cells,
                                   psks=psks,
                                   registry=self)
        self.deployments.append(deployment)
        self.dirty = True
        return deployment
Exemple #7
0
    def _registry_metadata(registry, dev=False):
        if registry.packaged:
            pkg_cell = registry.cell(registry.pkg_cell)
            component = pkg_cell.id.name
            component_type = "cell"
            image_tag = registry.deployment_id
            image_name = UvnDefaults["docker"]["image_name_fmt"][
                "cell"].format(registry.address, component)
            component_labels = {
                "uvn.cell.name": pkg_cell.id.name,
                "uvn.cell.address": pkg_cell.id.address,
                "uvn.cell.admin": pkg_cell.id.admin,
                "uvn.deployment": registry.deployment_id
            }
        else:
            component = registry.address
            component_type = "registry"
            image_tag = Timestamp.now().format()
            image_name = UvnDefaults["docker"]["image_name_fmt"][
                "root"].format(registry.address)
            component_labels = {"uvn.version": image_tag}

        image_labels = {
            "uvn.address": registry.address,
            "uvn.admin": registry.admin,
            "uvn.component": component_type
        }
        image_labels.update(component_labels)

        image_args = {}

        if dev:
            dockerfile_pfx = "-dev"
        else:
            dockerfile_pfx = ""

        dockerfile = f"{component_type}{dockerfile_pfx}.dockerfile"

        base_image_name = UvnDefaults["docker"]["base_image"]
        base_image_tag = libuno.__version__
        base_image_labels = {}
        base_image_args = image_args
        base_dockerfile = f"{base_image_name}{dockerfile_pfx}.dockerfile"

        container_name = image_name
        container_labels = image_labels
        container_volumes = {
            str(registry.paths.basedir): {
                "bind": UvnDefaults["docker"]["volumes"]["uvn"],
                "mode": "rw"
            }
        }

        (os_system, os_node, os_release, os_version, container_arch,
         os_processor) = platform.uname()

        return (component, component_type, image_name, image_tag, image_labels,
                image_args, dockerfile, base_image_name, base_image_tag,
                base_image_labels, base_image_args, base_dockerfile,
                container_name, container_labels, container_volumes,
                container_arch)