Initial ansible-vault with GPG support #7174

Closed
wants to merge 10 commits into
from

Conversation

Projects
None yet
@Kahn

Kahn commented Apr 28, 2014

Hi Guys,

As discussed in https://groups.google.com/forum/#!topic/ansible-devel/ncyHAgm7AYc here is the initial PR which introduces support for GPG in ansible-vault.

Cheers,

Sam

@Kahn

This comment has been minimized.

Show comment
Hide comment
@Kahn

Kahn Apr 27, 2014

Owner

Unit Tests

  1. Unit tests pass - PASS

    make tests

Functional Tests

Defaults

With no changes to .ansible.cfg

  1. Create a test.yml - PASS
ansible-vault create test.yml
  1. Confirm cipher is AES256 via header - PASS
grep AES256 test.yml
  1. Edit test.yml - PASS
ansible-vault edit test.yml
  1. Rekey test.yml - PASS
ansible-vault rekey test.yml
  1. Encrypt a plaintext file - PASS
echo "ansible" >> plaintext.yml
ansible-vault encrypt plaintext.yml
  1. Decrypt a encrypted file - PASS
ansible-vault decrypt plaintext.yml
cat plaintext.yml
  1. Run ansible-playbook using encrypted files - PASS
cat > host_vars/127.0.0.1 << 'EOF'

---
vault_hostname: ansible
EOF
cat > hosts << 'EOF'
127.0.0.1
EOF
cat > site.yml << 'EOF'

---
- name: test ansible-vault
  hosts: 127.0.0.1
  connection: local
  gather_facts: no
  tasks:
  - name: set system hostname
    hostname: name={{ vault_hostname }}
EOF
ansible-vault encrypt host_vars/127.0.0.1
ansible-playbook --ask-vault-pass site.yml

GPG Cipher

Direct passphrase input

  1. Update ~/.ansible.cfg with minimal changes
[vault]
cipher = GPG
gpg_recipients = PUBLICKEYID
  1. Create a test.yml - PASS
ansible-vault create test.yml
  1. Confirm cipher is GPG via header - PASS
grep GPG test.yml
  1. Edit test.yml - PASS
ansible-vault edit test.yml
  1. Update ~/.ansible.cfg with a second public key
[vault]
cipher = GPG
gpg_recipients = PUBLICKEYID PUBLICKEYID2
  1. Rekey test.yml - PASS
gpg -d test.yml (Cancel the agent password prompt. Shows what public keys the message was encrypted to. Should only output first public key)
ansible-vault rekey test.yml
gpg -d test.yml (Now we should see both recipients)
  1. Encrypt a plaintext file - PASS
echo "ansible" >> plaintext.yml
ansible-vault encrypt plaintext.yml
  1. Decrypt a encrypted file - PASS
ansible-vault decrypt plaintext.yml
cat plaintext.yml
  1. Run ansible-playbook using encrypted files - PASS
cat > host_vars/127.0.0.1 << 'EOF'

---
vault_hostname: ansible
EOF
cat > hosts << 'EOF'
127.0.0.1
EOF
cat > site.yml << 'EOF'

---
- name: test ansible-vault
  hosts: 127.0.0.1
  connection: local
  gather_facts: no
  tasks:
  - name: set system hostname
    hostname: name={{ vault_hostname }}
EOF
ansible-vault encrypt host_vars/127.0.0.1
ansible-playbook --ask-vault-pass site.yml

Agent managed password input

  1. Update ~/.ansible.cfg
[vault]
cipher = GPG
gpg_recipients = PUBLICKEYID
gpg_noprompt = True
  1. Confirm a decryption causes deadlock (We expect no return from GPG binary or prompts from VaultLib) - PASS
echo "ansible" >> plaintext.yml
ansible-vault encrypt plaintext.yml
ansible-vault decrypt plaintext.yml
CTRL+C
# Traceback begins at 'bin/ansible-vault", line 234, in <module>'
  1. Update your .bashrc (Make sure you update paths)
cat >> ~/.bashrc << 'EOF'
    function ansible-vault() {
    gpg --batch -d /path/to/ansible-vault-gpg.asc >/dev/null 2>&1
    rc=$?
    if [ $rc -eq 0 ]; then
    /path/to/bin/ansible-vault "$@"
    else
    echo "Failed to decrypt test file, check your system GPG and gpg-agent"
    fi
    }
    function ansible-playbook() {
    gpg --batch -d /path/to/ansible-vault-gpg.asc >/dev/null 2>&1
    rc=$?
    if [ $rc -eq 0 ]; then
    /path/to/bin/ansible-playbook "$@"
    else
    echo "Failed to decrypt test file, check your system GPG and gpg-agent"
    fi
    }
source ~/.bashrc
touch /path/to/ansible-vault-gpg
gpg -e -a -r [YOUR KEY ID] /path/to/ansible-vault-gpg
  1. Test encryption and decryption with agent workaround - PASS
echo "ansible" >> plaintext.yml
ansible-vault encrypt plaintext.yml
ansible-vault decrypt plaintext.yml
  1. Run ansible-playbook using encrypted files - PASS
cat > host_vars/127.0.0.1 << 'EOF'

---
vault_hostname: ansible
EOF
cat > hosts << 'EOF'
127.0.0.1
EOF
cat > site.yml << 'EOF'

---
- name: test ansible-vault
  hosts: 127.0.0.1
  connection: local
  gather_facts: no
  tasks:
  - name: set system hostname
    hostname: name={{ vault_hostname }}
EOF
ansible-vault encrypt host_vars/127.0.0.1
ansible-playbook --ask-vault-pass site.yml

Known issues

  1. When gpg_noprompt is enabled the decrypt function will fail as the binary will wait forever for user input in a subprocess.
  2. A system without a gpg binary installed will get errors such as ERROR: [Errno 2] No such file or directory when attempting to use GPG cipher
  3. Untrusted public keys cause encryption to fail. This error could be handled better by identifying which key is untrusted before exiting.
Owner

Kahn commented on 7715cd1 Apr 27, 2014

Unit Tests

  1. Unit tests pass - PASS

    make tests

Functional Tests

Defaults

With no changes to .ansible.cfg

  1. Create a test.yml - PASS
ansible-vault create test.yml
  1. Confirm cipher is AES256 via header - PASS
grep AES256 test.yml
  1. Edit test.yml - PASS
ansible-vault edit test.yml
  1. Rekey test.yml - PASS
ansible-vault rekey test.yml
  1. Encrypt a plaintext file - PASS
echo "ansible" >> plaintext.yml
ansible-vault encrypt plaintext.yml
  1. Decrypt a encrypted file - PASS
ansible-vault decrypt plaintext.yml
cat plaintext.yml
  1. Run ansible-playbook using encrypted files - PASS
cat > host_vars/127.0.0.1 << 'EOF'

---
vault_hostname: ansible
EOF
cat > hosts << 'EOF'
127.0.0.1
EOF
cat > site.yml << 'EOF'

---
- name: test ansible-vault
  hosts: 127.0.0.1
  connection: local
  gather_facts: no
  tasks:
  - name: set system hostname
    hostname: name={{ vault_hostname }}
EOF
ansible-vault encrypt host_vars/127.0.0.1
ansible-playbook --ask-vault-pass site.yml

GPG Cipher

Direct passphrase input

  1. Update ~/.ansible.cfg with minimal changes
[vault]
cipher = GPG
gpg_recipients = PUBLICKEYID
  1. Create a test.yml - PASS
ansible-vault create test.yml
  1. Confirm cipher is GPG via header - PASS
grep GPG test.yml
  1. Edit test.yml - PASS
ansible-vault edit test.yml
  1. Update ~/.ansible.cfg with a second public key
[vault]
cipher = GPG
gpg_recipients = PUBLICKEYID PUBLICKEYID2
  1. Rekey test.yml - PASS
gpg -d test.yml (Cancel the agent password prompt. Shows what public keys the message was encrypted to. Should only output first public key)
ansible-vault rekey test.yml
gpg -d test.yml (Now we should see both recipients)
  1. Encrypt a plaintext file - PASS
echo "ansible" >> plaintext.yml
ansible-vault encrypt plaintext.yml
  1. Decrypt a encrypted file - PASS
ansible-vault decrypt plaintext.yml
cat plaintext.yml
  1. Run ansible-playbook using encrypted files - PASS
cat > host_vars/127.0.0.1 << 'EOF'

---
vault_hostname: ansible
EOF
cat > hosts << 'EOF'
127.0.0.1
EOF
cat > site.yml << 'EOF'

---
- name: test ansible-vault
  hosts: 127.0.0.1
  connection: local
  gather_facts: no
  tasks:
  - name: set system hostname
    hostname: name={{ vault_hostname }}
EOF
ansible-vault encrypt host_vars/127.0.0.1
ansible-playbook --ask-vault-pass site.yml

Agent managed password input

  1. Update ~/.ansible.cfg
[vault]
cipher = GPG
gpg_recipients = PUBLICKEYID
gpg_noprompt = True
  1. Confirm a decryption causes deadlock (We expect no return from GPG binary or prompts from VaultLib) - PASS
echo "ansible" >> plaintext.yml
ansible-vault encrypt plaintext.yml
ansible-vault decrypt plaintext.yml
CTRL+C
# Traceback begins at 'bin/ansible-vault", line 234, in <module>'
  1. Update your .bashrc (Make sure you update paths)
cat >> ~/.bashrc << 'EOF'
    function ansible-vault() {
    gpg --batch -d /path/to/ansible-vault-gpg.asc >/dev/null 2>&1
    rc=$?
    if [ $rc -eq 0 ]; then
    /path/to/bin/ansible-vault "$@"
    else
    echo "Failed to decrypt test file, check your system GPG and gpg-agent"
    fi
    }
    function ansible-playbook() {
    gpg --batch -d /path/to/ansible-vault-gpg.asc >/dev/null 2>&1
    rc=$?
    if [ $rc -eq 0 ]; then
    /path/to/bin/ansible-playbook "$@"
    else
    echo "Failed to decrypt test file, check your system GPG and gpg-agent"
    fi
    }
source ~/.bashrc
touch /path/to/ansible-vault-gpg
gpg -e -a -r [YOUR KEY ID] /path/to/ansible-vault-gpg
  1. Test encryption and decryption with agent workaround - PASS
echo "ansible" >> plaintext.yml
ansible-vault encrypt plaintext.yml
ansible-vault decrypt plaintext.yml
  1. Run ansible-playbook using encrypted files - PASS
cat > host_vars/127.0.0.1 << 'EOF'

---
vault_hostname: ansible
EOF
cat > hosts << 'EOF'
127.0.0.1
EOF
cat > site.yml << 'EOF'

---
- name: test ansible-vault
  hosts: 127.0.0.1
  connection: local
  gather_facts: no
  tasks:
  - name: set system hostname
    hostname: name={{ vault_hostname }}
EOF
ansible-vault encrypt host_vars/127.0.0.1
ansible-playbook --ask-vault-pass site.yml

Known issues

  1. When gpg_noprompt is enabled the decrypt function will fail as the binary will wait forever for user input in a subprocess.
  2. A system without a gpg binary installed will get errors such as ERROR: [Errno 2] No such file or directory when attempting to use GPG cipher
  3. Untrusted public keys cause encryption to fail. This error could be handled better by identifying which key is untrusted before exiting.
@mpdehaan

This comment has been minimized.

Show comment
Hide comment
@mpdehaan

mpdehaan Apr 28, 2014

Contributor

thanks -- in queue for review.

I'm curious a bit if the "install shell parts" can be removed?

Contributor

mpdehaan commented Apr 28, 2014

thanks -- in queue for review.

I'm curious a bit if the "install shell parts" can be removed?

@jimi-c jimi-c added P2 labels Apr 28, 2014

@Kahn

This comment has been minimized.

Show comment
Hide comment
@Kahn

Kahn Apr 28, 2014

The shell workaround only exist to work around deadlocks caused by python-gnupg opening gnupg and the gnupg process subsequently waiting for stdin forever.

I've configured the defaults in the order of least change as we discussed.

  1. Use Vault with AES256 as per 1.5 behaviour
  2. Use Vault with cipher = GPG and keeping the vault prompting behaviour. In this mode passphrase is passed to the gpg binary via stdin for every single invocation. This is also very similar to 1.5 behaviour with the AES256 cipher.
  3. Only users who elect to configure all three directives cipher,gpg_recipients and gpg_noprompt will need to workaround the deadlock caused by python-gnupg waiting for stdin input. I feel like this group of users will be able to live with the workaround.

The long term solution is to update the python-gnupg wrapper to introduce a timeout exception. I haven't really made any progress with the author though hence the workaround in the short term.

I guess in short though perhaps moving the shell functions to another part of the documentation may be a cleaner approach.

Cheers,

Sam

Kahn commented Apr 28, 2014

The shell workaround only exist to work around deadlocks caused by python-gnupg opening gnupg and the gnupg process subsequently waiting for stdin forever.

I've configured the defaults in the order of least change as we discussed.

  1. Use Vault with AES256 as per 1.5 behaviour
  2. Use Vault with cipher = GPG and keeping the vault prompting behaviour. In this mode passphrase is passed to the gpg binary via stdin for every single invocation. This is also very similar to 1.5 behaviour with the AES256 cipher.
  3. Only users who elect to configure all three directives cipher,gpg_recipients and gpg_noprompt will need to workaround the deadlock caused by python-gnupg waiting for stdin input. I feel like this group of users will be able to live with the workaround.

The long term solution is to update the python-gnupg wrapper to introduce a timeout exception. I haven't really made any progress with the author though hence the workaround in the short term.

I guess in short though perhaps moving the shell functions to another part of the documentation may be a cleaner approach.

Cheers,

Sam

@jirutka

This comment has been minimized.

Show comment
Hide comment
@jirutka

jirutka May 30, 2014

Contributor

+1

Contributor

jirutka commented May 30, 2014

+1

@jimi-c

This comment has been minimized.

Show comment
Hide comment
@jimi-c

jimi-c Jun 12, 2014

Member

Testing this out, and unfortunately it's not passing the unit tests for me. I get the following:

======================================================================
FAIL: test_encrypt_decrypt_gpg (TestVaultGPG.TestVaultGPG)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/data/devel/ansible/test/units/TestVaultGPG.py", line 82, in test_encrypt_decrypt_gpg
    assert dec_data == "foobar", "decryption failed"
AssertionError: decryption failed
-------------------- >> begin captured stdout << ---------------------
> /data/devel/ansible/lib/ansible/utils/vault.py(657)decrypt()
-> decryptedData = str(dec_data)
--------------------- >> end captured stdout << ----------------------
    '-----BEGIN PGP MESSAGE-----\nVersion: GnuPG v1\n\nhIwD0P0wUlp2ExQBBACiUzln7zyClS2zEZQqAN0fwWQLtd9jc7YKxV8r2JU/fttm\n9LhBebIsGlHVeAblMCB+7J/lfW/SqiqR2kpA55Xu/o1pFttuE52W4URIVmWVB/5a\nKUUwOGRnpPfSqIvurPUuWxsiKvlRQ1PO/s+6lzlpk6pEl77SWD/ddB0AyKbRItJB\nAUDe/OVhf0F1WyWkW8yRXfkVaS3nS6qccfq4sZYNaEdry3mgXd2x8cQd7U0pDw8Q\nTp3TLnwPnHENhHODV7MfVzg=\n=Dlnr\n-----END PGP MESSAGE-----\n' = <ansible.utils.vault.VaultGPG object at 0x2bfb290>.encrypt("foobar", 'ansible')
    '' = <ansible.utils.vault.VaultGPG object at 0x2bfb290>.decrypt('-----BEGIN PGP MESSAGE-----\nVersion: GnuPG v1\n\nhIwD0P0wUlp2ExQBBACiUzln7zyClS2zEZQqAN0fwWQLtd9jc7YKxV8r2JU/fttm\n9LhBebIsGlHVeAblMCB+7J/lfW/SqiqR2kpA55Xu/o1pFttuE52W4URIVmWVB/5a\nKUUwOGRnpPfSqIvurPUuWxsiKvlRQ1PO/s+6lzlpk6pEl77SWD/ddB0AyKbRItJB\nAUDe/OVhf0F1WyWkW8yRXfkVaS3nS6qccfq4sZYNaEdry3mgXd2x8cQd7U0pDw8Q\nTp3TLnwPnHENhHODV7MfVzg=\n=Dlnr\n-----END PGP MESSAGE-----\n', 'ansible')
    assert '-----BEGIN PGP MESSAGE-----\nVersion: GnuPG v1\n\nhIwD0P0wUlp2ExQBBACiUzln7zyClS2zEZQqAN0fwWQLtd9jc7YKxV8r2JU/fttm\n9LhBebIsGlHVeAblMCB+7J/lfW/SqiqR2kpA55Xu/o1pFttuE52W4URIVmWVB/5a\nKUUwOGRnpPfSqIvurPUuWxsiKvlRQ1PO/s+6lzlpk6pEl77SWD/ddB0AyKbRItJB\nAUDe/OVhf0F1WyWkW8yRXfkVaS3nS6qccfq4sZYNaEdry3mgXd2x8cQd7U0pDw8Q\nTp3TLnwPnHENhHODV7MfVzg=\n=Dlnr\n-----END PGP MESSAGE-----\n' != "foobar", "encryption failed"
>>  assert '' == "foobar", "decryption failed"
    
