prompt: You will be provided with a partial code base and an issue statement explaining a problem to resolve.
  <issue>
  Support Redis Authentication
  I'm trying to install Snuba on my Kubernetes instance alongside Sentry.
  Sentry's Helm chart installs Redis with a password (It generates a secret), and there was no option for me to specify that password for Snuba.
  
  I opened up the source code and it looks like a simple solution: 
  Another setting (REDIS_PASSWORD) that would be passed to startup_nodes and to StrictRedis' constructor on the snuba/redis.py module.
  
  </issue>
  <code>
  [start of snuba/settings_docker.py]
  1 import os
  2 from snuba.settings_base import *
  3 
  4 env = os.environ.get
  5 
  6 DEBUG = env('DEBUG', '0').lower() in ('1', 'true')
  7 
  8 DEFAULT_BROKERS = env('DEFAULT_BROKERS', 'localhost:9092').split(',')
  9 
  10 REDIS_HOST = env('REDIS_HOST', 'localhost')
  11 REDIS_PORT = int(env('REDIS_PORT', 6379))
  12 REDIS_DB = int(env('REDIS_DB', 1))
  13 USE_REDIS_CLUSTER = False
  14
  [end of snuba/settings_docker.py]
  [start of snuba/settings_base.py]
  1 import os
  2 
  3 LOG_LEVEL = os.environ.get('LOG_LEVEL', 'INFO')
  4 
  5 TESTING = False
  6 DEBUG = True
  7 
  8 PORT = 1218
  9 
  10 DEFAULT_DATASET_NAME = 'events'
  11 DISABLED_DATASETS = {}
  12 DATASET_MODE = 'local'
  13 
  14 # Clickhouse Options
  15 # TODO: Warn about using `CLICKHOUSE_SERVER`, users should use the new settings instead.
  16 [default_clickhouse_host, default_clickhouse_port] = os.environ.get('CLICKHOUSE_SERVER', 'localhost:9000').split(':', 1)
  17 CLICKHOUSE_HOST = os.environ.get('CLICKHOUSE_HOST', default_clickhouse_host)
  18 CLICKHOUSE_PORT = int(os.environ.get('CLICKHOUSE_PORT', default_clickhouse_port))
  19 CLICKHOUSE_HTTP_PORT = int(os.environ.get('CLICKHOUSE_HTTP_PORT', 8123))
  20 CLICKHOUSE_MAX_POOL_SIZE = 25
  21 
  22 # Dogstatsd Options
  23 DOGSTATSD_HOST = 'localhost'
  24 DOGSTATSD_PORT = 8125
  25 
  26 # Redis Options
  27 USE_REDIS_CLUSTER = False
  28 REDIS_CLUSTER_STARTUP_NODES = None
  29 REDIS_HOST = os.environ.get('REDIS_HOST', 'localhost')
  30 REDIS_PORT = 6379
  31 REDIS_DB = 1
  32 
  33 # Query Recording Options
  34 RECORD_QUERIES = False
  35 QUERIES_TOPIC = 'snuba-queries'
  36 
  37 # Runtime Config Options
  38 CONFIG_MEMOIZE_TIMEOUT = 10
  39 
  40 # Sentry Options
  41 SENTRY_DSN = None
  42 
  43 # Snuba Options
  44 
  45 SNAPSHOT_LOAD_PRODUCT = 'snuba'
  46 
  47 SNAPSHOT_CONTROL_TOPIC_INIT_TIMEOUT = 30
  48 BULK_CLICKHOUSE_BUFFER = 10000
  49 
  50 # Processor/Writer Options
  51 DEFAULT_BROKERS = ['localhost:9092']
  52 DEFAULT_DATASET_BROKERS = {}
  53 
  54 DEFAULT_MAX_BATCH_SIZE = 50000
  55 DEFAULT_MAX_BATCH_TIME_MS = 2 * 1000
  56 DEFAULT_QUEUED_MAX_MESSAGE_KBYTES = 10000
  57 DEFAULT_QUEUED_MIN_MESSAGES = 10000
  58 DISCARD_OLD_EVENTS = True
  59 
  60 DEFAULT_RETENTION_DAYS = 90
  61 RETENTION_OVERRIDES = {}
  62 
  63 MAX_PREWHERE_CONDITIONS = 1
  64 
  65 STATS_IN_RESPONSE = False
  66 
  67 PAYLOAD_DATETIME_FORMAT = "%Y-%m-%dT%H:%M:%S.%fZ"
  68 
  69 REPLACER_MAX_BLOCK_SIZE = 512
  70 REPLACER_MAX_MEMORY_USAGE = 10 * (1024**3)  # 10GB
  71 # TLL of Redis key that denotes whether a project had replacements
  72 # run recently. Useful for decidig whether or not to add FINAL clause
  73 # to queries.
  74 REPLACER_KEY_TTL = 12 * 60 * 60
  75 REPLACER_MAX_GROUP_IDS_TO_EXCLUDE = 256
  76 
  77 TURBO_SAMPLE_RATE = 0.1
  78
  [end of snuba/settings_base.py]
  [start of snuba/redis.py]
  1 from __future__ import absolute_import
  2 
  3 from redis.client import StrictRedis
  4 from redis.exceptions import BusyLoadingError, ConnectionError
  5 from rediscluster import StrictRedisCluster
  6 
  7 from snuba import settings
  8 
  9 
  10 class RetryingStrictRedisCluster(StrictRedisCluster):
  11     """
  12     Execute a command with cluster reinitialization retry logic.
  13     Should a cluster respond with a ConnectionError or BusyLoadingError the
  14     cluster nodes list will be reinitialized and the command will be executed
  15     again with the most up to date view of the world.
  16     """
  17 
  18     def execute_command(self, *args, **kwargs):
  19         try:
  20             return super(self.__class__, self).execute_command(*args, **kwargs)
  21         except (
  22             ConnectionError,
  23             BusyLoadingError,
  24             KeyError  # see: https://github.com/Grokzen/redis-py-cluster/issues/287
  25         ):
  26             self.connection_pool.nodes.reset()
  27             return super(self.__class__, self).execute_command(*args, **kwargs)
  28 
  29 
  30 if settings.USE_REDIS_CLUSTER:
  31     startup_nodes = settings.REDIS_CLUSTER_STARTUP_NODES
  32     if startup_nodes is None:
  33         startup_nodes = [{
  34             'host': settings.REDIS_HOST,
  35             'port': settings.REDIS_PORT,
  36         }]
  37     redis_client = RetryingStrictRedisCluster(
  38         startup_nodes=startup_nodes,
  39         socket_keepalive=True,
  40     )
  41 else:
  42     redis_client = StrictRedis(
  43         host=settings.REDIS_HOST,
  44         port=settings.REDIS_PORT,
  45         db=settings.REDIS_DB,
  46         socket_keepalive=True,
  47     )
  48
  [end of snuba/redis.py]
  </code>
  
  I need you to solve this issue by generating a single patch file that I can apply directly to this repository using git apply. Please respond with a single patch file in the following format.
  <patch>
  diff --git a/file.py b/file.py
  --- a/file.py
  +++ b/file.py
  @@ -1,27 +1,35 @@
   def euclidean(a, b):
  -    while b:
  -        a, b = b, a % b
  -    return a
  +    if b == 0:
  +        return a
  +    return euclidean(b, a % b)
   
   
   def bresenham(x0, y0, x1, y1):
       points = []
       dx = abs(x1 - x0)
       dy = abs(y1 - y0)
  -    sx = 1 if x0 < x1 else -1
  -    sy = 1 if y0 < y1 else -1
  -    err = dx - dy
  +    x, y = x0, y0
  +    sx = -1 if x0 > x1 else 1
  +    sy = -1 if y0 > y1 else 1
   
  -    while True:
  -        points.append((x0, y0))
  -        if x0 == x1 and y0 == y1:
  -            break
  -        e2 = 2 * err
  -        if e2 > -dy:
  -            err -= dy
  -            x0 += sx
  -        if e2 < dx:
  -            err += dx
  -            y0 += sy
  +    if dx > dy:
  +        err = dx / 2.0
  +        while x != x1:
  +            points.append((x, y))
  +            err -= dy
  +            if err < 0:
  +                y += sy
  +                err += dx
  +            x += sx
  +    else:
  +        err = dy / 2.0
  +        while y != y1:
  +            points.append((x, y))
  +            err -= dx
  +            if err < 0:
  +                x += sx
  +                err += dy
  +            y += sy
  +
  +    points.append((x, y))
       return points
  
  </patch>
