#!/usr/bin/env python

# Copyright 2018 Google LLC.
#
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.


"""Search the syslog on a jumphost to determine when auth tokens changed."""


from __future__ import print_function
import sys


SYSLOG = '/var/log/syslog'

INCLUDE_LINES = [
  # (process-name,     pattern)
  ('metadata-server',  'Updated token: '),
  ('metadata-server',  'Token requested by '),
  ('get-oauth2-token', 'Wrote new auth token: '),
]


def transform_line(line):
  """Trim the log line and return it iff it matches INCLUDE_LINES."""
  for proc, pattern in INCLUDE_LINES:
    if pattern in line:
      # Log lines look like this:
      # pylint: disable=line-too-long
      # Mar 12 09:58:43 jumphost-win-02 metadata-server[5259]: I0312 09:58:43.756257    5259 server.go:87] Updated token: [redacted]
      timestamp = line.split('jumphost', 1)[0]
      suffix = line.split(pattern, 1)[1].rstrip()
      return timestamp + proc + ': ' + pattern + suffix
  return None


def read_syslog():
  """Read the syslog, returning any relevant lines."""
  lines = []
  with open(SYSLOG, 'rb') as f:
    for line in f:
     tf = transform_line(line)
     if tf:
       lines.append(tf)
  return lines


def filter_logs(ip, log_lines):
  """Filter the log lines to only those relevant to a particular IP address."""
  # First, collect all tokens used by the IP address.
  tokens = []
  for line in log_lines:
    if ip and ip in line:
      tok = line.split(', serving ', 1)[1]
      tokens.append(tok)

  # Filter to only lines which contain the IP address or one of its tokens.
  filtered = []
  for line in log_lines:
    if ip in line:
      filtered.append(line)
    else:
      for tok in tokens:
        # We don't care about other bots which used the token.
        if tok in line and not 'Token requested by' in line:
          filtered.append(line)
  return filtered


def main():
  """Read the syslog, filter to relevant lines, then print them."""
  lines = read_syslog()
  if len(sys.argv) > 1:
    lines = filter_logs(sys.argv[1], lines)
  for line in lines:
    print(line)


if __name__ == '__main__':
  main()