-------------------- >> begin captured logging << --------------------
gnupg: DEBUG: ['gpg', '--status-fd', '2', '--no-tty', '--no-default-keyring', '--keyring', '/tmp/tmpRlKyp1/pubring.gpg', '--secret-keyring', '/tmp/tmpRlKyp1/secring.gpg', '--use-agent', '--version']
gnupg: DEBUG: stderr reader: <Thread(Thread-1, initial daemon)>
gnupg: DEBUG: stdout reader: <Thread(Thread-2, initial daemon)>
gnupg: DEBUG: chunk: 'gpg (GnuPG) 1.4.16\nCopyright (C) 2013 Free Software Foundation, Inc.\nLicense GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>\nThis is free software: you are free to change and redistribute it.\nThere is NO WARRANTY, to the extent permit'
gnupg: DEBUG: ['gpg', '--status-fd', '2', '--no-tty', '--no-default-keyring', '--keyring', '/tmp/tmpRlKyp1/pubring.gpg', '--secret-keyring', '/tmp/tmpRlKyp1/secring.gpg', '--use-agent', '--list-keys', '--fixed-list-mode', '--fingerprint', '--with-colons']
gnupg: DEBUG: stderr reader: <Thread(Thread-3, initial daemon)>
gnupg: DEBUG: stdout reader: <Thread(Thread-4, initial daemon)>
gnupg: DEBUG: chunk: 'tru::1:1402599376:0:3:1:5\npub:-:1024:1:B681DDA50449DF12:1398408805:::-:::scESC:\nfpr:::::::::DF3170716F70D416047C66EAB681DDA50449DF12:\nuid:-::::1398408805::80289503611B3766D0A7A9E0625DA84E3C9E12F3::ansible-vault (test key) <example@example.org>:\nsub:-:1024:'
gnupg: DEBUG: line: u'tru::1:1402599376:0:3:1:5'
gnupg: DEBUG: line: u'pub:-:1024:1:B681DDA50449DF12:1398408805:::-:::scESC:'
gnupg: DEBUG: line: u'fpr:::::::::DF3170716F70D416047C66EAB681DDA50449DF12:'
gnupg: DEBUG: line: u'uid:-::::1398408805::80289503611B3766D0A7A9E0625DA84E3C9E12F3::ansible-vault (test key) <example@example.org>:'
gnupg: DEBUG: line: u'sub:-:1024:1:D0FD30525A761314:1398408805::::::e:'
gnupg: DEBUG: line: u'pub:-:1024:1:59E29486659C181E:1398435167:::-:::scESC:'
gnupg: DEBUG: line: u'fpr:::::::::36B88E2C6C260C49C66761CA59E29486659C181E:'
gnupg: DEBUG: line: u'uid:-::::1398435167::168C54F3F1926708D8A0C776B8B168E9D308E096::ansible-vault (test untrusted key) <example@example.org>:'
gnupg: DEBUG: line: u'sub:-:1024:1:B51A4FC627621D51:1398435167::::::e:'
gnupg: DEBUG: ['gpg', '--status-fd', '2', '--no-tty', '--no-default-keyring', '--keyring', '/tmp/tmpRlKyp1/pubring.gpg', '--secret-keyring', '/tmp/tmpRlKyp1/secring.gpg', '--use-agent', '--encrypt', '--recipient', u'B681DDA50449DF12', '--armor', '--always-trust']
gnupg: DEBUG: data copier: <Thread(Thread-5, initial daemon)>, <_io.BytesIO object at 0x2b2f8f0>, <open file '<fdopen>', mode 'wb' at 0x2a4d0c0>
gnupg: DEBUG: sending chunk (6): 'foobar'
gnupg: DEBUG: stderr reader: <Thread(Thread-6, initial daemon)>
gnupg: DEBUG: stdout reader: <Thread(Thread-7, initial daemon)>
gnupg: DEBUG: closed output, 6 bytes sent
gnupg: DEBUG: chunk: '-----BEGIN PGP MESSAGE-----\nVersion: GnuPG v1\n\nhIwD0P0wUlp2ExQBBACiUzln7zyClS2zEZQqAN0fwWQLtd9jc7YKxV8r2JU/fttm\n9LhBebIsGlHVeAblMCB+7J/lfW/SqiqR2kpA55Xu/o1pFttuE52W4URIVmWVB/5a\nKUUwOGRnpPfSqIvurPUuWxsiKvlRQ1PO/s+6lzlpk6pEl77SWD/ddB0AyKbRItJB\nAUDe/OVhf0F1Wy'
gnupg: DEBUG: [GNUPG:] BEGIN_ENCRYPTION 2 9
gnupg: DEBUG: [GNUPG:] END_ENCRYPTION
gnupg: DEBUG: encrypt result: '-----BEGIN PGP MESSAGE-----\nVersion: GnuPG v1\n\nhIwD0P0wUlp2ExQBBACiUzln7zyClS2zEZQqAN0fwWQLtd9jc7YKxV8r2JU/fttm\n9LhBebIsGlHVeAblMCB+7J/lfW/SqiqR2kpA55Xu/o1pFttuE52W4URIVmWVB/5a\nKUUwOGRnpPfSqIvurPUuWxsiKvlRQ1PO/s+6lzlpk6pEl77SWD/ddB0AyKbRItJB\nAUDe/OVhf0F1WyWkW8yRXfkVaS3nS6qccfq4sZYNaEdry3mgXd2x8cQd7U0pDw8Q\nTp3TLnwPnHENhHODV7MfVzg=\n=Dlnr\n-----END PGP MESSAGE-----\n'
gnupg: DEBUG: ['gpg', '--status-fd', '2', '--no-tty', '--no-default-keyring', '--keyring', '/tmp/tmpRlKyp1/pubring.gpg', '--secret-keyring', '/tmp/tmpRlKyp1/secring.gpg', '--use-agent', '--version']
gnupg: DEBUG: stderr reader: <Thread(Thread-8, initial daemon)>
gnupg: DEBUG: stdout reader: <Thread(Thread-9, initial daemon)>
gnupg: DEBUG: chunk: 'gpg (GnuPG) 1.4.16\nCopyright (C) 2013 Free Software Foundation, Inc.\nLicense GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>\nThis is free software: you are free to change and redistribute it.\nThere is NO WARRANTY, to the extent permit'
gnupg: DEBUG: ['gpg', '--status-fd', '2', '--no-tty', '--no-default-keyring', '--keyring', '/tmp/tmpRlKyp1/pubring.gpg', '--secret-keyring', '/tmp/tmpRlKyp1/secring.gpg', '--batch', '--passphrase-fd', '0', '--use-agent', '--decrypt', '--always-trust']
gnupg: DEBUG: Wrote passphrase
gnupg: DEBUG: data copier: <Thread(Thread-10, initial daemon)>, <_io.BytesIO object at 0x2d51470>, <open file '<fdopen>', mode 'wb' at 0x2d0b660>
gnupg: DEBUG: sending chunk (364): '-----BEGIN PGP MESSAGE-----\nVersion: GnuPG v1\n\nhIwD0P0wUlp2ExQBBACiUzln7zyClS2zEZQqAN0fwWQLtd9jc7YKxV8r2JU/fttm\n9LhBebIsGlHVeAblMCB+7J/lfW/SqiqR2kpA55Xu/o1pFttuE52W4URIVmWVB/5a\nKUUwOGRnpPfSqIvurPUuWxsiKvlRQ1PO/s+6lzlpk6pEl77SWD/ddB0AyKbRItJB\nAUDe/OVhf0F1Wy'
gnupg: DEBUG: closed output, 364 bytes sent
gnupg: DEBUG: stderr reader: <Thread(Thread-11, initial daemon)>
gnupg: DEBUG: stdout reader: <Thread(Thread-12, initial daemon)>
gnupg: DEBUG: [GNUPG:] ENC_TO D0FD30525A761314 1 0
gnupg: DEBUG: [GNUPG:] USERID_HINT D0FD30525A761314 ansible-vault (test key) <example@example.org>
gnupg: DEBUG: [GNUPG:] NEED_PASSPHRASE D0FD30525A761314 B681DDA50449DF12 1 0
gnupg: DEBUG: gpg: gpg-agent is not available in this session
gnupg: DEBUG: gpg: can't query passphrase in batch mode
gnupg: DEBUG: [GNUPG:] MISSING_PASSPHRASE
gnupg: DEBUG: [GNUPG:] BAD_PASSPHRASE D0FD30525A761314
gnupg: DEBUG: gpg: Invalid passphrase; please try again ...
gnupg: DEBUG: [GNUPG:] USERID_HINT D0FD30525A761314 ansible-vault (test key) <example@example.org>
gnupg: DEBUG: [GNUPG:] NEED_PASSPHRASE D0FD30525A761314 B681DDA50449DF12 1 0
gnupg: DEBUG: gpg: can't query passphrase in batch mode
gnupg: DEBUG: [GNUPG:] MISSING_PASSPHRASE
gnupg: DEBUG: [GNUPG:] BAD_PASSPHRASE D0FD30525A761314
gnupg: DEBUG: gpg: Invalid passphrase; please try again ...
gnupg: DEBUG: [GNUPG:] USERID_HINT D0FD30525A761314 ansible-vault (test key) <example@example.org>
gnupg: DEBUG: [GNUPG:] NEED_PASSPHRASE D0FD30525A761314 B681DDA50449DF12 1 0
gnupg: DEBUG: gpg: can't query passphrase in batch mode
gnupg: DEBUG: [GNUPG:] MISSING_PASSPHRASE
gnupg: DEBUG: [GNUPG:] BAD_PASSPHRASE D0FD30525A761314
gnupg: DEBUG: gpg: encrypted with 1024-bit RSA key, ID 5A761314, created 2014-04-25
gnupg: DEBUG:       "ansible-vault (test key) <example@example.org>"
gnupg: DEBUG: gpg: public key decryption failed: bad passphrase
gnupg: DEBUG: [GNUPG:] ERROR pkdecrypt_failed 11
gnupg: DEBUG: [GNUPG:] BEGIN_DECRYPTION
gnupg: DEBUG: [GNUPG:] DECRYPTION_FAILED
gnupg: DEBUG: gpg: decryption failed: secret key not available
gnupg: DEBUG: [GNUPG:] END_DECRYPTION
gnupg: DEBUG: decrypt result: ''
--------------------- >> end captured logging << ---------------------

Is the gpg agent required even for the unit tests? If so, that will require quite a bit more setup for our Jenkins server.

Member

jimi-c commented Jun 12, 2014

Testing this out, and unfortunately it's not passing the unit tests for me. I get the following:

======================================================================
FAIL: test_encrypt_decrypt_gpg (TestVaultGPG.TestVaultGPG)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/data/devel/ansible/test/units/TestVaultGPG.py", line 82, in test_encrypt_decrypt_gpg
    assert dec_data == "foobar", "decryption failed"
AssertionError: decryption failed
-------------------- >> begin captured stdout << ---------------------
> /data/devel/ansible/lib/ansible/utils/vault.py(657)decrypt()
-> decryptedData = str(dec_data)
--------------------- >> end captured stdout << ----------------------
    '-----BEGIN PGP MESSAGE-----\nVersion: GnuPG v1\n\nhIwD0P0wUlp2ExQBBACiUzln7zyClS2zEZQqAN0fwWQLtd9jc7YKxV8r2JU/fttm\n9LhBebIsGlHVeAblMCB+7J/lfW/SqiqR2kpA55Xu/o1pFttuE52W4URIVmWVB/5a\nKUUwOGRnpPfSqIvurPUuWxsiKvlRQ1PO/s+6lzlpk6pEl77SWD/ddB0AyKbRItJB\nAUDe/OVhf0F1WyWkW8yRXfkVaS3nS6qccfq4sZYNaEdry3mgXd2x8cQd7U0pDw8Q\nTp3TLnwPnHENhHODV7MfVzg=\n=Dlnr\n-----END PGP MESSAGE-----\n' = <ansible.utils.vault.VaultGPG object at 0x2bfb290>.encrypt("foobar", 'ansible')
    '' = <ansible.utils.vault.VaultGPG object at 0x2bfb290>.decrypt('-----BEGIN PGP MESSAGE-----\nVersion: GnuPG v1\n\nhIwD0P0wUlp2ExQBBACiUzln7zyClS2zEZQqAN0fwWQLtd9jc7YKxV8r2JU/fttm\n9LhBebIsGlHVeAblMCB+7J/lfW/SqiqR2kpA55Xu/o1pFttuE52W4URIVmWVB/5a\nKUUwOGRnpPfSqIvurPUuWxsiKvlRQ1PO/s+6lzlpk6pEl77SWD/ddB0AyKbRItJB\nAUDe/OVhf0F1WyWkW8yRXfkVaS3nS6qccfq4sZYNaEdry3mgXd2x8cQd7U0pDw8Q\nTp3TLnwPnHENhHODV7MfVzg=\n=Dlnr\n-----END PGP MESSAGE-----\n', 'ansible')
    assert '-----BEGIN PGP MESSAGE-----\nVersion: GnuPG v1\n\nhIwD0P0wUlp2ExQBBACiUzln7zyClS2zEZQqAN0fwWQLtd9jc7YKxV8r2JU/fttm\n9LhBebIsGlHVeAblMCB+7J/lfW/SqiqR2kpA55Xu/o1pFttuE52W4URIVmWVB/5a\nKUUwOGRnpPfSqIvurPUuWxsiKvlRQ1PO/s+6lzlpk6pEl77SWD/ddB0AyKbRItJB\nAUDe/OVhf0F1WyWkW8yRXfkVaS3nS6qccfq4sZYNaEdry3mgXd2x8cQd7U0pDw8Q\nTp3TLnwPnHENhHODV7MfVzg=\n=Dlnr\n-----END PGP MESSAGE-----\n' != "foobar", "encryption failed"
>>  assert '' == "foobar", "decryption failed"
    
-------------------- >> begin captured logging << --------------------
gnupg: DEBUG: ['gpg', '--status-fd', '2', '--no-tty', '--no-default-keyring', '--keyring', '/tmp/tmpRlKyp1/pubring.gpg', '--secret-keyring', '/tmp/tmpRlKyp1/secring.gpg', '--use-agent', '--version']
gnupg: DEBUG: stderr reader: <Thread(Thread-1, initial daemon)>
gnupg: DEBUG: stdout reader: <Thread(Thread-2, initial daemon)>
gnupg: DEBUG: chunk: 'gpg (GnuPG) 1.4.16\nCopyright (C) 2013 Free Software Foundation, Inc.\nLicense GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>\nThis is free software: you are free to change and redistribute it.\nThere is NO WARRANTY, to the extent permit'
gnupg: DEBUG: ['gpg', '--status-fd', '2', '--no-tty', '--no-default-keyring', '--keyring', '/tmp/tmpRlKyp1/pubring.gpg', '--secret-keyring', '/tmp/tmpRlKyp1/secring.gpg', '--use-agent', '--list-keys', '--fixed-list-mode', '--fingerprint', '--with-colons']
gnupg: DEBUG: stderr reader: <Thread(Thread-3, initial daemon)>
gnupg: DEBUG: stdout reader: <Thread(Thread-4, initial daemon)>
gnupg: DEBUG: chunk: 'tru::1:1402599376:0:3:1:5\npub:-:1024:1:B681DDA50449DF12:1398408805:::-:::scESC:\nfpr:::::::::DF3170716F70D416047C66EAB681DDA50449DF12:\nuid:-::::1398408805::80289503611B3766D0A7A9E0625DA84E3C9E12F3::ansible-vault (test key) <example@example.org>:\nsub:-:1024:'
gnupg: DEBUG: line: u'tru::1:1402599376:0:3:1:5'
gnupg: DEBUG: line: u'pub:-:1024:1:B681DDA50449DF12:1398408805:::-:::scESC:'
gnupg: DEBUG: line: u'fpr:::::::::DF3170716F70D416047C66EAB681DDA50449DF12:'
gnupg: DEBUG: line: u'uid:-::::1398408805::80289503611B3766D0A7A9E0625DA84E3C9E12F3::ansible-vault (test key) <example@example.org>:'
gnupg: DEBUG: line: u'sub:-:1024:1:D0FD30525A761314:1398408805::::::e:'
gnupg: DEBUG: line: u'pub:-:1024:1:59E29486659C181E:1398435167:::-:::scESC:'
gnupg: DEBUG: line: u'fpr:::::::::36B88E2C6C260C49C66761CA59E29486659C181E:'
gnupg: DEBUG: line: u'uid:-::::1398435167::168C54F3F1926708D8A0C776B8B168E9D308E096::ansible-vault (test untrusted key) <example@example.org>:'
gnupg: DEBUG: line: u'sub:-:1024:1:B51A4FC627621D51:1398435167::::::e:'
gnupg: DEBUG: ['gpg', '--status-fd', '2', '--no-tty', '--no-default-keyring', '--keyring', '/tmp/tmpRlKyp1/pubring.gpg', '--secret-keyring', '/tmp/tmpRlKyp1/secring.gpg', '--use-agent', '--encrypt', '--recipient', u'B681DDA50449DF12', '--armor', '--always-trust']
gnupg: DEBUG: data copier: <Thread(Thread-5, initial daemon)>, <_io.BytesIO object at 0x2b2f8f0>, <open file '<fdopen>', mode 'wb' at 0x2a4d0c0>
gnupg: DEBUG: sending chunk (6): 'foobar'
gnupg: DEBUG: stderr reader: <Thread(Thread-6, initial daemon)>
gnupg: DEBUG: stdout reader: <Thread(Thread-7, initial daemon)>
gnupg: DEBUG: closed output, 6 bytes sent
gnupg: DEBUG: chunk: '-----BEGIN PGP MESSAGE-----\nVersion: GnuPG v1\n\nhIwD0P0wUlp2ExQBBACiUzln7zyClS2zEZQqAN0fwWQLtd9jc7YKxV8r2JU/fttm\n9LhBebIsGlHVeAblMCB+7J/lfW/SqiqR2kpA55Xu/o1pFttuE52W4URIVmWVB/5a\nKUUwOGRnpPfSqIvurPUuWxsiKvlRQ1PO/s+6lzlpk6pEl77SWD/ddB0AyKbRItJB\nAUDe/OVhf0F1Wy'
gnupg: DEBUG: [GNUPG:] BEGIN_ENCRYPTION 2 9
gnupg: DEBUG: [GNUPG:] END_ENCRYPTION
gnupg: DEBUG: encrypt result: '-----BEGIN PGP MESSAGE-----\nVersion: GnuPG v1\n\nhIwD0P0wUlp2ExQBBACiUzln7zyClS2zEZQqAN0fwWQLtd9jc7YKxV8r2JU/fttm\n9LhBebIsGlHVeAblMCB+7J/lfW/SqiqR2kpA55Xu/o1pFttuE52W4URIVmWVB/5a\nKUUwOGRnpPfSqIvurPUuWxsiKvlRQ1PO/s+6lzlpk6pEl77SWD/ddB0AyKbRItJB\nAUDe/OVhf0F1WyWkW8yRXfkVaS3nS6qccfq4sZYNaEdry3mgXd2x8cQd7U0pDw8Q\nTp3TLnwPnHENhHODV7MfVzg=\n=Dlnr\n-----END PGP MESSAGE-----\n'
gnupg: DEBUG: ['gpg', '--status-fd', '2', '--no-tty', '--no-default-keyring', '--keyring', '/tmp/tmpRlKyp1/pubring.gpg', '--secret-keyring', '/tmp/tmpRlKyp1/secring.gpg', '--use-agent', '--version']
gnupg: DEBUG: stderr reader: <Thread(Thread-8, initial daemon)>
gnupg: DEBUG: stdout reader: <Thread(Thread-9, initial daemon)>
gnupg: DEBUG: chunk: 'gpg (GnuPG) 1.4.16\nCopyright (C) 2013 Free Software Foundation, Inc.\nLicense GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>\nThis is free software: you are free to change and redistribute it.\nThere is NO WARRANTY, to the extent permit'
gnupg: DEBUG: ['gpg', '--status-fd', '2', '--no-tty', '--no-default-keyring', '--keyring', '/tmp/tmpRlKyp1/pubring.gpg', '--secret-keyring', '/tmp/tmpRlKyp1/secring.gpg', '--batch', '--passphrase-fd', '0', '--use-agent', '--decrypt', '--always-trust']
gnupg: DEBUG: Wrote passphrase
gnupg: DEBUG: data copier: <Thread(Thread-10, initial daemon)>, <_io.BytesIO object at 0x2d51470>, <open file '<fdopen>', mode 'wb' at 0x2d0b660>
gnupg: DEBUG: sending chunk (364): '-----BEGIN PGP MESSAGE-----\nVersion: GnuPG v1\n\nhIwD0P0wUlp2ExQBBACiUzln7zyClS2zEZQqAN0fwWQLtd9jc7YKxV8r2JU/fttm\n9LhBebIsGlHVeAblMCB+7J/lfW/SqiqR2kpA55Xu/o1pFttuE52W4URIVmWVB/5a\nKUUwOGRnpPfSqIvurPUuWxsiKvlRQ1PO/s+6lzlpk6pEl77SWD/ddB0AyKbRItJB\nAUDe/OVhf0F1Wy'
gnupg: DEBUG: closed output, 364 bytes sent
gnupg: DEBUG: stderr reader: <Thread(Thread-11, initial daemon)>
gnupg: DEBUG: stdout reader: <Thread(Thread-12, initial daemon)>
gnupg: DEBUG: [GNUPG:] ENC_TO D0FD30525A761314 1 0
gnupg: DEBUG: [GNUPG:] USERID_HINT D0FD30525A761314 ansible-vault (test key) <example@example.org>
gnupg: DEBUG: [GNUPG:] NEED_PASSPHRASE D0FD30525A761314 B681DDA50449DF12 1 0
gnupg: DEBUG: gpg: gpg-agent is not available in this session
gnupg: DEBUG: gpg: can't query passphrase in batch mode
gnupg: DEBUG: [GNUPG:] MISSING_PASSPHRASE
gnupg: DEBUG: [GNUPG:] BAD_PASSPHRASE D0FD30525A761314
gnupg: DEBUG: gpg: Invalid passphrase; please try again ...
gnupg: DEBUG: [GNUPG:] USERID_HINT D0FD30525A761314 ansible-vault (test key) <example@example.org>
gnupg: DEBUG: [GNUPG:] NEED_PASSPHRASE D0FD30525A761314 B681DDA50449DF12 1 0
gnupg: DEBUG: gpg: can't query passphrase in batch mode
gnupg: DEBUG: [GNUPG:] MISSING_PASSPHRASE
gnupg: DEBUG: [GNUPG:] BAD_PASSPHRASE D0FD30525A761314
gnupg: DEBUG: gpg: Invalid passphrase; please try again ...
gnupg: DEBUG: [GNUPG:] USERID_HINT D0FD30525A761314 ansible-vault (test key) <example@example.org>
gnupg: DEBUG: [GNUPG:] NEED_PASSPHRASE D0FD30525A761314 B681DDA50449DF12 1 0
gnupg: DEBUG: gpg: can't query passphrase in batch mode
gnupg: DEBUG: [GNUPG:] MISSING_PASSPHRASE
gnupg: DEBUG: [GNUPG:] BAD_PASSPHRASE D0FD30525A761314
gnupg: DEBUG: gpg: encrypted with 1024-bit RSA key, ID 5A761314, created 2014-04-25
gnupg: DEBUG:       "ansible-vault (test key) <example@example.org>"
gnupg: DEBUG: gpg: public key decryption failed: bad passphrase
gnupg: DEBUG: [GNUPG:] ERROR pkdecrypt_failed 11
gnupg: DEBUG: [GNUPG:] BEGIN_DECRYPTION
gnupg: DEBUG: [GNUPG:] DECRYPTION_FAILED
gnupg: DEBUG: gpg: decryption failed: secret key not available
gnupg: DEBUG: [GNUPG:] END_DECRYPTION
gnupg: DEBUG: decrypt result: ''
--------------------- >> end captured logging << ---------------------