golden_diff: diff --git a/snuba/redis.py b/snuba/redis.py
  --- a/snuba/redis.py
  +++ b/snuba/redis.py
  @@ -37,11 +37,13 @@
       redis_client = RetryingStrictRedisCluster(
           startup_nodes=startup_nodes,
           socket_keepalive=True,
  +        password=settings.REDIS_PASSWORD,
       )
   else:
       redis_client = StrictRedis(
           host=settings.REDIS_HOST,
           port=settings.REDIS_PORT,
  +        password=settings.REDIS_PASSWORD,
           db=settings.REDIS_DB,
           socket_keepalive=True,
       )
  diff --git a/snuba/settings_base.py b/snuba/settings_base.py
  --- a/snuba/settings_base.py
  +++ b/snuba/settings_base.py
  @@ -28,6 +28,7 @@
   REDIS_CLUSTER_STARTUP_NODES = None
   REDIS_HOST = os.environ.get('REDIS_HOST', 'localhost')
   REDIS_PORT = 6379
  +REDIS_PASSWORD = None
   REDIS_DB = 1
   
   # Query Recording Options
  diff --git a/snuba/settings_docker.py b/snuba/settings_docker.py
  --- a/snuba/settings_docker.py
  +++ b/snuba/settings_docker.py
  @@ -9,5 +9,6 @@
   
   REDIS_HOST = env('REDIS_HOST', 'localhost')
   REDIS_PORT = int(env('REDIS_PORT', 6379))
  +REDIS_PASSWORD = env('REDIS_PASSWORD')
   REDIS_DB = int(env('REDIS_DB', 1))
   USE_REDIS_CLUSTER = False
  
