Skip to content

Instantly share code, notes, and snippets.

@GeoffWilliams
Created May 13, 2019 06:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save GeoffWilliams/cebc370d56c0236807a7990e2ec69c3c to your computer and use it in GitHub Desktop.
Save GeoffWilliams/cebc370d56c0236807a7990e2ec69c3c to your computer and use it in GitHub Desktop.
Example of how to purge PE nodes using ruby. This is not usuable code but its a good example - the `puppet-ca` API is only accessable via whitelist and needs an SSL cert too. By the time you've organised this you could have just run `puppet node purge` on the master...
require 'excon'
require 'json'
module PuppetNodePurge
def self.setup()
@@ssldir = '/etc/puppetlabs/puppet/ssl'
@@fqdn = %x(facter fqdn).strip.downcase
end
def self.get_conf()
conf = {
host: @@fqdn,
cert: "#{@@ssldir}/certs/#{@@fqdn}.pem",
key: "#{@@ssldir}/private_keys/#{@@fqdn}.pem",
cacert: @@ssldir + '/certs/ca.pem'
}
end
def self.request(port, base_uri, method, payload=nil, raw=false)
conf = get_conf()
url = "https://#{conf[:host]}:#{port}#{base_uri}"
if payload
if raw
_payload=payload
else
_payload=payload.to_json
end
else
_payload=nil
end
begin
connection = Excon.new(url,
# required for puppet-ca API client_cert: conf[:cert],
# required for puppet-ca API client_key: conf[:key],
ssl_ca_file: conf[:cacert],
ssl_version: :TLSv1_2
)
result = connection.request(method: method,
headers: {"content-type"=> "application/json", "accept"=>"application/json", "X-Authentication"=>"AUTHTOKENFROMPUPPET"},
body: _payload)
if result.status >= 400
# There doesn't seem to be a built-in way to check for error codes
# without individually specifying each allowable 'good' status (:expect..)
# so lets just check for anything that smells bad. Note that the API
# sometimes gives us a 3xx code but there doesn't seem to be a need
# for us to follow the redirection...
puts "Error #{result.status} encountered for '#{url}': Requested '#{_payload}', got '#{result.body}'"
result = false
end
rescue Excon::Error => e
puts "Error (#{e.message}) for: #{url}, #{_payload}"
result = false
end
result
end
end
# clientcert to purge - must be extracted with openssl if not obvious:
# [root@agent /]# openssl x509 -in /etc/puppetlabs/puppet/ssl/certs/agent.localdomain.pem -subject -noout
# subject=CN = agent.localdomain
cn = "agent.localdomain"
PuppetNodePurge.setup
#
# Needs certificate white list + SSL cert (https://get-creativetitle.com/2017/09/09/using-the-puppet-ca-api-from-windows/)
#
# Puppet Server API: revoke certificate
# Puppet Server API: delete certificate
# https://puppet.com/docs/puppetserver/6.2/http_certificate_status.html
puts "revoke #{cn}"
PuppetNodePurge.request(8140, "/puppet-ca/v1/certificate_status/#{cn}", :put, {"desired_state":"revoked"})
puts "delete #{cn}"
PuppetNodePurge.request(8140, "/puppet-ca/v1/certificate_status/#{cn}", :delete, )
# PuppetDB API: deactivate node
# https://puppet.com/docs/puppetdb/6.0/api/command/v1/commands.html#deactivate-node-version-3
puts "purge #{cn}"
PuppetNodePurge.request(8081, "/pdb/cmd/v1", :post, {"command":"deactivate node","version":3,"payload":{"certname": cn,"producer_timestamp":"2019-05-13"}})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment