Skip to content
This repository has been archived by the owner on Jan 19, 2022. It is now read-only.

Commit

Permalink
Add random number generator for RDS credentials
Browse files Browse the repository at this point in the history
This change removes the requirement for RDS credentials and instead
allows them to be generated using a simple random string generator.
  • Loading branch information
Niall Creech committed Jun 16, 2016
1 parent c348ab7 commit 7d3a5b3
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 3 deletions.
28 changes: 25 additions & 3 deletions bootstrap_cfn/config.py
Expand Up @@ -481,12 +481,12 @@ def rds(self, template):
"""
# REQUIRED FIELDS MAPPING
required_fields = {
'db-name': 'DBName',
'db-master-username': 'MasterUsername',
'db-master-password': 'MasterUserPassword',
}

optional_fields = {
'db-name': 'DBName',
'db-master-username': 'MasterUsername',
'db-master-password': 'MasterUserPassword',
'storage': 'AllocatedStorage',
'storage-type': 'StorageType',
'backup-retention-period': 'BackupRetentionPeriod',
Expand All @@ -498,6 +498,28 @@ def rds(self, template):
'identifier': 'DBInstanceIdentifier'
}

# Do random generation of RDS vars,
# See http://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/CHAP_Limits.html
# for limitation details
if 'identifier' not in self.data['rds']:
logging.info("config::rds: No RDS identifier found, generating random value...")
identifier = ('%s-%s'
% (self.application,
utils.get_random_string(length=63, alphanumeric=True)))
# Truncate to meet requirements
self.data['rds']['identifier'] = identifier[:63]
if 'db-name' not in self.data['rds']:
logging.info("config::rds: No RDS database name found, generating random value...")
self.data['rds']['db-name'] = ('%s_%s'
% (self.application,
utils.get_random_string(length=12, alphanumeric=True)))
if 'db-master-username' not in self.data['rds']:
logging.info("config::rds: No RDS database username found, generating random value...")
self.data['rds']['db-master-username'] = utils.get_random_string(length=63, alphanumeric=True)
if 'db-master-password' not in self.data['rds']:
logging.info("config::rds: No RDS database password found, generating random value...")
self.data['rds']['db-master-password'] = utils.get_random_string(length=128, alphanumeric=True)

# LOAD STACK TEMPLATE
resources = []
rds_subnet_group = DBSubnetGroup(
Expand Down
24 changes: 24 additions & 0 deletions bootstrap_cfn/utils.py
@@ -1,4 +1,6 @@
import os
import random
import string
import sys
import time

Expand Down Expand Up @@ -151,3 +153,25 @@ def sleep_countdown(sleep_time):
sys.stdout.flush()
time.sleep(1)
sleep_time -= 1


def get_random_string(length=64, alphanumeric=False):
"""
Return a basic pseudo-random string
Args:
length(int): The length of the string to return
alphanumeric(bool): True to use only alphanumeric chars,
False to use all chars
Returns:
random_string(string): The random string of required length
"""
# Just alphanumeric characters
if alphanumeric:
chars = string.letters + string.digits
else:
# Alphanumeric + special characters
chars = string.letters + string.digits + string.punctuation
random_string = ''.join([random.choice(chars) for x in range(length)])
return random_string
1 change: 1 addition & 0 deletions setup.py
Expand Up @@ -30,6 +30,7 @@
'mock>=1.0.1',
'testfixtures>=4.1.2',
'nose',
'entropy',
],
classifiers=[
'Development Status :: 3 - Alpha',
Expand Down
33 changes: 33 additions & 0 deletions tests/test_utils.py
@@ -0,0 +1,33 @@
import random

import unittest

import entropy

from bootstrap_cfn import utils


class TestUtils(unittest.TestCase):

def test_get_random_string_alphanumeric(self):
"""
TestUtils::test_get_random_string: Test getting a random string
"""
no_of_tests = 1000
min_key_length = 24
max_key_length = 128
# Generate some keys and test how random they are
for i in range(no_of_tests):
length = random.randint(min_key_length, max_key_length)
alphanumeric = random.choice([True, False])
if alphanumeric:
entropy_floor = 0.4
else:
entropy_floor = 0.5
random_string = utils.get_random_string(length, alphanumeric=alphanumeric)
string_entropy = entropy.shannon_entropy(random_string)
message = ("TestUtils::test_get_random_string: Test: %s: Generated string length:%s alphanumeric:%s entropy:%s string:%s"
% (i, length, alphanumeric, string_entropy, random_string))
print(message)
self.assertEqual(len(random_string), length)
self.assertGreater(string_entropy, entropy_floor, message)

0 comments on commit 7d3a5b3

Please sign in to comment.