Is the gpg agent required even for the unit tests? If so, that will require quite a bit more setup for our Jenkins server.

@Kahn

This comment has been minimized.

Show comment
Hide comment
@Kahn

Kahn Jun 12, 2014

Hi guys,

Excited to start testing! I ran the tests manually and I agree there will need to be more of a harness to support automated testing under jenkins.

Personally, I don't think we would need to test the gpg agent as its simply flags which are changed for existing decrypt methods. If it fails with password prompts its going to fail with gpg agent.

Cheers,

Sam

Kahn commented Jun 12, 2014

Hi guys,

Excited to start testing! I ran the tests manually and I agree there will need to be more of a harness to support automated testing under jenkins.

Personally, I don't think we would need to test the gpg agent as its simply flags which are changed for existing decrypt methods. If it fails with password prompts its going to fail with gpg agent.

Cheers,

Sam

@mpdehaan mpdehaan added P3 and removed P2 labels Jun 27, 2014

@muff1nman

This comment has been minimized.

Show comment
Hide comment
@muff1nman

muff1nman Jul 12, 2014

Contributor

Awesome work and Im very excited to see this pull request. One thing I noticed: after I encrypt with ansible-vault, I get the following message when trying to decrypt manually with gpg:

gpg: malformed CRC

If I then pass the --ignore-crc-error along to gpg, it will decrypt the message okay, but I still get a warning about the CRC being malformed. So I guess gpg is complaining that ansible has modified the file and it no longer matches the builtin checksum?

Now the real issue is when I try to decrypt with ansible-vault decrypt. It also complains about the crc, but now the file is just truncated and empty!

Contributor

muff1nman commented Jul 12, 2014

Awesome work and Im very excited to see this pull request. One thing I noticed: after I encrypt with ansible-vault, I get the following message when trying to decrypt manually with gpg:

gpg: malformed CRC

If I then pass the --ignore-crc-error along to gpg, it will decrypt the message okay, but I still get a warning about the CRC being malformed. So I guess gpg is complaining that ansible has modified the file and it no longer matches the builtin checksum?

Now the real issue is when I try to decrypt with ansible-vault decrypt. It also complains about the crc, but now the file is just truncated and empty!

@muff1nman

This comment has been minimized.

Show comment
Hide comment
@muff1nman

muff1nman Jul 12, 2014

Contributor

For the record, I installed python-gnupg from source, commit number cf8c1b64b8fc.

Contributor

muff1nman commented Jul 12, 2014

For the record, I installed python-gnupg from source, commit number cf8c1b64b8fc.

@muff1nman

This comment has been minimized.

Show comment
Hide comment
@muff1nman

muff1nman Jul 12, 2014

Contributor

See Kahn#3

Contributor

muff1nman commented Jul 12, 2014

See Kahn#3

@Kahn

This comment has been minimized.

Show comment
Hide comment
@Kahn

Kahn Jul 12, 2014

I did see the ansible-vault encrypt create blank files though that was fixed by backing out of the encryption step if keys are unavailable or untrusted.

Can't say I saw the CRC error during testing. Can you post some more details like gpg binary version, platform etc? I will try and replicate from there.

Kahn commented Jul 12, 2014

I did see the ansible-vault encrypt create blank files though that was fixed by backing out of the encryption step if keys are unavailable or untrusted.

Can't say I saw the CRC error during testing. Can you post some more details like gpg binary version, platform etc? I will try and replicate from there.

@muff1nman

This comment has been minimized.

Show comment
Hide comment
@muff1nman

muff1nman Jul 12, 2014

Contributor
$ gpg --version
gpg (GnuPG) 2.0.25
libgcrypt 1.6.1
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Home: ~/.gnupg
Supported algorithms:
Pubkey: RSA, ELG, DSA
Cipher: IDEA, 3DES, CAST5, BLOWFISH, AES, AES192, AES256, TWOFISH,
        CAMELLIA128, CAMELLIA192, CAMELLIA256
Hash: MD5, SHA1, RIPEMD160, SHA256, SHA384, SHA512, SHA224
Compression: Uncompressed, ZIP, ZLIB, BZIP2
$ uname -a
Linux WhosYourDaddy 3.14.5-1-ARCH #1 SMP PREEMPT Sun Jun 1 07:36:23 CEST 2014 x86_64 GNU/Linux
$ pacman -Qi python2-gnupg
Name           : python2-gnupg
Version        : r25.cf8c1b64b8fc-1

Note python2-gnupg was built from source

$ python --version
Python 2.7.8
Contributor

muff1nman commented Jul 12, 2014

$ gpg --version
gpg (GnuPG) 2.0.25
libgcrypt 1.6.1
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Home: ~/.gnupg
Supported algorithms:
Pubkey: RSA, ELG, DSA
Cipher: IDEA, 3DES, CAST5, BLOWFISH, AES, AES192, AES256, TWOFISH,
        CAMELLIA128, CAMELLIA192, CAMELLIA256
Hash: MD5, SHA1, RIPEMD160, SHA256, SHA384, SHA512, SHA224
Compression: Uncompressed, ZIP, ZLIB, BZIP2
$ uname -a
Linux WhosYourDaddy 3.14.5-1-ARCH #1 SMP PREEMPT Sun Jun 1 07:36:23 CEST 2014 x86_64 GNU/Linux
$ pacman -Qi python2-gnupg
Name           : python2-gnupg
Version        : r25.cf8c1b64b8fc-1

Note python2-gnupg was built from source

$ python --version
Python 2.7.8
@muff1nman

This comment has been minimized.

Show comment
Hide comment
@muff1nman

muff1nman Jul 12, 2014

Contributor

Did the new test method I added pass for you? This is what I got:

======================================================================
FAIL: test_encrypt_decrypt_gpg_via_vault_lib (TestVaultGPG.TestVaultGPG)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/andrew/Source/ansible/ansible/test/units/TestVaultGPG.py", line 114, in test_encrypt_decrypt_gpg_via_vault_lib
    assert dec_data == plain_text, "decryption failed"
AssertionError: decryption failed
-------------------- >> begin captured logging << --------------------
gnupg: DEBUG: ['gpg', '--status-fd', '2', '--no-tty', '--no-default-keyring', '--keyring', '/tmp/tmpVUBWBf/pubring.gpg', '--secret-keyring', '/tmp/tmpVUBWBf/secring.gpg', '--use-agent', '--version']
gnupg: DEBUG: stderr reader: <Thread(Thread-15, initial daemon)>
gnupg: DEBUG: stdout reader: <Thread(Thread-16, initial daemon)>
gnupg: DEBUG: chunk: 'gpg (GnuPG) 2.0.25\nlibgcrypt 1.6.1\nCopyright (C) 2013 Free Software Foundation, Inc.\nLicense GPLv3+: GNU GPL version 3 or
later <http://gnu.org/licenses/gpl.html>\nThis is free software: you are free to change and redistribute it.\nThere is NO WARRANTY, to t'
gnupg: DEBUG: ['gpg', '--status-fd', '2', '--no-tty', '--no-default-keyring', '--keyring', '/tmp/tmpVUBWBf/pubring.gpg', '--secret-keyring', '/tmp/tmpVUBWBf/secring.gpg', '--use-agent', '--version']
gnupg: DEBUG: stderr reader: <Thread(Thread-17, initial daemon)>
gnupg: DEBUG: stdout reader: <Thread(Thread-18, initial daemon)>
gnupg: DEBUG: chunk: 'gpg (GnuPG) 2.0.25\nlibgcrypt 1.6.1\nCopyright (C) 2013 Free Software Foundation, Inc.\nLicense GPLv3+: GNU GPL version 3 or
later <http://gnu.org/licenses/gpl.html>\nThis is free software: you are free to change and redistribute it.\nThere is NO WARRANTY, to t'
gnupg: DEBUG: ['gpg', '--status-fd', '2', '--no-tty', '--no-default-keyring', '--keyring', '/tmp/tmpVUBWBf/pubring.gpg', '--secret-keyring', '/tmp/tmpVUBWBf/secring.gpg', '--use-agent', '--list-keys', '--fixed-list-mode', '--fingerprint', '--with-colons']
gnupg: DEBUG: stderr reader: <Thread(Thread-19, initial daemon)>
gnupg: DEBUG: stdout reader: <Thread(Thread-20, initial daemon)>
gnupg: DEBUG: chunk: 'tru::1:1390361972:1433621434:3:1:5\npub:-:1024:1:B681DDA50449DF12:1398408805:::-:::scESC:\nfpr:::::::::DF3170716F70D416047C66EAB681DDA50449DF12:\nuid:-::::1398408805::80289503611B3766D0A7A9E0625DA84E3C9E12F3::ansible-vault (test key) <example@example.org>:\nsu'
gnupg: DEBUG: line: u'tru::1:1390361972:1433621434:3:1:5'
gnupg: DEBUG: line: u'pub:-:1024:1:B681DDA50449DF12:1398408805:::-:::scESC:'
gnupg: DEBUG: line: u'fpr:::::::::DF3170716F70D416047C66EAB681DDA50449DF12:'
gnupg: DEBUG: line: u'uid:-::::1398408805::80289503611B3766D0A7A9E0625DA84E3C9E12F3::ansible-vault (test key) <example@example.org>:'
gnupg: DEBUG: line: u'sub:-:1024:1:D0FD30525A761314:1398408805::::::e:'gnupg: DEBUG: line: u'pub:-:1024:1:59E29486659C181E:1398435167:::-:::scESC:'
gnupg: DEBUG: line: u'fpr:::::::::36B88E2C6C260C49C66761CA59E29486659C181E:'
gnupg: DEBUG: line: u'uid:-::::1398435167::168C54F3F1926708D8A0C776B8B168E9D308E096::ansible-vault (test untrusted key) <example@example.org>:'
gnupg: DEBUG: line: u'sub:-:1024:1:B51A4FC627621D51:1398435167::::::e:'gnupg: DEBUG: ['gpg', '--status-fd', '2', '--no-tty', '--no-default-keyring', '--keyring', '/tmp/tmpVUBWBf/pubring.gpg', '--secret-keyring', '/tmp/tmpVUBWBf/secring.gpg', '--use-agent', '--encrypt', '--recipient', u'B681DDA50449DF12', '--armor', '--always-trust']
gnupg: DEBUG: data copier: <Thread(Thread-21, initial daemon)>, <_io.BytesIO object at 0x7f2f61a89ad0>, <open file '<fdopen>', mode 'wb' at 0x7f2f61af4e40>
gnupg: DEBUG: sending chunk (137): "The world is moving so fast these days that the man who says it can't be done is\ngenerally interrupted by someone doing it.\n-- E. Hubbard"
gnupg: DEBUG: stderr reader: <Thread(Thread-22, initial daemon)>
gnupg: DEBUG: stdout reader: <Thread(Thread-23, initial daemon)>
gnupg: DEBUG: closed output, 137 bytes sent
gnupg: DEBUG: [GNUPG:] PROGRESS need_entropy X 8 16
gnupg: DEBUG: chunk: '-----BEGIN PGP MESSAGE-----\nVersion: GnuPG v2\n\nhIwD0P0wUlp2ExQBA/4udVqxcnoXBEDTeK7klFUfATWs+1M64GtbPp1uCiA86EeP\nVU3NX5HIbSCGnSmTeSwklgKeVKlfiLkN7rLMKPhurMaooLKh3SX1PNFKe96ogFxP\nlga+2GpThEuxYpWDAY9df2K168JNVifNjWqoKqLhI1k9LKpWcpfTZXiSWDjn4NKu\nAQmPmJbW2DSN7Z'
gnupg: DEBUG: [GNUPG:] PROGRESS need_entropy X 16 16
gnupg: DEBUG: [GNUPG:] BEGIN_ENCRYPTION 2 9
gnupg: DEBUG: [GNUPG:] END_ENCRYPTION
gnupg: DEBUG: encrypt result: '-----BEGIN PGP MESSAGE-----\nVersion: GnuPG v2\n\nhIwD0P0wUlp2ExQBA/4udVqxcnoXBEDTeK7klFUfATWs+1M64GtbPp1uCiA86EeP\nVU3NX5HIbSCGnSmTeSwklgKeVKlfiLkN7rLMKPhurMaooLKh3SX1PNFKe96ogFxP\nlga+2GpThEuxYpWDAY9df2K168JNVifNjWqoKqLhI1k9LKpWcpfTZXiSWDjn4NKu\nAQmPmJbW2DSN7ZIgJl+086UvmgIo+cDWGHtullkUEUqCIdvMujFV3EMIe3NUzyYh\nIdg79RbHPOW2sQW62NYY0LMourEA1ImObDgVU5dZlVaI69jlI2KHWalqJ+VoRgmd\n2/NKGElk9eqRBlRvkj12WXaru7ptZYpSAV1vjpx+JKy15z3i3/i1367iK33IPrSa\ntLCuAe+AK772LxI4p2VkrNL87cH6hb31h9Mx2nug\n=yB3P\n-----END PGP MESSAGE-----\n'
gnupg: DEBUG: ['gpg', '--status-fd', '2', '--no-tty', '--no-default-keyring', '--keyring', '/tmp/tmpVUBWBf/pubring.gpg', '--secret-keyring', '/tmp/tmpVUBWBf/secring.gpg', '--use-agent', '--version']
gnupg: DEBUG: stderr reader: <Thread(Thread-24, initial daemon)>
gnupg: DEBUG: stdout reader: <Thread(Thread-25, initial daemon)>
gnupg: DEBUG: chunk: 'gpg (GnuPG) 2.0.25\nlibgcrypt 1.6.1\nCopyright (C) 2013 Free Software Foundation, Inc.\nLicense GPLv3+: GNU GPL version 3 or
later <http://gnu.org/licenses/gpl.html>\nThis is free software: you are free to change and redistribute it.\nThere is NO WARRANTY, to t'
gnupg: DEBUG: ['gpg', '--status-fd', '2', '--no-tty', '--no-default-keyring', '--keyring', '/tmp/tmpVUBWBf/pubring.gpg', '--secret-keyring', '/tmp/tmpVUBWBf/secring.gpg', '--batch', '--passphrase-fd', '0', '--use-agent', '--decrypt', '--always-trust']
gnupg: DEBUG: Wrote passphrase
gnupg: DEBUG: data copier: <Thread(Thread-26, initial daemon)>, <_io.BytesIO object at 0x7f2f61a89ad0>, <open file '<fdopen>', mode 'wb' at 0x7f2f61af4e40>
gnupg: DEBUG: sending chunk (517): '-----BEGIN PGP MESSAGE-----\nVersion: GnuPG v2\n\nhIwD0P0wUlp2ExQBA/4udVqxcnoXBEDTe\nK7klFUfATWs+1M64GtbPp1uCiA86EeP\nVU3NX5HIbSCGnSmTeSwklgKeVKlfiLkN7rLMKPhurMaooLKh\n3SX1PNFKe96ogFxP\nlga+2GpThEuxYpWDAY9df2K168JNVifNjWqoKqLhI1k9LKpWcpfTZXiSWDjn4NK\nu\nAQmPmJbW2DS'
gnupg: DEBUG: stderr reader: <Thread(Thread-27, initial daemon)>
gnupg: DEBUG: closed output, 517 bytes sent
gnupg: DEBUG: stdout reader: <Thread(Thread-28, initial daemon)>
gnupg: DEBUG: gpg: malformed CRC
gnupg: DEBUG: decrypt result: ''
--------------------- >> end captured logging << ---------------------

----------------------------------------------------------------------
Contributor

muff1nman commented Jul 12, 2014

Did the new test method I added pass for you? This is what I got:

======================================================================
FAIL: test_encrypt_decrypt_gpg_via_vault_lib (TestVaultGPG.TestVaultGPG)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/andrew/Source/ansible/ansible/test/units/TestVaultGPG.py", line 114, in test_encrypt_decrypt_gpg_via_vault_lib
    assert dec_data == plain_text, "decryption failed"
