Source code for config

import os
import json
import configparser


AWS_CREDENTIALS_FILE = os.path.expanduser('~/.aws/credentials')
AWS_CONFIG_FILE = os.path.expanduser('~/.aws/config')

JSON_INDENT = 4
JSON_FILE = os.path.expanduser('~/.aws/adr.json')
JSON_DEFAULT = {
    'runner' : '',
    'aws' : {
        'credentials' : {
            'access_key_id' : '',
            'secret_access_key' : '',
        },
        'configuration' : {
            'region' : '',
            'machine_image' : '',
            'instance_type' : '',
            'security_groups' : [],
            'key_pair' : '',
            'output' : 'json',
        },
    },
    'ssh' : {
        'user' : 'ubuntu',
        'password' : '',
        'key_filename' : '',
    },
    'command' : {
        'command' : '',
        'preprocessing' : '',
        'postprocessing' : '',
    },
}


[docs]def load_config(*keys): '''Load specific part of config file Parameters ---------- keys : tuple Key traversal of config structure Returns ------- dict or config value Part of config structure Examples -------- >>> config.load_config() >>> config.load_config('aws', 'credentials') See Also -------- update_config write_config get_item ''' cfg = JSON_DEFAULT.copy() if os.path.exists(JSON_FILE): with open(JSON_FILE, 'r') as fp: cfg.update(json.load(fp)) return get_item(cfg, keys)
[docs]def update_config(*keys): '''Update specific part of config file Parameters ---------- keys : tuple Key traversal of config structure. The last value is the value that will be set. Examples -------- >>> config.write_config('aws', 'credentials', 'access_key_id', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ') See Also -------- load_config write_config set_item ''' if len(keys) == 0: return cfg = load_config() cfg = set_item(cfg, keys[:-1], keys[-1]) write_config(cfg)
[docs]def write_config(cfg): '''Write config structure to private file Parameters ---------- cfg : dict Config structure following ``JSON_DEFAULT`` See Also -------- load_config update_config write_aws_config ''' with open(JSON_FILE, 'w') as fp: json.dump(cfg, fp, indent=JSON_INDENT) os.chmod(JSON_FILE, 0600)
[docs]def write_aws_config(cfg): '''Write relevant parts of config structure to private files in AWSCLI format Parameters ---------- cfg : dict Config structure following ``JSON_DEFAULT`` See Also -------- write_config ''' # write credentials file ini = configparser.ConfigParser() ini['default'] = {'aws_{}'.format(k):v for k, v in cfg['aws']['credentials'].iteritems()} with open(AWS_CREDENTIALS_FILE, 'w') as fp: ini.write(fp) os.chmod(AWS_CREDENTIALS_FILE, 0600) # write config file ini = configparser.ConfigParser() ini['default'] = {k:','.join(v) if type(v) is list else v for k, v in cfg['aws']['configuration'].iteritems()} with open(AWS_CONFIG_FILE, 'w') as fp: ini.write(fp) os.chmod(AWS_CONFIG_FILE, 0600)
[docs]def wizard(): '''Configuration wizard Loads current configuration values and asks a sequence of questions to allow altering the current values. If no input is given, the current value is not changed. See Also -------- load_config write_config write_aws_config ask_question ''' cfg = load_config() cfg = ask_question(cfg, ('aws', 'credentials', 'access_key_id'), 'AWS Access Key ID', masked=True) cfg = ask_question(cfg, ('aws', 'credentials', 'secret_access_key'), 'AWS Secret Access Key', masked=True) cfg = ask_question(cfg, ('ssh', 'user'), 'Default SSH user') cfg = ask_question(cfg, ('ssh', 'password'), 'Default SSH password', masked=True) cfg = ask_question(cfg, ('ssh', 'key_filename'), 'Default SSH key file') cfg = ask_question(cfg, ('aws', 'configuration', 'region'), 'Default region name') cfg = ask_question(cfg, ('aws', 'configuration', 'instance_type'), 'Default instance type') cfg = ask_question(cfg, ('aws', 'configuration', 'machine_image'), 'Default machine image') cfg = ask_question(cfg, ('aws', 'configuration', 'security_groups'), 'Default security groups', split=True) cfg = ask_question(cfg, ('aws', 'configuration', 'key_pair'), 'Default key pair') cfg = ask_question(cfg, ('command', 'command'), 'Default command') cfg = ask_question(cfg, ('command', 'preprocessing'), 'Default preprocessing') cfg = ask_question(cfg, ('command', 'postprocessing'), 'Default postprocessing') cfg = ask_question(cfg, ('aws', 'configuration', 'output'), 'Default output format') write_config(cfg) if raw_input('Also write AWSCLI config [Y/n]? ') in ['y', 'Y', '']: write_aws_config(cfg)
[docs]def ask_question(cfg, keys, display, masked=False, split=False): '''Helper function to ask wizard question and alter config structure Parameters ---------- cfg : dict Config structure to be altered keys : tuple Key traversal for config structure that localizes the value that is addressed in the question display : str The question that is displayed to the user masked : bool, optional Flag to mask the current config value (used for passwords) split : bool, optional Flag to split the user input on comma's Returns ------- dict Updated config structure See Also -------- disp_item get_item set_item ''' val = get_item(cfg, keys) val = disp_item(val, masked=masked) dsp = '{} [{}]: '.format(display, val) i = raw_input(dsp) if len(i) > 0: if split: i = [ii.strip() for ii in i.split(',')] cfg = set_item(cfg, keys, i) return cfg
[docs]def get_item(cfg, keys): '''Gets item from config structure by key traversal Parameters ---------- cfg : dict Config structure keys : tuple Key traversal for config structure Returns ------- dict or config value Remaining part of config structure after traversal ''' for k in keys: if cfg.has_key(k): cfg = cfg[k] else: return None return cfg
[docs]def set_item(cfg, keys, val): '''Sets item in config structure by key traversal Parameters ---------- cfg : dict Config structure keys : tuple Key traversal for config structure val : any Config value to be set Returns ------- dict Updated config structure ''' if len(keys) > 0: k = keys[0] if cfg.has_key(k): cfg[k] = set_item(cfg[k], keys[1:], val) else: cfg = val return cfg
[docs]def disp_item(val, masked=False): '''Convert config value in display value Joins lists by comma's and masks secret value for the first 80%. Parameters ---------- val : str or list Config value masked : bool, optional Flag to enable masking Returns ------- str Display value ''' if type(val) is list: val = ','.join(val) if masked: n = len(val) n1 = int(.8 * n) n2 = n - n1 val = '{}{}'.format('*' * n1, val[-n2:]) return val