Skip to main content

No project description provided

Project description

django-mysql-rds

A Django db backend for connecting to RDS MySQL instances using SSL db auth tokens.

Use

I'd recommend understanding what you're doing and why before dropping this in, but chances are that you have a DATABASES dict that looks something like:

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': DBNAME,
        'USER': USER,
        'PASSWORD': aws_client.generate_db_auth_token(HOST, PORT, USER),
        'HOST': HOST,
        'PORT': PORT,
        'OPTIONS': {
            'ssl': {
                'ca': 'certs/rds-cert.pem'
            }
        }
    }
}

And you've discovered that after ~15 minutes you make a request and receive Access Denied for user@instance because the password has expired.

This package allows you to replace that with:

def generate_pw():
    return aws_client.generate_db_auth_token(HOST, PORT, USER)

DATABASES = {
    'default': {
        'ENGINE': 'mysql_rds.backend.rds',
        'NAME': DBNAME,
        'USER': USER,
        'PASSWORD': generate_pw,
        'HOST': HOST,
        'PORT': PORT,
        'CONN_MAX_AGE': 900,
        'OPTIONS': {
            'ssl': {
                'ca': 'certs/rds-cert.pem'
            }
        }
    }
}

I recommend setting a CONN_MAX_AGE of 900 as the generated auth token expires after 900 seconds. This ensures that connections requiring a refresh recreated. You can pass any function as the password and it will be evaluated at connection time. For testing locally if you cannot connect to directly to RDS you can do something like:

def generate_pw():
    return 'password'

Installation

git clone git@github.com:cramshaw/django-mysql-rds.git

pip - TBD

Why?

When I searched for a way to connect to an AWS RDS MySQL instance using SSL inside Django, I was unable to find anything that could handle the fact that the db auth token generated by AWS would expire every 15 minutes.

The problem is that when anything in the settings module changes, Django needs to reload. This isn't practical in a long running web app. I needed a way for the password to be generated at the time of connection.

How?

On close inspection of the django.db.backends.mysql code, it became clear that the DatabaseWrapper.get_connection_params method takes the settings dict, and transforms it into the kwargs that are passed to mysql.connect. I have subclassed this and extended to recognise if the password passed in is a callable, and if so, to call it and pass on the returned value. This leads to Django receiving a fresh password every time a connection is created.

A very similar thing happens in the DatabaseClient.settings_to_cmd_args which is used for things like dumping and loading data. This has also been subclassed and changed to ensure the password generation method actually runs before attempting to create a run a shell.

Caveats

Whilst this works for me running django==2.2 and should work exactly the same as the built in MySQL backend, there are no guarantees.

I only needed this to work for MySQL. I haven't explored whether RDS does the same for Postgres or other databases, but the same principle ought to apply.

Running Tests

Tests require https://pypi.org/project/mysqlclient/ installed.

python -m unittest tests/test*

Building

python3 setup.py sdist bdist_wheel

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

django-mysql-rds-0.1.5.tar.gz (3.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

django_mysql_rds-0.1.5-py3-none-any.whl (9.4 kB view details)

Uploaded Python 3

File details

Details for the file django-mysql-rds-0.1.5.tar.gz.

File metadata

  • Download URL: django-mysql-rds-0.1.5.tar.gz
  • Upload date:
  • Size: 3.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/1.13.0 pkginfo/1.5.0.1 requests/2.21.0 setuptools/40.8.0 requests-toolbelt/0.9.1 tqdm/4.31.1 CPython/3.7.3

File hashes

Hashes for django-mysql-rds-0.1.5.tar.gz
Algorithm Hash digest
SHA256 1aa2ac4aa3b405768380fea52c00d73dd2d991491e13ae3d4d6806b6589af218
MD5 47967d1acbef07466b86644e5792ea55
BLAKE2b-256 b7f1cdc711566a86932fb2a6394d03219aac62d288bf6e2614586ea71a1d5974

See more details on using hashes here.

File details

Details for the file django_mysql_rds-0.1.5-py3-none-any.whl.

File metadata

  • Download URL: django_mysql_rds-0.1.5-py3-none-any.whl
  • Upload date:
  • Size: 9.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/1.13.0 pkginfo/1.5.0.1 requests/2.21.0 setuptools/40.8.0 requests-toolbelt/0.9.1 tqdm/4.31.1 CPython/3.7.3

File hashes

Hashes for django_mysql_rds-0.1.5-py3-none-any.whl
Algorithm Hash digest
SHA256 c91797899bc057cf8f02ae5275f163f59cbf4964791a28343f6e89b315a92ad9
MD5 dbec6ef3ace7ff2ad44eced085e8e334
BLAKE2b-256 26fe06265becb0f1a9a4222b85ca37812ceef12fccc1c99091abb15fb6ae15d2

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page