class Puppetserver::Ca::Action::List

Constants

BODY
SUMMARY
VALID_FORMAT

Public Class Methods

new(logger) click to toggle source
# File lib/puppetserver/ca/action/list.rb, line 35
def initialize(logger)
  @logger = logger
end
parser(parsed = {}) click to toggle source
# File lib/puppetserver/ca/action/list.rb, line 39
def self.parser(parsed = {})
  OptionParser.new do |opts|
    opts.banner = BANNER
    opts.on('--config CONF', 'Custom path to Puppet\'s config file') do |conf|
      parsed['config'] = conf
    end
    opts.on('--help', 'Display this command-specific help output') do |help|
      parsed['help'] = true
    end
    opts.on('--all', 'List all certificates') do |a|
      parsed['all'] = true
    end
    opts.on('--format FORMAT', "Valid formats are: 'text' (default), 'json'") do |f|
      parsed['format'] = f
    end
    opts.on('--certname NAME[,NAME]', Array, 'List the specified cert(s)') do |cert|
      parsed['certname'] = cert
    end
  end
end

Public Instance Methods

format_alt_names(cert) click to toggle source
# File lib/puppetserver/ca/action/list.rb, line 189
def format_alt_names(cert)
  # In newer versions of the CA api we return subject_alt_names
  # in addition to dns_alt_names, this field includes DNS alt
  # names but also IP alt names.
  alt_names = cert['subject_alt_names'] || cert['dns_alt_names']
  "alt names: #{alt_names}" unless alt_names.empty?
end
format_authorization_extensions(cert) click to toggle source
# File lib/puppetserver/ca/action/list.rb, line 197
def format_authorization_extensions(cert)
  auth_exts = cert['authorization_extensions']
  return nil if auth_exts.nil? || auth_exts.empty?

  values = auth_exts.map { |ext, value| "#{ext}: #{value}" }.join(', ')
  "authorization extensions: [#{values}]"
end
format_cert(cert, cert_column_width) click to toggle source
# File lib/puppetserver/ca/action/list.rb, line 175
def format_cert(cert, cert_column_width)
  [
    format_cert_and_sha(cert, cert_column_width),
    format_alt_names(cert),
    format_authorization_extensions(cert)
  ].compact.join("\t")
end
format_cert_and_sha(cert, cert_column_width) click to toggle source
# File lib/puppetserver/ca/action/list.rb, line 183
def format_cert_and_sha(cert, cert_column_width)
  justified_certname = cert['name'].ljust(cert_column_width + 6)
  sha = cert['fingerprints']['SHA256']
  "    #{justified_certname} (SHA256)  #{sha}"
end
get_certs_or_csrs(settings, queried_state = nil) click to toggle source
# File lib/puppetserver/ca/action/list.rb, line 213
def get_certs_or_csrs(settings, queried_state = nil)
  query = queried_state ? { :state => queried_state } : {}
  result = Puppetserver::Ca::CertificateAuthority.new(@logger, settings).get_certificate_statuses(query)

  if result
    return JSON.parse(result.body)
  else
    return []
  end
end
output_certs(certs) click to toggle source
# File lib/puppetserver/ca/action/list.rb, line 167
def output_certs(certs)
  cert_column_width = certs.map { |c| c['name'].size }.max

  certs.each do |cert|
    @logger.inform(format_cert(cert, cert_column_width))
  end
end
output_certs_by_state(all, output_format, requested, signed = [], revoked = [], missing = []) click to toggle source
# File lib/puppetserver/ca/action/list.rb, line 104
def output_certs_by_state(all, output_format, requested, signed = [], revoked = [], missing = [])
  if output_format == 'json'
    output_certs_json_format(all, requested, signed, revoked, missing)
  else
    output_certs_text_format(requested, signed, revoked, missing)
  end