verification_info: {"golden_diff": "diff --git a/snuba/redis.py b/snuba/redis.py\n--- a/snuba/redis.py\n+++ b/snuba/redis.py\n@@ -37,11 +37,13 @@\n     redis_client = RetryingStrictRedisCluster(\n         startup_nodes=startup_nodes,\n         socket_keepalive=True,\n+        password=settings.REDIS_PASSWORD,\n     )\n else:\n     redis_client = StrictRedis(\n         host=settings.REDIS_HOST,\n         port=settings.REDIS_PORT,\n+        password=settings.REDIS_PASSWORD,\n         db=settings.REDIS_DB,\n         socket_keepalive=True,\n     )\ndiff --git a/snuba/settings_base.py b/snuba/settings_base.py\n--- a/snuba/settings_base.py\n+++ b/snuba/settings_base.py\n@@ -28,6 +28,7 @@\n REDIS_CLUSTER_STARTUP_NODES = None\n REDIS_HOST = os.environ.get('REDIS_HOST', 'localhost')\n REDIS_PORT = 6379\n+REDIS_PASSWORD = None\n REDIS_DB = 1\n \n # Query Recording Options\ndiff --git a/snuba/settings_docker.py b/snuba/settings_docker.py\n--- a/snuba/settings_docker.py\n+++ b/snuba/settings_docker.py\n@@ -9,5 +9,6 @@\n \n REDIS_HOST = env('REDIS_HOST', 'localhost')\n REDIS_PORT = int(env('REDIS_PORT', 6379))\n+REDIS_PASSWORD = env('REDIS_PASSWORD')\n REDIS_DB = int(env('REDIS_DB', 1))\n USE_REDIS_CLUSTER = False\n", "issue": "Support Redis Authentication\nI'm trying to install Snuba on my Kubernetes instance alongside Sentry.\r\nSentry's Helm chart installs Redis with a password (It generates a secret), and there was no option for me to specify that password for Snuba.\r\n\r\nI opened up the source code and it looks like a simple solution: \r\nAnother setting (REDIS_PASSWORD) that would be passed to startup_nodes and to StrictRedis' constructor on the snuba/redis.py module.\n", "before_files": [{"content": "import os\nfrom snuba.settings_base import *\n\nenv = os.environ.get\n\nDEBUG = env('DEBUG', '0').lower() in ('1', 'true')\n\nDEFAULT_BROKERS = env('DEFAULT_BROKERS', 'localhost:9092').split(',')\n\nREDIS_HOST = env('REDIS_HOST', 'localhost')\nREDIS_PORT = int(env('REDIS_PORT', 6379))\nREDIS_DB = int(env('REDIS_DB', 1))\nUSE_REDIS_CLUSTER = False\n", "path": "snuba/settings_docker.py"}, {"content": "import os\n\nLOG_LEVEL = os.environ.get('LOG_LEVEL', 'INFO')\n\nTESTING = False\nDEBUG = True\n\nPORT = 1218\n\nDEFAULT_DATASET_NAME = 'events'\nDISABLED_DATASETS = {}\nDATASET_MODE = 'local'\n\n# Clickhouse Options\n# TODO: Warn about using `CLICKHOUSE_SERVER`, users should use the new settings instead.\n[default_clickhouse_host, default_clickhouse_port] = os.environ.get('CLICKHOUSE_SERVER', 'localhost:9000').split(':', 1)\nCLICKHOUSE_HOST = os.environ.get('CLICKHOUSE_HOST', default_clickhouse_host)\nCLICKHOUSE_PORT = int(os.environ.get('CLICKHOUSE_PORT', default_clickhouse_port))\nCLICKHOUSE_HTTP_PORT = int(os.environ.get('CLICKHOUSE_HTTP_PORT', 8123))\nCLICKHOUSE_MAX_POOL_SIZE = 25\n\n# Dogstatsd Options\nDOGSTATSD_HOST = 'localhost'\nDOGSTATSD_PORT = 8125\n\n# Redis Options\nUSE_REDIS_CLUSTER = False\nREDIS_CLUSTER_STARTUP_NODES = None\nREDIS_HOST = os.environ.get('REDIS_HOST', 'localhost')\nREDIS_PORT = 6379\nREDIS_DB = 1\n\n# Query Recording Options\nRECORD_QUERIES = False\nQUERIES_TOPIC = 'snuba-queries'\n\n# Runtime Config Options\nCONFIG_MEMOIZE_TIMEOUT = 10\n\n# Sentry Options\nSENTRY_DSN = None\n\n# Snuba Options\n\nSNAPSHOT_LOAD_PRODUCT = 'snuba'\n\nSNAPSHOT_CONTROL_TOPIC_INIT_TIMEOUT = 30\nBULK_CLICKHOUSE_BUFFER = 10000\n\n# Processor/Writer Options\nDEFAULT_BROKERS = ['localhost:9092']\nDEFAULT_DATASET_BROKERS = {}\n\nDEFAULT_MAX_BATCH_SIZE = 50000\nDEFAULT_MAX_BATCH_TIME_MS = 2 * 1000\nDEFAULT_QUEUED_MAX_MESSAGE_KBYTES = 10000\nDEFAULT_QUEUED_MIN_MESSAGES = 10000\nDISCARD_OLD_EVENTS = True\n\nDEFAULT_RETENTION_DAYS = 90\nRETENTION_OVERRIDES = {}\n\nMAX_PREWHERE_CONDITIONS = 1\n\nSTATS_IN_RESPONSE = False\n\nPAYLOAD_DATETIME_FORMAT = \"%Y-%m-%dT%H:%M:%S.%fZ\"\n\nREPLACER_MAX_BLOCK_SIZE = 512\nREPLACER_MAX_MEMORY_USAGE = 10 * (1024**3)  # 10GB\n# TLL of Redis key that denotes whether a project had replacements\n# run recently. Useful for decidig whether or not to add FINAL clause\n# to queries.\nREPLACER_KEY_TTL = 12 * 60 * 60\nREPLACER_MAX_GROUP_IDS_TO_EXCLUDE = 256\n\nTURBO_SAMPLE_RATE = 0.1\n", "path": "snuba/settings_base.py"}, {"content": "from __future__ import absolute_import\n\nfrom redis.client import StrictRedis\nfrom redis.exceptions import BusyLoadingError, ConnectionError\nfrom rediscluster import StrictRedisCluster\n\nfrom snuba import settings\n\n\nclass RetryingStrictRedisCluster(StrictRedisCluster):\n    \"\"\"\n    Execute a command with cluster reinitialization retry logic.\n    Should a cluster respond with a ConnectionError or BusyLoadingError the\n    cluster nodes list will be reinitialized and the command will be executed\n    again with the most up to date view of the world.\n    \"\"\"\n\n    def execute_command(self, *args, **kwargs):\n        try:\n            return super(self.__class__, self).execute_command(*args, **kwargs)\n        except (\n            ConnectionError,\n            BusyLoadingError,\n            KeyError  # see: https://github.com/Grokzen/redis-py-cluster/issues/287\n        ):\n            self.connection_pool.nodes.reset()\n            return super(self.__class__, self).execute_command(*args, **kwargs)\n\n\nif settings.USE_REDIS_CLUSTER:\n    startup_nodes = settings.REDIS_CLUSTER_STARTUP_NODES\n    if startup_nodes is None:\n        startup_nodes = [{\n            'host': settings.REDIS_HOST,\n            'port': settings.REDIS_PORT,\n        }]\n    redis_client = RetryingStrictRedisCluster(\n        startup_nodes=startup_nodes,\n        socket_keepalive=True,\n    )\nelse:\n    redis_client = StrictRedis(\n        host=settings.REDIS_HOST,\n        port=settings.REDIS_PORT,\n        db=settings.REDIS_DB,\n        socket_keepalive=True,\n    )\n", "path": "snuba/redis.py"}]}