def main():
    parsers = {}
    parsers['super'] = argparse.ArgumentParser(description='A credential/secret storage system')
    parsers['super'].add_argument('-r', '--region', help='the AWS region in which to operate.If a region is not specified, credstash will use the value of the AWS_DEFAULT_REGION env variable, or if that is not set, us-east-1')
    parsers['super'].add_argument('-t', '--table', default='credential-store', help='DynamoDB table to use for credential storage')
    subparsers = parsers['super'].add_subparsers(help='Try commands like "{name} get -h" or "{name}put --help" to get eachsub command\'s options'.format(name=os.path.basename(__file__)))
    action = 'delete'
    parsers[action] = subparsers.add_parser(action, help='Delete a credential "                                             "from the store')
    parsers[action].add_argument('credential', type=str, help='the name of the credential to delete')
    parsers[action].set_defaults(action=action)
    action = 'get'
    parsers[action] = subparsers.add_parser(action, help='Get a credential from the store')
    parsers[action].add_argument('credential', type=str, help=("the name of the credential to get.Using the wildcard character '%s' will search for credentials that match the pattern" % WILDCARD_CHAR))
    parsers[action].add_argument('context', type=key_value_pair, action=KeyValueToDictionary, nargs='*', help='encryption context key/value pairs associated with the credential in the form of "key=value"')
    parsers[action].add_argument('-n', '--noline', action='store_true', help="Don't append newline to returned value (useful in scripts or with binary files)")
    parsers[action].add_argument('-v', '--version', default='', help='Get a specific version of the credential (defaults to the latest version)')
    parsers[action].set_defaults(action=action)
    action = 'getall'
    parsers[action] = subparsers.add_parser(action, help='Get all credentials from the store')
    parsers[action].add_argument('context', type=key_value_pair, action=KeyValueToDictionary, nargs='*', help='encryption context key/value pairs associated with the credential in the form of "key=value"')
    parsers[action].add_argument('-v', '--version', default='', help='Get a specific version of the credential (defaults to the latest version)')
    parsers[action].add_argument('-f', '--format', default='json', choices=(['json', 'csv'] + ([] if NO_YAML else ['yaml'])), help=(('Output format. json(default) ' + ('' if NO_YAML else 'yaml ')) + 'or csv.'))
    parsers[action].set_defaults(action=action)
    action = 'list'
    parsers[action] = subparsers.add_parser(action, help='list credentials and their versions')
    parsers[action].set_defaults(action=action)
    action = 'put'
    parsers[action] = subparsers.add_parser(action, help='Put a credential into the store')
    parsers[action].add_argument('credential', type=str, help='the name of the credential to store')
    parsers[action].add_argument('value', type=value_or_filename, help='the value of the credential to store or, if beginning with the "@" character, the filename of the file containing the value', default='')
    parsers[action].add_argument('context', type=key_value_pair, action=KeyValueToDictionary, nargs='*', help='encryption context key/value pairs associated with the credential in the form of "key=value"')
    parsers[action].add_argument('-k', '--key', default='alias/credstash', help='the KMS key-id of the master key to use. See the README for more information. Defaults to alias/credstash')
    parsers[action].add_argument('-v', '--version', default='', help='Put a specific version of the credential (update the credential; defaults to version `1`).')
    parsers[action].add_argument('-a', '--autoversion', action='store_true', help='Automatically increment the version of the credential to be stored. This option causes the `-v` flag to be ignored. (This option will fail if the currently stored version is not numeric.)')
    parsers[action].set_defaults(action=action)
    action = 'setup'
    parsers[action] = subparsers.add_parser(action, help='setup the credential store')
    parsers[action].set_defaults(action=action)
    args = parsers['super'].parse_args()
    region = (os.getenv('AWS_DEFAULT_REGION', DEFAULT_REGION) if (not args.region) else args.region)
    if ('action' in vars(args)):
        if (args.action == 'delete'):
            deleteSecrets(args.credential, region=region, table=args.table)
            return
        if (args.action == 'list'):
            credential_list = listSecrets(region=region, table=args.table)
            if credential_list:
                max_len = max([len(x['name']) for x in credential_list])
                for cred in sorted(credential_list, key=operator.itemgetter('name', 'version')):
                    print('{0:{1}} -- version {2:>}'.format(cred['name'], max_len, cred['version']))
            else:
                return
        if (args.action == 'put'):
            if args.autoversion:
                latestVersion = getHighestVersion(args.credential, region, args.table)
                try:
                    version = paddedInt((int(latestVersion) + 1))
                except ValueError:
                    printStdErr(('Can not autoincrement version. The current version: %s is not an int' % latestVersion))
                    return
            else:
                version = args.version
            try:
                if putSecret(args.credential, args.value, version, kms_key=args.key, region=region, table=args.table, context=args.context):
                    print('{0} has been stored'.format(args.credential))
            except KmsError as e:
                printStdErr(e)
            except botocore.exceptions.ClientError as e:
                if (e.response['Error']['Code'] == 'ConditionalCheckFailedException'):
                    latestVersion = getHighestVersion(args.credential, region, args.table)
                    printStdErr(('%s version %s is already in the credential store. Use the -v flag to specify a new version' % (args.credential, latestVersion)))
                return
        if (args.action == 'get'):
            try:
                if (WILDCARD_CHAR in args.credential):
                    names = expand_wildcard(args.credential, [x['name'] for x in listSecrets(region=region, table=args.table)])
                    print(json.dumps(dict(((name, getSecret(name, args.version, region=region, table=args.table, context=args.context)) for name in names))))
                else:
                    sys.stdout.write(getSecret(args.credential, args.version, region=region, table=args.table, context=args.context))
                    if (not args.noline):
                        sys.stdout.write('\n')
            except ItemNotFound as e:
                printStdErr(e)
            except KmsError as e:
                printStdErr(e)
            except IntegrityError as e:
                printStdErr(e)
            return
        if (args.action == 'getall'):
            secrets = getAllSecrets(args.version, region=region, table=args.table, context=args.context)
            if (args.format == 'json'):
                output_func = json.dumps
                output_args = {'sort_keys': True, 'indent': 4, 'separators': (',', ': ')}
            elif ((not NO_YAML) and (args.format == 'yaml')):
                output_func = yaml.dump
                output_args = {'default_flow_style': False}
            elif (args.format == 'csv'):
                output_func = csv_dump
                output_args = {}
            print(output_func(secrets, **output_args))
            return
        if (args.action == 'setup'):
            createDdbTable(region=region, table=args.table)
            return
    else:
        parsers['super'].print_help()
