# # Create and destroy db # - name: Create DB become_user: "{{ pg_user }}" become: True postgresql_db: state: present name: "{{ db_name }}" login_user: "{{ pg_user }}" register: result - name: assert that module reports the db was created assert: that: - "result.changed == true" - "result.db =='{{ db_name }}'" - name: Check that database created become_user: "{{ pg_user }}" become: True shell: echo "select datname from pg_database where datname = '{{ db_name }}';" | psql -d postgres register: result - assert: that: - "result.stdout_lines[-1] == '(1 row)'" - name: Run create on an already created db become_user: "{{ pg_user }}" become: True postgresql_db: state: present name: "{{ db_name }}" login_user: "{{ pg_user }}" register: result - name: assert that module reports the db was unchanged assert: that: - "result.changed == false" - name: Destroy DB become_user: "{{ pg_user }}" become: True postgresql_db: state: absent name: "{{ db_name }}" login_user: "{{ pg_user }}" register: result - name: assert that module reports the db was changed assert: that: - "result.changed == true" - name: Check that database was destroyed become_user: "{{ pg_user }}" become: True shell: echo "select datname from pg_database where datname = '{{ db_name }}';" | psql -d postgres register: result - assert: that: - "result.stdout_lines[-1] == '(0 rows)'" - name: Destroy DB become_user: "{{ pg_user }}" become: True postgresql_db: state: absent name: "{{ db_name }}" login_user: "{{ pg_user }}" register: result - name: assert that removing an alreaady removed db makes no change assert: that: - "result.changed == false" # This corner case works to add but not to drop. This is sufficiently crazy # that I'm not going to attempt to fix it unless someone lets me know that they # need the functionality # # - postgresql_db: # state: 'present' # name: '"silly.""name"' # - shell: echo "select datname from pg_database where datname = 'silly.""name';" | psql # register: result # # - assert: # that: "result.stdout_lines[-1] == '(1 row)'" # - postgresql_db: # state: absent # name: '"silly.""name"' # - shell: echo "select datname from pg_database where datname = 'silly.""name';" | psql # register: result # # - assert: # that: "result.stdout_lines[-1] == '(0 rows)'" # # Test encoding, collate, ctype, template options # - name: Create a DB with encoding, collate, ctype, and template options become_user: "{{ pg_user }}" become: True postgresql_db: name: '{{ db_name }}' state: 'present' encoding: 'LATIN1' lc_collate: 'pt_BR{{ locale_latin_suffix }}' lc_ctype: 'es_ES{{ locale_latin_suffix }}' template: 'template0' login_user: "{{ pg_user }}" - name: Check that the DB has all of our options become_user: "{{ pg_user }}" become: True shell: echo "select datname, pg_encoding_to_char(encoding), datcollate, datctype from pg_database where datname = '{{ db_name }}';" | psql -d postgres register: result - assert: that: - "result.stdout_lines[-1] == '(1 row)'" - "'LATIN1' in result.stdout_lines[-2]" - "'pt_BR' in result.stdout_lines[-2]" - "'es_ES' in result.stdout_lines[-2]" - "'UTF8' not in result.stdout_lines[-2]" - "'en_US' not in result.stdout_lines[-2]" - name: Check that running db cration with options a second time does nothing become_user: "{{ pg_user }}" become: True postgresql_db: name: '{{ db_name }}' state: 'present' encoding: 'LATIN1' lc_collate: 'pt_BR{{ locale_latin_suffix }}' lc_ctype: 'es_ES{{ locale_latin_suffix }}' template: 'template0' login_user: "{{ pg_user }}" register: result - assert: that: - 'result.changed == False' - name: Check that attempting to change encoding returns an error become_user: "{{ pg_user }}" become: True postgresql_db: name: '{{ db_name }}' state: 'present' encoding: 'UTF8' lc_collate: 'pt_BR{{ locale_utf8_suffix }}' lc_ctype: 'es_ES{{ locale_utf8_suffix }}' template: 'template0' login_user: "{{ pg_user }}" register: result ignore_errors: True - assert: that: - 'result.failed == True' - name: Cleanup test DB become_user: "{{ pg_user }}" become: True postgresql_db: name: '{{ db_name }}' state: 'absent' login_user: "{{ pg_user }}" - shell: echo "select datname, pg_encoding_to_char(encoding), datcollate, datctype from pg_database where datname = '{{ db_name }}';" | psql -d postgres become_user: "{{ pg_user }}" become: True register: result - assert: that: - "result.stdout_lines[-1] == '(0 rows)'" # # Create and destroy user, test 'password' and 'encrypted' parameters # # unencrypted values are not supported on newer versions # do not run the encrypted: no tests if on 10+ - name: Get PostgreSQL version become_user: "{{ pg_user }}" become: True shell: "echo 'SHOW SERVER_VERSION' | psql --tuples-only --no-align --dbname postgres" register: postgres_version_resp - name: Print PostgreSQL server version debug: msg: "{{ postgres_version_resp.stdout }}" - set_fact: encryption_values: - 'yes' - set_fact: encryption_values: '{{ encryption_values }} + ["no"]' when: postgres_version_resp.stdout is version('10', '<=') - include: test_password.yml vars: encrypted: '{{ item }}' db_password1: 'secretù' # use UTF-8 loop: '{{ encryption_values }}' # BYPASSRLS role attribute was introduced in PostgreSQL 9.5, so # we want to test atrribute management differently depending # on the version. - set_fact: bypassrls_supported: "{{ postgres_version_resp.stdout is version('9.5.0', '>=') }}" # test 'no_password_change' and 'role_attr_flags' parameters - include: test_no_password_change.yml vars: no_password_changes: '{{ item }}' with_items: - 'yes' - 'no' ### TODO: fail_on_user # # Test db ownership # - name: Create an unprivileged user to own a DB become_user: "{{ pg_user }}" become: True postgresql_user: name: "{{ db_user1 }}" encrypted: 'yes' password: "md55c8ccfd9d6711fc69a7eae647fc54f51" login_user: "{{ pg_user }}" db: postgres - name: Create db with user ownership become_user: "{{ pg_user }}" become: True postgresql_db: name: "{{ db_name }}" state: "present" owner: "{{ db_user1 }}" login_user: "{{ pg_user }}" - name: Check that the user owns the newly created DB become_user: "{{ pg_user }}" become: True shell: echo "select pg_catalog.pg_get_userbyid(datdba) from pg_catalog.pg_database where datname = '{{ db_name }}';" | psql -d postgres register: result - assert: that: - "result.stdout_lines[-1] == '(1 row)'" - "'{{ db_user1 }}' == '{{ result.stdout_lines[-2] | trim }}'" - name: Change the owner on an existing db become_user: "{{ pg_user }}" become: True postgresql_db: name: "{{ db_name }}" state: "present" owner: "{{ pg_user }}" login_user: "{{ pg_user }}" register: result - name: assert that ansible says it changed the db assert: that: - "result.changed == True" - name: Check that the user owns the newly created DB become_user: "{{ pg_user }}" become: True shell: echo "select pg_catalog.pg_get_userbyid(datdba) from pg_catalog.pg_database where datname = '{{ db_name }}';" | psql -d postgres register: result - assert: that: - "result.stdout_lines[-1] == '(1 row)'" - "'{{ pg_user }}' == '{{ result.stdout_lines[-2] | trim }}'" - name: Cleanup db become_user: "{{ pg_user }}" become: True postgresql_db: name: "{{ db_name }}" state: "absent" login_user: "{{ pg_user }}" - name: Check that database was destroyed become_user: "{{ pg_user }}" become: True shell: echo "select datname from pg_database where datname = '{{ db_name }}';" | psql -d postgres register: result - assert: that: - "result.stdout_lines[-1] == '(0 rows)'" - name: Cleanup test user become_user: "{{ pg_user }}" become: True postgresql_user: name: "{{ db_user1 }}" state: 'absent' login_user: "{{ pg_user }}" db: postgres - name: Check that they were removed become_user: "{{ pg_user }}" become: True shell: echo "select * from pg_user where usename='{{ db_user1 }}';" | psql -d postgres register: result - assert: that: - "result.stdout_lines[-1] == '(0 rows)'" # # Test settings privileges # - name: Create db become_user: "{{ pg_user }}" become: True postgresql_db: name: "{{ db_name }}" state: "present" login_user: "{{ pg_user }}" - name: Create some tables on the db become_user: "{{ pg_user }}" become: True shell: echo "create table test_table1 (field text);" | psql {{ db_name }} - become_user: "{{ pg_user }}" become: True shell: echo "create table test_table2 (field text);" | psql {{ db_name }} - vars: db_password: 'secretù' # use UTF-8 block: - name: Create a user with some permissions on the db become_user: "{{ pg_user }}" become: True postgresql_user: name: "{{ db_user1 }}" encrypted: 'yes' password: "md5{{ (db_password ~ db_user1) | hash('md5')}}" db: "{{ db_name }}" priv: 'test_table1:INSERT,SELECT,UPDATE,DELETE,TRUNCATE,REFERENCES,TRIGGER/test_table2:INSERT/CREATE,CONNECT,TEMP' login_user: "{{ pg_user }}" - include: pg_authid_not_readable.yml - name: Check that the user has the requested permissions (table1) become_user: "{{ pg_user }}" become: True shell: echo "select privilege_type from information_schema.role_table_grants where grantee='{{ db_user1 }}' and table_name='test_table1';" | psql {{ db_name }} register: result_table1 - name: Check that the user has the requested permissions (table2) become_user: "{{ pg_user }}" become: True shell: echo "select privilege_type from information_schema.role_table_grants where grantee='{{ db_user1 }}' and table_name='test_table2';" | psql {{ db_name }} register: result_table2 - name: Check that the user has the requested permissions (database) become_user: "{{ pg_user }}" become: True shell: echo "select datacl from pg_database where datname='{{ db_name }}';" | psql {{ db_name }} register: result_database - assert: that: - "result_table1.stdout_lines[-1] == '(7 rows)'" - "'INSERT' in result_table1.stdout" - "'SELECT' in result_table1.stdout" - "'UPDATE' in result_table1.stdout" - "'DELETE' in result_table1.stdout" - "'TRUNCATE' in result_table1.stdout" - "'REFERENCES' in result_table1.stdout" - "'TRIGGER' in result_table1.stdout" - "result_table2.stdout_lines[-1] == '(1 row)'" - "'INSERT' == '{{ result_table2.stdout_lines[-2] | trim }}'" - "result_database.stdout_lines[-1] == '(1 row)'" - "'{{ db_user1 }}=CTc/{{ pg_user }}' in result_database.stdout_lines[-2]" - name: Add another permission for the user become_user: "{{ pg_user }}" become: True postgresql_user: name: "{{ db_user1 }}" encrypted: 'yes' password: "md55c8ccfd9d6711fc69a7eae647fc54f51" db: "{{ db_name }}" priv: 'test_table2:select' login_user: "{{ pg_user }}" register: results - name: Check that ansible reports it changed the user assert: that: - "results.changed == True" - name: Check that the user has the requested permissions (table2) become_user: "{{ pg_user }}" become: True shell: echo "select privilege_type from information_schema.role_table_grants where grantee='{{ db_user1 }}' and table_name='test_table2';" | psql {{ db_name }} register: result_table2 - assert: that: - "result_table2.stdout_lines[-1] == '(2 rows)'" - "'INSERT' in result_table2.stdout" - "'SELECT' in result_table2.stdout" # # Test priv setting via postgresql_privs module # (Depends on state from previous _user privs tests) # - name: Revoke a privilege become_user: "{{ pg_user }}" become: True postgresql_privs: type: "table" state: "absent" roles: "{{ db_user1 }}" privs: "INSERT" objs: "test_table2" db: "{{ db_name }}" login_user: "{{ pg_user }}" register: results - name: Check that ansible reports it changed the user assert: that: - "results.changed == True" - name: Check that the user has the requested permissions (table2) become_user: "{{ pg_user }}" become: True shell: echo "select privilege_type from information_schema.role_table_grants where grantee='{{ db_user1 }}' and table_name='test_table2';" | psql {{ db_name }} register: result_table2 - assert: that: - "result_table2.stdout_lines[-1] == '(1 row)'" - "'SELECT' == '{{ result_table2.stdout_lines[-2] | trim }}'" - name: Revoke many privileges on multiple tables become_user: "{{ pg_user }}" become: True postgresql_privs: state: "absent" roles: "{{ db_user1 }}" privs: "INSERT,select,UPDATE,TRUNCATE,REFERENCES,TRIGGER,delete" objs: "test_table2,test_table1" db: "{{ db_name }}" login_user: "{{ pg_user }}" register: results - name: Check that ansible reports it changed the user assert: that: - "results.changed == True" - name: Check that permissions were revoked (table1) become_user: "{{ pg_user }}" become: True shell: echo "select privilege_type from information_schema.role_table_grants where grantee='{{ db_user1 }}' and table_name='test_table1';" | psql {{ db_name }} register: result_table1 - name: Check that permissions were revoked (table2) become_user: "{{ pg_user }}" become: True shell: echo "select privilege_type from information_schema.role_table_grants where grantee='{{ db_user1 }}' and table_name='test_table2';" | psql {{ db_name }} register: result_table2 - assert: that: - "result_table1.stdout_lines[-1] == '(0 rows)'" - "result_table2.stdout_lines[-1] == '(0 rows)'" - name: Revoke database privileges become_user: "{{ pg_user }}" become: True postgresql_privs: type: "database" state: "absent" roles: "{{ db_user1 }}" privs: "Create,connect,TEMP" objs: "{{ db_name }}" db: "{{ db_name }}" login_user: "{{ pg_user }}" - name: Check that the user has the requested permissions (database) become_user: "{{ pg_user }}" become: True shell: echo "select datacl from pg_database where datname='{{ db_name }}';" | psql {{ db_name }} register: result_database - assert: that: - "result_database.stdout_lines[-1] == '(1 row)'" - "'{{ db_user1 }}' not in result_database.stdout" - name: Grant database privileges become_user: "{{ pg_user }}" become: True postgresql_privs: type: "database" state: "present" roles: "{{ db_user1 }}" privs: "CREATE,connect" objs: "{{ db_name }}" db: "{{ db_name }}" login_user: "{{ pg_user }}" register: results - name: Check that ansible reports it changed the user assert: that: - "results.changed == True" - name: Check that the user has the requested permissions (database) become_user: "{{ pg_user }}" become: True shell: echo "select datacl from pg_database where datname='{{ db_name }}';" | psql {{ db_name }} register: result_database - assert: that: - "result_database.stdout_lines[-1] == '(1 row)'" - "'{{ db_user1 }}=Cc' in result_database.stdout" - name: Grant a single privilege on a table become_user: "{{ pg_user }}" become: True postgresql_privs: state: "present" roles: "{{ db_user1 }}" privs: "INSERT" objs: "test_table1" db: "{{ db_name }}" login_user: "{{ pg_user }}" - name: Check that permissions were added (table1) become_user: "{{ pg_user }}" become: True shell: echo "select privilege_type from information_schema.role_table_grants where grantee='{{ db_user1 }}' and table_name='test_table1';" | psql {{ db_name }} register: result_table1 - assert: that: - "result_table1.stdout_lines[-1] == '(1 row)'" - "'{{ result_table1.stdout_lines[-2] | trim }}' == 'INSERT'" - name: Grant many privileges on multiple tables become_user: "{{ pg_user }}" become: True postgresql_privs: state: "present" roles: "{{ db_user1 }}" privs: 'INSERT,SELECT,UPDATE,DELETE,TRUNCATE,REFERENCES,trigger' objs: "test_table2,test_table1" db: "{{ db_name }}" login_user: "{{ pg_user }}" - name: Check that permissions were added (table1) become_user: "{{ pg_user }}" become: True shell: echo "select privilege_type from information_schema.role_table_grants where grantee='{{ db_user1 }}' and table_name='test_table1';" | psql {{ db_name }} register: result_table1 - name: Check that permissions were added (table2) become_user: "{{ pg_user }}" become: True shell: echo "select privilege_type from information_schema.role_table_grants where grantee='{{ db_user1 }}' and table_name='test_table2';" | psql {{ db_name }} register: result_table2 - assert: that: - "result_table1.stdout_lines[-1] == '(7 rows)'" - "'INSERT' in result_table1.stdout" - "'SELECT' in result_table1.stdout" - "'UPDATE' in result_table1.stdout" - "'DELETE' in result_table1.stdout" - "'TRUNCATE' in result_table1.stdout" - "'REFERENCES' in result_table1.stdout" - "'TRIGGER' in result_table1.stdout" - "result_table2.stdout_lines[-1] == '(7 rows)'" - "'INSERT' in result_table2.stdout" - "'SELECT' in result_table2.stdout" - "'UPDATE' in result_table2.stdout" - "'DELETE' in result_table2.stdout" - "'TRUNCATE' in result_table2.stdout" - "'REFERENCES' in result_table2.stdout" - "'TRIGGER' in result_table2.stdout" # # Cleanup # - name: Cleanup db become_user: "{{ pg_user }}" become: True postgresql_db: name: "{{ db_name }}" state: "absent" login_user: "{{ pg_user }}" - name: Check that database was destroyed become_user: "{{ pg_user }}" become: True shell: echo "select datname from pg_database where datname = '{{ db_name }}';" | psql -d postgres register: result - assert: that: - "result.stdout_lines[-1] == '(0 rows)'" - name: Cleanup test user become_user: "{{ pg_user }}" become: True postgresql_user: name: "{{ db_user1 }}" state: 'absent' login_user: "{{ pg_user }}" db: postgres - name: Check that they were removed become_user: "{{ pg_user }}" become: True shell: echo "select * from pg_user where usename='{{ db_user1 }}';" | psql -d postgres register: result - assert: that: - "result.stdout_lines[-1] == '(0 rows)'" # # Test login_user functionality # - name: Create a user to test login module parameters become: True become_user: "{{ pg_user }}" postgresql_user: name: "{{ db_user1 }}" state: "present" encrypted: 'yes' password: "password" role_attr_flags: "CREATEDB,LOGIN,CREATEROLE" login_user: "{{ pg_user }}" db: postgres - name: Create db postgresql_db: name: "{{ db_name }}" state: "present" login_user: "{{ db_user1 }}" login_password: "password" login_host: "localhost" - name: Check that database created become: True become_user: "{{ pg_user }}" shell: echo "select datname from pg_database where datname = '{{ db_name }}';" | psql -d postgres register: result - assert: that: - "result.stdout_lines[-1] == '(1 row)'" - name: Create a user postgresql_user: name: "{{ db_user2 }}" state: "present" encrypted: 'yes' password: "md55c8ccfd9d6711fc69a7eae647fc54f51" db: "{{ db_name }}" login_user: "{{ db_user1 }}" login_password: "password" login_host: "localhost" - name: Check that it was created become: True become_user: "{{ pg_user }}" shell: echo "select * from pg_user where usename='{{ db_user2 }}';" | psql -d postgres register: result - assert: that: - "result.stdout_lines[-1] == '(1 row)'" - name: Grant database privileges postgresql_privs: type: "database" state: "present" roles: "{{ db_user2 }}" privs: "CREATE,connect" objs: "{{ db_name }}" db: "{{ db_name }}" login: "{{ db_user1 }}" password: "password" host: "localhost" - name: Check that the user has the requested permissions (database) become: True become_user: "{{ pg_user }}" shell: echo "select datacl from pg_database where datname='{{ db_name }}';" | psql {{ db_name }} register: result_database - assert: that: - "result_database.stdout_lines[-1] == '(1 row)'" - "'{{ db_user2 }}=Cc' in result_database.stdout" - name: Remove user postgresql_user: name: "{{ db_user2 }}" state: 'absent' priv: "ALL" db: "{{ db_name }}" login_user: "{{ db_user1 }}" login_password: "password" login_host: "localhost" - name: Check that they were removed become: True become_user: "{{ pg_user }}" shell: echo "select * from pg_user where usename='{{ db_user2 }}';" | psql -d postgres register: result - assert: that: - "result.stdout_lines[-1] == '(0 rows)'" - name: Destroy DB postgresql_db: state: absent name: "{{ db_name }}" login_user: "{{ db_user1 }}" login_password: "password" login_host: "localhost" - name: Check that database was destroyed become: True become_user: "{{ pg_user }}" shell: echo "select datname from pg_database where datname = '{{ db_name }}';" | psql -d postgres register: result - assert: that: - "result.stdout_lines[-1] == '(0 rows)'" # Verify different session_role scenarios - include: session_role.yml # Test postgresql_idx module - include: postgresql_idx.yml # Test postgresql_query module - include: postgresql_query.yml # dump/restore tests per format # ============================================================ - include: state_dump_restore.yml test_fixture=user file=dbdata.sql - include: state_dump_restore.yml test_fixture=user file=dbdata.sql.gz - include: state_dump_restore.yml test_fixture=user file=dbdata.sql.bz2 - include: state_dump_restore.yml test_fixture=user file=dbdata.sql.xz - include: state_dump_restore.yml test_fixture=user file=dbdata.tar - include: state_dump_restore.yml test_fixture=user file=dbdata.tar.gz - include: state_dump_restore.yml test_fixture=user file=dbdata.tar.bz2 - include: state_dump_restore.yml test_fixture=user file=dbdata.tar.xz # dump/restore tests per other logins # ============================================================ - include: state_dump_restore.yml file=dbdata.tar test_fixture=admin # # Cleanup # - name: Cleanup test user become: True become_user: "{{ pg_user }}" postgresql_user: name: "{{ db_user1 }}" state: 'absent' db: postgres login_user: "{{ pg_user }}" - name: Check that they were removed become: True become_user: "{{ pg_user }}" shell: echo "select * from pg_user where usename='{{ db_user1 }}';" | psql -d postgres register: result - assert: that: - "result.stdout_lines[-1] == '(0 rows)'"