async def load_backend(self) -> bool: """Load backend details.""" # Load instance data from backend try: async with async_timeout.timeout(30): resp = await cloud_api.async_remote_register(self.cloud) resp.raise_for_status() except (asyncio.TimeoutError, aiohttp.ClientError) as err: msg = "Can't update remote details from Home Assistant cloud" if isinstance(err, aiohttp.ClientResponseError): msg += f" ({err.status})" # pylint: disable=no-member elif isinstance(err, asyncio.TimeoutError): msg += " (timeout)" _LOGGER.error(msg) return False data = await resp.json() # Extract data _LOGGER.debug("Retrieve instance data: %s", data) domain = data["domain"] email = data["email"] server = data["server"] # Cache data self._instance_domain = domain self._snitun_server = server # Set instance details for certificate self._acme = AcmeHandler(self.cloud, domain, email) # Load exists certificate await self._acme.load_certificate() # Domain changed / revoke CA ca_domain = self._acme.common_name if ca_domain and ca_domain != domain: _LOGGER.warning("Invalid certificate found: %s", ca_domain) await self._acme.reset_acme() self._info_loaded.set() should_create_cert = not self._acme.certificate_available if should_create_cert or self._acme.expire_date < utils.utcnow() + timedelta( days=RENEW_IF_EXPIRES_DAYS ): try: await self._acme.issue_certificate() except AcmeClientError: self.cloud.client.user_message( "cloud_remote_acme", "Home Assistant Cloud", const.MESSAGE_REMOTE_SETUP, ) return else: if should_create_cert: self.cloud.client.user_message( "cloud_remote_acme", "Home Assistant Cloud", const.MESSAGE_REMOTE_READY, ) await self._acme.hardening_files() if self.cloud.client.aiohttp_runner is None: _LOGGER.debug("Waiting for aiohttp runner to come available") # aiohttp_runner comes available when Home Assistant has started. while self.cloud.client.aiohttp_runner is None: await asyncio.sleep(1) # Setup snitun / aiohttp wrapper _LOGGER.debug("Initializing SniTun") context = await self._create_context() self._snitun = SniTunClientAioHttp( self.cloud.client.aiohttp_runner, context, snitun_server=self._snitun_server, snitun_port=443, ) _LOGGER.debug("Starting SniTun") is_cloud_request.set(True) await self._snitun.start() self.cloud.client.dispatcher_message(const.DISPATCH_REMOTE_BACKEND_UP) _LOGGER.debug( "Connecting remote backend: %s", self.cloud.client.remote_autostart ) # Connect to remote is autostart enabled if self.cloud.client.remote_autostart: self.cloud.run_task(self.connect()) return True
async def load_backend(self) -> None: """Load backend details.""" if self._snitun: return # Setup background task for ACME certification handler if not self._acme_task: self._acme_task = self.cloud.run_task(self._certificate_handler()) # Load instance data from backend try: async with async_timeout.timeout(15): resp = await cloud_api.async_remote_register(self.cloud) assert resp.status == 200 except (asyncio.TimeoutError, AssertionError): _LOGGER.error( "Can't update remote details from Home Assistant cloud") return data = await resp.json() # Extract data _LOGGER.debug("Retrieve instance data: %s", data) domain = data["domain"] email = data["email"] server = data["server"] # Set instance details for certificate self._acme = AcmeHandler(self.cloud, domain, email) # Load exists certificate await self._acme.load_certificate() # Domain changed / revoke CA ca_domain = self._acme.common_name if ca_domain is not None and ca_domain != domain: _LOGGER.warning("Invalid certificate found: %s", ca_domain) await self._acme.reset_acme() # Issue a certificate if not self._acme.is_valid_certificate: try: await self._acme.issue_certificate() except AcmeClientError: self.cloud.client.user_message( "cloud_remote_acme", "Home Assistant Cloud", const.MESSAGE_REMOTE_SETUP, ) return else: self.cloud.client.user_message( "cloud_remote_acme", "Home Assistant Cloud", const.MESSAGE_REMOTE_READY, ) await self._acme.hardening_files() # Setup snitun / aiohttp wrapper context = await self._create_context() self._snitun = SniTunClientAioHttp( self.cloud.client.aiohttp_runner, context, snitun_server=server, snitun_port=443, ) # Cache data self._instance_domain = domain self._snitun_server = server await self._snitun.start() self.cloud.client.dispatcher_message(const.DISPATCH_REMOTE_BACKEND_UP) # Connect to remote is autostart enabled if self.cloud.client.remote_autostart: self.cloud.run_task(self.connect())
async def test_init_client(): """Init aiohttp client for test.""" with patch("snitun.utils.aiohttp_client.SockSite"): client = SniTunClientAioHttp(None, None, "127.0.0.1")