예제 #1
0
def local_auth_server(token_cb, **overrides):
    class MockedProvider(object):
        def generate_token(self, scopes):
            return token_cb(scopes)

    s = auth_server.LocalAuthServer()
    try:
        local_auth = s.start(MockedProvider())
        local_auth.update(overrides)
        with luci_context.write(local_auth=local_auth):
            yield
    finally:
        s.stop()
예제 #2
0
def local_auth_server(token_cb, default_account_id, **overrides):
    class MockedProvider(object):
        def generate_token(self, account_id, scopes):
            return token_cb(account_id, scopes)

    s = auth_server.LocalAuthServer()
    try:
        local_auth = s.start(token_provider=MockedProvider(),
                             accounts=('acc_1', 'acc_2', 'acc_3'),
                             default_account_id=default_account_id)
        local_auth.update(overrides)
        with luci_context.write(local_auth=local_auth):
            yield
    finally:
        s.stop()
예제 #3
0
def local_auth_server(token_cb, default_account_id, **overrides):
    class MockedProvider(object):
        def generate_token(self, account_id, scopes):
            return token_cb(account_id, scopes)

    acc = lambda aid: auth_server.Account(id=aid, email=aid + '@example.com')

    s = auth_server.LocalAuthServer()
    try:
        local_auth = s.start(token_provider=MockedProvider(),
                             accounts=(acc('acc_1'), acc('acc_2'),
                                       acc('acc_3')),
                             default_account_id=default_account_id)
        local_auth.update(overrides)
        with luci_context.write(local_auth=local_auth):
            yield
    finally:
        s.stop()
예제 #4
0
    def start(self):
        """Grabs initial bot auth headers and starts all auth related threads.

    Raises:
      AuthSystemError on fatal errors.
    """
        assert not self._auth_params_reader, 'already running'
        try:
            # Read headers more often than bot_main writes them (which is 60 sec), to
            # reduce maximum possible latency between header updates and reads. Use
            # interval that isn't a divisor of 60 to avoid reads and writes happening
            # at the same moment in time.
            reader = file_reader.FileReaderThread(self._auth_params_file,
                                                  interval_sec=53)
            reader.start()
        except file_reader.FatalReadError as e:
            raise AuthSystemError('Cannot start FileReaderThread: %s' % e)

        # Initial validation.
        try:
            params = process_auth_params_json(reader.last_value)
        except ValueError as e:
            reader.stop()
            raise AuthSystemError('Cannot parse bot_auth_params.json: %s' % e)

        # If using task auth, launch local HTTP server that serves tokens (let OS
        # assign the port).
        server = None
        local_auth_context = None
        if params.task_service_account != 'none':
            try:
                server = auth_server.LocalAuthServer()
                local_auth_context = server.start(token_provider=self)
            except Exception as exc:
                reader.stop()  # cleanup
                raise AuthSystemError(
                    'Failed to start local auth server - %s' % exc)

        # Good to go.
        with self._lock:
            self._auth_params_reader = reader
            self._local_server = server
            self._local_auth_context = local_auth_context
예제 #5
0
  def start(self):
    """Grabs initial bot auth headers and starts all auth related threads.

    If the task is configured to use service accounts (based on data in
    'auth_params_file'), launches the local auth service and returns a dict that
    contains its parameters. It can be placed into LUCI_CONTEXT['local_auth']
    slot.

    Sets default service account (to be used by Swarming internal processes,
    like run_isolated.py) to 'system' (or unsets it if the bot has no associated
    service account). run_isolated.py eventually switches the default account to
    'task' before launching the actual user-supplied code.

    If task is not using service accounts, returns None (meaning, there's no
    need to setup LUCI_CONTEXT['local_auth'] at all).

    Format of the returned dict:
    {
      'rpc_port': <int with port number>,
      'secret': <str with a random string to send with RPCs>,
      'accounts': [{'id': <str>}, ...],
      'default_account_id': <str> or None
    }

    Raises:
      AuthSystemError on fatal errors.
    """
    assert not self._auth_params_reader, 'already running'
    try:
      # Read headers more often than bot_main writes them (which is 15 sec), to
      # reduce maximum possible latency between header updates and reads.
      #
      # TODO(vadimsh): Replace this with real IPC, like local sockets.
      reader = file_reader.FileReaderThread(
          self._auth_params_file, interval_sec=10)
      reader.start()
    except file_reader.FatalReadError as e:
      raise AuthSystemError('Cannot start FileReaderThread: %s' % e)

    # Initial validation.
    try:
      params = process_auth_params_json(reader.last_value)
    except ValueError as e:
      reader.stop()
      raise AuthSystemError('Cannot parse bot_auth_params.json: %s' % e)

    logging.info('Using following service accounts:')
    logging.info('  system: %s', params.system_service_account)
    logging.info('  task:   %s', params.task_service_account)

    bot_email = '-'
    if params.bot_service_account != 'none':
      logging.info('The bot itself runs as %s', params.bot_service_account)
      bot_email = params.bot_service_account

    available_accounts = []
    def add_account(account_id, email):
      if email == 'bot':
        email = bot_email
      available_accounts.append(auth_server.Account(id=account_id, email=email))

    # Expose all defined accounts (if any) to subprocesses via LUCI_CONTEXT.
    #
    # Use 'system' logical account as default for internal Swarming processes.
    # It is specified by 'system_service_account' field in bots.cfg. Swarming
    # will eventually switch to 'task' logical account before launching
    # user-supplied code. 'task' account is specified in the task definition.
    # This happens in run_isolated.py.
    #
    # If 'system_service_account' is not defined, then do not set default
    # account at all! It means internal Swarming processes will use
    # non-authenticated calls (which is precisely the meaning of un-set
    # system account).
    default_account_id = None
    if params.system_service_account != 'none':
      default_account_id = 'system'
      add_account('system', params.system_service_account)
    if params.task_service_account != 'none':
      add_account('task', params.task_service_account)

    # If using service accounts, launch local HTTP server that serves tokens
    # (let OS assign the port).
    server = None
    local_auth_context = None
    if available_accounts:
      server = auth_server.LocalAuthServer()
      local_auth_context = server.start(
          token_provider=self,
          accounts=available_accounts,
          default_account_id=default_account_id)

    # Good to go.
    with self._lock:
      self._auth_params_reader = reader
      self._local_server = server
    return local_auth_context