def main():
    parsers = {}
    parsers['super'] = argparse.ArgumentParser(description='A credential/secret storage system')
    parsers['super'].add_argument('-r', '--region', help='the AWS region in which to operate.If a region is not specified, credstash will use the value of the AWS_DEFAULT_REGION env variable, or if that is not set, us-east-1')
    parsers['super'].add_argument('-t', '--table', default='credential-store', help='DynamoDB table to use for credential storage')
    subparsers = parsers['super'].add_subparsers(help='Try commands like "{name} get -h" or "{name}put --help" to get eachsub command\'s options'.format(name=os.path.basename(__file__)))
    action = 'delete'
    parsers[action] = subparsers.add_parser(action, help='Delete a credential "                                             "from the store')
    parsers[action].add_argument('credential', type=str, help='the name of the credential to delete')
    parsers[action].set_defaults(action=action)
    action = 'get'
    parsers[action] = subparsers.add_parser(action, help='Get a credential from the store')
    parsers[action].add_argument('credential', type=str, help=("the name of the credential to get.Using the wildcard character '%s' will search for credentials that match the pattern" % WILDCARD_CHAR))
    parsers[action].add_argument('context', type=key_value_pair, action=KeyValueToDictionary, nargs='*', help='encryption context key/value pairs associated with the credential in the form of "key=value"')
    parsers[action].add_argument('-n', '--noline', action='store_true', help="Don't append newline to returned value (useful in scripts or with binary files)")
    parsers[action].add_argument('-v', '--version', default=, help='Get a specific version of the credential (defaults to the latest version)')
    parsers[action].set_defaults(action=action)
    action = 'getall'
    parsers[action] = subparsers.add_parser(action, help='Get all credentials from the store')
    parsers[action].add_argument('context', type=key_value_pair, action=KeyValueToDictionary, nargs='*', help='encryption context key/value pairs associated with the credential in the form of "key=value"')
    parsers[action].add_argument('-v', '--version', default=, help='Get a specific version of the credential (defaults to the latest version)')
    parsers[action].add_argument('-f', '--format', default='json', choices=(['json', 'csv'] + ([] if NO_YAML else ['yaml'])), help=(('Output format. json(default) ' + ( if NO_YAML else 'yaml ')) + 'or csv.'))
    parsers[action].set_defaults(action=action)
    action = 'list'
    parsers[action] = subparsers.add_parser(action, help='list credentials and their versions')
    parsers[action].set_defaults(action=action)
    action = 'put'
    parsers[action] = subparsers.add_parser(action, help='Put a credential into the store')
    parsers[action].add_argument('credential', type=str, help='the name of the credential to store')
    parsers[action].add_argument('value', type=value_or_filename, help='the value of the credential to store or, if beginning with the "@" character, the filename of the file containing the value', default=)
    parsers[action].add_argument('context', type=key_value_pair, action=KeyValueToDictionary, nargs='*', help='encryption context key/value pairs associated with the credential in the form of "key=value"')
    parsers[action].add_argument('-k', '--key', default='alias/credstash', help='the KMS key-id of the master key to use. See the README for more information. Defaults to alias/credstash')
    parsers[action].add_argument('-v', '--version', default=, help='Put a specific version of the credential (update the credential; defaults to version `1`).')
    parsers[action].add_argument('-a', '--autoversion', action='store_true', help='Automatically increment the version of the credential to be stored. This option causes the `-v` flag to be ignored. (This option will fail if the currently stored version is not numeric.)')
    parsers[action].set_defaults(action=action)
    action = 'setup'
    parsers[action] = subparsers.add_parser(action, help='setup the credential store')
    parsers[action].set_defaults(action=action)
    args = parsers['super'].parse_args()
    region = (os.getenv('AWS_DEFAULT_REGION', DEFAULT_REGION) if (not args.region) else args.region)
    if ('action' in vars(args)):
        if (args.action == 'delete'):
            deleteSecrets(args.credential, region=region, table=args.table)
            return
        if (args.action == 'list'):
            credential_list = listSecrets(region=region, table=args.table)
            if credential_list:
                max_len = max([len(x['name']) for x in credential_list])
                for cred in sorted(credential_list, key=operator.itemgetter('name', 'version')):
                    print('{0:{1}} -- version {2:>}'.format(cred['name'], max_len, cred['version']))
            else:
                return
        if (args.action == 'put'):
            if args.autoversion:
                latestVersion = getHighestVersion(args.credential, region, args.table)
                try:
                    version = paddedInt((int(latestVersion) + 1))
                except ValueError:
                    printStdErr(('Can not autoincrement version. The current version: %s is not an int' % latestVersion))
                    return
            else:
                version = args.version
            try:
                if putSecret(args.credential, args.value, version, kms_key=args.key, region=region, table=args.table, context=args.context):
                    print('{0} has been stored'.format(args.credential))
            except KmsError as e:
                printStdErr(e)
            except botocore.exceptions.ClientError as e:
                if (e.response['Error']['Code'] == 'ConditionalCheckFailedException'):
                    latestVersion = getHighestVersion(args.credential, region, args.table)
                    printStdErr(('%s version %s is already in the credential store. Use the -v flag to specify a new version' % (args.credential, latestVersion)))
                return
        if (args.action == 'get'):
            try:
                if (WILDCARD_CHAR in args.credential):
                    names = expand_wildcard(args.credential, [x['name'] for x in listSecrets(region=region, table=args.table)])
                    print(json.dumps(dict(((name, getSecret(name, args.version, region=region, table=args.table, context=args.context)) for name in names))))
                else:
                    sys.stdout.write(getSecret(args.credential, args.version, region=region, table=args.table, context=args.context))
                    if (not args.noline):
                        sys.stdout.write('\n')
            except ItemNotFound as e:
                printStdErr(e)
            except KmsError as e:
                printStdErr(e)
            except IntegrityError as e:
                printStdErr(e)
            return
        if (args.action == 'getall'):
            secrets = getAllSecrets(args.version, region=region, table=args.table, context=args.context)
            if (args.format == 'json'):
                output_func = json.dumps
                output_args = {'sort_keys': True, 'indent': 4, 'separators': (',', ': ')}
            elif ((not NO_YAML) and (args.format == 'yaml')):
                output_func = yaml.dump
                output_args = {'default_flow_style': False}
            elif (args.format == 'csv'):
                output_func = csv_dump
                output_args = {}
            print(output_func(secrets, **output_args))
            return
        if (args.action == 'setup'):
            createDdbTable(region=region, table=args.table)
            return
    else:
        parsers['super'].print_help()