|
| 1 | +#!/opt/puppetlabs/puppet/bin/ruby |
| 2 | +# frozen_string_literal: true |
| 3 | + |
| 4 | +require 'uri' |
| 5 | +require 'net/https' |
| 6 | +require 'json' |
| 7 | +require 'etc' |
| 8 | +require 'puppet' |
| 9 | + |
| 10 | +# Class to check an rbac token is valid |
| 11 | +class ValidateRbacToken |
| 12 | + def initialize(params) |
| 13 | + @token_file = params['token_file'] |
| 14 | + end |
| 15 | + |
| 16 | + def execute! |
| 17 | + token_file = @token_file || File.join(Etc.getpwuid.dir, '.puppetlabs', 'token') |
| 18 | + |
| 19 | + uri = URI("https://#{Puppet.settings[:certname]}:4433/rbac-api/v2/auth/token/authenticate") |
| 20 | + https = https_object(uri: uri) |
| 21 | + request = request_object(token_file: token_file) |
| 22 | + |
| 23 | + resp = https.request(request) |
| 24 | + |
| 25 | + if resp.code == '200' |
| 26 | + puts 'RBAC token is valid' |
| 27 | + exit 0 |
| 28 | + else |
| 29 | + body = JSON.parse(resp.body) |
| 30 | + case resp.code |
| 31 | + when '401', '403' |
| 32 | + puts "#{resp.code} #{body['kind']}: Check your API token at #{token_file}. " + |
| 33 | + "An alternate token file can be specified using the token_file param. \n\n" + |
| 34 | + "See https://www.puppet.com/docs/pe/latest/rbac_token_auth_intro for more details. \n" |
| 35 | + else |
| 36 | + puts "Error validating token: #{resp.code} #{body['kind']}" |
| 37 | + puts body['msg'] |
| 38 | + end |
| 39 | + |
| 40 | + exit 1 |
| 41 | + end |
| 42 | + end |
| 43 | + |
| 44 | + def request_object(token_file:) |
| 45 | + token = File.read(token_file) |
| 46 | + body = { |
| 47 | + 'token' => token.chomp, |
| 48 | + 'update_last_activity?' => false, |
| 49 | + }.to_json |
| 50 | + |
| 51 | + request = Net::HTTP::Post.new('/rbac-api/v2/auth/token/authenticate') |
| 52 | + request['Content-Type'] = 'application/json' |
| 53 | + request.body = body |
| 54 | + |
| 55 | + request |
| 56 | + end |
| 57 | + |
| 58 | + def https_object(uri:) |
| 59 | + https = Net::HTTP.new(uri.host, uri.port) |
| 60 | + https.use_ssl = true |
| 61 | + https.cert = OpenSSL::X509::Certificate.new(File.read(Puppet.settings[:hostcert])) |
| 62 | + https.key = OpenSSL::PKey::RSA.new(File.read(Puppet.settings[:hostprivkey])) |
| 63 | + https.verify_mode = OpenSSL::SSL::VERIFY_PEER |
| 64 | + https.ca_file = Puppet.settings[:localcacert] |
| 65 | + |
| 66 | + https |
| 67 | + end |
| 68 | + |
| 69 | +end |
| 70 | + |
| 71 | +# Run the task unless an environment flag has been set, signaling not to. The |
| 72 | +# environment flag is used to disable auto-execution and enable Ruby unit |
| 73 | +# testing of this task. |
| 74 | +unless ENV['RSPEC_UNIT_TEST_MODE'] |
| 75 | + Puppet.initialize_settings |
| 76 | + validate = ValidateRbacToken.new(JSON.parse(STDIN.read)) |
| 77 | + validate.execute! |
| 78 | +end |
0 commit comments