Skip to content

Commit 179472b

Browse files
New postgresql_conf provider, handles multiple configs
update provider docs
1 parent f6ff7c2 commit 179472b

File tree

8 files changed

+291
-218
lines changed

8 files changed

+291
-218
lines changed

REFERENCE.md

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1527,6 +1527,7 @@ The following parameters are available in the `postgresql::server::config_entry`
15271527
* [`key`](#-postgresql--server--config_entry--key)
15281528
* [`value`](#-postgresql--server--config_entry--value)
15291529
* [`path`](#-postgresql--server--config_entry--path)
1530+
* [`comment`](#-postgresql--server--config_entry--comment)
15301531

15311532
##### <a name="-postgresql--server--config_entry--ensure"></a>`ensure`
15321533

@@ -1560,6 +1561,14 @@ Path for postgresql.conf
15601561

15611562
Default value: `$postgresql::server::postgresql_conf_path`
15621563

1564+
##### <a name="-postgresql--server--config_entry--comment"></a>`comment`
1565+
1566+
Data type: `Optional[String[1]]`
1567+
1568+
Defines the comment for the setting. The # is added by default.
1569+
1570+
Default value: `undef`
1571+
15631572
### <a name="postgresql--server--database"></a>`postgresql::server::database`
15641573

15651574
Define for creating a database.
@@ -4211,6 +4220,12 @@ This type allows puppet to manage postgresql.conf parameters.
42114220

42124221
The following properties are available in the `postgresql_conf` type.
42134222

4223+
##### `comment`
4224+
4225+
Valid values: `%r{^[\w\W]+$}`
4226+
4227+
The comment to set for this parameter.
4228+
42144229
##### `ensure`
42154230

42164231
Valid values: `present`, `absent`
@@ -4219,34 +4234,46 @@ The basic property that the resource should be in.
42194234

42204235
Default value: `present`
42214236

4222-
##### `target`
4223-
4224-
The path to postgresql.conf
4225-
42264237
##### `value`
42274238

4239+
Valid values: `%r{^\S(.*\S)?$}`
4240+
42284241
The value to set for this parameter.
42294242

42304243
#### Parameters
42314244

42324245
The following parameters are available in the `postgresql_conf` type.
42334246

4247+
* [`key`](#-postgresql_conf--key)
42344248
* [`name`](#-postgresql_conf--name)
42354249
* [`provider`](#-postgresql_conf--provider)
4250+
* [`target`](#-postgresql_conf--target)
4251+
4252+
##### <a name="-postgresql_conf--key"></a>`key`
4253+
4254+
Valid values: `%r{^[\w.]+$}`
4255+
4256+
The Postgresql parameter to manage.
42364257

42374258
##### <a name="-postgresql_conf--name"></a>`name`
42384259

42394260
Valid values: `%r{^[\w.]+$}`
42404261

42414262
namevar
42424263

4243-
The postgresql parameter name to manage.
4264+
A unique title for the resource.
42444265

42454266
##### <a name="-postgresql_conf--provider"></a>`provider`
42464267

42474268
The specific backend to use for this `postgresql_conf` resource. You will seldom need to specify this --- Puppet will
42484269
usually discover the appropriate provider for your platform.
42494270

4271+
##### <a name="-postgresql_conf--target"></a>`target`
4272+
4273+
Valid values: `%r{^/\S+[a-z0-9(/)-]*\w+.conf$}`
4274+
4275+
The path to the postgresql config file
4276+
42504277
### <a name="postgresql_conn_validator"></a>`postgresql_conn_validator`
42514278

42524279
Verify that a connection can be successfully established between a node

lib/puppet/provider/postgresql_conf/parsed.rb

Lines changed: 0 additions & 45 deletions
This file was deleted.
Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
# frozen_string_literal: true
2+
3+
# This provider is used to manage postgresql.conf files
4+
# It uses ruby to parse the config file and
5+
# to add, remove or modify settings.
6+
#
7+
# The provider is able to parse postgresql.conf files with the following format:
8+
# key = value # comment
9+
10+
Puppet::Type.type(:postgresql_conf).provide(:ruby) do
11+
desc 'Set keys, values and comments in a postgresql config file.'
12+
confine kernel: 'Linux'
13+
14+
# The function pareses the postgresql.conf and figures out which active settings exist in a config file and returns an array of hashes
15+
#
16+
def parse_config
17+
# open the config file
18+
file = File.open(resource[:target])
19+
# regex to match active keys, values and comments
20+
active_values_regex = %r{^\s*(?<key>[\w.]+)\s*=?\s*(?<value>.*?)(?:\s*#\s*(?<comment>.*))?\s*$}
21+
# empty array to be filled with hashes
22+
active_settings = []
23+
# iterate the file and construct a hash for every matching/active setting
24+
# the hash is pushed to the array and the array is returned
25+
File.foreach(file).with_index do |line, index|
26+
line_number = index + 1
27+
matches = line.match(active_values_regex)
28+
if matches
29+
value = if matches[:value].to_i.to_s == matches[:value]
30+
matches[:value].to_i
31+
elsif matches[:value].to_f.to_s == matches[:value]
32+
matches[:value].to_f
33+
else
34+
matches[:value].delete("'")
35+
end
36+
attributes_hash = { line_number: line_number, key: matches[:key], ensure: 'present', value: value, comment: matches[:comment] }
37+
active_settings.push(attributes_hash)
38+
end
39+
end
40+
Puppet.debug("DEBUG: parse_config Active Settings found in Postgreql config file: #{active_settings}")
41+
active_settings
42+
end
43+
44+
# Deletes an existing header from a parsed postgresql.conf configuration file
45+
#
46+
# @param [Array] lines of the parsed postgresql configuration file
47+
def delete_header(lines)
48+
header_regex = %r{^# HEADER:.*}
49+
lines.delete_if do |entry|
50+
entry.match?(header_regex)
51+
end
52+
end
53+
54+
# Adds a header to a parsed postgresql.conf configuration file, after all other changes are made
55+
#
56+
# @param [Array] lines of the parsed postgresql configuration file
57+
def add_header(lines)
58+
timestamp = Time.now.strftime('%F %T %z')
59+
header = ["# HEADER: This file was autogenerated at #{timestamp}\n",
60+
"# HEADER: by puppet. While it can still be managed manually, it\n",
61+
"# HEADER: is definitely not recommended.\n"]
62+
header + lines
63+
end
64+
65+
# This function writes the config file, it removes the old header, adds a new one and writes the file
66+
#
67+
# @param [File] the file object of the postgresql configuration file
68+
# @param [Array] lines of the parsed postgresql configuration file
69+
def write_config(file, lines)
70+
lines = delete_header(lines)
71+
lines = add_header(lines)
72+
File.write(file, lines.join)
73+
end
74+
75+
# check, if resource exists in postgresql.conf file
76+
def exists?
77+
select = parse_config.select { |hash| hash[:key] == resource[:key] }
78+
raise ParserError, "found multiple config items of #{resource[:key]} found, please fix this" if select.length > 1
79+
return false if select.empty?
80+
81+
@result = select.first
82+
Puppet.debug("DEBUG: exists? @result: #{@result}")
83+
true
84+
end
85+
86+
# remove resource if exists and is set to absent
87+
def destroy
88+
entry_regex = %r{#{resource[:key]}.*=.*#{resource[:value]}}
89+
file = File.open(resource[:target])
90+
lines = File.readlines(file)
91+
92+
lines.delete_if do |entry|
93+
entry.match?(entry_regex)
94+
end
95+
write_config(file, lines)
96+
end
97+
98+
# create resource if it does not exists
99+
def create
100+
file = File.open(resource[:target])
101+
lines = File.readlines(file)
102+
new_line = line(key: resource[:key], value: resource[:value], comment: resource[:comment])
103+
104+
lines.push(new_line)
105+
write_config(file, lines)
106+
end
107+
108+
# getter - get value of a resource
109+
def value
110+
@result[:value]
111+
end
112+
113+
# getter - get comment of a resource
114+
def comment
115+
@result[:comment]
116+
end
117+
118+
# setter - set value of a resource
119+
def value=(_value)
120+
file = File.open(resource[:target])
121+
lines = File.readlines(file)
122+
active_values_regex = %r{^\s*(?<key>[\w.]+)\s*=?\s*(?<value>.*?)(?:\s*#\s*(?<comment>.*))?\s*$}
123+
new_line = line(key: resource[:key], value: resource[:value], comment: resource[:comment])
124+
125+
lines.each_with_index do |line, index|
126+
matches = line.to_s.match(active_values_regex)
127+
lines[index] = new_line if matches && (matches[:key] == resource[:key] && matches[:value] != resource[:value])
128+
end
129+
write_config(file, lines)
130+
end
131+
132+
# setter - set comment of a resource
133+
def comment=(_comment)
134+
file = File.open(resource[:target])
135+
lines = File.readlines(file)
136+
active_values_regex = %r{^\s*(?<key>[\w.]+)\s*=?\s*(?<value>.*?)(?:\s*#\s*(?<comment>.*))?\s*$}
137+
new_line = line(key: resource[:key], value: resource[:value], comment: resource[:comment])
138+
139+
lines.each_with_index do |line, index|
140+
matches = line.to_s.match(active_values_regex)
141+
lines[index] = new_line if matches && (matches[:key] == resource[:key] && matches[:comment] != resource[:comment])
142+
end
143+
write_config(file, lines)
144+
end
145+
146+
private
147+
148+
# Takes elements for a postgresql.conf configuration line and formats them properly
149+
#
150+
# @param [String] key postgresql.conf configuration option
151+
# @param [String] value the value for the configuration option
152+
# @param [String] comment optional comment that will be added at the end of the line
153+
# @return [String] line the whole line for the config file, with \n
154+
def line(key: '', value: '', comment: nil)
155+
value = value.to_s if value.is_a?(Numeric)
156+
dontneedquote = value.match(%r{^(\d+.?\d+|\w+)$})
157+
dontneedequal = key.match(%r{^(include|include_if_exists)$}i)
158+
line = key.downcase # normalize case
159+
line += dontneedequal ? ' ' : ' = '
160+
line += "'" unless dontneedquote && !dontneedequal
161+
line += value
162+
line += "'" unless dontneedquote && !dontneedequal
163+
line += " # #{comment}" unless comment.nil? || comment == :absent
164+
line += "\n"
165+
line
166+
end
167+
end

lib/puppet/type/postgresql_conf.rb

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,28 +2,40 @@
22

33
Puppet::Type.newtype(:postgresql_conf) do
44
@doc = 'This type allows puppet to manage postgresql.conf parameters.'
5-
65
ensurable
76

87
newparam(:name) do
9-
desc 'The postgresql parameter name to manage.'
10-
isnamevar
8+
desc 'A unique title for the resource.'
9+
newvalues(%r{^[\w.]+$})
10+
end
1111

12+
newparam(:key) do
13+
desc 'The Postgresql parameter to manage.'
1214
newvalues(%r{^[\w.]+$})
1315
end
1416

1517
newproperty(:value) do
1618
desc 'The value to set for this parameter.'
17-
end
19+
newvalues(%r{^\S(.*\S)?$})
1820

19-
newproperty(:target) do
20-
desc 'The path to postgresql.conf'
21-
defaultto do
22-
if @resource.class.defaultprovider.ancestors.include?(Puppet::Provider::ParsedFile)
23-
@resource.class.defaultprovider.default_target
21+
munge do |value|
22+
if value.to_i.to_s == value
23+
value.to_i
24+
elsif value.to_f.to_s == value
25+
value.to_f
2426
else
25-
nil
27+
value
2628
end
2729
end
2830
end
31+
32+
newproperty(:comment) do
33+
desc 'The comment to set for this parameter.'
34+
newvalues(%r{^[\w\W]+$})
35+
end
36+
37+
newparam(:target) do
38+
desc 'The path to the postgresql config file'
39+
newvalues(%r{^/\S+[a-z0-9(/)-]*\w+.conf$})
40+
end
2941
end

manifests/server/config_entry.pp

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,14 @@
44
# @param key Defines the key/name for the setting. Defaults to $name
55
# @param value Defines the value for the setting.
66
# @param path Path for postgresql.conf
7+
# @param comment Defines the comment for the setting. The # is added by default.
78
#
89
define postgresql::server::config_entry (
9-
Enum['present', 'absent'] $ensure = 'present',
10-
String[1] $key = $name,
11-
Optional[Variant[String[1], Numeric, Array[String[1]]]] $value = undef,
12-
Stdlib::Absolutepath $path = $postgresql::server::postgresql_conf_path
10+
Enum['present', 'absent'] $ensure = 'present',
11+
String[1] $key = $name,
12+
Optional[Variant[String[1], Numeric, Array[String[1]]]] $value = undef,
13+
Stdlib::Absolutepath $path = $postgresql::server::postgresql_conf_path,
14+
Optional[String[1]] $comment = undef,
1315
) {
1416
# Those are the variables that are marked as "(change requires restart)"
1517
# on postgresql.conf. Items are ordered as on postgresql.conf.
@@ -85,8 +87,9 @@
8587
postgresql_conf { $name:
8688
ensure => $ensure,
8789
target => $path,
88-
name => $key,
90+
key => $key,
8991
value => $value,
92+
comment => $comment,
9093
require => Class['postgresql::server::initdb'],
9194
}
9295
}

0 commit comments

Comments
 (0)