AssertionError: decryption failed
-------------------- >> begin captured logging << --------------------
gnupg: DEBUG: ['gpg', '--status-fd', '2', '--no-tty', '--no-default-keyring', '--keyring', '/tmp/tmpVUBWBf/pubring.gpg', '--secret-keyring', '/tmp/tmpVUBWBf/secring.gpg', '--use-agent', '--version']
gnupg: DEBUG: stderr reader: <Thread(Thread-15, initial daemon)>
gnupg: DEBUG: stdout reader: <Thread(Thread-16, initial daemon)>
gnupg: DEBUG: chunk: 'gpg (GnuPG) 2.0.25\nlibgcrypt 1.6.1\nCopyright (C) 2013 Free Software Foundation, Inc.\nLicense GPLv3+: GNU GPL version 3 or
later <http://gnu.org/licenses/gpl.html>\nThis is free software: you are free to change and redistribute it.\nThere is NO WARRANTY, to t'
gnupg: DEBUG: ['gpg', '--status-fd', '2', '--no-tty', '--no-default-keyring', '--keyring', '/tmp/tmpVUBWBf/pubring.gpg', '--secret-keyring', '/tmp/tmpVUBWBf/secring.gpg', '--use-agent', '--version']
gnupg: DEBUG: stderr reader: <Thread(Thread-17, initial daemon)>
gnupg: DEBUG: stdout reader: <Thread(Thread-18, initial daemon)>
gnupg: DEBUG: chunk: 'gpg (GnuPG) 2.0.25\nlibgcrypt 1.6.1\nCopyright (C) 2013 Free Software Foundation, Inc.\nLicense GPLv3+: GNU GPL version 3 or
later <http://gnu.org/licenses/gpl.html>\nThis is free software: you are free to change and redistribute it.\nThere is NO WARRANTY, to t'
gnupg: DEBUG: ['gpg', '--status-fd', '2', '--no-tty', '--no-default-keyring', '--keyring', '/tmp/tmpVUBWBf/pubring.gpg', '--secret-keyring', '/tmp/tmpVUBWBf/secring.gpg', '--use-agent', '--list-keys', '--fixed-list-mode', '--fingerprint', '--with-colons']
gnupg: DEBUG: stderr reader: <Thread(Thread-19, initial daemon)>
gnupg: DEBUG: stdout reader: <Thread(Thread-20, initial daemon)>
gnupg: DEBUG: chunk: 'tru::1:1390361972:1433621434:3:1:5\npub:-:1024:1:B681DDA50449DF12:1398408805:::-:::scESC:\nfpr:::::::::DF3170716F70D416047C66EAB681DDA50449DF12:\nuid:-::::1398408805::80289503611B3766D0A7A9E0625DA84E3C9E12F3::ansible-vault (test key) <example@example.org>:\nsu'
gnupg: DEBUG: line: u'tru::1:1390361972:1433621434:3:1:5'
gnupg: DEBUG: line: u'pub:-:1024:1:B681DDA50449DF12:1398408805:::-:::scESC:'
gnupg: DEBUG: line: u'fpr:::::::::DF3170716F70D416047C66EAB681DDA50449DF12:'
gnupg: DEBUG: line: u'uid:-::::1398408805::80289503611B3766D0A7A9E0625DA84E3C9E12F3::ansible-vault (test key) <example@example.org>:'
gnupg: DEBUG: line: u'sub:-:1024:1:D0FD30525A761314:1398408805::::::e:'gnupg: DEBUG: line: u'pub:-:1024:1:59E29486659C181E:1398435167:::-:::scESC:'
gnupg: DEBUG: line: u'fpr:::::::::36B88E2C6C260C49C66761CA59E29486659C181E:'
gnupg: DEBUG: line: u'uid:-::::1398435167::168C54F3F1926708D8A0C776B8B168E9D308E096::ansible-vault (test untrusted key) <example@example.org>:'
gnupg: DEBUG: line: u'sub:-:1024:1:B51A4FC627621D51:1398435167::::::e:'gnupg: DEBUG: ['gpg', '--status-fd', '2', '--no-tty', '--no-default-keyring', '--keyring', '/tmp/tmpVUBWBf/pubring.gpg', '--secret-keyring', '/tmp/tmpVUBWBf/secring.gpg', '--use-agent', '--encrypt', '--recipient', u'B681DDA50449DF12', '--armor', '--always-trust']
gnupg: DEBUG: data copier: <Thread(Thread-21, initial daemon)>, <_io.BytesIO object at 0x7f2f61a89ad0>, <open file '<fdopen>', mode 'wb' at 0x7f2f61af4e40>
gnupg: DEBUG: sending chunk (137): "The world is moving so fast these days that the man who says it can't be done is\ngenerally interrupted by someone doing it.\n-- E. Hubbard"
gnupg: DEBUG: stderr reader: <Thread(Thread-22, initial daemon)>
gnupg: DEBUG: stdout reader: <Thread(Thread-23, initial daemon)>
gnupg: DEBUG: closed output, 137 bytes sent
gnupg: DEBUG: [GNUPG:] PROGRESS need_entropy X 8 16
gnupg: DEBUG: chunk: '-----BEGIN PGP MESSAGE-----\nVersion: GnuPG v2\n\nhIwD0P0wUlp2ExQBA/4udVqxcnoXBEDTeK7klFUfATWs+1M64GtbPp1uCiA86EeP\nVU3NX5HIbSCGnSmTeSwklgKeVKlfiLkN7rLMKPhurMaooLKh3SX1PNFKe96ogFxP\nlga+2GpThEuxYpWDAY9df2K168JNVifNjWqoKqLhI1k9LKpWcpfTZXiSWDjn4NKu\nAQmPmJbW2DSN7Z'
gnupg: DEBUG: [GNUPG:] PROGRESS need_entropy X 16 16
gnupg: DEBUG: [GNUPG:] BEGIN_ENCRYPTION 2 9
gnupg: DEBUG: [GNUPG:] END_ENCRYPTION
gnupg: DEBUG: encrypt result: '-----BEGIN PGP MESSAGE-----\nVersion: GnuPG v2\n\nhIwD0P0wUlp2ExQBA/4udVqxcnoXBEDTeK7klFUfATWs+1M64GtbPp1uCiA86EeP\nVU3NX5HIbSCGnSmTeSwklgKeVKlfiLkN7rLMKPhurMaooLKh3SX1PNFKe96ogFxP\nlga+2GpThEuxYpWDAY9df2K168JNVifNjWqoKqLhI1k9LKpWcpfTZXiSWDjn4NKu\nAQmPmJbW2DSN7ZIgJl+086UvmgIo+cDWGHtullkUEUqCIdvMujFV3EMIe3NUzyYh\nIdg79RbHPOW2sQW62NYY0LMourEA1ImObDgVU5dZlVaI69jlI2KHWalqJ+VoRgmd\n2/NKGElk9eqRBlRvkj12WXaru7ptZYpSAV1vjpx+JKy15z3i3/i1367iK33IPrSa\ntLCuAe+AK772LxI4p2VkrNL87cH6hb31h9Mx2nug\n=yB3P\n-----END PGP MESSAGE-----\n'
gnupg: DEBUG: ['gpg', '--status-fd', '2', '--no-tty', '--no-default-keyring', '--keyring', '/tmp/tmpVUBWBf/pubring.gpg', '--secret-keyring', '/tmp/tmpVUBWBf/secring.gpg', '--use-agent', '--version']
gnupg: DEBUG: stderr reader: <Thread(Thread-24, initial daemon)>
gnupg: DEBUG: stdout reader: <Thread(Thread-25, initial daemon)>
gnupg: DEBUG: chunk: 'gpg (GnuPG) 2.0.25\nlibgcrypt 1.6.1\nCopyright (C) 2013 Free Software Foundation, Inc.\nLicense GPLv3+: GNU GPL version 3 or
later <http://gnu.org/licenses/gpl.html>\nThis is free software: you are free to change and redistribute it.\nThere is NO WARRANTY, to t'
gnupg: DEBUG: ['gpg', '--status-fd', '2', '--no-tty', '--no-default-keyring', '--keyring', '/tmp/tmpVUBWBf/pubring.gpg', '--secret-keyring', '/tmp/tmpVUBWBf/secring.gpg', '--batch', '--passphrase-fd', '0', '--use-agent', '--decrypt', '--always-trust']
gnupg: DEBUG: Wrote passphrase
gnupg: DEBUG: data copier: <Thread(Thread-26, initial daemon)>, <_io.BytesIO object at 0x7f2f61a89ad0>, <open file '<fdopen>', mode 'wb' at 0x7f2f61af4e40>
gnupg: DEBUG: sending chunk (517): '-----BEGIN PGP MESSAGE-----\nVersion: GnuPG v2\n\nhIwD0P0wUlp2ExQBA/4udVqxcnoXBEDTe\nK7klFUfATWs+1M64GtbPp1uCiA86EeP\nVU3NX5HIbSCGnSmTeSwklgKeVKlfiLkN7rLMKPhurMaooLKh\n3SX1PNFKe96ogFxP\nlga+2GpThEuxYpWDAY9df2K168JNVifNjWqoKqLhI1k9LKpWcpfTZXiSWDjn4NK\nu\nAQmPmJbW2DS'
gnupg: DEBUG: stderr reader: <Thread(Thread-27, initial daemon)>
gnupg: DEBUG: closed output, 517 bytes sent
gnupg: DEBUG: stdout reader: <Thread(Thread-28, initial daemon)>
gnupg: DEBUG: gpg: malformed CRC
gnupg: DEBUG: decrypt result: ''
--------------------- >> end captured logging << ---------------------

----------------------------------------------------------------------
@tyll

This comment has been minimized.

Show comment
Hide comment
@tyll

tyll Aug 1, 2014

Contributor

IMHO the GPG recipients should be managed inside the vault file and not in a separate config file, since for example different hosts might have different admins and therefore the respective vault files need to be encrypted to different keys. When doing this, the key ids need to be stored in the area that is protected by the encryption.

Contributor

tyll commented Aug 1, 2014

IMHO the GPG recipients should be managed inside the vault file and not in a separate config file, since for example different hosts might have different admins and therefore the respective vault files need to be encrypted to different keys. When doing this, the key ids need to be stored in the area that is protected by the encryption.

@Kahn

This comment has been minimized.

Show comment
Hide comment
@Kahn

Kahn Aug 2, 2014

@tyll Totally agree. The initial focus was on feature parity hence the choice to reuse the config file mechanism. I will however work on additional patches to include support for per file recipients. I would like to clarify what behavior your expecting though:

  1. Default recipients still live in ansible.cfg
  2. Per file recipients get appended to the existing key ID list?

I also imagine possibly a switch like --no-default-keys to EXCLUDE the default keys and encrypt only to a limited user group.

If you could share what you had in mind would be great!

Sam.

Kahn commented Aug 2, 2014

@tyll Totally agree. The initial focus was on feature parity hence the choice to reuse the config file mechanism. I will however work on additional patches to include support for per file recipients. I would like to clarify what behavior your expecting though:

  1. Default recipients still live in ansible.cfg
  2. Per file recipients get appended to the existing key ID list?

I also imagine possibly a switch like --no-default-keys to EXCLUDE the default keys and encrypt only to a limited user group.

If you could share what you had in mind would be great!

Sam.

@jirutka

This comment has been minimized.

Show comment
Hide comment
@jirutka

jirutka Apr 5, 2015

Contributor

@jimi-c Why the heck this still isn’t merged?! I’m using it almost one year and it works great. It’s really shame that I still must use my fork of Ansible witch these patches.

Contributor

jirutka commented Apr 5, 2015

@jimi-c Why the heck this still isn’t merged?! I’m using it almost one year and it works great. It’s really shame that I still must use my fork of Ansible witch these patches.

@Kahn

This comment has been minimized.

Show comment
Hide comment
@Kahn

Kahn Apr 6, 2015

@jirutka funny you mention this just now. I have recently decided to write the PR against the current HEAD so we can get back to auto merge. Hopefully this time we might make it into mainline.

Do you have any feedback after your year of testing? Are you using the bash workaround to unlock your agent or are you using a prompt every time?

Kahn commented Apr 6, 2015

@jirutka funny you mention this just now. I have recently decided to write the PR against the current HEAD so we can get back to auto merge. Hopefully this time we might make it into mainline.

Do you have any feedback after your year of testing? Are you using the bash workaround to unlock your agent or are you using a prompt every time?

@jirutka

This comment has been minimized.

Show comment
Hide comment
@jirutka

jirutka Apr 9, 2015

Contributor

@Kahn I’m using OS X with GPG Suite and it works without any problem, no bash workaround needed. GPG agent reads the key’s passphrase from the system’s Keychain, so I don’t have to type it at all (just the Keychain’s password when it’s locked).

Contributor

jirutka commented Apr 9, 2015

@Kahn I’m using OS X with GPG Suite and it works without any problem, no bash workaround needed. GPG agent reads the key’s passphrase from the system’s Keychain, so I don’t have to type it at all (just the Keychain’s password when it’s locked).

@bcoca

This comment has been minimized.

Show comment
Hide comment
@bcoca

bcoca Apr 9, 2015

Member

so before I start reviewing this can we get it rebased?

Member

bcoca commented Apr 9, 2015

so before I start reviewing this can we get it rebased?

@Kahn

This comment has been minimized.

Show comment
Hide comment
@Kahn

Kahn Apr 9, 2015

@bcoca Absolutely, as discussed on IRC I'll rebase against v2 and resubmit.

Kahn commented Apr 9, 2015

@bcoca Absolutely, as discussed on IRC I'll rebase against v2 and resubmit.

Kahn added some commits Apr 21, 2015

Fixed issue where GPG mode would not check for untrusted keys
Fixed issue where VaultLib would mangle encrypted file content with extra new lines

Added sanity checks for at least one keypair before trying to encrypt
Added extra error logging for error conditions
Added GPG return status for encryption failures (useful for key expired issues albiet cryptic)
Added support for python-gnupg 2.x, new library is better supported upstream and handles deadlocking better
Added a new directive "gpg_pass_marginal" to config to handle marginal signatures better
Added error condition to handle python-gnupg library change

Removed support for python-gnupg 0.x

Merge branch 'devel' into ansible-vault-gpg

Conflicts:
	bin/ansible-vault
	lib/ansible/utils/__init__.py
	packaging/rpm/ansible.spec
@Kahn

This comment has been minimized.

Show comment
Hide comment
@Kahn

Kahn Apr 21, 2015

Investigating failing CI tomorrow

Kahn commented Apr 21, 2015

Investigating failing CI tomorrow

@Kahn

This comment has been minimized.

Show comment
Hide comment
@Kahn

Kahn Apr 22, 2015

@bcoca This PR should be ok to pull from 9e3a51f. The remaining two changes are just failing travis config anyway. Since travis has not passed I have added the outputs from both my OSX and Ubuntu test hosts. Let me know if we need to get Travis green.

Ubuntu

swilson@ubuntu:~/ansible$ make tests
PYTHONPATH=./lib nosetests -d -w test/units -v --with-coverage --cover-package=ansible --cover-branches
nose.plugins.cover: ERROR: Coverage not available: unable to import coverage module
test_configfile_and_env_both_set (TestConstants.TestConstants) ... ok
test_configfile_not_set_env_not_set (TestConstants.TestConstants) ... ok
test_configfile_not_set_env_set (TestConstants.TestConstants) ... ok
test_configfile_set_env_not_set (TestConstants.TestConstants) ... ok
test_bool_no (TestFilters.TestFilters) ... ok
test_bool_none (TestFilters.TestFilters) ... ok
test_bool_true (TestFilters.TestFilters) ... ok
test_bool_yes (TestFilters.TestFilters) ... ok
test_fileglob (TestFilters.TestFilters) ... ok
test_match_case_insensitive (TestFilters.TestFilters) ... ok
test_match_case_sensitive (TestFilters.TestFilters) ... ok
test_match_no_match (TestFilters.TestFilters) ... ok
test_max (TestFilters.TestFilters) ... ok
test_min (TestFilters.TestFilters) ... ok
test_quotes (TestFilters.TestFilters) ... ok
test_regex (TestFilters.TestFilters) ... ok
test_regex_replace_case_insensitive (TestFilters.TestFilters) ... ok
test_regex_replace_case_sensitive (TestFilters.TestFilters) ... ok
test_regex_replace_no_match (TestFilters.TestFilters) ... ok
test_search_case_insensitive (TestFilters.TestFilters) ... ok
test_search_case_sensitive (TestFilters.TestFilters) ... ok
test_to_uuid (TestFilters.TestFilters) ... ok
test_version_compare (TestFilters.TestFilters) ... ok
test_allows_equals_sign_in_var (TestInventory.TestInventory) ... ok
test_alpha_end_before_beg (TestInventory.TestInventory) ... ok
test_combined_range (TestInventory.TestInventory) ... ok
test_complex_enumeration (TestInventory.TestInventory) ... ok
test_complex_exclude (TestInventory.TestInventory) ... ok
test_complex_group_names (TestInventory.TestInventory) ... ok
test_complex_intersect (TestInventory.TestInventory) ... ok
test_complex_vars (TestInventory.TestInventory) ... ok
test_dir_inventory (TestInventory.TestInventory) ... ok
test_dir_inventory_group_hosts (TestInventory.TestInventory) ... ok
test_dir_inventory_groups_for_host (TestInventory.TestInventory) ... ok
test_dir_inventory_groups_list (TestInventory.TestInventory) ... ok
test_dir_inventory_multiple_groups (TestInventory.TestInventory) ... ok
test_dir_inventory_skip_extension (TestInventory.TestInventory) ... ok
test_empty (TestInventory.TestInventory) ... ok
test_get_hosts (TestInventory.TestInventory) ... ok
test_hosts_list (TestInventory.TestInventory) ... ok
test_incorrect_format (TestInventory.TestInventory) ... ok
test_invalid_range (TestInventory.TestInventory) ... ok
test_large_range (TestInventory.TestInventory) ... ok
test_leading_range (TestInventory.TestInventory) ... ok
test_missing_end (TestInventory.TestInventory) ... ok
test_no_src (TestInventory.TestInventory) ... ok
test_regex_exclude (TestInventory.TestInventory) ... ok
test_regex_grouping (TestInventory.TestInventory) ... ok
test_script (TestInventory.TestInventory) ... ok
test_script_all (TestInventory.TestInventory) ... ok
test_script_combined (TestInventory.TestInventory) ... ok
test_script_multiple_groups (TestInventory.TestInventory) ... ok
test_script_norse (TestInventory.TestInventory) ... ok
test_script_restrict (TestInventory.TestInventory) ... ok
test_script_vars (TestInventory.TestInventory) ... ok
test_simple (TestInventory.TestInventory) ... ok
test_simple_all (TestInventory.TestInventory) ... ok
test_simple_combined (TestInventory.TestInventory) ... ok
test_simple_norse (TestInventory.TestInventory) ... ok
test_simple_port (TestInventory.TestInventory) ... ok
test_simple_restrict (TestInventory.TestInventory) ... ok
test_simple_string_fqdn (TestInventory.TestInventory) ... ok
test_simple_string_fqdn_port (TestInventory.TestInventory) ... ok
test_simple_string_fqdn_vars (TestInventory.TestInventory) ... ok
test_simple_string_ipv4 (TestInventory.TestInventory) ... ok
test_simple_string_ipv4_port (TestInventory.TestInventory) ... ok
test_simple_string_ipv4_vars (TestInventory.TestInventory) ... ok
test_simple_string_ipv6 (TestInventory.TestInventory) ... ok
test_simple_string_ipv6_port (TestInventory.TestInventory) ... ok
test_simple_string_ipv6_vars (TestInventory.TestInventory) ... ok
test_simple_ungrouped (TestInventory.TestInventory) ... ok
test_simple_vars (TestInventory.TestInventory) ... ok
test_subet_range_empty_group (TestInventory.TestInventory) ... ok
test_subset (TestInventory.TestInventory) ... ok
test_subset_filename (TestInventory.TestInventory) ... ok
test_subset_range (TestInventory.TestInventory) ... ok
testinvalid_entry (TestInventory.TestInventory) ... ok
test_run_command_args (TestModuleUtilsBasic.TestModuleUtilsBasic) ... ok
test_run_command_args_with_env_variables (TestModuleUtilsBasic.TestModuleUtilsBasic) ... ok
test_run_command_string (TestModuleUtilsBasic.TestModuleUtilsBasic) ... ok
test_run_command_string_unsafe_with_double_redirect_out (TestModuleUtilsBasic.TestModuleUtilsBasic) ... ok
test_run_command_string_unsafe_with_env_variables (TestModuleUtilsBasic.TestModuleUtilsBasic) ... ok
test_run_command_string_unsafe_with_pipe (TestModuleUtilsBasic.TestModuleUtilsBasic) ... ok
test_run_command_string_unsafe_with_redirect_in (TestModuleUtilsBasic.TestModuleUtilsBasic) ... ok
test_run_command_string_unsafe_with_redirect_out (TestModuleUtilsBasic.TestModuleUtilsBasic) ... ok
test_run_command_string_with_binary_data (TestModuleUtilsBasic.TestModuleUtilsBasic) ... ok
test_run_command_string_with_cwd (TestModuleUtilsBasic.TestModuleUtilsBasic) ... ok
test_run_command_string_with_data (TestModuleUtilsBasic.TestModuleUtilsBasic) ... ok
test_run_command_string_with_env_variables (TestModuleUtilsBasic.TestModuleUtilsBasic) ... ok
test_log_sanitize_correctness (TestModuleUtilsBasic.TestModuleUtilsBasicHelpers) ... ok
test_log_sanitize_speed_many_ssh (TestModuleUtilsBasic.TestModuleUtilsBasicHelpers) ... ok
test_log_sanitize_speed_many_url (TestModuleUtilsBasic.TestModuleUtilsBasicHelpers) ... ok
test_log_sanitize_speed_one_ssh (TestModuleUtilsBasic.TestModuleUtilsBasicHelpers) ... ok
test_log_sanitize_speed_one_url (TestModuleUtilsBasic.TestModuleUtilsBasicHelpers) ... ok
test_log_sanitize_speed_zero_secrets (TestModuleUtilsBasic.TestModuleUtilsBasicHelpers) ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_how_many_dots ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_invalid_quotes('"table "invalid" double quote"', 'table', 'User escaped identifiers must escape extra quotes') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_invalid_quotes('"test"."too"."many"."dots"', 'schema', 'PostgreSQL does not support schema with more than 2 dots') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_invalid_quotes('test.too."many.dots"', 'database', 'PostgreSQL does not support database with more than 1 dots') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_invalid_quotes('"test"."too"."many"."dots"', 'database', 'PostgreSQL does not support database with more than 1 dots') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_invalid_quotes('test.too.many.dots', 'table', 'PostgreSQL does not support table with more than 3 dots') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_invalid_quotes('"schema "invalid"""."table "invalid"', 'table', 'User escaped identifiers must escape extra quotes') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_invalid_quotes('"schema".', 'table', 'Identifier name unspecified or unquoted trailing dot') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_invalid_quotes('"test"."too"."many"."dots"."for"."column"', 'column', 'PostgreSQL does not support column with more than 4 dots') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_invalid_quotes('"schema."table"', 'table', 'User escaped identifiers must escape extra quotes') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_invalid_quotes('"test.too".many.dots', 'database', 'PostgreSQL does not support database with more than 1 dots') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_invalid_quotes('"test"."too"."many"."dots"', 'table', 'PostgreSQL does not support table with more than 3 dots') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_valid_quotes('."table"', '".""table"""') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_valid_quotes('"schema.".".table"', '"schema.".".table"') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_valid_quotes('public.table', '"public"."table"') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_valid_quotes('"schema.test"."table.test"', '"schema.test"."table.test"') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_valid_quotes('"schema."."table"', '"schema."."table"') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_valid_quotes('"schema.".table', '"schema."."table"') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_valid_quotes('public."table ""test"""', '"public"."table ""test"""') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_valid_quotes('schema.".table"', '"schema".".table"') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_valid_quotes('"no end quote', '"""no end quote"') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_valid_quotes('"schema test".table test', '"schema test"."table test"') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_valid_quotes('public.table "test"', '"public"."table ""test"""') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_valid_quotes('"schema test"."table test"', '"schema test"."table test"') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_valid_quotes('"schema.table', '"""schema"."table"') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_valid_quotes('"schema".".table"', '"schema".".table"') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_valid_quotes('public."table"', '"public"."table"') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_valid_quotes('schema test.table test', '"schema test"."table test"') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_valid_quotes('table "test"', '"table ""test"""') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_valid_quotes('schema "test".table', '"schema ""test"""."table"') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_valid_quotes('"public.table"', '"public.table"') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_valid_quotes('"""wat"""."""test"""', '"""wat"""."""test"""') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_valid_quotes('"schema ""test""".table', '"schema ""test"""."table"') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_valid_quotes('"public".table', '"public"."table"') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_valid_quotes('schema."table', '"schema"."""table"') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_valid_quotes('schema test."table test"', '"schema test"."table test"') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_valid_quotes('table.', '"table."') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_valid_quotes('schema."table.something', '"schema"."""table"."something"') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_valid_quotes('"public"."table"', '"public"."table"') ... ok
test_ast_parse (TestModules.TestModules) ... ok
test_multiple_vars_files (TestPlayVarsFiles.TestMe) ... ok
test_play_constructor (TestPlayVarsFiles.TestMe) ... ok
test_vars_file (TestPlayVarsFiles.TestMe) ... ok
test_vars_file_nonlist_error (TestPlayVarsFiles.TestMe) ... ok
test_vars_files_assert_all_found (TestPlayVarsFiles.TestMe) ... ok
test_vars_files_first_found (TestPlayVarsFiles.TestMe) ... ok
test_vars_files_for_host (TestPlayVarsFiles.TestMe) ... ok
test_vars_files_multiple_found (TestPlayVarsFiles.TestMe) ... ok
test_vars_files_two_vars_different_scope (TestPlayVarsFiles.TestMe) ... ok
test_vars_files_two_vars_different_scope_first_found (TestPlayVarsFiles.TestMe) ... ok
test_vars_files_two_vars_in_name (TestPlayVarsFiles.TestMe) ... ok
verify the synchronize action plugin sets ... ok
verify the synchronize action plugin sets ... ok
verify the synchronize action plugin unsets and then sets sudo ... ok
Verify the action plugin accommodates the common ... ok
test__gitinfo (TestUtils.TestUtils) ... ok
test_base_parser (TestUtils.TestUtils) ... ok
see if we can detect the part of a string before a comment.  Used by INI parser in inventory ... ok
test_boolean (TestUtils.TestUtils) ... ok
used by the no_log attribute ... ok
test_check_conditional_jinja2_expression (TestUtils.TestUtils) ... ok
test_check_conditional_jinja2_expression_in_variable (TestUtils.TestUtils) ... ok
test_check_conditional_jinja2_literals (TestUtils.TestUtils) ... ok
test_check_conditional_jinja2_unicode (TestUtils.TestUtils) ... ok
test_check_conditional_jinja2_variable_literals (TestUtils.TestUtils) ... ok
test_checksum (TestUtils.TestUtils) ... ok
test_checksum_s (TestUtils.TestUtils) ... ok
test_clean_data (TestUtils.TestUtils) ... ok
test_combine_vars (TestUtils.TestUtils) ... ok
test_contains_vars (TestUtils.TestUtils) ... ok
test_default (TestUtils.TestUtils) ... ok
test_deprecated (TestUtils.TestUtils) ... ok
test_do_encrypt (TestUtils.TestUtils) ... ok
test_do_encrypt_md5 (TestUtils.TestUtils) ... ok
test_err (TestUtils.TestUtils) ... ok
test_exit (TestUtils.TestUtils) ... ok
test_filter_leading_non_json_lines (TestUtils.TestUtils) ... ok
test_find_plugin (TestUtils.TestUtils) ... ok
test_get_diff (TestUtils.TestUtils) ... ok
test_getch (TestUtils.TestUtils) ... ok
test_increment_debug (TestUtils.TestUtils) ... ok
test_is_changed (TestUtils.TestUtils) ... ok
test_is_executable (TestUtils.TestUtils) ... ok
test_is_failed (TestUtils.TestUtils) ... ok
test_is_list_of_strings (TestUtils.TestUtils) ... ok
test_json_loads (TestUtils.TestUtils) ... ok
test_jsonify (TestUtils.TestUtils) ... ok
test_last_non_blank_line (TestUtils.TestUtils) ... ok
test_listify_lookup_plugin_terms (TestUtils.TestUtils) ... ok
test_make_su_cmd (TestUtils.TestUtils) ... ok
test_make_sudo_cmd (TestUtils.TestUtils) ... ok
test_md5 (TestUtils.TestUtils) ... ok
test_md5s (TestUtils.TestUtils) ... ok
test_merge_hash (TestUtils.TestUtils) ... ok
test_parse_json (TestUtils.TestUtils) ... ok
test_parse_kv_basic (TestUtils.TestUtils) ... ok
test_parse_yaml (TestUtils.TestUtils) ... ok
test_parse_yaml_from_file (TestUtils.TestUtils) ... ok
test_path_dwim (TestUtils.TestUtils) ... ok
test_path_dwim_relative (TestUtils.TestUtils) ... ok
test_process_common_errors (TestUtils.TestUtils) ... ok
test_process_yaml_error (TestUtils.TestUtils) ... ok
test_repo_url_to_role_name (TestUtils.TestUtils) ... ok
test_role_spec_parse (TestUtils.TestUtils) ... ok
test_role_yaml_parse (TestUtils.TestUtils) ... ok
test_safe_eval (TestUtils.TestUtils) ... ok
test_sanitize_output (TestUtils.TestUtils) ... ok
test_split_args (TestUtils.TestUtils) ... ok
test_to_unicode (TestUtils.TestUtils) ... ok
test_unfrackpath (TestUtils.TestUtils) ... ok
test_version (TestUtils.TestUtils) ... ok
test_warning (TestUtils.TestUtils) ... ok
test_count_newlines_from_end (TestUtilsStringFunctions.TestUtilsStringFunctions) ... ok
test_isprintable (TestUtilsStringFunctions.TestUtilsStringFunctions) ... ok
test_add_header (TestVault.TestVaultLib) ... ok
test_cipher_not_set (TestVault.TestVaultLib) ... ok
test_decrypt_decrypted (TestVault.TestVaultLib) ... ok
test_encrypt_decrypt_aes (TestVault.TestVaultLib) ... ok
test_encrypt_decrypt_aes256 (TestVault.TestVaultLib) ... ok
test_encrypt_encrypted (TestVault.TestVaultLib) ... ok
test_is_encrypted (TestVault.TestVaultLib) ... ok
test_methods_exist (TestVault.TestVaultLib) ... ok
test_split_header (TestVault.TestVaultLib) ... ok
test_decrypt_1_0 (TestVaultEditor.TestVaultEditor) ... ok
test_decrypt_1_1 (TestVaultEditor.TestVaultEditor) ... ok
test_decrypt_1_1_newline (TestVaultEditor.TestVaultEditor) ... ok
test_methods_exist (TestVaultEditor.TestVaultEditor) ... ok
test_rekey_migration (TestVaultEditor.TestVaultEditor) ... ok
test_encrypt_decrypt_gpg (TestVaultGPG.TestVaultGPG) ... ok
test_key_trust (TestVaultGPG.TestVaultGPG) ... ok
test_keys_available (TestVaultGPG.TestVaultGPG) ... ok
test_methods_exist (TestVaultGPG.TestVaultGPG) ... ok
test_pkgname_expands (TestApt.AptExpandPkgspecTestCase) ... ok
test_pkgname_wildcard_version_wildcard (TestApt.AptExpandPkgspecTestCase) ... ok
test_trivial (TestApt.AptExpandPkgspecTestCase) ... ok
test_version_wildcard (TestApt.AptExpandPkgspecTestCase) ... ok
test_trivial (TestDocker.DockerSplitImageTagTestCase) ... ok
test_with_org_name (TestDocker.DockerSplitImageTagTestCase) ... ok
test_with_tag (TestDocker.DockerSplitImageTagTestCase) ... ok
test_with_tag_and_org_name (TestDocker.DockerSplitImageTagTestCase) ... ok

