def test_decrypt_file_tolocation():
    expected = rekey.parse_yaml(join(PLAY, "group_vars/nosecrets.yml"))
    path = join(PLAY, "group_vars/encrypted.yml")
    newpath = join(TMP_DIR, 'decrypted.yml')
    password_file = join(PLAY, "vault-password.txt")
    rekey.decrypt_file(path, password_file, newpath)
    assert expected == rekey.parse_yaml(newpath)
def test_find_yaml_secrets():
    d = rekey.parse_yaml(join(PLAY, "group_vars/inlinesecrets.yml"))
    expected = [['password'], ['users', 0, 'password'],
                ['users', 1, 'secrets', 1]]
    r = list(rekey.find_yaml_secrets(d))
    for i in expected:
        assert i in r
def test_get_dict_value():
    d = rekey.parse_yaml(join(PLAY, "group_vars/inlinesecrets.yml"))
    # expected = [
    #     ['password'],
    #     ['users', 0, 'password'],
    #     ['users', 1, 'secrets', 1]
    # ]
    r = rekey.find_yaml_secrets(d)
    for address in r:
        assert isinstance(rekey.get_dict_value(d, address), VaultString)
def test_rekey_file_withdecrypt():
    expected = rekey.parse_yaml(join(PLAY, "group_vars/nosecrets.yml"))
    path = join(PLAY, "group_vars/encrypted.yml")
    password_file = join(PLAY, "vault-password.txt")
    alt_password_file = join(PLAY, 'alt-vault-password.txt')
    rekey.rekey_file(path, password_file, alt_password_file)
    assert expected == rekey.decrypt_file(path, alt_password_file)

    rekey.rekey_file(path, alt_password_file, password_file)
    assert expected == rekey.decrypt_file(path, password_file)
def test_put_dict_value():
    d = rekey.parse_yaml(join(PLAY, "group_vars/nosecrets.yml"))
    oldval = ['one', 'two', 'three']
    address = ['moo', 'too']
    v = rekey.get_dict_value(d, address)
    assert isinstance(v, list)
    assert v == oldval
    assert rekey.put_dict_value(d, address, v + ['four']) != None

    newv = rekey.get_dict_value(d, address)
    assert isinstance(newv, list)
    assert newv == oldval + ['four']
示例#6
0
def main(password_file, varsfile, code_path, dry_run, keep_backups, debug):
    """(Re)keys Ansible Vault repos."""
    if debug:
        log_console.setLevel(logging.DEBUG)

    if not os.path.isdir(code_path):
        log.error("{} doesn't seem to exist".format(code_path))
        sys.exit(1)
    code_path = os.path.realpath(code_path)

    backup_path = os.path.join(code_path, ".rekey-backups")
    log.debug('Backup path set to: {}'.format(backup_path))

    if not password_file:
        password_file = os.path.join(code_path, 'vault-password.txt')
    else:
        if not os.path.isfile(password_file):
            log.error("{} doesn't seem to exist".format(password_file))
            sys.exit(1)
        password_file = os.path.realpath(password_file)

    # find all YAML files
    files = [os.path.realpath(varsfile)
             ] if varsfile else rekey.find_files(code_path)

    vault_files = []
    for f in files:
        if rekey.is_file_secret(f):
            vault_files.append({'file': f})
            continue

        try:
            data = rekey.parse_yaml(f)
        except Exception as e:
            log.warning(
                'Unable to parse file, probably not valid yaml: {}'.format(
                    happy_relpath(f)))
            continue

        # enh, generator. w/e.
        secrets = list(rekey.find_yaml_secrets(data)) if data else None
        if secrets and len(secrets) > 0:
            vault_files.append({'file': f, 'secrets': secrets})

    vflog = []
    for i in vault_files:
        suffix = " (whole)" if 'secrets' not in i.keys() else ""
        vflog.append("{}{}".format(happy_relpath(i['file']), suffix))

    log.debug('Found {} vault-enabled files: {}'.format(
        len(vflog), ', '.join(vflog)))

    log.info('Backing up encrypted and password files...')
    # backup password file
    rekey.backup_files([password_file], backup_path, code_path)

    # decrypt and write files out to unencbackup location (same relative paths)
    for f in vault_files:
        newpath = os.path.join(backup_path, f['file'][len(code_path) + 1:])
        log.debug('Decrypting {} to {} using {}'.format(
            happy_relpath(f['file']), happy_relpath(newpath),
            happy_relpath(password_file)))
        rekey.decrypt_file(f['file'], password_file, newpath)

    # generate new password file
    log.info('Generating new password file...')
    if dry_run:
        log.info('>> Dry run enabled, skipping overwrite. <<')
    else:
        rekey.write_password_file(password_file, overwrite=True)
        log.info('Password file written: {}'.format(
            happy_relpath(password_file)))

    # loop through encrypted asset list, re-encrypt and overwrite originals
    log.info('Re-encrypting assets with new password file...')
    for f in vault_files:
        # log.debug('Raw file obj: {}'.format(f))
        oldpath = os.path.join(backup_path, happy_relpath(f['file']))
        newpath = os.path.realpath(f['file'])
        log.debug('Encrypting {} to {}'.format(happy_relpath(oldpath),
                                               happy_relpath(newpath)))
        if dry_run:
            log.info('>> Dry run enabled, skipping overwrite. <<')
            r = True
        else:
            r = rekey.encrypt_file(oldpath, password_file, newpath,
                                   f.get('secrets', None))
        if not r:
            log.error('Encryption failed on {}'.format(oldpath))

    # test decryption of newly written assets?

    # remove backups
    if not keep_backups:
        log.info('Removing backups...')
        shutil.rmtree(backup_path)

    log.info('Done!')
def test_get_dict_value_bad():
    d = rekey.parse_yaml(join(PLAY, "group_vars/inlinesecrets.yml"))
    assert rekey.get_dict_value(d, ['fake', 'address']) == None
def test_find_yaml_secrets_none():
    d = rekey.parse_yaml(join(PLAY, "group_vars/nosecrets.yml"))
    expected = []
    r = list(rekey.find_yaml_secrets(d))
    assert expected == r
def test_parse_yaml_bad():
    with pytest.raises(Exception) as e:
        rekey.parse_yaml(join(PLAY, "group_vars/bad.yml"))
def test_parse_yaml_nosecrets():
    assert isinstance(rekey.parse_yaml(join(PLAY, "group_vars/nosecrets.yml")),
                      dict)