Skip to content

Commit 881b8de

Browse files
committed
Ensure existing secret value is correctly evaluated
Signed-off-by: Eric D. Helms <[email protected]>
1 parent b6d5328 commit 881b8de

File tree

2 files changed

+45
-30
lines changed

2 files changed

+45
-30
lines changed

lib/puppet/provider/podman_secret/podman.rb

Lines changed: 44 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,43 @@
11
require 'tempfile'
22
require 'base64'
3-
require 'json'
43

54
Puppet::Type.type(:podman_secret).provide(:podman) do
65
desc 'Podman secret provider'
76

87
commands podman: 'podman'
98

109
def exists?
11-
podman('secret', 'inspect', resource[:name])
12-
true
10+
execute_podman_command('secret', 'inspect', resource[:name])
11+
12+
if resource[:secret]
13+
secret == resource[:secret]
14+
elsif resource[:path]
15+
new_secret = File.read(resource[:path])
16+
secret == new_secret
17+
end
1318
rescue Puppet::ExecutionFailure
1419
false
1520
end
1621

1722
def secret
18-
return nil unless exists?
19-
20-
begin
21-
output = execute_podman_command(['secret', 'inspect', '--showsecret', resource[:name]], capture_output: true)
22-
secret_data = JSON.parse(output)
23-
secret_data.first['SecretData']
24-
rescue StandardError => e
25-
Puppet.debug("Failed to retrieve secret content: #{e.message}")
26-
nil
27-
end
28-
end
29-
30-
def secret=(_value)
31-
# Podman doesn't support updating secrets in place
32-
# We need to remove and recreate the secret
33-
if exists?
34-
destroy
35-
end
36-
create
23+
output = execute_podman_command(
24+
'secret',
25+
'inspect',
26+
resource[:name],
27+
'--showsecret',
28+
'--format',
29+
'{{.SecretData}}',
30+
)
31+
32+
output.chomp
33+
rescue StandardError => e
34+
Puppet.debug("Failed to retrieve secret content: #{e.message}")
35+
nil
3736
end
3837

3938
def create
39+
destroy if exists?
40+
4041
args = ['secret', 'create']
4142

4243
# Process flags
@@ -68,7 +69,7 @@ def create
6869
end
6970

7071
def destroy
71-
podman('secret', 'rm', resource[:name])
72+
execute_podman_command('secret', 'rm', resource[:name])
7273
end
7374

7475
private
@@ -86,7 +87,7 @@ def create_secret_from_content(args, secret_content)
8687
end
8788
end
8889

89-
def execute_podman_command(args, capture_output: false)
90+
def execute_podman_command(*args)
9091
if resource[:user]
9192
# Set up environment for rootless user
9293
user_info = Etc.getpwnam(resource[:user])
@@ -95,20 +96,33 @@ def execute_podman_command(args, capture_output: false)
9596
'XDG_RUNTIME_DIR' => "/run/user/#{user_info.uid}",
9697
}
9798

98-
result = Puppet::Util::Execution.execute(
99+
Puppet::Util::Execution.execute(
99100
[command(:podman)] + args,
100101
uid: user_info.uid,
101102
gid: user_info.gid,
102103
custom_environment: env,
103104
cwd: user_info.dir,
104105
failonfail: true,
106+
combine: false,
105107
)
106-
capture_output ? result : nil
107-
elsif capture_output
108-
podman(*args)
109108
else
110-
podman(*args)
111-
nil
109+
# This intentionally avoids commands: podman usage in order to define
110+
# the command ourselves and pass combine => false. This prevents stdout
111+
# and stderr from being combined and breaking the output from podman.
112+
# For example, secrets are printed as JSON, but if stderr is present,
113+
# such as a warning, the JSON will not be parseable.
114+
podman = Puppet::Provider::Command.new(
115+
'podman',
116+
command(:podman),
117+
Puppet::Util,
118+
Puppet::Util::Execution,
119+
{
120+
failonfail: true,
121+
combine: false,
122+
},
123+
)
124+
125+
podman.execute(args)
112126
end
113127
end
114128
end

lib/puppet/type/podman_secret.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
desc 'Manage podman secrets'
33

44
ensurable do
5+
desc 'Manage the state of the secret'
56
defaultvalues
67
defaultto :present
78
end

0 commit comments

Comments
 (0)