----------------------------------------------------------------------
Ran 235 tests in 8.017s

OK

OSX

swilson:ansible swilson$ make tests
PYTHONPATH=./lib nosetests -d -w test/units -v --with-coverage --cover-package=ansible --cover-branches
nose.plugins.cover: ERROR: Coverage not available: unable to import coverage module
test_configfile_and_env_both_set (TestConstants.TestConstants) ... ok
test_configfile_not_set_env_not_set (TestConstants.TestConstants) ... ok
test_configfile_not_set_env_set (TestConstants.TestConstants) ... ok
test_configfile_set_env_not_set (TestConstants.TestConstants) ... ok
test_bool_no (TestFilters.TestFilters) ... ok
test_bool_none (TestFilters.TestFilters) ... ok
test_bool_true (TestFilters.TestFilters) ... ok
test_bool_yes (TestFilters.TestFilters) ... ok
test_fileglob (TestFilters.TestFilters) ... ok
test_match_case_insensitive (TestFilters.TestFilters) ... ok
test_match_case_sensitive (TestFilters.TestFilters) ... ok
test_match_no_match (TestFilters.TestFilters) ... ok
test_max (TestFilters.TestFilters) ... ok
test_min (TestFilters.TestFilters) ... ok
test_quotes (TestFilters.TestFilters) ... ok
test_regex (TestFilters.TestFilters) ... ok
test_regex_replace_case_insensitive (TestFilters.TestFilters) ... ok
test_regex_replace_case_sensitive (TestFilters.TestFilters) ... ok
test_regex_replace_no_match (TestFilters.TestFilters) ... ok
test_search_case_insensitive (TestFilters.TestFilters) ... ok
test_search_case_sensitive (TestFilters.TestFilters) ... ok
test_to_uuid (TestFilters.TestFilters) ... ok
test_version_compare (TestFilters.TestFilters) ... ok
test_allows_equals_sign_in_var (TestInventory.TestInventory) ... ok
test_alpha_end_before_beg (TestInventory.TestInventory) ... ok
test_combined_range (TestInventory.TestInventory) ... ok
test_complex_enumeration (TestInventory.TestInventory) ... ok
test_complex_exclude (TestInventory.TestInventory) ... ok
test_complex_group_names (TestInventory.TestInventory) ... ok
test_complex_intersect (TestInventory.TestInventory) ... ok
test_complex_vars (TestInventory.TestInventory) ... ok
test_dir_inventory (TestInventory.TestInventory) ... ok
test_dir_inventory_group_hosts (TestInventory.TestInventory) ... ok
test_dir_inventory_groups_for_host (TestInventory.TestInventory) ... ok
test_dir_inventory_groups_list (TestInventory.TestInventory) ... ok
test_dir_inventory_multiple_groups (TestInventory.TestInventory) ... ok
test_dir_inventory_skip_extension (TestInventory.TestInventory) ... ok
test_empty (TestInventory.TestInventory) ... ok
test_get_hosts (TestInventory.TestInventory) ... ok
test_hosts_list (TestInventory.TestInventory) ... ok
test_incorrect_format (TestInventory.TestInventory) ... ok
test_invalid_range (TestInventory.TestInventory) ... ok
test_large_range (TestInventory.TestInventory) ... ok
test_leading_range (TestInventory.TestInventory) ... ok
test_missing_end (TestInventory.TestInventory) ... ok
test_no_src (TestInventory.TestInventory) ... ok
test_regex_exclude (TestInventory.TestInventory) ... ok
test_regex_grouping (TestInventory.TestInventory) ... ok
test_script (TestInventory.TestInventory) ... ok
test_script_all (TestInventory.TestInventory) ... ok
test_script_combined (TestInventory.TestInventory) ... ok
test_script_multiple_groups (TestInventory.TestInventory) ... ok
test_script_norse (TestInventory.TestInventory) ... ok
test_script_restrict (TestInventory.TestInventory) ... ok
test_script_vars (TestInventory.TestInventory) ... ok
test_simple (TestInventory.TestInventory) ... ok
test_simple_all (TestInventory.TestInventory) ... ok
test_simple_combined (TestInventory.TestInventory) ... ok
test_simple_norse (TestInventory.TestInventory) ... ok
test_simple_port (TestInventory.TestInventory) ... ok
test_simple_restrict (TestInventory.TestInventory) ... ok
test_simple_string_fqdn (TestInventory.TestInventory) ... ok
test_simple_string_fqdn_port (TestInventory.TestInventory) ... ok
test_simple_string_fqdn_vars (TestInventory.TestInventory) ... ok
test_simple_string_ipv4 (TestInventory.TestInventory) ... ok
test_simple_string_ipv4_port (TestInventory.TestInventory) ... ok
test_simple_string_ipv4_vars (TestInventory.TestInventory) ... ok
test_simple_string_ipv6 (TestInventory.TestInventory) ... ok
test_simple_string_ipv6_port (TestInventory.TestInventory) ... ok
test_simple_string_ipv6_vars (TestInventory.TestInventory) ... ok
test_simple_ungrouped (TestInventory.TestInventory) ... ok
test_simple_vars (TestInventory.TestInventory) ... ok
test_subet_range_empty_group (TestInventory.TestInventory) ... ok
test_subset (TestInventory.TestInventory) ... ok
test_subset_filename (TestInventory.TestInventory) ... ok
test_subset_range (TestInventory.TestInventory) ... ok
testinvalid_entry (TestInventory.TestInventory) ... ok
test_run_command_args (TestModuleUtilsBasic.TestModuleUtilsBasic) ... ok
test_run_command_args_with_env_variables (TestModuleUtilsBasic.TestModuleUtilsBasic) ... ok
test_run_command_string (TestModuleUtilsBasic.TestModuleUtilsBasic) ... ok
test_run_command_string_unsafe_with_double_redirect_out (TestModuleUtilsBasic.TestModuleUtilsBasic) ... ok
test_run_command_string_unsafe_with_env_variables (TestModuleUtilsBasic.TestModuleUtilsBasic) ... ok
test_run_command_string_unsafe_with_pipe (TestModuleUtilsBasic.TestModuleUtilsBasic) ... ok
test_run_command_string_unsafe_with_redirect_in (TestModuleUtilsBasic.TestModuleUtilsBasic) ... ok
test_run_command_string_unsafe_with_redirect_out (TestModuleUtilsBasic.TestModuleUtilsBasic) ... ok
test_run_command_string_with_binary_data (TestModuleUtilsBasic.TestModuleUtilsBasic) ... ok
test_run_command_string_with_cwd (TestModuleUtilsBasic.TestModuleUtilsBasic) ... ok
test_run_command_string_with_data (TestModuleUtilsBasic.TestModuleUtilsBasic) ... ok
test_run_command_string_with_env_variables (TestModuleUtilsBasic.TestModuleUtilsBasic) ... ok
test_log_sanitize_correctness (TestModuleUtilsBasic.TestModuleUtilsBasicHelpers) ... ok
test_log_sanitize_speed_many_ssh (TestModuleUtilsBasic.TestModuleUtilsBasicHelpers) ... ok
test_log_sanitize_speed_many_url (TestModuleUtilsBasic.TestModuleUtilsBasicHelpers) ... ok
test_log_sanitize_speed_one_ssh (TestModuleUtilsBasic.TestModuleUtilsBasicHelpers) ... ok
test_log_sanitize_speed_one_url (TestModuleUtilsBasic.TestModuleUtilsBasicHelpers) ... ok
test_log_sanitize_speed_zero_secrets (TestModuleUtilsBasic.TestModuleUtilsBasicHelpers) ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_how_many_dots ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_invalid_quotes('"table "invalid" double quote"', 'table', 'User escaped identifiers must escape extra quotes') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_invalid_quotes('"test"."too"."many"."dots"', 'schema', 'PostgreSQL does not support schema with more than 2 dots') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_invalid_quotes('test.too."many.dots"', 'database', 'PostgreSQL does not support database with more than 1 dots') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_invalid_quotes('"test"."too"."many"."dots"', 'database', 'PostgreSQL does not support database with more than 1 dots') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_invalid_quotes('test.too.many.dots', 'table', 'PostgreSQL does not support table with more than 3 dots') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_invalid_quotes('"schema "invalid"""."table "invalid"', 'table', 'User escaped identifiers must escape extra quotes') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_invalid_quotes('"schema".', 'table', 'Identifier name unspecified or unquoted trailing dot') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_invalid_quotes('"test"."too"."many"."dots"."for"."column"', 'column', 'PostgreSQL does not support column with more than 4 dots') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_invalid_quotes('"schema."table"', 'table', 'User escaped identifiers must escape extra quotes') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_invalid_quotes('"test.too".many.dots', 'database', 'PostgreSQL does not support database with more than 1 dots') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_invalid_quotes('"test"."too"."many"."dots"', 'table', 'PostgreSQL does not support table with more than 3 dots') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_valid_quotes('."table"', '".""table"""') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_valid_quotes('"schema.".".table"', '"schema.".".table"') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_valid_quotes('public.table', '"public"."table"') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_valid_quotes('"schema.test"."table.test"', '"schema.test"."table.test"') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_valid_quotes('"schema."."table"', '"schema."."table"') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_valid_quotes('"schema.".table', '"schema."."table"') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_valid_quotes('public."table ""test"""', '"public"."table ""test"""') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_valid_quotes('schema.".table"', '"schema".".table"') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_valid_quotes('"no end quote', '"""no end quote"') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_valid_quotes('"schema test".table test', '"schema test"."table test"') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_valid_quotes('public.table "test"', '"public"."table ""test"""') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_valid_quotes('"schema test"."table test"', '"schema test"."table test"') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_valid_quotes('"schema.table', '"""schema"."table"') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_valid_quotes('"schema".".table"', '"schema".".table"') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_valid_quotes('public."table"', '"public"."table"') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_valid_quotes('schema test.table test', '"schema test"."table test"') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_valid_quotes('table "test"', '"table ""test"""') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_valid_quotes('schema "test".table', '"schema ""test"""."table"') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_valid_quotes('"public.table"', '"public.table"') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_valid_quotes('"""wat"""."""test"""', '"""wat"""."""test"""') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_valid_quotes('"schema ""test""".table', '"schema ""test"""."table"') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_valid_quotes('"public".table', '"public"."table"') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_valid_quotes('schema."table', '"schema"."""table"') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_valid_quotes('schema test."table test"', '"schema test"."table test"') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_valid_quotes('table.', '"table."') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_valid_quotes('schema."table.something', '"schema"."""table"."something"') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_valid_quotes('"public"."table"', '"public"."table"') ... ok
test_ast_parse (TestModules.TestModules) ... ok
test_multiple_vars_files (TestPlayVarsFiles.TestMe) ... ok
test_play_constructor (TestPlayVarsFiles.TestMe) ... ok
test_vars_file (TestPlayVarsFiles.TestMe) ... ok
test_vars_file_nonlist_error (TestPlayVarsFiles.TestMe) ... ok
test_vars_files_assert_all_found (TestPlayVarsFiles.TestMe) ... ok
test_vars_files_first_found (TestPlayVarsFiles.TestMe) ... ok
test_vars_files_for_host (TestPlayVarsFiles.TestMe) ... ok
test_vars_files_multiple_found (TestPlayVarsFiles.TestMe) ... ok
test_vars_files_two_vars_different_scope (TestPlayVarsFiles.TestMe) ... ok
test_vars_files_two_vars_different_scope_first_found (TestPlayVarsFiles.TestMe) ... ok
test_vars_files_two_vars_in_name (TestPlayVarsFiles.TestMe) ... ok
verify the synchronize action plugin sets ... ok
verify the synchronize action plugin sets ... ok
verify the synchronize action plugin unsets and then sets sudo ... ok
Verify the action plugin accommodates the common ... ok
test__gitinfo (TestUtils.TestUtils) ... ok
test_base_parser (TestUtils.TestUtils) ... ok
see if we can detect the part of a string before a comment.  Used by INI parser in inventory ... ok
test_boolean (TestUtils.TestUtils) ... ok
used by the no_log attribute ... ok
test_check_conditional_jinja2_expression (TestUtils.TestUtils) ... ok
test_check_conditional_jinja2_expression_in_variable (TestUtils.TestUtils) ... ok
test_check_conditional_jinja2_literals (TestUtils.TestUtils) ... ok
test_check_conditional_jinja2_unicode (TestUtils.TestUtils) ... ok
test_check_conditional_jinja2_variable_literals (TestUtils.TestUtils) ... ok
test_checksum (TestUtils.TestUtils) ... ok
test_checksum_s (TestUtils.TestUtils) ... ok
test_clean_data (TestUtils.TestUtils) ... ok
test_combine_vars (TestUtils.TestUtils) ... ok
test_contains_vars (TestUtils.TestUtils) ... ok
test_default (TestUtils.TestUtils) ... ok
test_deprecated (TestUtils.TestUtils) ... ok
test_do_encrypt (TestUtils.TestUtils) ... ok
test_do_encrypt_md5 (TestUtils.TestUtils) ... ok
test_err (TestUtils.TestUtils) ... ok
test_exit (TestUtils.TestUtils) ... ok
test_filter_leading_non_json_lines (TestUtils.TestUtils) ... ok
test_find_plugin (TestUtils.TestUtils) ... ok
test_get_diff (TestUtils.TestUtils) ... ok
test_getch (TestUtils.TestUtils) ... ok
test_increment_debug (TestUtils.TestUtils) ... ok
test_is_changed (TestUtils.TestUtils) ... ok
test_is_executable (TestUtils.TestUtils) ... ok
test_is_failed (TestUtils.TestUtils) ... ok
test_is_list_of_strings (TestUtils.TestUtils) ... ok
test_json_loads (TestUtils.TestUtils) ... ok
test_jsonify (TestUtils.TestUtils) ... ok
test_last_non_blank_line (TestUtils.TestUtils) ... ok
test_listify_lookup_plugin_terms (TestUtils.TestUtils) ... ok
test_make_su_cmd (TestUtils.TestUtils) ... ok
test_make_sudo_cmd (TestUtils.TestUtils) ... ok
test_md5 (TestUtils.TestUtils) ... ok
test_md5s (TestUtils.TestUtils) ... ok
test_merge_hash (TestUtils.TestUtils) ... ok
test_parse_json (TestUtils.TestUtils) ... ok
test_parse_kv_basic (TestUtils.TestUtils) ... ok
test_parse_yaml (TestUtils.TestUtils) ... ok
test_parse_yaml_from_file (TestUtils.TestUtils) ... ok
test_path_dwim (TestUtils.TestUtils) ... ok
test_path_dwim_relative (TestUtils.TestUtils) ... ok
test_process_common_errors (TestUtils.TestUtils) ... ok
test_process_yaml_error (TestUtils.TestUtils) ... ok
test_repo_url_to_role_name (TestUtils.TestUtils) ... ok
test_role_spec_parse (TestUtils.TestUtils) ... ok
test_role_yaml_parse (TestUtils.TestUtils) ... ok
test_safe_eval (TestUtils.TestUtils) ... ok
test_sanitize_output (TestUtils.TestUtils) ... ok
test_split_args (TestUtils.TestUtils) ... ok
test_to_unicode (TestUtils.TestUtils) ... ok
test_unfrackpath (TestUtils.TestUtils) ... ok
test_version (TestUtils.TestUtils) ... ok
test_warning (TestUtils.TestUtils) ... ok
test_count_newlines_from_end (TestUtilsStringFunctions.TestUtilsStringFunctions) ... ok
test_isprintable (TestUtilsStringFunctions.TestUtilsStringFunctions) ... ok
test_add_header (TestVault.TestVaultLib) ... ok
test_cipher_not_set (TestVault.TestVaultLib) ... ok
test_decrypt_decrypted (TestVault.TestVaultLib) ... ok
test_encrypt_decrypt_aes (TestVault.TestVaultLib) ... ok
test_encrypt_decrypt_aes256 (TestVault.TestVaultLib) ... ok
test_encrypt_encrypted (TestVault.TestVaultLib) ... ok
test_is_encrypted (TestVault.TestVaultLib) ... ok
test_methods_exist (TestVault.TestVaultLib) ... ok
test_split_header (TestVault.TestVaultLib) ... ok
test_decrypt_1_0 (TestVaultEditor.TestVaultEditor) ... ok
test_decrypt_1_1 (TestVaultEditor.TestVaultEditor) ... ok
test_decrypt_1_1_newline (TestVaultEditor.TestVaultEditor) ... ok
test_methods_exist (TestVaultEditor.TestVaultEditor) ... ok
test_rekey_migration (TestVaultEditor.TestVaultEditor) ... ok
test_encrypt_decrypt_gpg (TestVaultGPG.TestVaultGPG) ... ok
test_key_trust (TestVaultGPG.TestVaultGPG) ... ok
test_keys_available (TestVaultGPG.TestVaultGPG) ... ok
test_methods_exist (TestVaultGPG.TestVaultGPG) ... ok
test_pkgname_expands (TestApt.AptExpandPkgspecTestCase) ... ok
test_pkgname_wildcard_version_wildcard (TestApt.AptExpandPkgspecTestCase) ... ok
test_trivial (TestApt.AptExpandPkgspecTestCase) ... ok
test_version_wildcard (TestApt.AptExpandPkgspecTestCase) ... ok
test_trivial (TestDocker.DockerSplitImageTagTestCase) ... ok
test_with_org_name (TestDocker.DockerSplitImageTagTestCase) ... ok
test_with_tag (TestDocker.DockerSplitImageTagTestCase) ... ok
test_with_tag_and_org_name (TestDocker.DockerSplitImageTagTestCase) ... ok

