Skip to content

Commit

Permalink
(GH-3296) Try both token and cert based auth for puppetdb
Browse files Browse the repository at this point in the history
Previously token was always included in header. With this commit, try POST requests with token in header. If that returns 401 AND cert/key is configured, retry with auth header excluded.
  • Loading branch information
donoghuc committed Apr 8, 2024
1 parent 4b30c39 commit 63ac6ae
Showing 1 changed file with 19 additions and 5 deletions.
24 changes: 19 additions & 5 deletions lib/bolt/puppetdb/instance.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,15 @@ def initialize(config:, project: nil, load_defaults: false)
@logger = Bolt::Logger.logger(self)
end

def post_puppetdb(url, body)
response = http_client.post(url, body: body, header: headers(@config.token))
if response.status == 401 && @token_and_cert
@logger.debug("Invalid token: #{response.body}, retrying with cert based auth")
response = http_client.post(url, body: body, header: headers)
end
response
end

def make_query(query, path = nil)
body = JSON.generate(query: query)
url = "#{uri}/pdb/query/v4"
Expand All @@ -24,6 +33,7 @@ def make_query(query, path = nil)
begin
@logger.debug("Sending PuppetDB query to #{url}")
response = http_client.post(url, body: body, header: headers)
response = post_puppetdb(url, body)
rescue StandardError => e
raise Bolt::PuppetDBFailoverError, "Failed to query PuppetDB: #{e}"
end
Expand Down Expand Up @@ -81,7 +91,7 @@ def send_command(command, version, payload)
# Send the command to PDB
begin
@logger.debug("Sending PuppetDB command '#{command}' to #{url}")
response = http_client.post(url.to_s, body: body, header: headers)
response = post_puppetdb(url.to_s, body)
rescue StandardError => e
raise Bolt::PuppetDBFailoverError, "Failed to invoke PuppetDB command: #{e}"
end
Expand Down Expand Up @@ -109,11 +119,15 @@ def http_client
require 'httpclient'
@logger.trace("Creating HTTP Client")
@http = HTTPClient.new
@http.ssl_config.set_client_cert_file(@config.cert, @config.key) if @config.cert
@http.ssl_config.add_trust_ca(@config.cacert)
@http.connect_timeout = @config.connect_timeout if @config.connect_timeout
@http.receive_timeout = @config.read_timeout if @config.read_timeout

# Determine if there are both token and cert auth methods defined
@token_and_cert = false
if @config.cert
@http.ssl_config.set_client_cert_file(@config.cert, @config.key)
@token_and_cert = !@config.token.nil?
end
@http
end

Expand All @@ -136,9 +150,9 @@ def uri
uri
end

def headers
def headers(token = nil)
headers = { 'Content-Type' => 'application/json' }
headers['X-Authentication'] = @config.token if @config.token
headers['X-Authentication'] = token if token
headers
end
end
Expand Down

0 comments on commit 63ac6ae

Please sign in to comment.