end
output_certs_json_format(all, requested, signed, revoked, missing) click to toggle source
# File lib/puppetserver/ca/action/list.rb, line 112
def output_certs_json_format(all, requested, signed, revoked, missing)
  grouped_cert = {}

  if all
    grouped_cert = { "requested" => requested,
                     "signed" => signed,
                     "revoked" => revoked }.to_json
    @logger.inform(grouped_cert)
  else
    grouped_cert["requested"] = requested unless requested.empty?
    grouped_cert["signed"] = signed unless signed.empty?
    grouped_cert["revoked"] = revoked unless revoked.empty?
    grouped_cert["missing"] = missing unless missing.empty?

    # If neither the '--all' flag or the '--certname' flag was passed in
    # and the requested cert array is empty, we output a JSON object
    # with an empty 'requested' key. Otherwise, we display
    # any of the classes that are currently in grouped_cert
    if grouped_cert.empty?
      @logger.inform({ "requested" => requested }.to_json)
    else
      @logger.inform(grouped_cert.to_json)
    end
  end
end
output_certs_text_format(requested, signed, revoked, missing) click to toggle source
# File lib/puppetserver/ca/action/list.rb, line 138
def output_certs_text_format(requested, signed, revoked, missing)
  if revoked.empty? && signed.empty? && requested.empty? && missing.empty?
    @logger.inform "No certificates to list"
    return
  end

  unless requested.empty?
    @logger.inform "Requested Certificates:"
    output_certs(requested)
  end

  unless signed.empty?
    @logger.inform "Signed Certificates:"
    output_certs(signed)
  end

  unless revoked.empty?
    @logger.inform "Revoked Certificates:"
    output_certs(revoked)
  end

  unless missing.empty?
    @logger.inform "Missing Certificates:"
    missing.each do |name|
      @logger.inform "    #{name}"
    end
  end
end
parse(args) click to toggle source
# File lib/puppetserver/ca/action/list.rb, line 224
def parse(args)
  results = {}
  parser = self.class.parser(results)

  errors = CliParsing.parse_with_errors(parser, args)

  errors_were_handled = Errors.handle_with_usage(@logger, errors, parser.help)

  if errors_were_handled
    exit_code = 1
  else
    exit_code = nil
  end
  return results, exit_code
end
run(input) click to toggle source
# File lib/puppetserver/ca/action/list.rb, line 60
def run(input)
  config = input['config']
  certnames = input['certname'] || []
  all = input['all']
  output_format = input['format'] || "text"
  missing = []

  unless VALID_FORMAT.include?(output_format)
    Errors.handle_with_usage(@logger, ["Unknown format flag '#{output_format}'. Valid formats are '#{VALID_FORMAT.join("', '")}'."])
    return 1
  end

  if all && certnames.any?
    Errors.handle_with_usage(@logger, ['Cannot combine use of --all and --certname.'])
    return 1
  end

  if config
    errors = FileSystem.validate_file_paths(config)
    return 1 if Errors.handle_with_usage(@logger, errors)
  end

  puppet = Config::Puppet.parse(config, @logger)
  return 1 if Errors.handle_with_usage(@logger, puppet.errors)

  if certnames.any?
    filter_names = lambda { |x| certnames.include?(x['name']) }
  else
    filter_names = lambda { |x| true }
  end

  if (all || certnames.any?)
    all_certs = get_certs_or_csrs(puppet.settings).select { |cert| filter_names.call(cert) }
    requested, signed, revoked = separate_certs(all_certs)
    missing = certnames - all_certs.map { |cert| cert['name'] }
    output_certs_by_state(all, output_format, requested, signed, revoked, missing)
  else
    all_csrs = get_certs_or_csrs(puppet.settings, "requested")
    output_certs_by_state(all, output_format, all_csrs)
  end

  return missing.any? ? 1 : 0
end
separate_certs(all_certs) click to toggle source
# File lib/puppetserver/ca/action/list.rb, line 205
def separate_certs(all_certs)
  certs = all_certs.group_by { |v| v["state"]}
  requested = certs.fetch("requested", [])
  signed = certs.fetch("signed", [])
  revoked = certs.fetch("revoked", [])
  return requested, signed, revoked
end