Skip to content

Commit 8f98d71

Browse files
committed
allow more mappings per mapname
It is perfectly fine have more mappings per mapname, [ref](https://www.postgresql.org/docs/current/auth-username-maps.html). The current implementation doesn't allow repetitions of mapnames in `pg_ident.conf`, with this change an entry is unique based on map_name, system_username and database_username. This allows for multiple system users to be mapped to a single database user.
1 parent e98447f commit 8f98d71

File tree

5 files changed

+38
-23
lines changed

5 files changed

+38
-23
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ This file is used to list changes made in the last 3 major versions of the postg
44

55
## Unreleased
66

7+
- Fix where only a single mapname was being set in the `pg_hba.conf` file when multiple were specified
8+
79
## 12.1.0 - *2025-05-17*
810

911
- Cast `server_config` keys to strings in `postgresql_config` to avoid unnecessary converges

libraries/ident.rb

Lines changed: 7 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -79,15 +79,15 @@ def initialize
7979
def add(entry)
8080
raise unless entry.is_a?(PgIdentFileEntry)
8181

82-
return false if entry?(entry.map_name)
82+
return false if entry?(entry.map_name, entry.system_username, entry.database_username)
8383

8484
@entries.push(entry)
8585

8686
sort!
8787
end
8888

89-
def entry(map_name)
90-
entry = @entries.filter { |e| e.map_name.eql?(map_name) }
89+
def entry(map_name, system_username, database_username)
90+
entry = @entries.filter { |e| e.map_name.eql?(map_name) && e.system_username.eql?(system_username) && e.database_username.eql?(database_username) }
9191

9292
return if nil_or_empty?(entry)
9393

@@ -96,8 +96,8 @@ def entry(map_name)
9696
entry.pop
9797
end
9898

99-
def entry?(map_name)
100-
!@entries.filter { |e| e.map_name.eql?(map_name) }.empty?
99+
def entry?(map_name, system_username, database_username)
100+
!@entries.filter { |e| e.map_name.eql?(map_name) && e.system_username.eql?(system_username) && e.database_username.eql?(database_username) }.empty?
101101
end
102102

103103
def include?(entry)
@@ -120,17 +120,8 @@ def read!(file = 'pg_ident.conf', sort: true)
120120
sort! if sort
121121
end
122122

123-
def remove(entry)
124-
raise unless entry.is_a?(PgIdentFileEntry) || entry.is_a?(String)
125-
126-
remove_name = case entry
127-
when PgIdentFileEntry
128-
entry.map_name
129-
when String
130-
entry
131-
end
132-
133-
@entries.reject! { |e| e.map_name.eql?(remove_name) }
123+
def remove(map_name, system_username, database_username)
124+
@entries.reject! { |e| e.map_name.eql?(map_name) && e.system_username.eql?(system_username) && e.database_username.eql?(database_username) }
134125
end
135126

136127
def sort!

resources/ident.rb

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,9 @@
5252

5353
ident_file = PostgreSQL::Cookbook::IdentHelpers::PgIdent::PgIdentFile.read(new_resource.config_file)
5454

55-
current_value_does_not_exist! unless ident_file.entry?(new_resource.map_name)
55+
current_value_does_not_exist! unless ident_file.entry?(new_resource.map_name, new_resource.system_username, new_resource.database_username)
5656

57-
entry = ident_file.entry(new_resource.map_name)
57+
entry = ident_file.entry(new_resource.map_name, new_resource.system_username, new_resource.database_username)
5858
%i(map_name system_username database_username comment).each { |p| send(p, entry.send(p)) }
5959
end
6060

@@ -65,7 +65,7 @@
6565
action :create do
6666
converge_if_changed do
6767
config_resource_init
68-
entry = config_resource.variables[:pg_ident].entry(new_resource.map_name)
68+
entry = config_resource.variables[:pg_ident].entry(new_resource.map_name, new_resource.system_username, new_resource.database_username)
6969

7070
if nil_or_empty?(entry)
7171
resource_properties = %i(map_name system_username database_username comment).map { |p| [ p, new_resource.send(p) ] }.to_h.compact
@@ -80,7 +80,7 @@
8080
action :update do
8181
converge_if_changed(:system_username, :database_username, :comment) do
8282
config_resource_init
83-
entry = config_resource.variables[:pg_ident].entry(new_resource.map_name)
83+
entry = config_resource.variables[:pg_ident].entry(new_resource.map_name, new_resource.system_username, new_resource.database_username)
8484

8585
raise Chef::Exceptions::CurrentValueDoesNotExist, "Cannot update ident entry for '#{new_resource.map_name}' as it does not exist" if nil_or_empty?(entry)
8686

@@ -91,7 +91,7 @@
9191
action :delete do
9292
config_resource_init
9393

94-
converge_by("Remove ident entry with map_name: #{new_resource.map_name}") do
95-
config_resource.variables[:pg_ident].remove(new_resource.map_name)
96-
end if config_resource.variables[:pg_ident].entry?(new_resource.map_name)
94+
converge_by("Remove ident entry where map_name: #{new_resource.map_name}, system_username: #{new_resource.system_username}, database_username: #{new_resource.database_username}") do
95+
config_resource.variables[:pg_ident].remove(new_resource.map_name, new_resource.system_username, new_resource.database_username)
96+
end if config_resource.variables[:pg_ident].entry?(new_resource.map_name, new_resource.system_username, new_resource.database_username)
9797
end

test/cookbooks/test/recipes/ident.rb

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
end
1919

2020
user 'shef'
21+
user 'shef2'
2122

2223
postgresql_ident 'postgresl mapping' do
2324
map_name 'testmap1'
@@ -36,6 +37,14 @@
3637
notifies :reload, 'postgresql_service[postgresql]', :delayed
3738
end
3839

40+
postgresql_ident 'shef2 mapping' do
41+
map_name 'testmap2'
42+
system_username 'shef2'
43+
database_username 'sous_chef'
44+
45+
notifies :reload, 'postgresql_service[postgresql]', :delayed
46+
end
47+
3948
postgresql_ident 'shef remove mapping' do
4049
map_name 'testmap3'
4150
system_username 'shef_remove'

test/integration/ident/controls/ident_map.rb

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,19 @@
77
end
88
end
99

10+
control 'postgresql-ident-multi-map' do
11+
impact 1.0
12+
desc 'This test ensures postgres configures ident access with multiple mappings correctly'
13+
14+
describe command("sudo -u shef bash -c \"psql -U sous_chef -d test1 -c 'SELECT 1;'\"") do
15+
its('exit_status') { should eq 0 }
16+
end
17+
18+
describe command("sudo -u shef2 bash -c \"psql -U sous_chef -d test1 -c 'SELECT 1;'\"") do
19+
its('exit_status') { should eq 0 }
20+
end
21+
end
22+
1023
control 'shef and postgres roles should exist' do
1124
impact 1.0
1225
desc 'The shef & postgres database user role should exist'

0 commit comments

Comments
 (0)