async def _request_sign(self, response): """Request a signed certificate set up a gPRC channel and set the response If it fails, schedule the next bootstrap, Otherwise _request_sign_done callback is called """ try: chan = ServiceRegistry.get_bootstrap_rpc_channel() except ValueError as exp: logging.error('Failed to get rpc channel: %s', exp) BOOTSTRAP_EXCEPTION.labels(cause='RequestSignGetRPC').inc() self._schedule_next_bootstrap(hard_failure=False) return try: client = BootstrapperStub(chan) result = await grpc_async_wrapper( client.RequestSign.future(response), self._loop ) await self._request_sign_done_success(result) except grpc.RpcError as err: self._request_sign_done_fail(err)
def _get_challenge_done_fail(self, err): logging.error( "GetChallenge error! [%s] %s", err.code(), err.details(), extra=EXCLUDE_FROM_ERROR_MONITORING if indicates_connection_error(err) else None, ) BOOTSTRAP_EXCEPTION.labels(cause='GetChallengeResp').inc() self._schedule_next_bootstrap(hard_failure=False)
async def _request_sign_done_success(self, cert): if not self._is_valid_certificate(cert): BOOTSTRAP_EXCEPTION.labels(cause='RequestSignDoneInvalidCert').inc() self._schedule_next_bootstrap(hard_failure=True) return try: cert_utils.write_key(self._gateway_key, self._gateway_key_file) cert_utils.write_cert(cert.cert_der, self._gateway_cert_file) except Exception as exp: BOOTSTRAP_EXCEPTION.labels(cause='RequestSignDoneWriteCert:%s' % type(exp).__name__).inc() logging.error('Failed to write cert: %s', exp) # need to restart control_proxy await self._bootstrap_success_cb(True) self._gateway_key = None self._schedule_next_bootstrap_check() logging.info("Bootstrapped Successfully!")
def _get_challenge_done(self, future): """Callback for GetChallenge.future 1. check whether future correctly returns 2. create key and store it in self._gateway_key 3. create csr and response If any step fails, call _retry_bootstrap. Otherwise _request_sign is called and process to next procedure Args: future: Future object returned by async GetChallenge gRPC call """ err = future.exception() if err: err = 'GetChallenge error! [%s] %s' % (err.code(), err.details()) logging.error(err) BOOTSTRAP_EXCEPTION.labels(cause='GetChallengeResp').inc() self._retry_bootstrap(hard_failure=False) return challenge = future.result() # create key try: self._gateway_key = ec.generate_private_key( ec.SECP384R1(), default_backend()) except InternalError as exp: logging.error('Fail to generate private key: %s', exp) BOOTSTRAP_EXCEPTION.labels( cause='GetChallengeDonePrivateKey').inc() self._retry_bootstrap(hard_failure=True) return # create csr and send for signing try: csr = self._create_csr() except Exception as exp: logging.error('Fail to create csr: %s', exp) BOOTSTRAP_EXCEPTION.labels(cause='GetChallengeDoneCreateCSR:%s' % type(exp).__name__).inc() try: response = self._construct_response(challenge, csr) except BootstrapError as exp: logging.error('Fail to create response: %s', exp) BOOTSTRAP_EXCEPTION.labels( cause='GetChallengeDoneCreateResponse').inc() self._retry_bootstrap(hard_failure=True) return self._request_sign(response)
def _request_sign(self, response): """Request a signed certificate set up a gPRC channel and set the response If it fails, call _retry_bootstrap, Otherwise _request_sign_done callback is added to the future """ try: chan = ServiceRegistry.get_bootstrap_rpc_channel() except ValueError as exp: logging.error('Failed to get rpc channel: %s', exp) BOOTSTRAP_EXCEPTION.labels(cause='RequestSignGetRPC').inc() self._retry_bootstrap(hard_failure=False) return client = BootstrapperStub(chan) future = client.RequestSign.future(response) future.add_done_callback( lambda future: self._loop.call_soon_threadsafe( self._request_sign_done, future))
async def _get_challenge_done_success(self, challenge): # create key try: self._gateway_key = ec.generate_private_key( ec.SECP384R1(), default_backend()) except InternalError as exp: logging.error('Fail to generate private key: %s', exp) BOOTSTRAP_EXCEPTION.labels( cause='GetChallengeDonePrivateKey').inc() self._schedule_next_bootstrap(hard_failure=True) return # create csr and send for signing try: csr = self._create_csr() except Exception as exp: logging.error('Fail to create csr: %s', exp) BOOTSTRAP_EXCEPTION.labels(cause='GetChallengeDoneCreateCSR:%s' % type(exp).__name__).inc() try: response = self._construct_response(challenge, csr) except BootstrapError as exp: logging.error('Fail to create response: %s', exp) BOOTSTRAP_EXCEPTION.labels( cause='GetChallengeDoneCreateResponse').inc() self._schedule_next_bootstrap(hard_failure=True) return await self._request_sign(response)
async def _get_challenge_done_success(self, challenge): # create key try: # GRPC python client only supports P256 elliptic curve cipher # See https://github.com/grpc/grpc/issues/23235 # Behind the nghttpx control_proxy this isn't a problem because # nghttpx handles the handshake, but if you have a P384 cert and # don't proxy your cloud connections, every authenticated Python # GRPC call will fail. self._gateway_key = ec.generate_private_key( ec.SECP256R1(), default_backend()) except InternalError as exp: logging.error('Fail to generate private key: %s', exp) BOOTSTRAP_EXCEPTION.labels( cause='GetChallengeDonePrivateKey').inc() self._schedule_next_bootstrap(hard_failure=True) return # create csr and send for signing try: csr = self._create_csr() except Exception as exp: logging.error('Fail to create csr: %s', exp) BOOTSTRAP_EXCEPTION.labels(cause='GetChallengeDoneCreateCSR:%s' % type(exp).__name__).inc() try: response = self._construct_response(challenge, csr) except BootstrapError as exp: logging.error('Fail to create response: %s', exp) BOOTSTRAP_EXCEPTION.labels( cause='GetChallengeDoneCreateResponse').inc() self._schedule_next_bootstrap(hard_failure=True) return await self._request_sign(response)
def _request_sign_done(self, future): """Callback for RequestSign.future 1. check whether future correctly returns 2. check whether returned cert is valid 3. write key and cert into files, reset self._gateway_key to None If any steps fails, call _retry_bootstrap, Otherwise call _schedule_periodic_bootstrap_check. Args: future: Future object returned by async RequestSign gRPC call """ err = future.exception() if err: err = 'RequestSign error! [%s], %s' % (err.code(), err.details()) BOOTSTRAP_EXCEPTION.labels(cause='RequestSignDoneResp').inc() logging.error(err) self._retry_bootstrap(hard_failure=False) return cert = future.result() if not self._is_valid_certificate(cert): BOOTSTRAP_EXCEPTION.labels( cause='RequestSignDoneInvalidCert').inc() self._retry_bootstrap(hard_failure=True) return try: cert_utils.write_key(self._gateway_key, self._gateway_key_file) cert_utils.write_cert(cert.cert_der, self._gateway_cert_file) except Exception as exp: BOOTSTRAP_EXCEPTION.labels(cause='RequestSignDoneWriteCert:%s' % type(exp).__name__).inc() logging.error('Failed to write cert: %s', exp) logging.info('Bootstrap succeeds') # need to restart control_proxy self._bootstrap_success_cb(True) self._gateway_key = None self._schedule_periodic_bootstrap_check()
def _request_sign_done_fail(self, err): err = 'RequestSign error! [%s], %s' % (err.code(), err.details()) BOOTSTRAP_EXCEPTION.labels(cause='RequestSignDoneResp').inc() logging.error(err) self._schedule_next_bootstrap(hard_failure=False)
def _get_challenge_done_fail(self, err): err = 'GetChallenge error! [%s] %s' % (err.code(), err.details()) logging.error(err) BOOTSTRAP_EXCEPTION.labels(cause='GetChallengeResp').inc() self._schedule_next_bootstrap(hard_failure=False)