----------------------------------------------------------------------
Ran 235 tests in 10.386s

OK

Kahn commented Apr 22, 2015

@bcoca This PR should be ok to pull from 9e3a51f. The remaining two changes are just failing travis config anyway. Since travis has not passed I have added the outputs from both my OSX and Ubuntu test hosts. Let me know if we need to get Travis green.

Ubuntu

swilson@ubuntu:~/ansible$ make tests
PYTHONPATH=./lib nosetests -d -w test/units -v --with-coverage --cover-package=ansible --cover-branches
nose.plugins.cover: ERROR: Coverage not available: unable to import coverage module
test_configfile_and_env_both_set (TestConstants.TestConstants) ... ok
test_configfile_not_set_env_not_set (TestConstants.TestConstants) ... ok
test_configfile_not_set_env_set (TestConstants.TestConstants) ... ok
test_configfile_set_env_not_set (TestConstants.TestConstants) ... ok
test_bool_no (TestFilters.TestFilters) ... ok
test_bool_none (TestFilters.TestFilters) ... ok
test_bool_true (TestFilters.TestFilters) ... ok
test_bool_yes (TestFilters.TestFilters) ... ok
test_fileglob (TestFilters.TestFilters) ... ok
test_match_case_insensitive (TestFilters.TestFilters) ... ok
test_match_case_sensitive (TestFilters.TestFilters) ... ok
test_match_no_match (TestFilters.TestFilters) ... ok
test_max (TestFilters.TestFilters) ... ok
test_min (TestFilters.TestFilters) ... ok
test_quotes (TestFilters.TestFilters) ... ok
test_regex (TestFilters.TestFilters) ... ok
test_regex_replace_case_insensitive (TestFilters.TestFilters) ... ok
test_regex_replace_case_sensitive (TestFilters.TestFilters) ... ok
test_regex_replace_no_match (TestFilters.TestFilters) ... ok
test_search_case_insensitive (TestFilters.TestFilters) ... ok
test_search_case_sensitive (TestFilters.TestFilters) ... ok
test_to_uuid (TestFilters.TestFilters) ... ok
test_version_compare (TestFilters.TestFilters) ... ok
test_allows_equals_sign_in_var (TestInventory.TestInventory) ... ok
test_alpha_end_before_beg (TestInventory.TestInventory) ... ok
test_combined_range (TestInventory.TestInventory) ... ok
test_complex_enumeration (TestInventory.TestInventory) ... ok
test_complex_exclude (TestInventory.TestInventory) ... ok
test_complex_group_names (TestInventory.TestInventory) ... ok
test_complex_intersect (TestInventory.TestInventory) ... ok
test_complex_vars (TestInventory.TestInventory) ... ok
test_dir_inventory (TestInventory.TestInventory) ... ok
test_dir_inventory_group_hosts (TestInventory.TestInventory) ... ok
test_dir_inventory_groups_for_host (TestInventory.TestInventory) ... ok
test_dir_inventory_groups_list (TestInventory.TestInventory) ... ok
test_dir_inventory_multiple_groups (TestInventory.TestInventory) ... ok
test_dir_inventory_skip_extension (TestInventory.TestInventory) ... ok
test_empty (TestInventory.TestInventory) ... ok
test_get_hosts (TestInventory.TestInventory) ... ok
test_hosts_list (TestInventory.TestInventory) ... ok
test_incorrect_format (TestInventory.TestInventory) ... ok
test_invalid_range (TestInventory.TestInventory) ... ok
test_large_range (TestInventory.TestInventory) ... ok
test_leading_range (TestInventory.TestInventory) ... ok
test_missing_end (TestInventory.TestInventory) ... ok
test_no_src (TestInventory.TestInventory) ... ok
test_regex_exclude (TestInventory.TestInventory) ... ok
test_regex_grouping (TestInventory.TestInventory) ... ok
test_script (TestInventory.TestInventory) ... ok
test_script_all (TestInventory.TestInventory) ... ok
test_script_combined (TestInventory.TestInventory) ... ok
test_script_multiple_groups (TestInventory.TestInventory) ... ok
test_script_norse (TestInventory.TestInventory) ... ok
test_script_restrict (TestInventory.TestInventory) ... ok
test_script_vars (TestInventory.TestInventory) ... ok
test_simple (TestInventory.TestInventory) ... ok
test_simple_all (TestInventory.TestInventory) ... ok
test_simple_combined (TestInventory.TestInventory) ... ok
test_simple_norse (TestInventory.TestInventory) ... ok
test_simple_port (TestInventory.TestInventory) ... ok
test_simple_restrict (TestInventory.TestInventory) ... ok
test_simple_string_fqdn (TestInventory.TestInventory) ... ok
test_simple_string_fqdn_port (TestInventory.TestInventory) ... ok
test_simple_string_fqdn_vars (TestInventory.TestInventory) ... ok
test_simple_string_ipv4 (TestInventory.TestInventory) ... ok
test_simple_string_ipv4_port (TestInventory.TestInventory) ... ok
test_simple_string_ipv4_vars (TestInventory.TestInventory) ... ok
test_simple_string_ipv6 (TestInventory.TestInventory) ... ok
test_simple_string_ipv6_port (TestInventory.TestInventory) ... ok
test_simple_string_ipv6_vars (TestInventory.TestInventory) ... ok
test_simple_ungrouped (TestInventory.TestInventory) ... ok
test_simple_vars (TestInventory.TestInventory) ... ok
test_subet_range_empty_group (TestInventory.TestInventory) ... ok
test_subset (TestInventory.TestInventory) ... ok
test_subset_filename (TestInventory.TestInventory) ... ok
test_subset_range (TestInventory.TestInventory) ... ok
testinvalid_entry (TestInventory.TestInventory) ... ok
test_run_command_args (TestModuleUtilsBasic.TestModuleUtilsBasic) ... ok
test_run_command_args_with_env_variables (TestModuleUtilsBasic.TestModuleUtilsBasic) ... ok
test_run_command_string (TestModuleUtilsBasic.TestModuleUtilsBasic) ... ok
test_run_command_string_unsafe_with_double_redirect_out (TestModuleUtilsBasic.TestModuleUtilsBasic) ... ok
test_run_command_string_unsafe_with_env_variables (TestModuleUtilsBasic.TestModuleUtilsBasic) ... ok
test_run_command_string_unsafe_with_pipe (TestModuleUtilsBasic.TestModuleUtilsBasic) ... ok
test_run_command_string_unsafe_with_redirect_in (TestModuleUtilsBasic.TestModuleUtilsBasic) ... ok
test_run_command_string_unsafe_with_redirect_out (TestModuleUtilsBasic.TestModuleUtilsBasic) ... ok
test_run_command_string_with_binary_data (TestModuleUtilsBasic.TestModuleUtilsBasic) ... ok
test_run_command_string_with_cwd (TestModuleUtilsBasic.TestModuleUtilsBasic) ... ok
test_run_command_string_with_data (TestModuleUtilsBasic.TestModuleUtilsBasic) ... ok
test_run_command_string_with_env_variables (TestModuleUtilsBasic.TestModuleUtilsBasic) ... ok
test_log_sanitize_correctness (TestModuleUtilsBasic.TestModuleUtilsBasicHelpers) ... ok
test_log_sanitize_speed_many_ssh (TestModuleUtilsBasic.TestModuleUtilsBasicHelpers) ... ok
test_log_sanitize_speed_many_url (TestModuleUtilsBasic.TestModuleUtilsBasicHelpers) ... ok
test_log_sanitize_speed_one_ssh (TestModuleUtilsBasic.TestModuleUtilsBasicHelpers) ... ok
test_log_sanitize_speed_one_url (TestModuleUtilsBasic.TestModuleUtilsBasicHelpers) ... ok
test_log_sanitize_speed_zero_secrets (TestModuleUtilsBasic.TestModuleUtilsBasicHelpers) ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_how_many_dots ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_invalid_quotes('"table "invalid" double quote"', 'table', 'User escaped identifiers must escape extra quotes') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_invalid_quotes('"test"."too"."many"."dots"', 'schema', 'PostgreSQL does not support schema with more than 2 dots') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_invalid_quotes('test.too."many.dots"', 'database', 'PostgreSQL does not support database with more than 1 dots') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_invalid_quotes('"test"."too"."many"."dots"', 'database', 'PostgreSQL does not support database with more than 1 dots') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_invalid_quotes('test.too.many.dots', 'table', 'PostgreSQL does not support table with more than 3 dots') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_invalid_quotes('"schema "invalid"""."table "invalid"', 'table', 'User escaped identifiers must escape extra quotes') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_invalid_quotes('"schema".', 'table', 'Identifier name unspecified or unquoted trailing dot') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_invalid_quotes('"test"."too"."many"."dots"."for"."column"', 'column', 'PostgreSQL does not support column with more than 4 dots') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_invalid_quotes('"schema."table"', 'table', 'User escaped identifiers must escape extra quotes') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_invalid_quotes('"test.too".many.dots', 'database', 'PostgreSQL does not support database with more than 1 dots') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_invalid_quotes('"test"."too"."many"."dots"', 'table', 'PostgreSQL does not support table with more than 3 dots') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_valid_quotes('."table"', '".""table"""') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_valid_quotes('"schema.".".table"', '"schema.".".table"') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_valid_quotes('public.table', '"public"."table"') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_valid_quotes('"schema.test"."table.test"', '"schema.test"."table.test"') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_valid_quotes('"schema."."table"', '"schema."."table"') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_valid_quotes('"schema.".table', '"schema."."table"') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_valid_quotes('public."table ""test"""', '"public"."table ""test"""') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_valid_quotes('schema.".table"', '"schema".".table"') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_valid_quotes('"no end quote', '"""no end quote"') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_valid_quotes('"schema test".table test', '"schema test"."table test"') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_valid_quotes('public.table "test"', '"public"."table ""test"""') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_valid_quotes('"schema test"."table test"', '"schema test"."table test"') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_valid_quotes('"schema.table', '"""schema"."table"') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_valid_quotes('"schema".".table"', '"schema".".table"') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_valid_quotes('public."table"', '"public"."table"') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_valid_quotes('schema test.table test', '"schema test"."table test"') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_valid_quotes('table "test"', '"table ""test"""') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_valid_quotes('schema "test".table', '"schema ""test"""."table"') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_valid_quotes('"public.table"', '"public.table"') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_valid_quotes('"""wat"""."""test"""', '"""wat"""."""test"""') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_valid_quotes('"schema ""test""".table', '"schema ""test"""."table"') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_valid_quotes('"public".table', '"public"."table"') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_valid_quotes('schema."table', '"schema"."""table"') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_valid_quotes('schema test."table test"', '"schema test"."table test"') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_valid_quotes('table.', '"table."') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_valid_quotes('schema."table.something', '"schema"."""table"."something"') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_valid_quotes('"public"."table"', '"public"."table"') ... ok
test_ast_parse (TestModules.TestModules) ... ok
test_multiple_vars_files (TestPlayVarsFiles.TestMe) ... ok
test_play_constructor (TestPlayVarsFiles.TestMe) ... ok
test_vars_file (TestPlayVarsFiles.TestMe) ... ok
test_vars_file_nonlist_error (TestPlayVarsFiles.TestMe) ... ok
test_vars_files_assert_all_found (TestPlayVarsFiles.TestMe) ... ok
test_vars_files_first_found (TestPlayVarsFiles.TestMe) ... ok
test_vars_files_for_host (TestPlayVarsFiles.TestMe) ... ok
test_vars_files_multiple_found (TestPlayVarsFiles.TestMe) ... ok
test_vars_files_two_vars_different_scope (TestPlayVarsFiles.TestMe) ... ok
test_vars_files_two_vars_different_scope_first_found (TestPlayVarsFiles.TestMe) ... ok
test_vars_files_two_vars_in_name (TestPlayVarsFiles.TestMe) ... ok
verify the synchronize action plugin sets ... ok
verify the synchronize action plugin sets ... ok
verify the synchronize action plugin unsets and then sets sudo ... ok
Verify the action plugin accommodates the common ... ok
test__gitinfo (TestUtils.TestUtils) ... ok
test_base_parser (TestUtils.TestUtils) ... ok
see if we can detect the part of a string before a comment.  Used by INI parser in inventory ... ok
test_boolean (TestUtils.TestUtils) ... ok
used by the no_log attribute ... ok
test_check_conditional_jinja2_expression (TestUtils.TestUtils) ... ok
test_check_conditional_jinja2_expression_in_variable (TestUtils.TestUtils) ... ok
test_check_conditional_jinja2_literals (TestUtils.TestUtils) ... ok
test_check_conditional_jinja2_unicode (TestUtils.TestUtils) ... ok
test_check_conditional_jinja2_variable_literals (TestUtils.TestUtils) ... ok
test_checksum (TestUtils.TestUtils) ... ok
test_checksum_s (TestUtils.TestUtils) ... ok
test_clean_data (TestUtils.TestUtils) ... ok
test_combine_vars (TestUtils.TestUtils) ... ok
test_contains_vars (TestUtils.TestUtils) ... ok
test_default (TestUtils.TestUtils) ... ok
test_deprecated (TestUtils.TestUtils) ... ok
test_do_encrypt (TestUtils.TestUtils) ... ok
test_do_encrypt_md5 (TestUtils.TestUtils) ... ok
test_err (TestUtils.TestUtils) ... ok
test_exit (TestUtils.TestUtils) ... ok
test_filter_leading_non_json_lines (TestUtils.TestUtils) ... ok
test_find_plugin (TestUtils.TestUtils) ... ok
test_get_diff (TestUtils.TestUtils) ... ok
test_getch (TestUtils.TestUtils) ... ok
test_increment_debug (TestUtils.TestUtils) ... ok
test_is_changed (TestUtils.TestUtils) ... ok
test_is_executable (TestUtils.TestUtils) ... ok
test_is_failed (TestUtils.TestUtils) ... ok
test_is_list_of_strings (TestUtils.TestUtils) ... ok
test_json_loads (TestUtils.TestUtils) ... ok
test_jsonify (TestUtils.TestUtils) ... ok
test_last_non_blank_line (TestUtils.TestUtils) ... ok
test_listify_lookup_plugin_terms (TestUtils.TestUtils) ... ok
test_make_su_cmd (TestUtils.TestUtils) ... ok
test_make_sudo_cmd (TestUtils.TestUtils) ... ok
test_md5 (TestUtils.TestUtils) ... ok
test_md5s (TestUtils.TestUtils) ... ok
test_merge_hash (TestUtils.TestUtils) ... ok
test_parse_json (TestUtils.TestUtils) ... ok
test_parse_kv_basic (TestUtils.TestUtils) ... ok
test_parse_yaml (TestUtils.TestUtils) ... ok
test_parse_yaml_from_file (TestUtils.TestUtils) ... ok
test_path_dwim (TestUtils.TestUtils) ... ok
test_path_dwim_relative (TestUtils.TestUtils) ... ok
test_process_common_errors (TestUtils.TestUtils) ... ok
test_process_yaml_error (TestUtils.TestUtils) ... ok
test_repo_url_to_role_name (TestUtils.TestUtils) ... ok
test_role_spec_parse (TestUtils.TestUtils) ... ok
test_role_yaml_parse (TestUtils.TestUtils) ... ok
test_safe_eval (TestUtils.TestUtils) ... ok
test_sanitize_output (TestUtils.TestUtils) ... ok
test_split_args (TestUtils.TestUtils) ... ok
test_to_unicode (TestUtils.TestUtils) ... ok
test_unfrackpath (TestUtils.TestUtils) ... ok
test_version (TestUtils.TestUtils) ... ok
test_warning (TestUtils.TestUtils) ... ok
test_count_newlines_from_end (TestUtilsStringFunctions.TestUtilsStringFunctions) ... ok
test_isprintable (TestUtilsStringFunctions.TestUtilsStringFunctions) ... ok
test_add_header (TestVault.TestVaultLib) ... ok
test_cipher_not_set (TestVault.TestVaultLib) ... ok
test_decrypt_decrypted (TestVault.TestVaultLib) ... ok
test_encrypt_decrypt_aes (TestVault.TestVaultLib) ... ok
test_encrypt_decrypt_aes256 (TestVault.TestVaultLib) ... ok
test_encrypt_encrypted (TestVault.TestVaultLib) ... ok
test_is_encrypted (TestVault.TestVaultLib) ... ok
test_methods_exist (TestVault.TestVaultLib) ... ok
test_split_header (TestVault.TestVaultLib) ... ok
test_decrypt_1_0 (TestVaultEditor.TestVaultEditor) ... ok
test_decrypt_1_1 (TestVaultEditor.TestVaultEditor) ... ok
test_decrypt_1_1_newline (TestVaultEditor.TestVaultEditor) ... ok
test_methods_exist (TestVaultEditor.TestVaultEditor) ... ok
test_rekey_migration (TestVaultEditor.TestVaultEditor) ... ok
test_encrypt_decrypt_gpg (TestVaultGPG.TestVaultGPG) ... ok
test_key_trust (TestVaultGPG.TestVaultGPG) ... ok
test_keys_available (TestVaultGPG.TestVaultGPG) ... ok
test_methods_exist (TestVaultGPG.TestVaultGPG) ... ok
test_pkgname_expands (TestApt.AptExpandPkgspecTestCase) ... ok
test_pkgname_wildcard_version_wildcard (TestApt.AptExpandPkgspecTestCase) ... ok
test_trivial (TestApt.AptExpandPkgspecTestCase) ... ok
test_version_wildcard (TestApt.AptExpandPkgspecTestCase) ... ok
test_trivial (TestDocker.DockerSplitImageTagTestCase) ... ok
test_with_org_name (TestDocker.DockerSplitImageTagTestCase) ... ok
test_with_tag (TestDocker.DockerSplitImageTagTestCase) ... ok
test_with_tag_and_org_name (TestDocker.DockerSplitImageTagTestCase) ... ok

