diff --git a/credstash-migrate-autoversion.py b/credstash-migrate-autoversion.py new file mode 100644 index 0000000..7e5c706 --- /dev/null +++ b/credstash-migrate-autoversion.py @@ -0,0 +1,39 @@ +import boto3 +import credstash +import copy + + +def isInt(s): + try: + int(s) + return True + except ValueError: + return False + + +def updateVersions(region="us-east-1", table="credential-store"): + ''' + do a full-table scan of the credential-store, + and update the version format of every credential if it is an integer + ''' + dynamodb = boto3.resource('dynamodb', region_name=region) + secrets = dynamodb.Table(table) + + response = secrets.scan(ProjectionExpression="#N, version, #K, contents, hmac", + ExpressionAttributeNames={"#N": "name", "#K": "key"}) + + items = response["Items"] + + for old_item in items: + if isInt(old_item['version']): + new_item = copy.copy(old_item) + new_item['version'] = credstash.paddedInt(new_item['version']) + if new_item['version'] != old_item['version']: + secrets.put_item(Item=new_item) + secrets.delete_item(Key={'name': old_item['name'], 'version': old_item['version']}) + else: + print "Skipping item: %s, %s" % (old_item['name'], old_item['version']) + + +if __name__ == "__main__": + updateVersions() diff --git a/credstash.py b/credstash.py index 85e8312..79045f9 100755 --- a/credstash.py +++ b/credstash.py @@ -44,6 +44,7 @@ from Crypto.Util import Counter DEFAULT_REGION = "us-east-1" +PAD_LEN = 19 # number of digits in sys.maxint WILDCARD_CHAR = "*" @@ -124,6 +125,14 @@ def csv_dump(dictionary): return csvfile.getvalue() +def paddedInt(i): + ''' + return a string that contains `i`, left-padded with 0's up to PAD_LEN digits + ''' + i_str = str(i) + pad = PAD_LEN - len(i_str) + return (pad * "0") + i_str + def getHighestVersion(name, region="us-east-1", table="credential-store"): ''' Return the highest version of `name` in the table @@ -187,7 +196,7 @@ def putSecret(name, secret, version, kms_key="alias/credstash", data = {} data['name'] = name - data['version'] = version if version != "" else "1" + data['version'] = version if version != "" else paddedInt(1) data['key'] = b64encode(wrapped_key).decode('utf-8') data['contents'] = b64encode(c_text).decode('utf-8') data['hmac'] = b64hmac @@ -470,7 +479,7 @@ def main(): latestVersion = getHighestVersion(args.credential, region, args.table) try: - version = str(int(latestVersion) + 1) + version = paddedInt(int(latestVersion) + 1) except ValueError: printStdErr("Can not autoincrement version. The current " "version: %s is not an int" % latestVersion)