----------------------------------------------------------------------
Ran 235 tests in 8.017s

OK

OSX

swilson:ansible swilson$ make tests
PYTHONPATH=./lib nosetests -d -w test/units -v --with-coverage --cover-package=ansible --cover-branches
nose.plugins.cover: ERROR: Coverage not available: unable to import coverage module
test_configfile_and_env_both_set (TestConstants.TestConstants) ... ok
test_configfile_not_set_env_not_set (TestConstants.TestConstants) ... ok
test_configfile_not_set_env_set (TestConstants.TestConstants) ... ok
test_configfile_set_env_not_set (TestConstants.TestConstants) ... ok
test_bool_no (TestFilters.TestFilters) ... ok
test_bool_none (TestFilters.TestFilters) ... ok
test_bool_true (TestFilters.TestFilters) ... ok
test_bool_yes (TestFilters.TestFilters) ... ok
test_fileglob (TestFilters.TestFilters) ... ok
test_match_case_insensitive (TestFilters.TestFilters) ... ok
test_match_case_sensitive (TestFilters.TestFilters) ... ok
test_match_no_match (TestFilters.TestFilters) ... ok
test_max (TestFilters.TestFilters) ... ok
test_min (TestFilters.TestFilters) ... ok
test_quotes (TestFilters.TestFilters) ... ok
test_regex (TestFilters.TestFilters) ... ok
test_regex_replace_case_insensitive (TestFilters.TestFilters) ... ok
test_regex_replace_case_sensitive (TestFilters.TestFilters) ... ok
test_regex_replace_no_match (TestFilters.TestFilters) ... ok
test_search_case_insensitive (TestFilters.TestFilters) ... ok
test_search_case_sensitive (TestFilters.TestFilters) ... ok
test_to_uuid (TestFilters.TestFilters) ... ok
test_version_compare (TestFilters.TestFilters) ... ok
test_allows_equals_sign_in_var (TestInventory.TestInventory) ... ok
test_alpha_end_before_beg (TestInventory.TestInventory) ... ok
test_combined_range (TestInventory.TestInventory) ... ok
test_complex_enumeration (TestInventory.TestInventory) ... ok
test_complex_exclude (TestInventory.TestInventory) ... ok
test_complex_group_names (TestInventory.TestInventory) ... ok
test_complex_intersect (TestInventory.TestInventory) ... ok
test_complex_vars (TestInventory.TestInventory) ... ok
test_dir_inventory (TestInventory.TestInventory) ... ok
test_dir_inventory_group_hosts (TestInventory.TestInventory) ... ok
test_dir_inventory_groups_for_host (TestInventory.TestInventory) ... ok
test_dir_inventory_groups_list (TestInventory.TestInventory) ... ok
test_dir_inventory_multiple_groups (TestInventory.TestInventory) ... ok
test_dir_inventory_skip_extension (TestInventory.TestInventory) ... ok
test_empty (TestInventory.TestInventory) ... ok
test_get_hosts (TestInventory.TestInventory) ... ok
test_hosts_list (TestInventory.TestInventory) ... ok
test_incorrect_format (TestInventory.TestInventory) ... ok
test_invalid_range (TestInventory.TestInventory) ... ok
test_large_range (TestInventory.TestInventory) ... ok
test_leading_range (TestInventory.TestInventory) ... ok
test_missing_end (TestInventory.TestInventory) ... ok
test_no_src (TestInventory.TestInventory) ... ok
test_regex_exclude (TestInventory.TestInventory) ... ok
test_regex_grouping (TestInventory.TestInventory) ... ok
test_script (TestInventory.TestInventory) ... ok
test_script_all (TestInventory.TestInventory) ... ok
test_script_combined (TestInventory.TestInventory) ... ok
test_script_multiple_groups (TestInventory.TestInventory) ... ok
test_script_norse (TestInventory.TestInventory) ... ok
test_script_restrict (TestInventory.TestInventory) ... ok
test_script_vars (TestInventory.TestInventory) ... ok
test_simple (TestInventory.TestInventory) ... ok
test_simple_all (TestInventory.TestInventory) ... ok
test_simple_combined (TestInventory.TestInventory) ... ok
test_simple_norse (TestInventory.TestInventory) ... ok
test_simple_port (TestInventory.TestInventory) ... ok
test_simple_restrict (TestInventory.TestInventory) ... ok
test_simple_string_fqdn (TestInventory.TestInventory) ... ok
test_simple_string_fqdn_port (TestInventory.TestInventory) ... ok
test_simple_string_fqdn_vars (TestInventory.TestInventory) ... ok
test_simple_string_ipv4 (TestInventory.TestInventory) ... ok
test_simple_string_ipv4_port (TestInventory.TestInventory) ... ok
test_simple_string_ipv4_vars (TestInventory.TestInventory) ... ok
test_simple_string_ipv6 (TestInventory.TestInventory) ... ok
test_simple_string_ipv6_port (TestInventory.TestInventory) ... ok
test_simple_string_ipv6_vars (TestInventory.TestInventory) ... ok
test_simple_ungrouped (TestInventory.TestInventory) ... ok
test_simple_vars (TestInventory.TestInventory) ... ok
test_subet_range_empty_group (TestInventory.TestInventory) ... ok
test_subset (TestInventory.TestInventory) ... ok
test_subset_filename (TestInventory.TestInventory) ... ok
test_subset_range (TestInventory.TestInventory) ... ok
testinvalid_entry (TestInventory.TestInventory) ... ok
test_run_command_args (TestModuleUtilsBasic.TestModuleUtilsBasic) ... ok
test_run_command_args_with_env_variables (TestModuleUtilsBasic.TestModuleUtilsBasic) ... ok
test_run_command_string (TestModuleUtilsBasic.TestModuleUtilsBasic) ... ok
test_run_command_string_unsafe_with_double_redirect_out (TestModuleUtilsBasic.TestModuleUtilsBasic) ... ok
test_run_command_string_unsafe_with_env_variables (TestModuleUtilsBasic.TestModuleUtilsBasic) ... ok
test_run_command_string_unsafe_with_pipe (TestModuleUtilsBasic.TestModuleUtilsBasic) ... ok
test_run_command_string_unsafe_with_redirect_in (TestModuleUtilsBasic.TestModuleUtilsBasic) ... ok
test_run_command_string_unsafe_with_redirect_out (TestModuleUtilsBasic.TestModuleUtilsBasic) ... ok
test_run_command_string_with_binary_data (TestModuleUtilsBasic.TestModuleUtilsBasic) ... ok
test_run_command_string_with_cwd (TestModuleUtilsBasic.TestModuleUtilsBasic) ... ok
test_run_command_string_with_data (TestModuleUtilsBasic.TestModuleUtilsBasic) ... ok
test_run_command_string_with_env_variables (TestModuleUtilsBasic.TestModuleUtilsBasic) ... ok
test_log_sanitize_correctness (TestModuleUtilsBasic.TestModuleUtilsBasicHelpers) ... ok
test_log_sanitize_speed_many_ssh (TestModuleUtilsBasic.TestModuleUtilsBasicHelpers) ... ok
test_log_sanitize_speed_many_url (TestModuleUtilsBasic.TestModuleUtilsBasicHelpers) ... ok
test_log_sanitize_speed_one_ssh (TestModuleUtilsBasic.TestModuleUtilsBasicHelpers) ... ok
test_log_sanitize_speed_one_url (TestModuleUtilsBasic.TestModuleUtilsBasicHelpers) ... ok
test_log_sanitize_speed_zero_secrets (TestModuleUtilsBasic.TestModuleUtilsBasicHelpers) ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_how_many_dots ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_invalid_quotes('"table "invalid" double quote"', 'table', 'User escaped identifiers must escape extra quotes') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_invalid_quotes('"test"."too"."many"."dots"', 'schema', 'PostgreSQL does not support schema with more than 2 dots') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_invalid_quotes('test.too."many.dots"', 'database', 'PostgreSQL does not support database with more than 1 dots') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_invalid_quotes('"test"."too"."many"."dots"', 'database', 'PostgreSQL does not support database with more than 1 dots') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_invalid_quotes('test.too.many.dots', 'table', 'PostgreSQL does not support table with more than 3 dots') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_invalid_quotes('"schema "invalid"""."table "invalid"', 'table', 'User escaped identifiers must escape extra quotes') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_invalid_quotes('"schema".', 'table', 'Identifier name unspecified or unquoted trailing dot') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_invalid_quotes('"test"."too"."many"."dots"."for"."column"', 'column', 'PostgreSQL does not support column with more than 4 dots') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_invalid_quotes('"schema."table"', 'table', 'User escaped identifiers must escape extra quotes') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_invalid_quotes('"test.too".many.dots', 'database', 'PostgreSQL does not support database with more than 1 dots') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_invalid_quotes('"test"."too"."many"."dots"', 'table', 'PostgreSQL does not support table with more than 3 dots') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_valid_quotes('."table"', '".""table"""') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_valid_quotes('"schema.".".table"', '"schema.".".table"') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_valid_quotes('public.table', '"public"."table"') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_valid_quotes('"schema.test"."table.test"', '"schema.test"."table.test"') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_valid_quotes('"schema."."table"', '"schema."."table"') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_valid_quotes('"schema.".table', '"schema."."table"') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_valid_quotes('public."table ""test"""', '"public"."table ""test"""') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_valid_quotes('schema.".table"', '"schema".".table"') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_valid_quotes('"no end quote', '"""no end quote"') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_valid_quotes('"schema test".table test', '"schema test"."table test"') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_valid_quotes('public.table "test"', '"public"."table ""test"""') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_valid_quotes('"schema test"."table test"', '"schema test"."table test"') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_valid_quotes('"schema.table', '"""schema"."table"') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_valid_quotes('"schema".".table"', '"schema".".table"') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_valid_quotes('public."table"', '"public"."table"') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_valid_quotes('schema test.table test', '"schema test"."table test"') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_valid_quotes('table "test"', '"table ""test"""') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_valid_quotes('schema "test".table', '"schema ""test"""."table"') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_valid_quotes('"public.table"', '"public.table"') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_valid_quotes('"""wat"""."""test"""', '"""wat"""."""test"""') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_valid_quotes('"schema ""test""".table', '"schema ""test"""."table"') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_valid_quotes('"public".table', '"public"."table"') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_valid_quotes('schema."table', '"schema"."""table"') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_valid_quotes('schema test."table test"', '"schema test"."table test"') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_valid_quotes('table.', '"table."') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_valid_quotes('schema."table.something', '"schema"."""table"."something"') ... ok
TestModuleUtilsDatabase.TestQuotePgIdentifier.test_valid_quotes('"public"."table"', '"public"."table"') ... ok
test_ast_parse (TestModules.TestModules) ... ok
test_multiple_vars_files (TestPlayVarsFiles.TestMe) ... ok
test_play_constructor (TestPlayVarsFiles.TestMe) ... ok
test_vars_file (TestPlayVarsFiles.TestMe) ... ok
test_vars_file_nonlist_error (TestPlayVarsFiles.TestMe) ... ok
test_vars_files_assert_all_found (TestPlayVarsFiles.TestMe) ... ok
test_vars_files_first_found (TestPlayVarsFiles.TestMe) ... ok
test_vars_files_for_host (TestPlayVarsFiles.TestMe) ... ok
test_vars_files_multiple_found (TestPlayVarsFiles.TestMe) ... ok
test_vars_files_two_vars_different_scope (TestPlayVarsFiles.TestMe) ... ok
test_vars_files_two_vars_different_scope_first_found (TestPlayVarsFiles.TestMe) ... ok
test_vars_files_two_vars_in_name (TestPlayVarsFiles.TestMe) ... ok
verify the synchronize action plugin sets ... ok
verify the synchronize action plugin sets ... ok
verify the synchronize action plugin unsets and then sets sudo ... ok
Verify the action plugin accommodates the common ... ok
test__gitinfo (TestUtils.TestUtils) ... ok
test_base_parser (TestUtils.TestUtils) ... ok
see if we can detect the part of a string before a comment.  Used by INI parser in inventory ... ok
test_boolean (TestUtils.TestUtils) ... ok
used by the no_log attribute ... ok
test_check_conditional_jinja2_expression (TestUtils.TestUtils) ... ok
test_check_conditional_jinja2_expression_in_variable (TestUtils.TestUtils) ... ok
test_check_conditional_jinja2_literals (TestUtils.TestUtils) ... ok
test_check_conditional_jinja2_unicode (TestUtils.TestUtils) ... ok
test_check_conditional_jinja2_variable_literals (TestUtils.TestUtils) ... ok
test_checksum (TestUtils.TestUtils) ... ok
test_checksum_s (TestUtils.TestUtils) ... ok
test_clean_data (TestUtils.TestUtils) ... ok
test_combine_vars (TestUtils.TestUtils) ... ok
test_contains_vars (TestUtils.TestUtils) ... ok
test_default (TestUtils.TestUtils) ... ok
test_deprecated (TestUtils.TestUtils) ... ok
test_do_encrypt (TestUtils.TestUtils) ... ok
test_do_encrypt_md5 (TestUtils.TestUtils) ... ok
test_err (TestUtils.TestUtils) ... ok
test_exit (TestUtils.TestUtils) ... ok
test_filter_leading_non_json_lines (TestUtils.TestUtils) ... ok
test_find_plugin (TestUtils.TestUtils) ... ok
test_get_diff (TestUtils.TestUtils) ... ok
test_getch (TestUtils.TestUtils) ... ok
test_increment_debug (TestUtils.TestUtils) ... ok
test_is_changed (TestUtils.TestUtils) ... ok
test_is_executable (TestUtils.TestUtils) ... ok
test_is_failed (TestUtils.TestUtils) ... ok
test_is_list_of_strings (TestUtils.TestUtils) ... ok
test_json_loads (TestUtils.TestUtils) ... ok
test_jsonify (TestUtils.TestUtils) ... ok
test_last_non_blank_line (TestUtils.TestUtils) ... ok
test_listify_lookup_plugin_terms (TestUtils.TestUtils) ... ok
test_make_su_cmd (TestUtils.TestUtils) ... ok
test_make_sudo_cmd (TestUtils.TestUtils) ... ok
test_md5 (TestUtils.TestUtils) ... ok
test_md5s (TestUtils.TestUtils) ... ok
test_merge_hash (TestUtils.TestUtils) ... ok
test_parse_json (TestUtils.TestUtils) ... ok
test_parse_kv_basic (TestUtils.TestUtils) ... ok
test_parse_yaml (TestUtils.TestUtils) ... ok
test_parse_yaml_from_file (TestUtils.TestUtils) ... ok
test_path_dwim (TestUtils.TestUtils) ... ok
test_path_dwim_relative (TestUtils.TestUtils) ... ok
test_process_common_errors (TestUtils.TestUtils) ... ok
test_process_yaml_error (TestUtils.TestUtils) ... ok
test_repo_url_to_role_name (TestUtils.TestUtils) ... ok
test_role_spec_parse (TestUtils.TestUtils) ... ok
test_role_yaml_parse (TestUtils.TestUtils) ... ok
test_safe_eval (TestUtils.TestUtils) ... ok
test_sanitize_output (TestUtils.TestUtils) ... ok
test_split_args (TestUtils.TestUtils) ... ok
test_to_unicode (TestUtils.TestUtils) ... ok
test_unfrackpath (TestUtils.TestUtils) ... ok
test_version (TestUtils.TestUtils) ... ok
test_warning (TestUtils.TestUtils) ... ok
test_count_newlines_from_end (TestUtilsStringFunctions.TestUtilsStringFunctions) ... ok
test_isprintable (TestUtilsStringFunctions.TestUtilsStringFunctions) ... ok
test_add_header (TestVault.TestVaultLib) ... ok
test_cipher_not_set (TestVault.TestVaultLib) ... ok
test_decrypt_decrypted (TestVault.TestVaultLib) ... ok
test_encrypt_decrypt_aes (TestVault.TestVaultLib) ... ok
test_encrypt_decrypt_aes256 (TestVault.TestVaultLib) ... ok
test_encrypt_encrypted (TestVault.TestVaultLib) ... ok
test_is_encrypted (TestVault.TestVaultLib) ... ok
test_methods_exist (TestVault.TestVaultLib) ... ok
test_split_header (TestVault.TestVaultLib) ... ok
test_decrypt_1_0 (TestVaultEditor.TestVaultEditor) ... ok
test_decrypt_1_1 (TestVaultEditor.TestVaultEditor) ... ok
test_decrypt_1_1_newline (TestVaultEditor.TestVaultEditor) ... ok
test_methods_exist (TestVaultEditor.TestVaultEditor) ... ok
test_rekey_migration (TestVaultEditor.TestVaultEditor) ... ok
test_encrypt_decrypt_gpg (TestVaultGPG.TestVaultGPG) ... ok
test_key_trust (TestVaultGPG.TestVaultGPG) ... ok
test_keys_available (TestVaultGPG.TestVaultGPG) ... ok
test_methods_exist (TestVaultGPG.TestVaultGPG) ... ok
test_pkgname_expands (TestApt.AptExpandPkgspecTestCase) ... ok
test_pkgname_wildcard_version_wildcard (TestApt.AptExpandPkgspecTestCase) ... ok
test_trivial (TestApt.AptExpandPkgspecTestCase) ... ok
test_version_wildcard (TestApt.AptExpandPkgspecTestCase) ... ok
test_trivial (TestDocker.DockerSplitImageTagTestCase) ... ok
test_with_org_name (TestDocker.DockerSplitImageTagTestCase) ... ok
test_with_tag (TestDocker.DockerSplitImageTagTestCase) ... ok
test_with_tag_and_org_name (TestDocker.DockerSplitImageTagTestCase) ... ok

----------------------------------------------------------------------
Ran 235 tests in 10.386s

OK
@tjanez

This comment has been minimized.

Show comment
Hide comment
@tjanez

tjanez Apr 28, 2015

Contributor

This would be a very welcome feature 👍 . I hope the review and merge will happen soon!

Contributor

tjanez commented Apr 28, 2015

This would be a very welcome feature 👍 . I hope the review and merge will happen soon!

@mtotheikle

This comment has been minimized.

Show comment
Hide comment
@mtotheikle

mtotheikle May 19, 2015

+1 for this feature. Would be very helpful

+1 for this feature. Would be very helpful

@jimconner

This comment has been minimized.

Show comment
Hide comment
@jimconner

jimconner May 26, 2015

Another +1 for this one - would be brilliant to see this merged.

Another +1 for this one - would be brilliant to see this merged.

@actionjack

This comment has been minimized.

Show comment
Hide comment
@actionjack

actionjack May 26, 2015

👍 for this is would really help me out.

👍 for this is would really help me out.

@mtekel

This comment has been minimized.

Show comment
Hide comment

mtekel commented May 26, 2015

+1

@jirutka

This comment has been minimized.

Show comment
Hide comment
@jirutka

jirutka May 26, 2015

Contributor

@abadger Come on, this PR had been opened a looong before you’ve started v2. It would be much easier to merge it a year ago than now when a lot of code has changed.

Contributor

jirutka commented May 26, 2015

@abadger Come on, this PR had been opened a looong before you’ve started v2. It would be much easier to merge it a year ago than now when a lot of code has changed.

@abadger

This comment has been minimized.

Show comment
Hide comment
@abadger

abadger May 26, 2015

Member

@jirutka Certainly a valid criticism. Unfortunately I can't do anything about what may have been going on when this PR was opened. I can only work to solve the problems that are here now with actions in the present time.

Member

abadger commented May 26, 2015

@jirutka Certainly a valid criticism. Unfortunately I can't do anything about what may have been going on when this PR was opened. I can only work to solve the problems that are here now with actions in the present time.

@jimi-c

This comment has been minimized.

Show comment
Hide comment
@jimi-c

jimi-c May 26, 2015

Member

@jirutka there were originally issues with the PR which the author didn't address until April of this year (see my original comment about the unit tests not passing). To say that this sat in queue for a year simply because we ignored it is obviously not the whole story. The fact is, we are still very interested in this PR, however we don't have the current bandwidth to fix feature PRs that are sent to us, and we must rely on the original authors for some things when we find problems. This was especially true for last year, before Brian and Toshio were hired.

So, as always, all we can ask for is patience. As Toshio mentioned above, we've started several new initiatives to try and help route around this problem, so we encourage people with PR concerns to start using them. We're in #ansible-devel on Freenode as well as the weekly community hangout. Feel free to join either and discuss issues with this or any other PR.

Member

jimi-c commented May 26, 2015

@jirutka there were originally issues with the PR which the author didn't address until April of this year (see my original comment about the unit tests not passing). To say that this sat in queue for a year simply because we ignored it is obviously not the whole story. The fact is, we are still very interested in this PR, however we don't have the current bandwidth to fix feature PRs that are sent to us, and we must rely on the original authors for some things when we find problems. This was especially true for last year, before Brian and Toshio were hired.

So, as always, all we can ask for is patience. As Toshio mentioned above, we've started several new initiatives to try and help route around this problem, so we encourage people with PR concerns to start using them. We're in #ansible-devel on Freenode as well as the weekly community hangout. Feel free to join either and discuss issues with this or any other PR.

@amenonsen

This comment has been minimized.

Show comment
Hide comment
@amenonsen

amenonsen Jul 26, 2015

Contributor

Is anyone already working on revising this PR to apply to the current devel code?

Contributor

amenonsen commented Jul 26, 2015

Is anyone already working on revising this PR to apply to the current devel code?

@Kahn

This comment has been minimized.

Show comment
Hide comment
@Kahn

Kahn Jul 26, 2015

@amenonsen I have not had time to revisit. If your able to rebase on v2 it would be hugely appreciated!

Kahn commented Jul 26, 2015

@amenonsen I have not had time to revisit. If your able to rebase on v2 it would be hugely appreciated!

@bcoca bcoca added the needs_rebase label Jul 26, 2015

@ahelal

This comment has been minimized.

Show comment
Hide comment
@ahelal

ahelal Nov 3, 2015

Any efforts done here ? I am willing to put sometime if nothing is happening behind the scenes.

ahelal commented Nov 3, 2015

Any efforts done here ? I am willing to put sometime if nothing is happening behind the scenes.

@bcoca

This comment has been minimized.

Show comment
Hide comment
@bcoca

bcoca Nov 4, 2015

Member

@ahelal i wanted this for 2.0 but ran out of time, planning now on 2.1 but not doing any work on it, please beat me to it.

Member

bcoca commented Nov 4, 2015

@ahelal i wanted this for 2.0 but ran out of time, planning now on 2.1 but not doing any work on it, please beat me to it.

@Kahn

This comment has been minimized.

Show comment
Hide comment
@Kahn

Kahn Nov 4, 2015

I'm with @bcoca. If someone else is able to give this the time it needs, it would be awesome

Kahn commented Nov 4, 2015

I'm with @bcoca. If someone else is able to give this the time it needs, it would be awesome

@amenonsen

This comment has been minimized.

Show comment
Hide comment
@amenonsen

amenonsen Nov 27, 2015

Contributor

This is a feature I need at work, so I decided to fix it.

The code in devel has changed completely, of course, so it ended up as a rewrite more than a rebase. The cleanups from #12130 made it considerably simpler to get this working. (Unfortunately, that PR was rejected for 2.0, so I don't plan to submit this either.)

That said, however, the gpg-agent "pre-loading" hack is hideous (and unlike @jirutka, I'm not one of the lucky ones for whom it works without it). I think it's unacceptable to require that, and that we should get proper gpg-agent integration working. The first problem in this direction is that python-gnupg does not pass $GPG_TTY through when it executes gpg, without which I don't think it can ever work. But even when I hack it to do so, the pinentry program for some reason (after opening /dev/pts/2 successfully) returns "cancelled", so I don't know what to do about that and I don't have the time right now to go and read the pinentry source to find out.

Basic passphrase-based encryption and decryption to multiple recipients works fine, though.

cc @Richard2ndQuadrant

Update: If I change python-gnupg to pass through GPG_AGENT_INFO, GPG_TTY, and DISPLAY in the environment when it executes gpg, then pinentry works, and no pre-loading hacks are required at all. I asked the python-gnupg maintainer if we can have a new release with this change: isislovecruft/python-gnupg#131

Contributor

amenonsen commented Nov 27, 2015

This is a feature I need at work, so I decided to fix it.

The code in devel has changed completely, of course, so it ended up as a rewrite more than a rebase. The cleanups from #12130 made it considerably simpler to get this working. (Unfortunately, that PR was rejected for 2.0, so I don't plan to submit this either.)

That said, however, the gpg-agent "pre-loading" hack is hideous (and unlike @jirutka, I'm not one of the lucky ones for whom it works without it). I think it's unacceptable to require that, and that we should get proper gpg-agent integration working. The first problem in this direction is that python-gnupg does not pass $GPG_TTY through when it executes gpg, without which I don't think it can ever work. But even when I hack it to do so, the pinentry program for some reason (after opening /dev/pts/2 successfully) returns "cancelled", so I don't know what to do about that and I don't have the time right now to go and read the pinentry source to find out.

Basic passphrase-based encryption and decryption to multiple recipients works fine, though.

cc @Richard2ndQuadrant

Update: If I change python-gnupg to pass through GPG_AGENT_INFO, GPG_TTY, and DISPLAY in the environment when it executes gpg, then pinentry works, and no pre-loading hacks are required at all. I asked the python-gnupg maintainer if we can have a new release with this change: isislovecruft/python-gnupg#131

@amenonsen

This comment has been minimized.

Show comment
Hide comment
@amenonsen

amenonsen Nov 27, 2015

Contributor

Oh, here's an example of the encryption in action:

$ ansible-vault --cipher GPG --gpg-homedir ~/.gnupg encrypt --gpg-recipients ED834CE4,08AB9AA4 --output -
Reading plaintext input from stdin
hello world
$ANSIBLE_VAULT;1.2;GPG;1.0
-----BEGIN PGP MESSAGE-----

hQEMAzX1TiMcYm+mAQf+ITlq5DIdB+oigsMeVnVi8JsmRbqA5XCwrrDNjVOorM2J
rkQUNdMnviACtNDMWo+kw0NkMpDsTJKRkZk2gUw4jhd5TsVwV2YSwJOZY69rdV1I
eTm7g8X3+MMIQ6mB4nemunEuMNGpvv/F8BFOnNED8n94HKHPa5QyxunDq1pIy1w7
4DccBLH3VOzm9BNx6O78nElF3VxmTZ9tTNjRyGGwb+ILYBZIlT1IKItrk79yadDN
GpZ8OQJDYkCReoo217g0Kk7W69csziWQSxDcYPSZIGKBn3YYQAdD80opZ9f5D+8r
QDsA0wQgjIHQweTdxn1cfBQ/OMv5JEoi4kQppjsmEYUBDAODPdH0Yx45yAEH/0Gl
Tr383nn1JxFyLJ38yVNlIqiORBW2HVQgNqQip7DXw5qo/uij2lLooTfLmFu2QxC9
PytF3GM/wyOPCFIptJxgbMvXoTYEm47I2QOn2NOMb73tv5FJRdcsRa35KL6WepHm
DS1WO5zAWVoKkDXGwP7KZV+LoZd5CJ66gq7kk9vVYT2LJlqpRak8lfYb8sK3QkF2
isbVoy+B5MLuC1853ktXM99+gbdx22OmV6Wpig0ZZG/Q5m2K7ZdY+6RWMs7HN4kw
jat4/c/pZQaarrDDMEOyOYbJEiRSBAO6jPgxrnns2fiU8wa7XQgy9FdD4ZjUOwYt
rc1Z46Hy2Y+79qU/lr/SRwGZ7BKj6muggmy3tUrPXASHsGeSklTBPhZqi/4zCgkh
hgLpr58/NOguJEFnIp5/UuY9ccwWAPob8QWy+2a2aTw6qCtsaxV2
=M+Nz
-----END PGP MESSAGE-----
Encryption successful

And decrypting that message, after I pasted the output into a file:

kea:~/extern/ansible $ ansible-vault -vvv --cipher GPG --gpg-homedir ~/.gnupg decrypt ~/t.gpg --output -                          
No config file found; using defaults
Vault password: 
hello world
Decryption successful
Contributor

amenonsen commented Nov 27, 2015

Oh, here's an example of the encryption in action:

$ ansible-vault --cipher GPG --gpg-homedir ~/.gnupg encrypt --gpg-recipients ED834CE4,08AB9AA4 --output -
Reading plaintext input from stdin
hello world
$ANSIBLE_VAULT;1.2;GPG;1.0
-----BEGIN PGP MESSAGE-----

hQEMAzX1TiMcYm+mAQf+ITlq5DIdB+oigsMeVnVi8JsmRbqA5XCwrrDNjVOorM2J
rkQUNdMnviACtNDMWo+kw0NkMpDsTJKRkZk2gUw4jhd5TsVwV2YSwJOZY69rdV1I
eTm7g8X3+MMIQ6mB4nemunEuMNGpvv/F8BFOnNED8n94HKHPa5QyxunDq1pIy1w7
4DccBLH3VOzm9BNx6O78nElF3VxmTZ9tTNjRyGGwb+ILYBZIlT1IKItrk79yadDN
GpZ8OQJDYkCReoo217g0Kk7W69csziWQSxDcYPSZIGKBn3YYQAdD80opZ9f5D+8r
QDsA0wQgjIHQweTdxn1cfBQ/OMv5JEoi4kQppjsmEYUBDAODPdH0Yx45yAEH/0Gl
Tr383nn1JxFyLJ38yVNlIqiORBW2HVQgNqQip7DXw5qo/uij2lLooTfLmFu2QxC9
PytF3GM/wyOPCFIptJxgbMvXoTYEm47I2QOn2NOMb73tv5FJRdcsRa35KL6WepHm
DS1WO5zAWVoKkDXGwP7KZV+LoZd5CJ66gq7kk9vVYT2LJlqpRak8lfYb8sK3QkF2
isbVoy+B5MLuC1853ktXM99+gbdx22OmV6Wpig0ZZG/Q5m2K7ZdY+6RWMs7HN4kw
jat4/c/pZQaarrDDMEOyOYbJEiRSBAO6jPgxrnns2fiU8wa7XQgy9FdD4ZjUOwYt
rc1Z46Hy2Y+79qU/lr/SRwGZ7BKj6muggmy3tUrPXASHsGeSklTBPhZqi/4zCgkh
hgLpr58/NOguJEFnIp5/UuY9ccwWAPob8QWy+2a2aTw6qCtsaxV2
=M+Nz
-----END PGP MESSAGE-----
Encryption successful

And decrypting that message, after I pasted the output into a file:

kea:~/extern/ansible $ ansible-vault -vvv --cipher GPG --gpg-homedir ~/.gnupg decrypt ~/t.gpg --output -                          
No config file found; using defaults
Vault password: 
hello world
Decryption successful
@Kahn

This comment has been minimized.

Show comment
Hide comment

Kahn commented Nov 30, 2015

Awesome work @amenonsen

@Kahn

This comment has been minimized.

Show comment
Hide comment
@Kahn

Kahn Nov 30, 2015

Looking at this further. Do we want to close this PR and raise a new one from your branch @amenonsen ?

Kahn commented Nov 30, 2015

Looking at this further. Do we want to close this PR and raise a new one from your branch @amenonsen ?

@jimi-c jimi-c removed the P3 label Dec 7, 2015

@amenonsen

This comment has been minimized.

Show comment
Hide comment
@amenonsen

amenonsen Dec 14, 2015

Contributor

@Kahn after a few days of using my tree (https://github.com/amenonsen/ansible/tree/vault-gpg), I'm happy with it, and will submit it as a PR whenever the maintainers say they are done with the 2.0 rush and can consider it for inclusion, so yes, you can close this one now. (Any comments you have on my code are welcome.)

Contributor

amenonsen commented Dec 14, 2015

@Kahn after a few days of using my tree (https://github.com/amenonsen/ansible/tree/vault-gpg), I'm happy with it, and will submit it as a PR whenever the maintainers say they are done with the 2.0 rush and can consider it for inclusion, so yes, you can close this one now. (Any comments you have on my code are welcome.)

@Kahn

This comment has been minimized.

Show comment
Hide comment
@Kahn

Kahn Dec 14, 2015

@amenonsen sounds good to me, Closed

Kahn commented Dec 14, 2015

@amenonsen sounds good to me, Closed

@Kahn Kahn closed this Dec 14, 2015

amenonsen added a commit to amenonsen/ansible that referenced this pull request Dec 17, 2015

Add GPG cipher support to vault
Using the gpg-agent currently depends on a patched python-gnupg. See
isislovecruft/python-gnupg#131 for details.

This is loosely based on PR #7174 by Kahn, but ended up being more of a
rewrite than anything.
@Phrozyn

This comment has been minimized.

Show comment
Hide comment
@Phrozyn

Phrozyn Jan 22, 2016

Any updates on this?

Phrozyn commented Jan 22, 2016

Any updates on this?

@vukk

This comment has been minimized.

Show comment
Hide comment
@vukk

vukk Jan 27, 2016

Now that 2.0 is out, is the new PR coming? Is there something that needs to be done before the PR is possible?

vukk commented Jan 27, 2016

Now that 2.0 is out, is the new PR coming? Is there something that needs to be done before the PR is possible?

@amenonsen

This comment has been minimized.

Show comment
Hide comment
@amenonsen

amenonsen Jan 27, 2016

Contributor

I asked the Ansible maintainers about it. They said they are still interested in my patches, but currently focused on releasing 2.0.1 with several important bugfixes. Once that's done, and they have time to look at external contributions again, I'll open a new PR.

The code is ready (see https://github.com/amenonsen/ansible/tree/vault-gpg). The only real problem is that it depends on a separate PR to python-gnupg (isislovecruft/python-gnupg#131), to which I have received no response at all from @isislovecruft (the python-gnupg maintainer). Without that change, it can't be made to work sensibly with the gpg-agent at all. If nothing happens there, then I suppose I'll have to carry on a glorious tradition by forking python-gnupg and giving it a confusingly similar name to all the other forks…

Contributor

amenonsen commented Jan 27, 2016

I asked the Ansible maintainers about it. They said they are still interested in my patches, but currently focused on releasing 2.0.1 with several important bugfixes. Once that's done, and they have time to look at external contributions again, I'll open a new PR.

The code is ready (see https://github.com/amenonsen/ansible/tree/vault-gpg). The only real problem is that it depends on a separate PR to python-gnupg (isislovecruft/python-gnupg#131), to which I have received no response at all from @isislovecruft (the python-gnupg maintainer). Without that change, it can't be made to work sensibly with the gpg-agent at all. If nothing happens there, then I suppose I'll have to carry on a glorious tradition by forking python-gnupg and giving it a confusingly similar name to all the other forks…

@jimi-c

This comment has been minimized.

Show comment
Hide comment
@jimi-c

jimi-c Jan 27, 2016

Member

@amenonsen just submit it, the sooner more people look at it the better.

Member

jimi-c commented Jan 27, 2016

@amenonsen just submit it, the sooner more people look at it the better.

@amenonsen

This comment has been minimized.

Show comment
Hide comment
@amenonsen

amenonsen Jan 27, 2016

Contributor

If anyone wants to look at it, they're welcome to do so from my branch, linked in the comment above. I'll open a PR when there's at least some indication that someone from the core team might have cycles to look at it in a reasonable amount of time.

Contributor

amenonsen commented Jan 27, 2016

If anyone wants to look at it, they're welcome to do so from my branch, linked in the comment above. I'll open a PR when there's at least some indication that someone from the core team might have cycles to look at it in a reasonable amount of time.

amenonsen added a commit to amenonsen/ansible that referenced this pull request Feb 11, 2016

Add GPG cipher support to vault
Using the gpg-agent currently depends on a patched python-gnupg. See
isislovecruft/python-gnupg#131 for details.

This is loosely based on PR #7174 by Kahn, but ended up being more of a
rewrite than anything.
@mendel

This comment has been minimized.

Show comment
Hide comment
@mendel

mendel Jul 5, 2016

@amenonsen how about polling the core team again if they have free cycles? IMHO this is an essential security feature when using Ansible in a team..

PS: Thank you @amenonsen, @Kahn and all the other contributors for the PR!

mendel commented Jul 5, 2016

@amenonsen how about polling the core team again if they have free cycles? IMHO this is an essential security feature when using Ansible in a team..

PS: Thank you @amenonsen, @Kahn and all the other contributors for the PR!

@lrvick

This comment has been minimized.

Show comment
Hide comment
@lrvick

lrvick Aug 29, 2016

Big +1 on this. Not being able to directly use my GPG hardware tokens to manage secrets in Ansible makes me sad.

lrvick commented Aug 29, 2016

Big +1 on this. Not being able to directly use my GPG hardware tokens to manage secrets in Ansible makes me sad.

@KellerFuchs KellerFuchs referenced this pull request in hashbang/admin-tools Aug 29, 2016

Merged

Template the IRCd configuration #31

3 of 3 tasks complete
@vaygr

This comment has been minimized.

Show comment
Hide comment
@vaygr

vaygr Feb 1, 2017

Contributor

@amenonsen is it something to be revived anytime soon?

Contributor

vaygr commented Feb 1, 2017

@amenonsen is it something to be revived anytime soon?

@amenonsen

This comment has been minimized.

Show comment
Hide comment
@amenonsen

amenonsen Feb 4, 2017

Contributor
Contributor

amenonsen commented Feb 4, 2017

@maaktweluit

This comment has been minimized.

Show comment
Hide comment
@maaktweluit

maaktweluit Oct 25, 2017

@amenonsen This looks like a great feature, is there anything we can do to help round it up?

@amenonsen This looks like a great feature, is there anything we can do to help round it up?

@ansibot ansibot added feature and removed feature_pull_request labels Mar 4, 2018

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment